diff options
Diffstat (limited to 'src')
150 files changed, 4320 insertions, 3180 deletions
diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp index 678e24c4682..6299ae802a7 100644 --- a/src/server/bnetserver/Main.cpp +++ b/src/server/bnetserver/Main.cpp @@ -57,8 +57,8 @@ void SignalHandler(const boost::system::error_code& error, int signalNumber); void KeepDatabaseAliveHandler(const boost::system::error_code& error); variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile); -boost::asio::io_service _ioService; -boost::asio::deadline_timer _dbPingTimer(_ioService); +std::unique_ptr<boost::asio::io_service> _ioService; +std::unique_ptr<boost::asio::deadline_timer> _dbPingTimer; uint32 _dbPingInterval; LoginDatabaseWorkerPool LoginDatabase; @@ -109,8 +109,10 @@ int main(int argc, char** argv) sIpcContext->Initialize(); + _ioService.reset(new boost::asio::io_service()); + // Get the list of realms for the server - sRealmList->Initialize(_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 10), worldListenPort); + sRealmList->Initialize(*_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 10), worldListenPort); // Start the listening port (acceptor) for auth connections int32 bnport = sConfigMgr->GetIntDefault("BattlenetPort", 1119); @@ -123,10 +125,10 @@ int main(int argc, char** argv) std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0"); - sSessionMgr.StartNetwork(_ioService, bindIp, bnport); + sSessionMgr.StartNetwork(*_ioService, bindIp, bnport); // Set signal handlers - boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM); + boost::asio::signal_set signals(*_ioService, SIGINT, SIGTERM); #if PLATFORM == PLATFORM_WINDOWS signals.add(SIGBREAK); #endif @@ -137,14 +139,19 @@ int main(int argc, char** argv) // Enabled a timed callback for handling the database keep alive ping _dbPingInterval = sConfigMgr->GetIntDefault("MaxPingTime", 30); - _dbPingTimer.expires_from_now(boost::posix_time::minutes(_dbPingInterval)); - _dbPingTimer.async_wait(KeepDatabaseAliveHandler); + _dbPingTimer.reset(new boost::asio::deadline_timer(*_ioService)); + _dbPingTimer->expires_from_now(boost::posix_time::minutes(_dbPingInterval)); + _dbPingTimer->async_wait(KeepDatabaseAliveHandler); sComponentMgr->Load(); sModuleMgr->Load(); // Start the io service worker loop - _ioService.run(); + _ioService->run(); + + _dbPingTimer->cancel(); + + sSessionMgr.StopNetwork(); sIpcContext->Close(); @@ -153,6 +160,8 @@ int main(int argc, char** argv) // Close the Database Pool and library StopDB(); + _ioService.reset(); + TC_LOG_INFO("server.bnetserver", "Halting process..."); return 0; } @@ -186,7 +195,7 @@ void StopDB() void SignalHandler(const boost::system::error_code& error, int /*signalNumber*/) { if (!error) - _ioService.stop(); + _ioService->stop(); } void KeepDatabaseAliveHandler(const boost::system::error_code& error) @@ -196,8 +205,8 @@ void KeepDatabaseAliveHandler(const boost::system::error_code& error) TC_LOG_INFO("server.bnetserver", "Ping MySQL to keep connection alive"); LoginDatabase.KeepAlive(); - _dbPingTimer.expires_from_now(boost::posix_time::minutes(_dbPingInterval)); - _dbPingTimer.async_wait(KeepDatabaseAliveHandler); + _dbPingTimer->expires_from_now(boost::posix_time::minutes(_dbPingInterval)); + _dbPingTimer->async_wait(KeepDatabaseAliveHandler); } } diff --git a/src/server/bnetserver/Realms/RealmList.cpp b/src/server/bnetserver/Realms/RealmList.cpp index 0f1a2df807e..fe4bfe3425e 100644 --- a/src/server/bnetserver/Realms/RealmList.cpp +++ b/src/server/bnetserver/Realms/RealmList.cpp @@ -52,6 +52,7 @@ void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInte void RealmList::Close() { _worldListener->End(); + _updateTimer->cancel(); } template<typename FieldType> diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp index bb0a92740e0..9345f1b659c 100644 --- a/src/server/bnetserver/Server/Session.cpp +++ b/src/server/bnetserver/Server/Session.cpp @@ -36,8 +36,37 @@ Battlenet::Session::ModuleHandler const Battlenet::Session::ModuleHandlers[MODUL &Battlenet::Session::HandleResumeModule, }; -Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket)), _accountId(0), _accountName(), _locale(), - _os(), _build(0), _gameAccountId(0), _gameAccountName(), _accountSecurityLevel(SEC_PLAYER), I(), s(), v(), b(), B(), K(), +void Battlenet::AccountInfo::LoadResult(Field* fields) +{ + // ba.id, ba.email, ba.locked, ba.lock_country, ba.last_ip, ba.failed_logins, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, bab.unbandate = bab.bandate FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab WHERE email = ? + Id = fields[0].GetUInt32(); + Login = fields[1].GetString(); + IsLockedToIP = fields[2].GetBool(); + LockCountry = fields[3].GetString(); + LastIP = fields[4].GetString(); + FailedLogins = fields[5].GetUInt32(); + IsBanned = fields[6].GetUInt64() != 0; + IsPermanenetlyBanned = fields[7].GetUInt64() != 0; +} + +void Battlenet::GameAccountInfo::LoadResult(Field* fields) +{ + // a.id, a.username, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, ab.unbandate = ab.bandate, aa.gmlevel + Id = fields[0].GetUInt32(); + Name = fields[1].GetString(); + IsBanned = fields[2].GetUInt64() != 0; + IsPermanenetlyBanned = fields[3].GetUInt64() != 0; + SecurityLevel = AccountTypes(fields[4].GetUInt8()); + + std::size_t hashPos = Name.find('#'); + if (hashPos != std::string::npos) + DisplayName = std::string("WoW") + Name.substr(hashPos + 1); + else + DisplayName = Name; +} + +Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket)), _accountInfo(new AccountInfo()), _gameAccountInfo(nullptr), _locale(), + _os(), _build(0), _ipCountry(), I(), s(), v(), b(), B(), K(), _reconnectProof(), _crypt(), _authed(false), _subscribedToRealmListUpdates(false), _toonOnline(false) { static uint8 const N_Bytes[] = @@ -63,7 +92,9 @@ Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket)), _ Battlenet::Session::~Session() { - sSessionMgr.RemoveSession(this); + delete _accountInfo; + if (_authed) + sSessionMgr.RemoveSession(this); } void Battlenet::Session::_SetVSFields(std::string const& pstr) @@ -83,7 +114,7 @@ void Battlenet::Session::_SetVSFields(std::string const& pstr) PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_VS_FIELDS); stmt->setString(0, v.AsHexStr()); stmt->setString(1, s.AsHexStr()); - stmt->setString(2, _accountName); + stmt->setString(2, _accountInfo->Login); LoginDatabase.Execute(stmt); } @@ -95,18 +126,12 @@ void Battlenet::Session::LogUnhandledPacket(PacketHeader const& header) void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest3 const& logonRequest) { - // Verify that this IP is not in the ip_banned table - LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS)); - - std::string ip_address = GetRemoteIpAddress().to_string(); - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED); - stmt->setString(0, ip_address); - if (PreparedQueryResult result = LoginDatabase.Query(stmt)) + if (_queryCallback) { Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(LOGIN_BANNED); + logonResponse->SetAuthResult(AUTH_LOGON_TOO_FAST); AsyncWrite(logonResponse); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Banned ip '%s:%d' tries to login!", ip_address.c_str(), GetRemotePort()); + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log too quick after previous attempt!", GetClientInfo().c_str()); return; } @@ -170,15 +195,20 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest3 const& _build = component.Build; } - _accountName = logonRequest.Login; + std::string login = logonRequest.Login; _locale = logonRequest.Locale; _os = logonRequest.Platform; - Utf8ToUpperOnlyLatin(_accountName); - stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO); - stmt->setString(0, _accountName); + Utf8ToUpperOnlyLatin(login); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO); + stmt->setString(0, login); + + _queryCallback = std::bind(&Battlenet::Session::HandleLogonRequestCallback, this, std::placeholders::_1); + _queryFuture = LoginDatabase.AsyncQuery(stmt); +} - PreparedQueryResult result = LoginDatabase.Query(stmt); +void Battlenet::Session::HandleLogonRequestCallback(PreparedQueryResult result) +{ if (!result) { Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); @@ -189,15 +219,27 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest3 const& } Field* fields = result->Fetch(); + _accountInfo->LoadResult(fields); - _accountId = fields[1].GetUInt32(); + std::string pStr = fields[8].GetString(); + std::string databaseV = fields[9].GetString(); + std::string databaseS = fields[10].GetString(); + + _gameAccounts.resize(result->GetRowCount()); + uint32 i = 0; + do + { + _gameAccounts[i++].LoadResult(result->Fetch() + 11); + } while (result->NextRow()); + + std::string ip_address = GetRemoteIpAddress().to_string(); // If the IP is 'locked', check that the player comes indeed from the correct IP address - if (fields[2].GetUInt8() == 1) // if ip is locked + if (_accountInfo->IsLockedToIP) { - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountName.c_str(), fields[4].GetCString(), ip_address.c_str()); + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountInfo->Login.c_str(), _accountInfo->LastIP.c_str(), ip_address.c_str()); - if (strcmp(fields[4].GetCString(), ip_address.c_str()) != 0) + if (_accountInfo->LastIP != ip_address) { Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED); @@ -207,48 +249,31 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest3 const& } else { - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to ip", _accountName.c_str()); - std::string accountCountry = fields[3].GetString(); - if (accountCountry.empty() || accountCountry == "00") - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to country", _accountName.c_str()); - else if (!accountCountry.empty()) + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to ip", _accountInfo->Login.c_str()); + if (_accountInfo->LockCountry.empty() || _accountInfo->LockCountry == "00") + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to country", _accountInfo->Login.c_str()); + else if (!_accountInfo->LockCountry.empty() && !_ipCountry.empty()) { - uint32 ip = inet_addr(ip_address.c_str()); - EndianConvertReverse(ip); - - stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY); - stmt->setUInt32(0, ip); - if (PreparedQueryResult sessionCountryQuery = LoginDatabase.Query(stmt)) + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to country: '%s' Player country is '%s'", _accountInfo->Login.c_str(), _accountInfo->LockCountry.c_str(), _ipCountry.c_str()); + if (_ipCountry != _accountInfo->LockCountry) { - std::string loginCountry = (*sessionCountryQuery)[0].GetString(); - TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to country: '%s' Player country is '%s'", _accountName.c_str(), accountCountry.c_str(), loginCountry.c_str()); - if (loginCountry != accountCountry) - { - Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED); - AsyncWrite(logonResponse); - return; - } + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED); + AsyncWrite(logonResponse); + return; } } } - //set expired bans to inactive - LoginDatabase.DirectExecute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_EXPIRED_BANS)); - // If the account is banned, reject the logon attempt - stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACTIVE_ACCOUNT_BAN); - stmt->setUInt32(0, _accountId); - PreparedQueryResult banresult = LoginDatabase.Query(stmt); - if (banresult) + if (_accountInfo->IsBanned) { - Field* fields = banresult->Fetch(); - if (fields[0].GetUInt32() == fields[1].GetUInt32()) + if (_accountInfo->IsPermanenetlyBanned) { Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); logonResponse->SetAuthResult(LOGIN_BANNED); AsyncWrite(logonResponse); - TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str()); + TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountInfo->Login.c_str()); return; } else @@ -256,13 +281,13 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest3 const& Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); logonResponse->SetAuthResult(LOGIN_SUSPENDED); AsyncWrite(logonResponse); - TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str()); + TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountInfo->Login.c_str()); return; } } SHA256Hash sha; - sha.UpdateData(_accountName); + sha.UpdateData(_accountInfo->Login); sha.Finalize(); I.SetBinary(sha.GetDigest(), sha.GetLength()); @@ -270,11 +295,6 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest3 const& ModuleInfo* password = sModuleMgr->CreateModule(_os, "Password"); ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint"); - std::string pStr = fields[0].GetString(); - - std::string databaseV = fields[5].GetString(); - std::string databaseS = fields[6].GetString(); - if (databaseV.size() != size_t(BufferSizes::SRP_6_V) * 2 || databaseS.size() != size_t(BufferSizes::SRP_6_S) * 2) _SetVSFields(pStr); else @@ -311,18 +331,33 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest3 const& void Battlenet::Session::HandleResumeRequest(Authentication::ResumeRequest const& resumeRequest) { - _accountName = resumeRequest.Login; + if (_queryCallback) + { + Authentication::ResumeResponse* logonResponse = new Authentication::ResumeResponse(); + logonResponse->SetAuthResult(AUTH_LOGON_TOO_FAST); + AsyncWrite(logonResponse); + TC_LOG_DEBUG("session", "[Battlenet::ResumeRequest] %s attempted to log too quick after previous attempt!", GetClientInfo().c_str()); + return; + } + + std::string login = resumeRequest.Login; _locale = resumeRequest.Locale; _os = resumeRequest.Platform; auto baseComponent = std::find_if(resumeRequest.Components.begin(), resumeRequest.Components.end(), [](Component const& c) { return c.Program == "base"; }); if (baseComponent != resumeRequest.Components.end()) _build = baseComponent->Build; - Utf8ToUpperOnlyLatin(_accountName); + Utf8ToUpperOnlyLatin(login); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_RECONNECT_INFO); - stmt->setString(0, _accountName); + stmt->setString(0, login); stmt->setString(1, resumeRequest.GameAccountName); - PreparedQueryResult result = LoginDatabase.Query(stmt); + + _queryCallback = std::bind(&Battlenet::Session::HandleResumeRequestCallback, this, std::placeholders::_1); + _queryFuture = LoginDatabase.AsyncQuery(stmt); +} + +void Battlenet::Session::HandleResumeRequestCallback(PreparedQueryResult result) +{ if (!result) { Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse(); @@ -332,11 +367,12 @@ void Battlenet::Session::HandleResumeRequest(Authentication::ResumeRequest const } Field* fields = result->Fetch(); + _accountInfo->LoadResult(fields); + K.SetHexStr(fields[8].GetString().c_str()); - _accountId = fields[0].GetUInt32(); - K.SetHexStr(fields[1].GetString().c_str()); - _gameAccountId = fields[2].GetUInt32(); - _gameAccountName = resumeRequest.GameAccountName; + _gameAccounts.resize(1); + _gameAccountInfo = &_gameAccounts[0]; + _gameAccountInfo->LoadResult(fields + 9); ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint"); ModuleInfo* resume = sModuleMgr->CreateModule(_os, "Resume"); @@ -385,7 +421,6 @@ void Battlenet::Session::HandleProofResponse(Authentication::ProofResponse const } AsyncWrite(response); - return; } void Battlenet::Session::HandlePing(Connection::Ping const& /*ping*/) @@ -404,7 +439,7 @@ void Battlenet::Session::HandleLogoutRequest(Connection::LogoutRequest const& /* PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); stmt->setString(0, ""); stmt->setBool(1, false); - stmt->setUInt32(2, _accountId); + stmt->setUInt32(2, _accountInfo->Id); LoginDatabase.Execute(stmt); } @@ -414,19 +449,28 @@ void Battlenet::Session::HandleConnectionClosing(Connection::ConnectionClosing c void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& /*listSubscribeRequest*/) { - WoWRealm::ListSubscribeResponse* listSubscribeResponse = new WoWRealm::ListSubscribeResponse(); + if (_subscribedToRealmListUpdates || _queryCallback) + return; PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS); - stmt->setUInt32(0, _gameAccountId); + stmt->setUInt32(0, _gameAccountInfo->Id); + + _queryCallback = std::bind(&Battlenet::Session::HandleListSubscribeRequestCallback, this, std::placeholders::_1); + _queryFuture = LoginDatabase.AsyncQuery(stmt); +} + +void Battlenet::Session::HandleListSubscribeRequestCallback(PreparedQueryResult result) +{ + WoWRealm::ListSubscribeResponse* listSubscribeResponse = new WoWRealm::ListSubscribeResponse(); - if (PreparedQueryResult countResult = LoginDatabase.Query(stmt)) + if (result) { do { - Field* fields = countResult->Fetch(); + Field* fields = result->Fetch(); uint32 build = fields[4].GetUInt32(); listSubscribeResponse->CharacterCounts.push_back({ RealmId(fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32(), (_build != build ? build : 0)), fields[0].GetUInt8() }); - } while (countResult->NextRow()); + } while (result->NextRow()); } for (RealmList::RealmMap::value_type const& i : sRealmList->GetRealms()) @@ -474,7 +518,7 @@ void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& join memcpy(sessionKey + hmac.GetLength(), hmac2.GetDigest(), hmac2.GetLength()); LoginDatabase.DirectPExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = %u, failed_logins = 0, os = '%s' WHERE id = %u", - ByteArrayToHexStr(sessionKey, 40, true).c_str(), GetRemoteIpAddress().to_string().c_str(), GetLocaleByName(_locale), _os.c_str(), _gameAccountId); + ByteArrayToHexStr(sessionKey, 40, true).c_str(), GetRemoteIpAddress().to_string().c_str(), GetLocaleByName(_locale), _os.c_str(), _gameAccountInfo->Id); joinResponse->IPv4.emplace_back(realm->ExternalAddress, realm->Port); if (realm->ExternalAddress != realm->LocalAddress) @@ -573,10 +617,72 @@ void Battlenet::Session::ReadHandler() void Battlenet::Session::Start() { - TC_LOG_TRACE("session", "Accepted connection from %s", GetRemoteIpAddress().to_string().c_str()); + std::string ip_address = GetRemoteIpAddress().to_string(); + TC_LOG_TRACE("session", "Accepted connection from %s", ip_address.c_str()); + + if (_queryCallback) + { + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_LOGON_TOO_FAST); + AsyncWrite(logonResponse); + TC_LOG_DEBUG("session", "[Session::Start] %s attempted to log too quick after previous attempt!", GetClientInfo().c_str()); + return; + } + + // Verify that this IP is not in the ip_banned table + LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS)); + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_INFO); + stmt->setString(0, ip_address); + stmt->setUInt32(1, inet_addr(ip_address.c_str())); + + _queryCallback = std::bind(&Battlenet::Session::CheckIpCallback, this, std::placeholders::_1); + _queryFuture = LoginDatabase.AsyncQuery(stmt); +} + +void Battlenet::Session::CheckIpCallback(PreparedQueryResult result) +{ + if (result) + { + bool banned = false; + do + { + Field* fields = result->Fetch(); + if (fields[0].GetUInt64() != 0) + banned = true; + + if (!fields[1].GetString().empty()) + _ipCountry = fields[1].GetString(); + + } while (result->NextRow()); + + if (banned) + { + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_INTERNAL_ERROR); + AsyncWrite(logonResponse); + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Banned ip '%s:%d' tries to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort()); + return; + } + } + AsyncRead(); } +bool Battlenet::Session::Update() +{ + if (!BattlenetSocket::Update()) + return false; + + if (_queryFuture.valid() && _queryFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready) + { + _queryCallback(_queryFuture.get()); + _queryCallback = nullptr; + } + + return true; +} + void Battlenet::Session::AsyncWrite(ServerPacket* packet) { if (!IsOpen()) @@ -626,7 +732,6 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke return false; } - BigNumber A, clientM1, clientChallenge; A.SetBinary(dataStream->ReadBytes(128).get(), 128); clientM1.SetBinary(dataStream->ReadBytes(32).get(), 32); @@ -707,7 +812,7 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke if (memcmp(M1.AsByteArray().get(), clientM1.AsByteArray().get(), 32)) { PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_FAILED_LOGINS); - stmt->setString(0, _accountName); + stmt->setString(0, _accountInfo->Login); LoginDatabase.Execute(stmt); Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); @@ -717,14 +822,7 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke return false; } - uint64 numAccounts = 0; - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNTS); - stmt->setUInt32(0, _accountId); - PreparedQueryResult result = LoginDatabase.Query(stmt); - if (result) - numAccounts = result->GetRowCount(); - - if (!numAccounts) + if (_gameAccounts.empty()) { Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); logonResponse->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); @@ -733,10 +831,8 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke return false; } - Field* fields = result->Fetch(); - //set expired game account bans to inactive - LoginDatabase.DirectExecute(LoginDatabase.GetPreparedStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS)); + LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS)); BigNumber M; sha.Initialize(); @@ -761,26 +857,17 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest(); proofRequest->Modules.push_back(password); - if (numAccounts > 1) + if (_gameAccounts.size() > 1) { BitStream accounts; state = 0; accounts.WriteBytes(&state, 1); - accounts.Write(numAccounts, 8); - do + accounts.Write(_gameAccounts.size(), 8); + for (GameAccountInfo const& gameAccount : _gameAccounts) { - fields = result->Fetch(); - std::ostringstream name; - std::string originalName = fields[1].GetString(); - std::size_t hashPos = originalName.find('#'); - if (hashPos != std::string::npos) - name << "WoW" << originalName.substr(hashPos + 1); - else - name << originalName; - accounts.Write(2, 8); - accounts.WriteString(name.str(), 8); - } while (result->NextRow()); + accounts.WriteString(gameAccount.DisplayName, 8); + } ModuleInfo* selectGameAccount = sModuleMgr->CreateModule(_os, "SelectGameAccount"); selectGameAccount->DataSize = accounts.GetSize(); @@ -791,29 +878,28 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke } else { - if (fields[4].GetBool()) + _gameAccountInfo = &_gameAccounts[0]; + + if (_gameAccountInfo->IsBanned) { delete proofRequest; Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - if (fields[2].GetUInt32() == fields[3].GetUInt32()) + if (_gameAccountInfo->IsPermanenetlyBanned) { logonResponse->SetAuthResult(LOGIN_BANNED); - TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); + TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str()); } else { logonResponse->SetAuthResult(LOGIN_SUSPENDED); - TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); + TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str()); } ReplaceResponse(response, logonResponse); return false; } - _gameAccountId = fields[0].GetUInt32(); - _gameAccountName = fields[1].GetString(); - proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint")); _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT); } @@ -842,21 +928,16 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se return false; } - PreparedStatement* stmt; - if (account.substr(0, 3) != "WoW") - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT); - stmt->setString(0, account); - } - else + for (std::size_t i = 0; i < _gameAccounts.size(); ++i) { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT_UNNAMED); - stmt->setUInt8(0, atol(account.substr(3).c_str())); + if (_gameAccounts[i].DisplayName == account) + { + _gameAccountInfo = &_gameAccounts[i]; + break; + } } - stmt->setUInt32(1, _accountId); - PreparedQueryResult result = LoginDatabase.Query(stmt); - if (!result) + if (!_gameAccountInfo) { Authentication::LogonResponse* complete = new Authentication::LogonResponse(); complete->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); @@ -865,28 +946,24 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se return false; } - Field* fields = result->Fetch(); - if (fields[4].GetBool()) + if (_gameAccountInfo->IsBanned) { Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - if (fields[2].GetUInt32() == fields[3].GetUInt32()) + if (_gameAccountInfo->IsPermanenetlyBanned) { logonResponse->SetAuthResult(LOGIN_BANNED); - TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); + TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str()); } else { logonResponse->SetAuthResult(LOGIN_SUSPENDED); - TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); + TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str()); } ReplaceResponse(response, logonResponse); return false; } - _gameAccountId = fields[0].GetUInt32(); - _gameAccountName = fields[1].GetString(); - Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest(); proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint")); ReplaceResponse(response, proofRequest); @@ -898,29 +975,26 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response) { Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); - if (dataStream->Read<uint8>(8) == 1) + if (dataStream->Read<uint8>(8) == 1 && _accountInfo && _gameAccountInfo) { - logonResponse->AccountId = _accountId; - logonResponse->GameAccountName = _gameAccountName; + logonResponse->AccountId = _accountInfo->Id; + logonResponse->GameAccountName = _gameAccountInfo->Name; logonResponse->GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS_LOCK; - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_FAILED_LOGINS); - stmt->setUInt32(0, _accountId); - if (PreparedQueryResult failedLoginsResult = LoginDatabase.Query(stmt)) - logonResponse->FailedLogins = (*failedLoginsResult)[0].GetUInt32(); + logonResponse->FailedLogins = _accountInfo->FailedLogins; SQLTransaction trans = LoginDatabase.BeginTransaction(); - stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO); stmt->setString(0, GetRemoteIpAddress().to_string()); stmt->setUInt8(1, GetLocaleByName(_locale)); stmt->setString(2, _os); - stmt->setUInt32(3, _accountId); + stmt->setUInt32(3, _accountInfo->Id); trans->Append(stmt); stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); stmt->setString(0, K.AsHexStr()); stmt->setBool(1, true); - stmt->setUInt32(2, _accountId); + stmt->setUInt32(2, _accountInfo->Id); trans->Append(stmt); LoginDatabase.CommitTransaction(trans); @@ -980,7 +1054,7 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket* if (memcmp(proof.GetDigest(), clientProof.get(), serverPart.GetLength())) { PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_FAILED_LOGINS); - stmt->setString(0, _accountName); + stmt->setString(0, _accountInfo->Login); LoginDatabase.Execute(stmt); TC_LOG_DEBUG("session", "[Battlenet::Resume] %s attempted to reconnect with invalid password!", GetClientInfo().c_str()); @@ -993,7 +1067,7 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket* PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); stmt->setString(0, K.AsHexStr()); stmt->setBool(1, true); - stmt->setUInt32(2, _accountId); + stmt->setUInt32(2, _accountInfo->Id); LoginDatabase.Execute(stmt); HmacSha256 serverProof(64, newSessionKey); @@ -1058,7 +1132,7 @@ Battlenet::WoWRealm::ListUpdate* Battlenet::Session::BuildListUpdate(Realm const WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate(); listUpdate->Timezone = realm->Timezone; listUpdate->Population = realm->PopulationLevel; - listUpdate->Lock = (realm->AllowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; + listUpdate->Lock = (realm->AllowedSecurityLevel > _gameAccountInfo->SecurityLevel) ? 1 : 0; listUpdate->Type = realm->Type; listUpdate->Name = realm->Name; @@ -1080,11 +1154,11 @@ std::string Battlenet::Session::GetClientInfo() const { std::ostringstream stream; stream << '[' << GetRemoteIpAddress() << ':' << GetRemotePort(); - if (!_accountName.empty()) - stream << ", Account: " << _accountName; + if (_accountInfo && !_accountInfo->Login.empty()) + stream << ", Account: " << _accountInfo->Login; - if (!_gameAccountName.empty()) - stream << ", Game account: " << _gameAccountName; + if (_gameAccountInfo) + stream << ", Game account: " << _gameAccountInfo->Name; stream << ']'; diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h index 37dcb5ef4f1..91890f9becb 100644 --- a/src/server/bnetserver/Server/Session.h +++ b/src/server/bnetserver/Server/Session.h @@ -22,6 +22,7 @@ #include "BattlenetPacketCrypt.h" #include "Socket.h" #include "BigNumber.h" +#include "Callback.h" #include <memory> #include <boost/asio/ip/tcp.hpp> @@ -52,6 +53,32 @@ namespace Battlenet Read = 0x4000 }; + struct AccountInfo + { + void LoadResult(Field* fields); + + uint32 Id; + std::string Login; + bool IsLockedToIP; + std::string LockCountry; + std::string LastIP; + uint32 FailedLogins; + bool IsBanned; + bool IsPermanenetlyBanned; + }; + + struct GameAccountInfo + { + void LoadResult(Field* fields); + + uint32 Id; + std::string Name; + std::string DisplayName; + bool IsBanned; + bool IsPermanenetlyBanned; + AccountTypes SecurityLevel; + }; + class Session : public Socket<Session> { typedef Socket<Session> BattlenetSocket; @@ -85,11 +112,12 @@ namespace Battlenet void HandleGetStreamItemsRequest(Cache::GetStreamItemsRequest const& getStreamItemsRequest); void Start() override; + bool Update() override; void UpdateRealms(std::vector<Realm const*>& realms, std::vector<RealmId>& deletedRealms); - uint32 GetAccountId() const { return _accountId; } - uint32 GetGameAccountId() const { return _gameAccountId; } + uint32 GetAccountId() const { return _accountInfo->Id; } + uint32 GetGameAccountId() const { return _gameAccountInfo->Id; } bool IsToonOnline() const { return _toonOnline; } void SetToonOnline(bool online) { _toonOnline = online; } @@ -107,6 +135,11 @@ namespace Battlenet typedef bool(Session::*ModuleHandler)(BitStream* dataStream, ServerPacket** response); static ModuleHandler const ModuleHandlers[MODULE_COUNT]; + void CheckIpCallback(PreparedQueryResult result); + void HandleLogonRequestCallback(PreparedQueryResult result); + void HandleResumeRequestCallback(PreparedQueryResult result); + void HandleListSubscribeRequestCallback(PreparedQueryResult result); + bool HandlePasswordModule(BitStream* dataStream, ServerPacket** response); bool HandleSelectGameAccountModule(BitStream* dataStream, ServerPacket** response); bool HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response); @@ -116,14 +149,15 @@ namespace Battlenet WoWRealm::ListUpdate* BuildListUpdate(Realm const* realm) const; std::string GetClientInfo() const; - uint32 _accountId; - std::string _accountName; + AccountInfo* _accountInfo; + GameAccountInfo* _gameAccountInfo; // Points at selected game account (inside _gameAccounts) + std::vector<GameAccountInfo> _gameAccounts; + std::string _locale; std::string _os; uint32 _build; - uint32 _gameAccountId; - std::string _gameAccountName; - AccountTypes _accountSecurityLevel; + + std::string _ipCountry; BigNumber N; BigNumber g; @@ -145,6 +179,9 @@ namespace Battlenet bool _authed; bool _subscribedToRealmListUpdates; bool _toonOnline; + + PreparedQueryResultFuture _queryFuture; + std::function<void(PreparedQueryResult)> _queryCallback; }; } diff --git a/src/server/bnetserver/Server/SessionManager.cpp b/src/server/bnetserver/Server/SessionManager.cpp index b5d4f5e11cc..d56e1f92f06 100644 --- a/src/server/bnetserver/Server/SessionManager.cpp +++ b/src/server/bnetserver/Server/SessionManager.cpp @@ -56,6 +56,7 @@ void Battlenet::SessionManager::RemoveSession(Session* session) Battlenet::Session* Battlenet::SessionManager::GetSession(uint32 accountId, uint32 gameAccountId) const { + boost::shared_lock<boost::shared_mutex> lock(_sessionMutex); auto itr = _sessions.find({ accountId, gameAccountId }); if (itr != _sessions.end()) return itr->second; @@ -65,6 +66,7 @@ Battlenet::Session* Battlenet::SessionManager::GetSession(uint32 accountId, uint std::list<Battlenet::Session*> Battlenet::SessionManager::GetSessions(uint32 accountId) const { + boost::shared_lock<boost::shared_mutex> lock(_sessionMutex); std::list<Session*> sessions; auto itr = _sessionsByAccountId.find(accountId); if (itr != _sessionsByAccountId.end()) diff --git a/src/server/bnetserver/Server/SessionManager.h b/src/server/bnetserver/Server/SessionManager.h index 5f95616bf74..3944e7db510 100644 --- a/src/server/bnetserver/Server/SessionManager.h +++ b/src/server/bnetserver/Server/SessionManager.h @@ -40,7 +40,7 @@ namespace Battlenet #pragma pack(pop) - class SessionManager : SocketMgr<Session> + class SessionManager : public SocketMgr<Session> { typedef SocketMgr<Session> BaseSocketMgr; typedef std::map<SessionInfo, Session*> SessionMap; @@ -64,7 +64,7 @@ namespace Battlenet std::list<Session*> GetSessions(uint32 accountId) const; template<typename Iterator> - void LockedForEach(Iterator iterator) + void LockedForEach(Iterator iterator) const { boost::shared_lock<boost::shared_mutex> lock(_sessionMutex); for (SessionMap::value_type const& pair : _sessions) @@ -79,7 +79,7 @@ namespace Battlenet SessionMap _sessions; SessionByAccountMap _sessionsByAccountId; - boost::shared_mutex _sessionMutex; + mutable boost::shared_mutex _sessionMutex; }; } diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp index 2b4a23e3593..bb752fd9b49 100644 --- a/src/server/collision/Management/MMapManager.cpp +++ b/src/server/collision/Management/MMapManager.cpp @@ -163,13 +163,9 @@ namespace MMAP return true; } - else - { - TC_LOG_ERROR("maps", "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y); - dtFree(data); - return false; - } + TC_LOG_ERROR("maps", "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y); + dtFree(data); return false; } @@ -233,9 +229,9 @@ namespace MMAP for (uint32 i = 0; i < sMapStore.GetNumRows(); ++i) { - if (const MapEntry* const map = sMapStore.LookupEntry(i)) + if (MapEntry const* map = sMapStore.LookupEntry(i)) { - if (map->ParentMapID == mapId) + if (map->ParentMapID == int32(mapId)) { PhasedTile* data = LoadTile(map->ID, x, y); // only a few tiles have terrain swaps, do not write error for them @@ -534,7 +530,7 @@ namespace MMAP } } } - + if (!swaps.empty()) { // for each of the calling unit's terrain swaps diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index e700a8b1708..e913880ac77 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -568,10 +568,10 @@ enum RBACPermissions RBAC_PERM_COMMAND_RELOAD_LOCALES_GOSSIP_MENU_OPTION = 661, // UNUSED RBAC_PERM_COMMAND_RELOAD_LOCALES_ITEM_SET_NAME = 663, - RBAC_PERM_COMMAND_RELOAD_LOCALES_NPC_TEXT = 664, + RBAC_PERM_COMMAND_RELOAD_QUEST_GREETING = 664, RBAC_PERM_COMMAND_RELOAD_LOCALES_PAGE_TEXT = 665, RBAC_PERM_COMMAND_RELOAD_LOCALES_POINTS_OF_INTEREST = 666, - RBAC_PERM_COMMAND_RELOAD_LOCALES_QUEST = 667, + RBAC_PERM_COMMAND_RELOAD_QUEST_LOCALE = 667, RBAC_PERM_COMMAND_RELOAD_MAIL_LEVEL_REWARD = 668, RBAC_PERM_COMMAND_RELOAD_MAIL_LOOT_TEMPLATE = 669, RBAC_PERM_COMMAND_RELOAD_MILLING_LOOT_TEMPLATE = 670, @@ -596,7 +596,7 @@ enum RBACPermissions RBAC_PERM_COMMAND_RELOAD_SMART_SCRIPTS = 689, RBAC_PERM_COMMAND_RELOAD_SPELL_REQUIRED = 690, RBAC_PERM_COMMAND_RELOAD_SPELL_AREA = 691, - // REUSE + RBAC_PERM_COMMAND_DEBUG_SEND_PLAYSCENE = 692, RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP = 693, RBAC_PERM_COMMAND_RELOAD_SPELL_LEARN_SPELL = 694, RBAC_PERM_COMMAND_RELOAD_SPELL_LOOT_TEMPLATE = 695, diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 95ee38590d6..cfe93b0cde3 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -398,7 +398,7 @@ template<class T> AchievementMgr<T>::~AchievementMgr() { } template<class T> -void AchievementMgr<T>::SendPacket(WorldPacket const* data) const { } +void AchievementMgr<T>::SendPacket(WorldPacket const* /*data*/) const { } template<> void AchievementMgr<Guild>::SendPacket(WorldPacket const* data) const @@ -628,7 +628,7 @@ void AchievementMgr<Guild>::SaveToDB(SQLTransaction& trans) } } template<class T> -void AchievementMgr<T>::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult) +void AchievementMgr<T>::LoadFromDB(PreparedQueryResult /*achievementResult*/, PreparedQueryResult /*criteriaResult*/) { } @@ -1750,13 +1750,13 @@ void AchievementMgr<Player>::CompletedAchievement(AchievementEntry const* achiev std::string subject = reward->subject; std::string text = reward->text; - int locIdx = GetOwner()->GetSession()->GetSessionDbLocaleIndex(); - if (locIdx >= 0) + LocaleConstant localeConstant = GetOwner()->GetSession()->GetSessionDbLocaleIndex(); + if (localeConstant >= LOCALE_enUS) { if (AchievementRewardLocale const* loc = sAchievementMgr->GetAchievementRewardLocale(achievement)) { - ObjectMgr::GetLocaleString(loc->subject, locIdx, subject); - ObjectMgr::GetLocaleString(loc->text, locIdx, text); + ObjectMgr::GetLocaleString(loc->subject, localeConstant, subject); + ObjectMgr::GetLocaleString(loc->text, localeConstant, text); } } diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 6ea09711667..06fa47cd09d 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -87,8 +87,8 @@ uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 //does not clear ram void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& trans) { - Item* pItem = GetAItem(auction->itemGUIDLow); - if (!pItem) + Item* item = GetAItem(auction->itemGUIDLow); + if (!item) return; uint32 bidderAccId = 0; @@ -123,7 +123,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& uint32 ownerAccId = ObjectMgr::GetPlayerAccountIdByGUID(ownerGuid); sLog->outCommand(bidderAccId, "GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)", - bidderName.c_str(), bidderAccId, pItem->GetTemplate()->GetDefaultLocaleName(), pItem->GetEntry(), pItem->GetCount(), auction->bid, ownerName.c_str(), ownerAccId); + bidderName.c_str(), bidderAccId, item->GetTemplate()->GetDefaultLocaleName(), item->GetEntry(), item->GetCount(), auction->bid, ownerName.c_str(), ownerAccId); } // receiver exist @@ -133,18 +133,18 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& // owner in `data` will set at mail receive and item extracting PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_OWNER); stmt->setUInt64(0, auction->bidder); - stmt->setUInt64(1, pItem->GetGUID().GetCounter()); + stmt->setUInt64(1, item->GetGUID().GetCounter()); trans->Append(stmt); if (bidder) { - bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidderGuid, 0, 0, auction->itemEntry); + bidder->GetSession()->SendAuctionWonNotification(auction, item); // FIXME: for offline player need also bidder->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1); } MailDraft(auction->BuildAuctionMailSubject(AUCTION_WON), AuctionEntry::BuildAuctionMailBody(auction->owner, auction->bid, auction->buyout, 0, 0)) - .AddItem(pItem) + .AddItem(item) .SendMailTo(trans, MailReceiver(bidder, auction->bidder), auction, MAIL_CHECK_MASK_COPIED); } else @@ -171,18 +171,20 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry* auction, SQLTransa ObjectGuid owner_guid = ObjectGuid::Create<HighGuid::Player>(auction->owner); Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid); uint32 owner_accId = ObjectMgr::GetPlayerAccountIdByGUID(owner_guid); + Item* item = GetAItem(auction->itemGUIDLow); + // owner exist if (owner || owner_accId) { uint32 profit = auction->bid + auction->deposit - auction->GetAuctionCut(); //FIXME: what do if owner offline - if (owner) + if (owner && item) { owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS, profit); owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD, auction->bid); //send auction owner notification, bidder must be current! - owner->GetSession()->SendAuctionOwnerNotification(auction); + owner->GetSession()->SendAuctionClosedNotification(auction, (float)sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY), true, item); } MailDraft(auction->BuildAuctionMailSubject(AUCTION_SUCCESSFUL), AuctionEntry::BuildAuctionMailBody(auction->bidder, auction->bid, auction->buyout, auction->deposit, auction->GetAuctionCut())) @@ -195,8 +197,8 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry* auction, SQLTransa void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry* auction, SQLTransaction& trans) { //return an item in auction to its owner by mail - Item* pItem = GetAItem(auction->itemGUIDLow); - if (!pItem) + Item* item = GetAItem(auction->itemGUIDLow); + if (!item) return; ObjectGuid owner_guid = ObjectGuid::Create<HighGuid::Player>(auction->owner); @@ -206,10 +208,10 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry* auction, SQLTransacti if (owner || owner_accId) { if (owner) - owner->GetSession()->SendAuctionOwnerNotification(auction); + owner->GetSession()->SendAuctionClosedNotification(auction, 0.0f, false, item); MailDraft(auction->BuildAuctionMailSubject(AUCTION_EXPIRED), AuctionEntry::BuildAuctionMailBody(0, 0, auction->buyout, auction->deposit, 0)) - .AddItem(pItem) + .AddItem(item) .SendMailTo(trans, MailReceiver(owner, auction->owner), auction, MAIL_CHECK_MASK_COPIED, 0); } else @@ -220,7 +222,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry* auction, SQLTransacti } //this function sends mail to old bidder -void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 newPrice, Player* newBidder, SQLTransaction& trans) +void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 /*newPrice*/, Player* /*newBidder*/, SQLTransaction& trans) { ObjectGuid oldBidder_guid = ObjectGuid::Create<HighGuid::Player>(auction->bidder); Player* oldBidder = ObjectAccessor::FindConnectedPlayer(oldBidder_guid); @@ -229,11 +231,13 @@ void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 new if (!oldBidder) oldBidder_accId = ObjectMgr::GetPlayerAccountIdByGUID(oldBidder_guid); + Item* item = GetAItem(auction->itemGUIDLow); + // old bidder exist if (oldBidder || oldBidder_accId) { - if (oldBidder && newBidder) - oldBidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, newBidder->GetGUID(), newPrice, auction->GetAuctionOutBid(), auction->itemEntry); + if (oldBidder && item) + oldBidder->GetSession()->SendAuctionOutBidNotification(auction, item); MailDraft(auction->BuildAuctionMailSubject(AUCTION_OUTBIDDED), AuctionEntry::BuildAuctionMailBody(auction->owner, auction->bid, auction->buyout, auction->deposit, auction->GetAuctionCut())) .AddMoney(auction->bid) @@ -242,18 +246,16 @@ void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 new } //this function sends mail, when auction is cancelled to old bidder -void AuctionHouseMgr::SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans, Item* item) +void AuctionHouseMgr::SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans) { ObjectGuid bidder_guid = ObjectGuid::Create<HighGuid::Player>(auction->bidder); Player* bidder = ObjectAccessor::FindConnectedPlayer(bidder_guid); uint32 bidder_accId = 0; + if (!bidder) bidder_accId = ObjectMgr::GetPlayerAccountIdByGUID(bidder_guid); - if (bidder) - bidder->GetSession()->SendAuctionRemovedNotification(auction->Id, auction->itemEntry, item->GetItemRandomPropertyId()); - // bidder exist if (bidder || bidder_accId) MailDraft(auction->BuildAuctionMailSubject(AUCTION_CANCELLED_TO_BIDDER), AuctionEntry::BuildAuctionMailBody(auction->owner, auction->bid, auction->buyout, auction->deposit, 0)) @@ -452,7 +454,6 @@ void AuctionHouseObject::Update() if (AuctionsMap.empty()) return; - SQLTransaction trans = CharacterDatabase.BeginTransaction(); for (AuctionEntryMap::iterator it = AuctionsMap.begin(); it != AuctionsMap.end();) @@ -494,40 +495,35 @@ void AuctionHouseObject::Update() CharacterDatabase.CommitTransaction(trans); } -void AuctionHouseObject::BuildListBidderItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount) +void AuctionHouseObject::BuildListBidderItems(WorldPackets::AuctionHouse::AuctionListBidderItemsResult& packet, Player* player, uint32& totalcount) { for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr) { AuctionEntry* Aentry = itr->second; if (Aentry && Aentry->bidder == player->GetGUID().GetCounter()) { - if (itr->second->BuildAuctionInfo(data)) - ++count; - + itr->second->BuildAuctionInfo(packet.Items, false); ++totalcount; } } } -void AuctionHouseObject::BuildListOwnerItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount) +void AuctionHouseObject::BuildListOwnerItems(WorldPackets::AuctionHouse::AuctionListOwnerItemsResult& packet, Player* player, uint32& totalcount) { for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr) { AuctionEntry* Aentry = itr->second; if (Aentry && Aentry->owner == player->GetGUID().GetCounter()) { - if (Aentry->BuildAuctionInfo(data)) - ++count; - + Aentry->BuildAuctionInfo(packet.Items, false); ++totalcount; } } } -void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player, +void AuctionHouseObject::BuildListAuctionItems(WorldPackets::AuctionHouse::AuctionListItemsResult& packet, Player* player, std::wstring const& wsearchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, uint8 usable, - uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, - uint32& count, uint32& totalcount) + uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32& totalcount) { time_t curTime = sWorld->GetGameTime(); @@ -612,48 +608,53 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player } // Add the item if no search term or if entered search term was found - if (count < 50 && totalcount >= listfrom) - { - ++count; - Aentry->BuildAuctionInfo(data); - } + if (packet.Items.size() < 50 && totalcount >= listfrom) + Aentry->BuildAuctionInfo(packet.Items, true); + ++totalcount; } } //this function inserts to WorldPacket auction's data -bool AuctionEntry::BuildAuctionInfo(WorldPacket& data) const +void AuctionEntry::BuildAuctionInfo(std::vector<WorldPackets::AuctionHouse::AuctionItem>& items, bool listAuctionItems) const { Item* item = sAuctionMgr->GetAItem(itemGUIDLow); if (!item) { TC_LOG_ERROR("misc", "AuctionEntry::BuildAuctionInfo: Auction %u has a non-existent item: " UI64FMTD, Id, itemGUIDLow); - return false; + return; } - data << uint32(Id); - data << uint32(item->GetEntry()); - for (uint8 i = 0; i < PROP_ENCHANTMENT_SLOT_0; ++i) // PROP_ENCHANTMENT_SLOT_0 = 10 + WorldPackets::AuctionHouse::AuctionItem auctionItem; + + auctionItem.AuctionItemID = Id; + auctionItem.Item.Initialize(item); + auctionItem.BuyoutPrice = buyout; + auctionItem.CensorBidInfo = false; + auctionItem.CensorServerSideInfo = listAuctionItems; + auctionItem.Charges = item->GetSpellCharges(); + auctionItem.Count = item->GetCount(); + auctionItem.DeleteReason = 0; // Always 0 ? + auctionItem.DurationLeft = (expire_time - time(NULL)) * IN_MILLISECONDS; + auctionItem.EndTime = expire_time; + auctionItem.Flags = 0; // todo + auctionItem.ItemGuid = item->GetGUID(); + auctionItem.MinBid = startbid; + auctionItem.Owner = ObjectGuid::Create<HighGuid::Player>(owner); + auctionItem.OwnerAccountID = ObjectGuid::Create<HighGuid::WowAccount>(ObjectMgr::GetPlayerAccountIdByGUID(auctionItem.Owner)); + auctionItem.MinIncrement = bidder ? GetAuctionOutBid() : 0; + auctionItem.Bidder = bidder ? ObjectGuid::Create<HighGuid::Player>(bidder) : ObjectGuid::Empty; + auctionItem.BidAmount = bidder ? bid : 0; + + for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; i++) { - data << uint32(item->GetEnchantmentId(EnchantmentSlot(i))); - data << uint32(item->GetEnchantmentDuration(EnchantmentSlot(i))); - data << uint32(item->GetEnchantmentCharges(EnchantmentSlot(i))); + if (!item->GetEnchantmentId((EnchantmentSlot) i)) + continue; + + auctionItem.Enchantments.emplace_back(item->GetEnchantmentId((EnchantmentSlot) i), item->GetEnchantmentDuration((EnchantmentSlot) i), item->GetEnchantmentCharges((EnchantmentSlot) i), i); } - data << int32(item->GetItemRandomPropertyId()); // Random item property id - data << uint32(item->GetItemSuffixFactor()); // SuffixFactor - data << uint32(item->GetCount()); // item->count - data << uint32(item->GetSpellCharges()); // item->charge FFFFFFF - data << uint32(0); // Unknown - data << uint64(owner); // Auction->owner - data << uint64(startbid); // Auction->startbid (not sure if useful) - data << uint64(bid ? GetAuctionOutBid() : 0); - // Minimal outbid - data << uint64(buyout); // Auction->buyout - data << uint32((expire_time - time(NULL)) * IN_MILLISECONDS); // time left - data << uint64(bidder); // auction->bidder current - data << uint64(bid); // current bid - return true; + items.emplace_back(auctionItem); } uint32 AuctionEntry::GetAuctionCut() const @@ -738,6 +739,7 @@ bool AuctionEntry::LoadFromDB(Field* fields) } return true; } + std::string AuctionEntry::BuildAuctionMailSubject(MailAuctionAnswers response) const { std::ostringstream strm; diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h index 4d73b1c3894..91b78668204 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.h +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h @@ -23,6 +23,7 @@ #include "DatabaseEnv.h" #include "DBCStructure.h" #include "ObjectGuid.h" +#include "AuctionHousePackets.h" class Item; class Player; @@ -84,7 +85,7 @@ struct AuctionEntry uint32 GetHouseFaction() const { return auctionHouseEntry->FactionID; } uint32 GetAuctionCut() const; uint32 GetAuctionOutBid() const; - bool BuildAuctionInfo(WorldPacket & data) const; + void BuildAuctionInfo(std::vector<WorldPackets::AuctionHouse::AuctionItem>& items, bool listAuctionItems) const; void DeleteFromDB(SQLTransaction& trans) const; void SaveToDB(SQLTransaction& trans) const; bool LoadFromDB(Field* fields); @@ -122,12 +123,11 @@ class AuctionHouseObject void Update(); - void BuildListBidderItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount); - void BuildListOwnerItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount); - void BuildListAuctionItems(WorldPacket& data, Player* player, + void BuildListBidderItems(WorldPackets::AuctionHouse::AuctionListBidderItemsResult& packet, Player* player, uint32& totalcount); + void BuildListOwnerItems(WorldPackets::AuctionHouse::AuctionListOwnerItemsResult& packet, Player* player, uint32& totalcount); + void BuildListAuctionItems(WorldPackets::AuctionHouse::AuctionListItemsResult& packet, Player* player, std::wstring const& searchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, uint8 usable, - uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, - uint32& count, uint32& totalcount); + uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32& totalcount); private: AuctionEntryMap AuctionsMap; @@ -166,7 +166,7 @@ class AuctionHouseMgr void SendAuctionSuccessfulMail(AuctionEntry* auction, SQLTransaction& trans); void SendAuctionExpiredMail(AuctionEntry* auction, SQLTransaction& trans); void SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 newPrice, Player* newBidder, SQLTransaction& trans); - void SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans, Item* item); + void SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans); static uint32 GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item* pItem, uint32 count); static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId); diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index 9ba72bc29b1..fbd02d20ee5 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -812,7 +812,7 @@ void BattlefieldWG::FillInitialWorldStates(WorldPackets::WorldState::InitWorldSt packet.Worldstates.emplace_back(uint32(BATTLEFIELD_WG_WORLD_STATE_ATTACKER), int32(GetAttackerTeam())); packet.Worldstates.emplace_back(uint32(BATTLEFIELD_WG_WORLD_STATE_DEFENDER), int32(GetDefenderTeam())); // Note: cleanup these two, their names look awkward - packet.Worldstates.emplace_back(uint32(BATTLEFIELD_WG_WORLD_STATE_ACTIVE), int32(IsWarTime() ? 0 : 1)); + packet.Worldstates.emplace_back(uint32(BATTLEFIELD_WG_WORLD_STATE_ACTIVE), int32(IsWarTime() ? 0 : 1)); packet.Worldstates.emplace_back(uint32(BATTLEFIELD_WG_WORLD_STATE_SHOW_WORLDSTATE), int32(IsWarTime() ? 1 : 0)); for (uint32 i = 0; i < 2; ++i) diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp index 6348359511b..ac6911681cb 100644 --- a/src/server/game/Battlegrounds/Arena.cpp +++ b/src/server/game/Battlegrounds/Arena.cpp @@ -172,8 +172,8 @@ void Arena::EndBattleground(uint32 winner) uint8 winnerTeam = winner == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; uint8 loserTeam = winner == ALLIANCE ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE; - _arenaTeamScores[winnerTeam].Assign(winnerChange, winnerMatchmakerRating, winnerArenaTeam->GetName()); - _arenaTeamScores[loserTeam].Assign(loserChange, loserMatchmakerRating, loserArenaTeam->GetName()); + _arenaTeamScores[winnerTeam].Assign(winnerTeamRating, winnerTeamRating + winnerChange, winnerMatchmakerRating); + _arenaTeamScores[loserTeam].Assign(loserTeamRating, loserTeamRating + loserChange, loserMatchmakerRating); TC_LOG_DEBUG("bg.arena", "Arena match Type: %u for Team1Id: %u - Team2Id: %u ended. WinnerTeamId: %u. Winner rating: +%d, Loser rating: %d", GetArenaType(), GetArenaTeamIdByIndex(TEAM_ALLIANCE), GetArenaTeamIdByIndex(TEAM_HORDE), winnerArenaTeam->GetId(), winnerChange, loserChange); @@ -190,8 +190,8 @@ void Arena::EndBattleground(uint32 winner) // Deduct 16 points from each teams arena-rating if there are no winners after 45+2 minutes else { - _arenaTeamScores[BG_TEAM_ALLIANCE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, winnerMatchmakerRating, winnerArenaTeam->GetName()); - _arenaTeamScores[BG_TEAM_HORDE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, loserMatchmakerRating, loserArenaTeam->GetName()); + _arenaTeamScores[BG_TEAM_ALLIANCE].Assign(winnerTeamRating, winnerTeamRating + ARENA_TIMELIMIT_POINTS_LOSS, winnerMatchmakerRating); + _arenaTeamScores[BG_TEAM_HORDE].Assign(loserTeamRating, loserTeamRating + ARENA_TIMELIMIT_POINTS_LOSS, loserMatchmakerRating); winnerArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); loserArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); diff --git a/src/server/game/Battlegrounds/ArenaScore.h b/src/server/game/Battlegrounds/ArenaScore.h index a5f032777ac..67666104d46 100644 --- a/src/server/game/Battlegrounds/ArenaScore.h +++ b/src/server/game/Battlegrounds/ArenaScore.h @@ -30,68 +30,7 @@ struct ArenaScore : public BattlegroundScore protected: ArenaScore(ObjectGuid playerGuid, uint32 team) : BattlegroundScore(playerGuid, team), TeamId(team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE) { } - void AppendToPacket(WorldPacket& data, ByteBuffer& content) final override - { - uint32 primaryTree = 0; - /* TODO: 6.x update to new talent system (and probably rewrite this packet) - if (Player* player = ObjectAccessor::FindPlayer(PlayerGuid)) - primaryTree = player->GetPrimaryTalentTree(player->GetActiveSpec());*/ - - data.WriteBit(0); // Unk 1 - data.WriteBit(0); // Unk 2 - data.WriteBit(PlayerGuid[2]); - data.WriteBit(/*!IsArena*/ 0); // IsArena - data.WriteBit(0); // Unk 4 - data.WriteBit(0); // Unk 5 - data.WriteBit(0); // Unk 6 - data.WriteBit(PlayerGuid[3]); - data.WriteBit(PlayerGuid[0]); - data.WriteBit(PlayerGuid[5]); - data.WriteBit(PlayerGuid[1]); - data.WriteBit(PlayerGuid[6]); - data.WriteBit(TeamId); - data.WriteBit(PlayerGuid[7]); - - content << uint32(HealingDone); // healing done - content << uint32(DamageDone); // damage done - - content.WriteByteSeq(PlayerGuid[4]); - content << uint32(KillingBlows); - - //if (unk5) - // content << int32(RatingChange); // RatingChange - - content.WriteByteSeq(PlayerGuid[5]); - - //if (unk 6) - // content << uint32(); - - //if (unk 2) - // content << uint32(); - - content.WriteByteSeq(PlayerGuid[1]); - content.WriteByteSeq(PlayerGuid[6]); - - content << int32(primaryTree); - - BuildObjectivesBlock(data, content); - - data.WriteBit(PlayerGuid[4]); - - content.WriteByteSeq(PlayerGuid[0]); - content.WriteByteSeq(PlayerGuid[3]); - - //if (unk 4) - // content << uint32() unk - - content.WriteByteSeq(PlayerGuid[7]); - content.WriteByteSeq(PlayerGuid[2]); - } - - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& /*content*/) final override - { - data.WriteBits(0, 24); // Objectives Count - } + void BuildObjectivesBlock(std::vector<int32>& /*stats*/) override { } // For Logging purpose std::string ToString() const override @@ -110,48 +49,27 @@ struct ArenaTeamScore friend class Battleground; protected: - ArenaTeamScore() : RatingChange(0), MatchmakerRating(0) { } + ArenaTeamScore() : OldRating(0), NewRating(0), MatchmakerRating(0) { } virtual ~ArenaTeamScore() { } void Reset() { - RatingChange = 0; + OldRating = 0; + NewRating = 0; MatchmakerRating = 0; - TeamName.clear(); } - void Assign(int32 ratingChange, uint32 matchMakerRating, std::string const& teamName) + void Assign(int32 oldRating, int32 newRating, uint32 matchMakerRating) { - RatingChange = ratingChange; + OldRating = oldRating; + NewRating = newRating; MatchmakerRating = matchMakerRating; - TeamName = teamName; - } - - void BuildRatingInfoBlock(WorldPacket& data) - { - uint32 ratingLost = std::abs(std::min(RatingChange, 0)); - uint32 ratingWon = std::max(RatingChange, 0); - - // should be old rating, new rating, and client will calculate rating change itself - data << uint32(MatchmakerRating); - data << uint32(ratingLost); - data << uint32(ratingWon); - } - - void BuildTeamInfoLengthBlock(WorldPacket& data) - { - data.WriteBits(TeamName.length(), 8); - } - - void BuildTeamInfoBlock(WorldPacket& data) - { - data.WriteString(TeamName); } - int32 RatingChange; + int32 OldRating; + int32 NewRating; uint32 MatchmakerRating; - std::string TeamName; }; #endif // TRINITY_ARENA_SCORE_H diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index b0015bf80c1..d635b40badc 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -408,7 +408,7 @@ void ArenaTeam::NotifyStatsChanged() SendStats(player->GetSession()); } -void ArenaTeam::Inspect(WorldSession* session, ObjectGuid guid) +void ArenaTeam::Inspect(WorldSession* /*session*/, ObjectGuid guid) { ArenaTeamMember* member = GetMember(guid); if (!member) diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index db7d2192b84..02050c8087b 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -38,6 +38,7 @@ #include "Util.h" #include "WorldPacket.h" #include "Transport.h" +#include "BattlegroundPackets.h" namespace Trinity { @@ -786,7 +787,7 @@ void Battleground::EndBattleground(uint32 winner) //we must set it this way, because end time is sent in packet! SetRemainingTime(TIME_AUTOCLOSE_BATTLEGROUND); - WorldPacket pvpLogData; + WorldPackets::Battleground::PVPLogData pvpLogData; BuildPvPLogDataPacket(pvpLogData); BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); @@ -882,7 +883,7 @@ void Battleground::EndBattleground(uint32 winner) BlockMovement(player); - player->SendDirectMessage(&pvpLogData); + player->SendDirectMessage(pvpLogData.Write()); WorldPacket data; sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, player->GetBattlegroundQueueJoinTime(GetTypeID()), GetElapsedTime(), GetArenaType()); @@ -1296,53 +1297,65 @@ bool Battleground::HasFreeSlots() const return GetPlayersSize() < GetMaxPlayers(); } -void Battleground::BuildPvPLogDataPacket(WorldPacket& data) +void Battleground::BuildPvPLogDataPacket(WorldPackets::Battleground::PVPLogData& pvpLogData) { - ByteBuffer buff; + if (GetStatus() == STATUS_WAIT_LEAVE) + pvpLogData.Winner.Set(GetWinner()); - data.Initialize(SMSG_PVP_LOG_DATA, (1 + 1 + 4 + 40 * GetPlayerScoresSize())); + pvpLogData.Players.reserve(GetPlayerScoresSize()); + for (auto const& score : PlayerScores) + { + WorldPackets::Battleground::PVPLogData::PlayerData playerData; - data.WriteBit(isRated()); - data.WriteBit(isArena()); + playerData.PlayerGUID = score.second->PlayerGuid; + playerData.Kills = score.second->KillingBlows; + playerData.Faction = score.second->TeamId; + if (score.second->HonorableKills || score.second->Deaths || score.second->BonusHonor) + { + WorldPackets::Battleground::PVPLogData::HonorData& honorData = playerData.Honor.Value; + honorData.HonorKills = score.second->HonorableKills; + honorData.Deaths = score.second->Deaths; + honorData.ContributionPoints = score.second->BonusHonor; - if (isArena()) - { - // it seems this must be according to BG_WINNER_A/H and _NOT_ TEAM_A/H - for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i) - _arenaTeamScores[i].BuildTeamInfoLengthBlock(data); - } + playerData.Honor.HasValue = true; + } - size_t countPos = data.bitwpos(); - data.WriteBits(0, 21); - for (auto const& score : PlayerScores) - score.second->AppendToPacket(data, buff); + playerData.DamageDone = score.second->DamageDone; + playerData.HealingDone = score.second->HealingDone; + score.second->BuildObjectivesBlock(playerData.Stats); - data.PutBits(countPos, GetPlayerScoresSize(), 21); - data.WriteBit(GetStatus() == STATUS_WAIT_LEAVE); // If Ended + if (Player* player = ObjectAccessor::GetObjectInMap(playerData.PlayerGUID, GetBgMap(), (Player*)nullptr)) + { + playerData.IsInWorld = true; + playerData.PrimaryTalentTree = player->GetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID); + } - if (isRated()) - { - // it seems this must be according to BG_WINNER_A/H and _NOT_ BG_TEAM_A/H - for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i) - _arenaTeamScores[i].BuildRatingInfoBlock(data); - } + //if (isRated()) + //{ + // playerData.PreMatchRating; + // playerData.RatingChange; + // playerData.PreMatchMMR; + // playerData.MmrChange; + //} - data.FlushBits(); - data.append(buff); + pvpLogData.Players.push_back(playerData); + } - if (isArena()) + if (isRated()) { - // it seems this must be according to BG_WINNER_A/H and _NOT_ TEAM_A/H + WorldPackets::Battleground::PVPLogData::RatingData& ratingData = pvpLogData.Ratings.Value; for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i) - _arenaTeamScores[i].BuildTeamInfoBlock(data); - } - - data << uint8(GetPlayersCountByTeam(HORDE)); + { + ratingData.Postmatch[i] = _arenaTeamScores[i].NewRating; + ratingData.Prematch[i] = _arenaTeamScores[i].OldRating; + ratingData.PrematchMMR[i] = _arenaTeamScores[i].MatchmakerRating; + } - if (GetStatus() == STATUS_WAIT_LEAVE) - data << uint8(GetWinner()); + pvpLogData.Ratings.HasValue = true; + } - data << uint8(GetPlayersCountByTeam(ALLIANCE)); + pvpLogData.PlayerCount[0] = int8(GetPlayersCountByTeam(HORDE)); + pvpLogData.PlayerCount[1] = int8(GetPlayersCountByTeam(ALLIANCE)); } bool Battleground::UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor) @@ -1811,14 +1824,15 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player) if (GetStatus() != STATUS_WAIT_LEAVE) return; - WorldPacket data; + WorldPackets::Battleground::PVPLogData pvpLogData; BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); BlockMovement(player); - BuildPvPLogDataPacket(data); - player->SendDirectMessage(&data); + BuildPvPLogDataPacket(pvpLogData); + player->SendDirectMessage(pvpLogData.Write()); + WorldPacket data; sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, player->GetBattlegroundQueueJoinTime(GetTypeID()), GetElapsedTime(), GetArenaType()); player->SendDirectMessage(&data); } diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index e5692c3eb02..0fe95a0c7a5 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -40,6 +40,14 @@ class BattlegroundMap; struct PvPDifficultyEntry; struct WorldSafeLocsEntry; +namespace WorldPackets +{ + namespace Battleground + { + class PVPLogData; + } +} + enum BattlegroundCriteriaId { BG_CRITERIA_CHECK_RESILIENT_VICTORY, @@ -376,7 +384,7 @@ class Battleground Group* GetBgRaid(uint32 TeamID) const { return TeamID == ALLIANCE ? m_BgRaids[TEAM_ALLIANCE] : m_BgRaids[TEAM_HORDE]; } void SetBgRaid(uint32 TeamID, Group* bg_raid); - void BuildPvPLogDataPacket(WorldPacket& data); + void BuildPvPLogDataPacket(WorldPackets::Battleground::PVPLogData& pvpLogData); virtual bool UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true); static TeamId GetTeamIndexByTeamId(uint32 Team) { return Team == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; } diff --git a/src/server/game/Battlegrounds/BattlegroundScore.h b/src/server/game/Battlegrounds/BattlegroundScore.h index 309c8bff17f..efaaa25c974 100644 --- a/src/server/game/Battlegrounds/BattlegroundScore.h +++ b/src/server/game/Battlegrounds/BattlegroundScore.h @@ -90,72 +90,7 @@ struct BattlegroundScore } } - virtual void AppendToPacket(WorldPacket& data, ByteBuffer& content) - { - uint32 primaryTree = 0; - /* TODO: 6.x update to new talent system (and probably rewrite this packet) - if (Player* player = ObjectAccessor::FindPlayer(PlayerGuid)) - primaryTree = player->GetPrimaryTalentTree(player->GetActiveSpec());*/ - - data.WriteBit(0); // Unk 1 - data.WriteBit(0); // Unk 2 - data.WriteBit(PlayerGuid[2]); - data.WriteBit(/*!IsArena*/ 1); // IsArena - data.WriteBit(0); // Unk 4 - data.WriteBit(0); // Unk 5 - data.WriteBit(0); // Unk 6 - data.WriteBit(PlayerGuid[3]); - data.WriteBit(PlayerGuid[0]); - data.WriteBit(PlayerGuid[5]); - data.WriteBit(PlayerGuid[1]); - data.WriteBit(PlayerGuid[6]); - data.WriteBit(TeamId); - data.WriteBit(PlayerGuid[7]); - - content << uint32(HealingDone); // healing done - content << uint32(DamageDone); // damage done - - //if (!IsArena) - //{ - content << uint32(BonusHonor / 100); - content << uint32(Deaths); - content << uint32(HonorableKills); - //} - - content.WriteByteSeq(PlayerGuid[4]); - content << uint32(KillingBlows); - - //if (unk 5) - // data << uint32() unk - - content.WriteByteSeq(PlayerGuid[5]); - - //if (unk 6) - // data << uint32() unk - - //if (unk 2) - // data << uint32() unk - - content.WriteByteSeq(PlayerGuid[1]); - content.WriteByteSeq(PlayerGuid[6]); - - content << int32(primaryTree); - - BuildObjectivesBlock(data, content); - - data.WriteBit(PlayerGuid[4]); - - content.WriteByteSeq(PlayerGuid[0]); - content.WriteByteSeq(PlayerGuid[3]); - - //if (unk 4) - // data << uint32() unk - - content.WriteByteSeq(PlayerGuid[7]); - content.WriteByteSeq(PlayerGuid[2]); - } - - virtual void BuildObjectivesBlock(WorldPacket& /*data*/, ByteBuffer& /*content*/) = 0; + virtual void BuildObjectivesBlock(std::vector<int32>& /*stats*/) = 0; // For Logging purpose virtual std::string ToString() const { return ""; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h index b0b06acaab6..48b2b94951c 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h @@ -260,11 +260,10 @@ struct BattlegroundABScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final override + void BuildObjectivesBlock(std::vector<int32>& stats) override { - data.WriteBits(2, 24); // Objectives Count - content << uint32(BasesAssaulted); - content << uint32(BasesDefended); + stats.push_back(BasesAssaulted); + stats.push_back(BasesDefended); } uint32 GetAttr1() const final override { return BasesAssaulted; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h index 533c41a2ed2..93516279cb0 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h @@ -1581,14 +1581,13 @@ struct BattlegroundAVScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final override + void BuildObjectivesBlock(std::vector<int32>& stats) override { - data.WriteBits(5, 24); // Objectives Count - content << uint32(GraveyardsAssaulted); - content << uint32(GraveyardsDefended); - content << uint32(TowersAssaulted); - content << uint32(TowersDefended); - content << uint32(MinesCaptured); + stats.push_back(GraveyardsAssaulted); + stats.push_back(GraveyardsDefended); + stats.push_back(TowersAssaulted); + stats.push_back(TowersDefended); + stats.push_back(MinesCaptured); } uint32 GetAttr1() const final override { return GraveyardsAssaulted; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBFG.h b/src/server/game/Battlegrounds/Zones/BattlegroundBFG.h index 993ffb37190..3694c62d663 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundBFG.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundBFG.h @@ -42,11 +42,10 @@ class BattlegroundBFGScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final + void BuildObjectivesBlock(std::vector<int32>& stats) { - data.WriteBits(2, 24); // Objectives Count - content << uint32(BasesAssaulted); - content << uint32(BasesDefended); + stats.push_back(BasesAssaulted); + stats.push_back(BasesDefended); } uint32 GetAttr1() const final override { return BasesAssaulted; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h index 53f5c9aa44f..d6a2991f01d 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h @@ -343,10 +343,9 @@ struct BattlegroundEYScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final override + void BuildObjectivesBlock(std::vector<int32>& stats) override { - data.WriteBits(1, 24); // Objectives Count - content << uint32(FlagCaptures); + stats.push_back(FlagCaptures); } uint32 GetAttr1() const final override { return FlagCaptures; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h index 36c5a460a34..64025cb8a4c 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h @@ -905,11 +905,10 @@ struct BattlegroundICScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final override + void BuildObjectivesBlock(std::vector<int32>& stats) override { - data.WriteBits(2, 24); // Objectives Count - content << uint32(BasesAssaulted); - content << uint32(BasesDefended); + stats.push_back(BasesAssaulted); + stats.push_back(BasesDefended); } uint32 GetAttr1() const final override { return BasesAssaulted; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h index 21c666c94ab..0877da8781a 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h @@ -531,11 +531,10 @@ struct BattlegroundSAScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final override + void BuildObjectivesBlock(std::vector<int32>& stats) override { - data.WriteBits(2, 24); // Objectives Count - content << uint32(DemolishersDestroyed); - content << uint32(GatesDestroyed); + stats.push_back(DemolishersDestroyed); + stats.push_back(GatesDestroyed); } uint32 GetAttr1() const final override { return DemolishersDestroyed; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundTP.h b/src/server/game/Battlegrounds/Zones/BattlegroundTP.h index a7e35ef2438..b11485d6025 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundTP.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundTP.h @@ -42,11 +42,10 @@ class BattlegroundTPScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final + void BuildObjectivesBlock(std::vector<int32>& stats) { - data.WriteBits(2, 24); // Objectives Count - content << uint32(FlagCaptures); - content << uint32(FlagReturns); + stats.push_back(FlagCaptures); + stats.push_back(FlagReturns); } uint32 GetAttr1() const final override { return FlagCaptures; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h index 734a42174a6..3736c01b045 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h @@ -170,11 +170,10 @@ struct BattlegroundWGScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final override + void BuildObjectivesBlock(std::vector<int32>& stats) override { - data.WriteBits(2, 24); // Objectives Count - content << uint32(FlagCaptures); - content << uint32(FlagReturns); + stats.push_back(FlagCaptures); + stats.push_back(FlagReturns); } uint32 GetAttr1() const final override { return FlagCaptures; } diff --git a/src/server/game/Chat/ChatLink.cpp b/src/server/game/Chat/ChatLink.cpp index ea12ff91a1d..89a7d64c432 100644 --- a/src/server/game/Chat/ChatLink.cpp +++ b/src/server/game/Chat/ChatLink.cpp @@ -242,7 +242,7 @@ bool QuestChatLink::ValidateName(char* buffer, const char* context) bool res = (_quest->GetLogTitle() == buffer); if (!res) - if (QuestLocale const* ql = sObjectMgr->GetQuestLocale(_quest->GetQuestId())) + if (QuestTemplateLocale const* ql = sObjectMgr->GetQuestLocale(_quest->GetQuestId())) for (uint8 i = 0; i < ql->LogTitle.size(); i++) if (ql->LogTitle[i] == buffer) { diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index df7496e4d94..bed2cc793f4 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -43,6 +43,7 @@ DB2Storage<KeyChainEntry> sKeyChainStore("KeyChain.db2", KeyCh DB2Storage<MountEntry> sMountStore("Mount.db2", MountFormat, HOTFIX_SEL_MOUNT); DB2Storage<OverrideSpellDataEntry> sOverrideSpellDataStore("OverrideSpellData.db2", OverrideSpellDataFormat, HOTFIX_SEL_OVERRIDE_SPELL_DATA); DB2Storage<PhaseXPhaseGroupEntry> sPhaseXPhaseGroupStore("PhaseXPhaseGroup.db2", PhaseXPhaseGroupFormat, HOTFIX_SEL_PHASE_GROUP); +DB2Storage<QuestPackageItemEntry> sQuestPackageItemStore("QuestPackageItem.db2", QuestPackageItemfmt, HOTFIX_SEL_QUEST_PACKAGE_ITEM); DB2Storage<SoundEntriesEntry> sSoundEntriesStore("SoundEntries.db2", SoundEntriesFormat, HOTFIX_SEL_SOUND_ENTRIES); DB2Storage<SpellAuraRestrictionsEntry> sSpellAuraRestrictionsStore("SpellAuraRestrictions.db2", SpellAuraRestrictionsFormat, HOTFIX_SEL_SPELL_AURA_RESTRICTIONS); DB2Storage<SpellCastingRequirementsEntry> sSpellCastingRequirementsStore("SpellCastingRequirements.db2", SpellCastingRequirementsFormat, HOTFIX_SEL_SPELL_CASTING_REQUIREMENTS); @@ -144,6 +145,7 @@ void DB2Manager::LoadStores(std::string const& dataPath) LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sMountStore, db2Path); LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sOverrideSpellDataStore, db2Path); LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sPhaseXPhaseGroupStore, db2Path); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sQuestPackageItemStore, db2Path); LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSoundEntriesStore, db2Path); LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellAuraRestrictionsStore, db2Path); LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellCastingRequirementsStore, db2Path); @@ -151,6 +153,7 @@ void DB2Manager::LoadStores(std::string const& dataPath) LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellLearnSpellStore, db2Path); LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellMiscStore, db2Path); LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellPowerStore, db2Path); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellPowerDifficultyStore, db2Path); LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellReagentsStore, db2Path); LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellRuneCostStore, db2Path); LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellTotemsStore, db2Path); @@ -198,6 +201,9 @@ void DB2Manager::LoadStores(std::string const& dataPath) if (PhaseEntry const* phase = sPhaseStore.LookupEntry(group->PhaseID)) _phasesByGroup[group->PhaseGroupID].insert(phase->ID); + for (QuestPackageItemEntry const* questPackageItem : sQuestPackageItemStore) + _questPackages[questPackageItem->QuestPackageID].push_back(questPackageItem); + for (SpellPowerEntry const* power : sSpellPowerStore) { if (SpellPowerDifficultyEntry const* powerDifficulty = sSpellPowerDifficultyStore.LookupEntry(power->ID)) @@ -487,6 +493,15 @@ MountEntry const* DB2Manager::GetMount(uint32 spellId) const return nullptr; } +std::vector<QuestPackageItemEntry const*> const* DB2Manager::GetQuestPackageItems(uint32 questPackageID) const +{ + auto itr = _questPackages.find(questPackageID); + if (itr != _questPackages.end()) + return &itr->second; + + return nullptr; +} + std::set<uint32> DB2Manager::GetPhasesForGroup(uint32 group) const { auto itr = _phasesByGroup.find(group); diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index 8fdf23ec58c..ece71c7413e 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -74,6 +74,7 @@ public: typedef std::unordered_map<uint32, std::set<ItemBonusTreeNodeEntry const*>> ItemBonusTreeContainer; typedef std::unordered_map<uint32, MountEntry const*> MountContainer; typedef std::unordered_map<uint32, std::set<uint32>> PhaseGroupContainer; + typedef std::unordered_map<uint32, std::vector<QuestPackageItemEntry const*>> QuestPackageItemContainer; typedef std::unordered_map<uint32, std::vector<SpellPowerEntry const*>> SpellPowerContainer; typedef std::unordered_map<uint32, std::unordered_map<uint32, std::vector<SpellPowerEntry const*>>> SpellPowerDifficultyContainer; @@ -97,6 +98,7 @@ public: std::set<uint32> GetItemBonusTree(uint32 itemId, uint32 itemBonusTreeMod) const; uint32 GetItemDisplayId(uint32 itemId, uint32 appearanceModId) const; MountEntry const* GetMount(uint32 spellId) const; + std::vector<QuestPackageItemEntry const*> const* GetQuestPackageItems(uint32 questPackageID) const; std::set<uint32> GetPhasesForGroup(uint32 group) const; std::vector<SpellPowerEntry const*> GetSpellPowers(uint32 spellId, Difficulty difficulty = DIFFICULTY_NONE, bool* hasDifficultyPowers = nullptr) const; @@ -112,6 +114,7 @@ private: ItemToBonusTreeContainer _itemToBonusTree; MountContainer _mountsBySpellId; PhaseGroupContainer _phasesByGroup; + QuestPackageItemContainer _questPackages; SpellPowerContainer _spellPowers; SpellPowerDifficultyContainer _spellPowerDifficulties; }; diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index 9aab120cc63..912ae5d60d5 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -296,6 +296,15 @@ struct PhaseXPhaseGroupEntry uint32 PhaseGroupID; }; +struct QuestPackageItemEntry +{ + uint32 ID; // 0 + uint32 QuestPackageID; // 1 + uint32 ItemID; // 2 + uint32 ItemCount; // 3 + uint32 FilterType; // 4 +}; + struct SoundEntriesEntry { uint32 ID; // 0 diff --git a/src/server/game/DataStores/DB2fmt.h b/src/server/game/DataStores/DB2fmt.h index baab3cf9302..f59c7b56f56 100644 --- a/src/server/game/DataStores/DB2fmt.h +++ b/src/server/game/DataStores/DB2fmt.h @@ -38,6 +38,7 @@ char const KeyChainFormat[] = "nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; char const MountFormat[] = "niiisssiii"; char const OverrideSpellDataFormat[] = "niiiiiiiiiiii"; char const PhaseXPhaseGroupFormat[] = "nii"; +char const QuestPackageItemfmt[] = "niiii"; char const SoundEntriesFormat[] = "nisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiififfiifffffii"; char const SpellAuraRestrictionsFormat[] = "niiiiiiii"; char const SpellCastingRequirementsFormat[] = "niiiiii"; diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index eb7c344ccf6..aca745c52a3 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -335,7 +335,7 @@ enum AreaFlags AREA_FLAG_WINTERGRASP = 0x01000000, // Wintergrasp and it's subzones AREA_FLAG_INSIDE = 0x02000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors AREA_FLAG_OUTSIDE = 0x04000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors - AREA_FLAG_WINTERGRASP_2 = 0x08000000, // Can Hearth And Resurrect From Area + AREA_FLAG_CAN_HEARTH_AND_RESURRECT = 0x08000000, // Can Hearth And Resurrect From Area AREA_FLAG_NO_FLY_ZONE = 0x20000000, // Marks zones where you cannot fly AREA_FLAG_UNK9 = 0x40000000 }; @@ -491,6 +491,14 @@ enum MountFlags MOUNT_FLAG_HIDE_IF_UNKNOWN = 0x40 }; +enum QuestPackageFilter +{ + QUEST_PACKAGE_FILTER_LOOT_SPECIALIZATION = 0, // Players can select this quest reward if it matches their selected loot specialization + QUEST_PACKAGE_FILTER_CLASS = 1, // Players can select this quest reward if it matches their class + QUEST_PACKAGE_FILTER_UNMATCHED = 2, // Players can select this quest reward if no class/loot_spec rewards are available + QUEST_PACKAGE_FILTER_EVERYONE = 3 // Players can always select this quest reward +}; + enum SkillRaceClassInfoFlags { SKILL_FLAG_NO_SKILLUP_MESSAGE = 0x2, diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 919c952f136..805885df51c 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -158,6 +158,9 @@ DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore(ItemRandomSuffi DBCStorage <ItemSetEntry> sItemSetStore(ItemSetEntryfmt); DBCStorage <ItemSetSpellEntry> sItemSetSpellStore(ItemSetSpellEntryfmt); ItemSetSpellsStore sItemSetSpellsStore; +DBCStorage <ItemSpecOverrideEntry> sItemSpecOverrideStore(ItemSpecOverrideEntryfmt); +ItemSpecOverridesStore sItemSpecOverridesStore; +DBCStorage <ItemSpecEntry> sItemSpecStore(ItemSpecEntryfmt); DBCStorage <LFGDungeonEntry> sLFGDungeonStore(LFGDungeonEntryfmt); DBCStorage <LightEntry> sLightStore(LightEntryfmt); @@ -477,6 +480,12 @@ void LoadDBCStores(const std::string& dataPath) if (ItemSetSpellEntry const* entry = sItemSetSpellStore.LookupEntry(i)) sItemSetSpellsStore[entry->ItemSetID].push_back(entry); + LoadDBC(availableDbcLocales, bad_dbc_files, sItemSpecStore, dbcPath, "ItemSpec.dbc");//19116 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemSpecOverrideStore, dbcPath, "ItemSpecOverride.dbc");//19116 + for (uint32 i = 0; i < sItemSpecOverrideStore.GetNumRows(); ++i) + if (ItemSpecOverrideEntry const* entry = sItemSpecOverrideStore.LookupEntry(i)) + sItemSpecOverridesStore[entry->ItemID].push_back(entry); + LoadDBC(availableDbcLocales, bad_dbc_files, sItemArmorQualityStore, dbcPath, "ItemArmorQuality.dbc");//19116 LoadDBC(availableDbcLocales, bad_dbc_files, sItemArmorShieldStore, dbcPath, "ItemArmorShield.dbc");//19116 LoadDBC(availableDbcLocales, bad_dbc_files, sItemArmorTotalStore, dbcPath, "ItemArmorTotal.dbc");//19116 diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index f16b56609dd..781b981c4c1 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -211,6 +211,9 @@ extern DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore; extern DBCStorage <ItemSetEntry> sItemSetStore; extern DBCStorage <ItemSetSpellEntry> sItemSetSpellStore; extern ItemSetSpellsStore sItemSetSpellsStore; +extern DBCStorage <ItemSpecOverrideEntry> sItemSpecOverrideStore; +extern ItemSpecOverridesStore sItemSpecOverridesStore; +extern DBCStorage <ItemSpecEntry> sItemSpecStore; extern DBCStorage <LFGDungeonEntry> sLFGDungeonStore; extern DBCStorage <LiquidTypeEntry> sLiquidTypeStore; extern DBCStorage <LockEntry> sLockStore; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 0d4ada1ab39..ae6722b7932 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -261,7 +261,7 @@ struct ChrClassesEntry uint32 AttackPowerPerStrength; // 10 Attack Power bonus per point of strength uint32 AttackPowerPerAgility; // 11 Attack Power bonus per point of agility uint32 RangedAttackPowerPerAgility; // 12 Ranged Attack Power bonus per point of agility - //uint32 DefaultSpec; // 13 + uint32 DefaultSpec; // 13 //uint32 CreateScreenFileDataID; // 14 //uint32 SelectScreenFileDataID; // 15 //uint32 LowResScreenFileDataID; // 16 @@ -1108,6 +1108,27 @@ struct ItemSetSpellEntry typedef std::vector<ItemSetSpellEntry const*> ItemSetSpells; typedef std::unordered_map<uint32, ItemSetSpells> ItemSetSpellsStore; +struct ItemSpecEntry +{ + uint32 ID; // 0 + uint32 MinLevel; // 1 + uint32 MaxLevel; // 2 + uint32 ItemType; // 3 + uint32 PrimaryStat; // 4 + uint32 SecondaryStat; // 5 + uint32 SpecID; // 6 +}; + +struct ItemSpecOverrideEntry +{ + uint32 ID; // 0 + uint32 ItemID; // 1 + uint32 SpecID; // 2 +}; + +typedef std::vector<ItemSpecOverrideEntry const*> ItemSpecOverrides; +typedef std::unordered_map<uint32, ItemSpecOverrides> ItemSpecOverridesStore; + struct LFGDungeonEntry { uint32 ID; // 0 diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 98677746c3c..271aca1c43f 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -37,7 +37,7 @@ char const CharStartOutfitEntryfmt[] = "dbbbXiiiiiiiiiiiiiiiiiiiiiiiiii"; char const CharSectionsEntryfmt[] = "diiixxxiii"; char const CharTitlesEntryfmt[] = "nxssix"; char const ChatChannelsEntryfmt[] = "nixsx"; -char const ChrClassesEntryfmt[] = "nixsxxxixiiiixxxxxx"; +char const ChrClassesEntryfmt[] = "nixsxxxixiiiiixxxxx"; char const ChrRacesEntryfmt[] = "niixiixxxxxxiisxxxxxxxxxxxxxxxxxxxxxxxxx"; char const ChrClassesXPowerTypesfmt[] = "nii"; char const ChrSpecializationEntryfmt[] = "nxiiiiiiiiixxxii"; @@ -105,6 +105,8 @@ char const ItemRandomPropertiesfmt[] = "nxiiiiis"; char const ItemRandomSuffixfmt[] = "nsxiiiiiiiiii"; char const ItemSetEntryfmt[] = "nsiiiiiiiiiiiiiiiiiii"; char const ItemSetSpellEntryfmt[] = "niiii"; +char const ItemSpecEntryfmt[] = "niiiiii"; +char const ItemSpecOverrideEntryfmt[] = "nii"; char const LFGDungeonEntryfmt[] = "nsiiixxiiiixxixixxxxxxxxxxxxx"; char const LightEntryfmt[] = "nifffxxxxxxxxxx"; char const LiquidTypefmt[] = "nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index db711bd9a47..b077f3e6110 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -1270,6 +1270,14 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false* if (player->GetMapId() == uint32(dungeon->map)) player->TeleportToBGEntryPoint(); + // in the case were we are the last in lfggroup then we must disband when porting out of the instance + if (group && group->GetMembersCount() == 1) + { + group->Disband(); + TC_LOG_DEBUG("lfg.teleport", "Player %s is last in lfggroup so we disband the group.", + player->GetName().c_str()); + } + return; } diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 3fd06e41458..f9496a05cf4 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -69,7 +69,6 @@ enum CreatureFlagsExtra #define MAX_KILL_CREDIT 2 #define MAX_CREATURE_MODELS 4 -#define MAX_CREATURE_QUEST_ITEMS 6 #define MAX_CREATURE_NAMES 4 #define CREATURE_MAX_SPELLS 8 #define MAX_CREATURE_DIFFICULTIES 3 @@ -136,7 +135,6 @@ struct CreatureTemplate float ModDamage; float ModExperience; bool RacialLeader; - uint32 questItems[MAX_CREATURE_QUEST_ITEMS]; uint32 movementId; bool RegenHealth; uint32 MechanicImmuneMask; @@ -205,6 +203,9 @@ struct CreatureTemplate } }; +typedef std::vector<uint32> CreatureQuestItemList; +typedef std::unordered_map<uint32, CreatureQuestItemList> CreatureQuestItemMap; + // Benchmarked: Faster than std::map (insert/find) typedef std::unordered_map<uint32, CreatureTemplate> CreatureTemplateContainer; @@ -271,7 +272,7 @@ struct GossipMenuItemsLocale struct PointOfInterestLocale { - StringVector IconName; + StringVector Name; }; #define MAX_EQUIPMENT_ITEMS 3 diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index c48ed5de26b..815c98c9710 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -235,10 +235,10 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID) text.Repeatable = quest->IsRepeatable(); std::string title = quest->GetLogTitle(); - int32 locale = _session->GetSessionDbLocaleIndex(); - if (locale >= 0) - if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID)) - ObjectMgr::GetLocaleString(localeData->LogTitle, locale, title); + LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); + if (localeConstant >= LOCALE_enUS) + if (QuestTemplateLocale const* localeData = sObjectMgr->GetQuestLocale(questID)) + ObjectMgr::GetLocaleString(localeData->LogTitle, localeConstant, title); if (questLevelInTitle) AddQuestLevelToTitle(title, quest->GetQuestLevel()); @@ -262,30 +262,31 @@ void PlayerMenu::SendCloseGossip() _session->SendPacket(packet.Write()); } -void PlayerMenu::SendPointOfInterest(uint32 poiId) const +void PlayerMenu::SendPointOfInterest(uint32 id) const { - PointOfInterest const* poi = sObjectMgr->GetPointOfInterest(poiId); - if (!poi) + PointOfInterest const* pointOfInterest = sObjectMgr->GetPointOfInterest(id); + if (!pointOfInterest) { - TC_LOG_ERROR("sql.sql", "Request to send non-existing POI (Id: %u), ignored.", poiId); + TC_LOG_ERROR("sql.sql", "Request to send non-existing PointOfInterest (Id: %u), ignored.", id); return; } - std::string iconText = poi->Name; - int32 locale = _session->GetSessionDbLocaleIndex(); - if (locale >= 0) - if (PointOfInterestLocale const* localeData = sObjectMgr->GetPointOfInterestLocale(poiId)) - ObjectMgr::GetLocaleString(localeData->IconName, locale, iconText); - - WorldPacket data(SMSG_GOSSIP_POI, 4 + 4 + 4 + 4 + 4 + 10); // guess size - data << uint32(poi->Flags); - data << float(poi->PositionX); - data << float(poi->PositionY); - data << uint32(poi->Icon); - data << uint32(poi->Importance); - data << iconText; - - _session->SendPacket(&data); + std::string name = pointOfInterest->Name; + + LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); + if (localeConstant >= LOCALE_enUS) + if (PointOfInterestLocale const* localeData = sObjectMgr->GetPointOfInterestLocale(id)) + ObjectMgr::GetLocaleString(localeData->Name, localeConstant, name); + + WorldPackets::NPC::GossipPOI packet; + + packet.Flags = pointOfInterest->Flags; + packet.Pos = pointOfInterest->Pos; + packet.Icon = pointOfInterest->Icon; + packet.Importance = pointOfInterest->Importance; + packet.Name = name; + + _session->SendPacket(packet.Write()); } /*********************************************************/ @@ -331,44 +332,49 @@ void QuestMenu::ClearMenu() _questMenuItems.clear(); } -void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string& Title, ObjectGuid npcGUID) +void PlayerMenu::SendQuestGiverQuestList(ObjectGuid guid) { WorldPackets::Quest::QuestGiverQuestList questList; - - questList.QuestGiverGUID = npcGUID; - questList.Greeting = Title; - questList.GreetEmoteDelay = eEmote._Delay; - questList.GreetEmoteType = eEmote._Emote; + questList.QuestGiverGUID = guid; + + if (QuestGreeting const* questGreeting = sObjectMgr->GetQuestGreeting(guid)) + { + questList.GreetEmoteDelay = questGreeting->greetEmoteDelay; + questList.GreetEmoteType = questGreeting->greetEmoteType; + questList.Greeting = questGreeting->greeting; + } + else + TC_LOG_ERROR("misc", "Guid: %s - No quest greeting found.", guid.ToString().c_str()); // Store this instead of checking the Singleton every loop iteration bool questLevelInTitle = sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS); for (uint32 i = 0; i < _questMenu.GetMenuItemCount(); ++i) { - QuestMenuItem const& qmi = _questMenu.GetItem(i); + QuestMenuItem const& questMenuItem = _questMenu.GetItem(i); - uint32 questID = qmi.QuestId; + uint32 questID = questMenuItem.QuestId; if (Quest const* quest = sObjectMgr->GetQuestTemplate(questID)) { std::string title = quest->GetLogTitle(); - int32 locale = _session->GetSessionDbLocaleIndex(); - if (locale >= 0) - if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID)) - ObjectMgr::GetLocaleString(localeData->LogTitle, locale, title); + LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); + if (localeConstant >= LOCALE_enUS) + if (QuestTemplateLocale const* questTemplateLocale = sObjectMgr->GetQuestLocale(questID)) + ObjectMgr::GetLocaleString(questTemplateLocale->LogTitle, localeConstant, title); if (questLevelInTitle) AddQuestLevelToTitle(title, quest->GetQuestLevel()); bool repeatable = false; // NYI - questList.GossipTexts.push_back(WorldPackets::Quest::GossipTextData(questID, qmi.QuestIcon, quest->GetQuestLevel(), quest->GetFlags(), quest->GetFlagsEx(), repeatable, title)); + questList.GossipTexts.push_back(WorldPackets::Quest::GossipTextData(questID, questMenuItem.QuestIcon, quest->GetQuestLevel(), quest->GetFlags(), quest->GetFlagsEx(), repeatable, title)); } } _session->SendPacket(questList.Write()); - TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_GIVER_QUEST_LIST_MESSAGE NPC=%s", npcGUID.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_GIVER_QUEST_LIST_MESSAGE NPC=%s", guid.ToString().c_str()); } void PlayerMenu::SendQuestGiverStatus(uint32 questStatus, ObjectGuid npcGUID) const @@ -386,23 +392,23 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU std::string questLogTitle = quest->GetLogTitle(); std::string questLogDescription = quest->GetLogDescription(); std::string questDescription = quest->GetQuestDescription(); - std::string portraitGiverText = quest->GetPortraitGiverText(); - std::string portraitGiverName = quest->GetPortraitGiverName(); - std::string portraitTurnInText = quest->GetPortraitTurnInText(); - std::string portraitTurnInName = quest->GetPortraitTurnInName(); + std::string portraitGiverText = quest->GetPortraitGiverText(); + std::string portraitGiverName = quest->GetPortraitGiverName(); + std::string portraitTurnInText = quest->GetPortraitTurnInText(); + std::string portraitTurnInName = quest->GetPortraitTurnInName(); - int32 locale = _session->GetSessionDbLocaleIndex(); - if (locale >= 0) + LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); + if (localeConstant >= LOCALE_enUS) { - if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) + if (QuestTemplateLocale const* questTemplateLocale = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { - ObjectMgr::GetLocaleString(localeData->LogTitle, locale, questLogTitle); - ObjectMgr::GetLocaleString(localeData->LogDescription, locale, questLogDescription); - ObjectMgr::GetLocaleString(localeData->QuestDescription, locale, questDescription); - ObjectMgr::GetLocaleString(localeData->PortraitGiverText, locale, portraitGiverText); - ObjectMgr::GetLocaleString(localeData->PortraitGiverName, locale, portraitGiverName); - ObjectMgr::GetLocaleString(localeData->PortraitTurnInText, locale, portraitTurnInText); - ObjectMgr::GetLocaleString(localeData->PortraitTurnInName, locale, portraitTurnInName); + ObjectMgr::GetLocaleString(questTemplateLocale->LogTitle, localeConstant, questLogTitle); + ObjectMgr::GetLocaleString(questTemplateLocale->LogDescription, localeConstant, questLogDescription); + ObjectMgr::GetLocaleString(questTemplateLocale->QuestDescription, localeConstant, questDescription); + ObjectMgr::GetLocaleString(questTemplateLocale->PortraitGiverText, localeConstant, portraitGiverText); + ObjectMgr::GetLocaleString(questTemplateLocale->PortraitGiverName, localeConstant, portraitGiverName); + ObjectMgr::GetLocaleString(questTemplateLocale->PortraitTurnInText, localeConstant, portraitTurnInText); + ObjectMgr::GetLocaleString(questTemplateLocale->PortraitTurnInName, localeConstant, portraitTurnInName); } } @@ -456,6 +462,8 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const { + LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); + std::string questLogTitle = quest->GetLogTitle(); std::string questLogDescription = quest->GetLogDescription(); std::string questDescription = quest->GetQuestDescription(); @@ -466,29 +474,19 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const std::string portraitTurnInText = quest->GetPortraitTurnInText(); std::string portraitTurnInName = quest->GetPortraitTurnInName(); - QuestObjectives const& objectives = quest->GetObjectives(); - - std::vector<std::string> questObjectiveDescription(objectives.size()); - for (uint8 i = 0; i < objectives.size(); ++i) - questObjectiveDescription[i] = objectives[i].Description; - - int32 locale = _session->GetSessionDbLocaleIndex(); - if (locale >= 0) + if (localeConstant >= LOCALE_enUS) { - if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) + if (QuestTemplateLocale const* questTemplateLocale = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { - ObjectMgr::GetLocaleString(localeData->LogTitle, locale, questLogTitle); - ObjectMgr::GetLocaleString(localeData->LogDescription, locale, questLogDescription); - ObjectMgr::GetLocaleString(localeData->QuestDescription, locale, questDescription); - ObjectMgr::GetLocaleString(localeData->AreaDescription, locale, areaDescription); - ObjectMgr::GetLocaleString(localeData->QuestCompletionLog, locale, questCompletionLog); - ObjectMgr::GetLocaleString(localeData->PortraitGiverText, locale, portraitGiverText); - ObjectMgr::GetLocaleString(localeData->PortraitGiverName, locale, portraitGiverName); - ObjectMgr::GetLocaleString(localeData->PortraitTurnInText, locale, portraitTurnInText); - ObjectMgr::GetLocaleString(localeData->PortraitTurnInName, locale, portraitTurnInName); - - for (uint8 i = 0; i < objectives.size(); ++i) - ObjectMgr::GetLocaleString(localeData->ObjectiveDescription[i], locale, questObjectiveDescription[i]); + ObjectMgr::GetLocaleString(questTemplateLocale->LogTitle, localeConstant, questLogTitle); + ObjectMgr::GetLocaleString(questTemplateLocale->LogDescription, localeConstant, questLogDescription); + ObjectMgr::GetLocaleString(questTemplateLocale->QuestDescription, localeConstant, questDescription); + ObjectMgr::GetLocaleString(questTemplateLocale->AreaDescription, localeConstant, areaDescription); + ObjectMgr::GetLocaleString(questTemplateLocale->QuestCompletionLog, localeConstant, questCompletionLog); + ObjectMgr::GetLocaleString(questTemplateLocale->PortraitGiverText, localeConstant, portraitGiverText); + ObjectMgr::GetLocaleString(questTemplateLocale->PortraitGiverName, localeConstant, portraitGiverName); + ObjectMgr::GetLocaleString(questTemplateLocale->PortraitTurnInText, localeConstant, portraitTurnInText); + ObjectMgr::GetLocaleString(questTemplateLocale->PortraitTurnInName, localeConstant, portraitTurnInName); } } @@ -533,6 +531,12 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const packet.Info.PortraitGiver = quest->GetQuestGiverPortrait(); packet.Info.PortraitTurnIn = quest->GetQuestTurnInPortrait(); + for (uint8 i = 0; i < QUEST_ITEM_DROP_COUNT; ++i) + { + packet.Info.ItemDrop[i] = quest->ItemDrop[i]; + packet.Info.ItemDropQuantity[i] = quest->ItemDropQuantity[i]; + } + if (!quest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS)) { for (uint8 i = 0; i < QUEST_REWARD_ITEM_COUNT; ++i) @@ -569,11 +573,15 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const packet.Info.QuestCompletionLog = questCompletionLog; packet.Info.AllowableRaces = quest->GetAllowableRaces(); - for (QuestObjective const& obj : quest->Objectives) + for (QuestObjective const& questObjective : quest->GetObjectives()) { - packet.Info.Objectives.push_back(obj); - // @todo update quets objective locales - //packet.Info.Objectives.back().Description = questObjectiveDescription[i]; + packet.Info.Objectives.push_back(questObjective); + + if (localeConstant >= LOCALE_enUS) + { + if (QuestObjectivesLocale const* questObjectivesLocale = sObjectMgr->GetQuestObjectivesLocale(questObjective.ID)) + ObjectMgr::GetLocaleString(questObjectivesLocale->Description, localeConstant, packet.Info.Objectives.back().Description); + } } for (uint32 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i) @@ -599,24 +607,24 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUID, bool enableNext) const { - std::string questTitle = quest->GetLogTitle(); - std::string questOfferRewardText = quest->GetOfferRewardText(); - std::string portraitGiverText = quest->GetPortraitGiverText(); - std::string portraitGiverName = quest->GetPortraitGiverName(); - std::string portraitTurnInText = quest->GetPortraitTurnInText(); - std::string portraitTurnInName = quest->GetPortraitTurnInName(); - - int32 locale = _session->GetSessionDbLocaleIndex(); - if (locale >= 0) + std::string questTitle = quest->GetLogTitle(); + std::string questOfferRewardText = quest->GetOfferRewardText(); + std::string portraitGiverText = quest->GetPortraitGiverText(); + std::string portraitGiverName = quest->GetPortraitGiverName(); + std::string portraitTurnInText = quest->GetPortraitTurnInText(); + std::string portraitTurnInName = quest->GetPortraitTurnInName(); + + LocaleConstant locale = _session->GetSessionDbLocaleIndex(); + if (locale >= LOCALE_enUS) { - if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) + if (QuestTemplateLocale const* questTemplateLocale = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { - ObjectMgr::GetLocaleString(localeData->LogTitle, locale, questTitle); - ObjectMgr::GetLocaleString(localeData->OfferRewardText, locale, questOfferRewardText); - ObjectMgr::GetLocaleString(localeData->PortraitGiverText, locale, portraitGiverText); - ObjectMgr::GetLocaleString(localeData->PortraitGiverName, locale, portraitGiverName); - ObjectMgr::GetLocaleString(localeData->PortraitTurnInText, locale, portraitTurnInText); - ObjectMgr::GetLocaleString(localeData->PortraitTurnInName, locale, portraitTurnInName); + ObjectMgr::GetLocaleString(questTemplateLocale->LogTitle, locale, questTitle); + ObjectMgr::GetLocaleString(questTemplateLocale->OfferRewardText, locale, questOfferRewardText); + ObjectMgr::GetLocaleString(questTemplateLocale->PortraitGiverText, locale, portraitGiverText); + ObjectMgr::GetLocaleString(questTemplateLocale->PortraitGiverName, locale, portraitGiverName); + ObjectMgr::GetLocaleString(questTemplateLocale->PortraitTurnInText, locale, portraitTurnInText); + ObjectMgr::GetLocaleString(questTemplateLocale->PortraitTurnInName, locale, portraitTurnInName); } } @@ -665,13 +673,13 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGU std::string questTitle = quest->GetLogTitle(); std::string requestItemsText = quest->GetRequestItemsText(); - int32 locale = _session->GetSessionDbLocaleIndex(); - if (locale >= 0) + LocaleConstant locale = _session->GetSessionDbLocaleIndex(); + if (locale >= LOCALE_enUS) { - if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) + if (QuestTemplateLocale const* questTemplateLocale = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { - ObjectMgr::GetLocaleString(localeData->LogTitle, locale, questTitle); - ObjectMgr::GetLocaleString(localeData->RequestItemsText, locale, requestItemsText); + ObjectMgr::GetLocaleString(questTemplateLocale->LogTitle, locale, questTitle); + ObjectMgr::GetLocaleString(questTemplateLocale->RequestItemsText, locale, requestItemsText); } } diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h index cc0da5ffb36..f244413a325 100644 --- a/src/server/game/Entities/Creature/GossipDef.h +++ b/src/server/game/Entities/Creature/GossipDef.h @@ -258,7 +258,7 @@ class PlayerMenu /*********************************************************/ void SendQuestGiverStatus(uint32 questStatus, ObjectGuid npcGUID) const; - void SendQuestGiverQuestList(QEmote const& eEmote, const std::string& Title, ObjectGuid npcGUID); + void SendQuestGiverQuestList(ObjectGuid npcGUID); void SendQuestQueryResponse(Quest const* quest) const; void SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGUID, bool activateAccept) const; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index e0c9968e588..3b22b68ce74 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -22,6 +22,7 @@ #include "CreatureAISelector.h" #include "DynamicTree.h" #include "GameObjectModel.h" +#include "GameObjectPackets.h" #include "GridNotifiersImpl.h" #include "Group.h" #include "GroupMgr.h" @@ -1371,9 +1372,9 @@ void GameObject::Use(Unit* user) { if (info->goober.pageID) // show page... { - WorldPacket data(SMSG_PAGE_TEXT, 8); - data << GetGUID(); - player->SendDirectMessage(&data); + WorldPackets::GameObject::PageText data; + data.GameObjectGUID = GetGUID(); + player->SendDirectMessage(data.Write()); } else if (info->goober.gossipID) { diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index b4492cd77c7..50bd1ebd9f5 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -30,8 +30,6 @@ class GameObjectAI; class Group; class Transport; -#define MAX_GAMEOBJECT_QUEST_ITEMS 6 - // from `gameobject_template` struct GameObjectTemplate { @@ -45,7 +43,6 @@ struct GameObjectTemplate uint32 faction; uint32 flags; float size; - uint32 questItems[MAX_GAMEOBJECT_QUEST_ITEMS]; int32 unkInt32; union { @@ -847,6 +844,9 @@ struct GameObjectData bool dbData; }; +typedef std::vector<uint32> GameObjectQuestItemList; +typedef std::unordered_map<uint32, GameObjectQuestItemList> GameObjectQuestItemMap; + // For containers: [GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY -> ... // For bobber: GO_NOT_READY ->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED-><deleted> // For door(closed):[GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY(close) -> ... diff --git a/src/server/game/Entities/Item/ItemTemplate.cpp b/src/server/game/Entities/Item/ItemTemplate.cpp index 983a263f725..10d8272fca8 100644 --- a/src/server/game/Entities/Item/ItemTemplate.cpp +++ b/src/server/game/Entities/Item/ItemTemplate.cpp @@ -20,6 +20,7 @@ #include "DB2Stores.h" #include "World.h" #include "ItemTemplate.h" +#include "Player.h" char const* ItemTemplate::GetName(LocaleConstant locale) const { @@ -136,3 +137,19 @@ void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamag minDamage = (GetStatScalingFactor() * -0.5f + 1.0f) * avgDamage; maxDamage = floor(float(avgDamage * (GetStatScalingFactor() * 0.5f + 1.0f) + 0.5f)); } + +bool ItemTemplate::CanWinForPlayer(Player const* player) const +{ + if (!Specializations.size()) + return true; + + uint32 spec = player->GetSpecId(player->GetActiveTalentGroup()); + if (!spec) + spec = player->GetDefaultSpecId(); + + if (!spec) + return false; + + UsableTalentSpecs::const_iterator itr = Specializations.find(spec); + return itr != Specializations.end(); +} diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h index eb5fbc2e022..9ab04727ced 100644 --- a/src/server/game/Entities/Item/ItemTemplate.h +++ b/src/server/game/Entities/Item/ItemTemplate.h @@ -584,6 +584,9 @@ const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] = #define MIN_ITEM_LEVEL 1 #define MAX_ITEM_LEVEL 1000 +class Player; +typedef std::set<uint32> UsableTalentSpecs; + struct ItemTemplate { ItemEntry const* BasicData; @@ -655,6 +658,7 @@ struct ItemTemplate uint32 MaxMoneyLoot; uint32 FlagsCu; float SpellPPMRate; + UsableTalentSpecs Specializations; // helpers bool CanChangeEquipStateInCombat() const @@ -701,6 +705,7 @@ struct ItemTemplate char const* GetDefaultLocaleName() const; uint32 GetArmor(uint32 itemLevel) const; void GetDamage(uint32 itemLevel, float& minDamage, float& maxDamage) const; + bool CanWinForPlayer(Player const* player) const; }; // Benchmarked: Faster than std::map (insert/find) diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 3fbe9fbf63a..e3869761118 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -52,6 +52,7 @@ #include "BattlefieldMgr.h" #include "Battleground.h" #include "Chat.h" +#include "GameObjectPackets.h" Object::Object() { @@ -760,6 +761,7 @@ void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* targe uint32* flags = NULL; uint32 visibleFlag = GetUpdateFieldData(target, flags); + ASSERT(flags); for (uint16 index = 0; index < m_valuesCount; ++index) { @@ -2358,9 +2360,9 @@ void WorldObject::SendMessageToSet(WorldPacket const* data, Player const* skippe void WorldObject::SendObjectDeSpawnAnim(ObjectGuid guid) { - WorldPacket data(SMSG_GAME_OBJECT_DESPAWN, 8); - data << guid; - SendMessageToSet(&data, true); + WorldPackets::GameObject::GameObjectDespawn packet; + packet.ObjectGUID = guid; + SendMessageToSet(packet.Write(), true); } void WorldObject::SetMap(Map* map) @@ -3315,7 +3317,7 @@ void WorldObject::RebuildTerrainSwaps() { // only add terrain swaps for current map MapEntry const* mapEntry = sMapStore.LookupEntry(swap); - if (!mapEntry || mapEntry->ParentMapID != GetMapId()) + if (!mapEntry || mapEntry->ParentMapID != int32(GetMapId())) continue; conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap); @@ -3346,7 +3348,7 @@ void WorldObject::RebuildWorldMapAreaSwaps() // Clear all world map area swaps, will be rebuilt below _worldMapAreaSwaps.clear(); - // get ALL default terrain swaps, if we are using it (condition is true) + // get ALL default terrain swaps, if we are using it (condition is true) // send the worldmaparea for it, to see swapped worldmaparea in client from other maps too, not just from our current TerrainPhaseInfo defaults = sObjectMgr->GetDefaultTerrainSwapStore(); for (TerrainPhaseInfo::const_iterator itr = defaults.begin(); itr != defaults.end(); ++itr) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 7e49ddd007d..8e8b81b6b99 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -9459,7 +9459,7 @@ uint32 Player::GetXPRestBonus(uint32 xp) SetRestBonus(GetRestBonus() - rested_bonus); - TC_LOG_DEBUG("entities.player", "Player gain %u xp (+ %u Rested Bonus). Rested points=%f", xp+rested_bonus, rested_bonus, GetRestBonus()); + TC_LOG_DEBUG("entities.player", "GetXPRestBonus: Player %s (%u) gain %u xp (+%u Rested Bonus). Rested points=%f", GetName().c_str(), GetGUID().GetCounter(), xp + rested_bonus, rested_bonus, GetRestBonus()); return rested_bonus; } @@ -13605,30 +13605,40 @@ void Player::SendItemDurations() (*itr)->SendTimeUpdate(this); } -void Player::SendNewItem(Item* item, uint32 count, bool received, bool created, bool broadcast) +void Player::SendNewItem(Item* item, uint32 quantity, bool pushed, bool created, bool broadcast) { - if (!item) // prevent crash + if (!item) // prevent crash return; - // last check 2.0.10 - WorldPacket data(SMSG_ITEM_PUSH_RESULT, (8+4+4+4+1+4+4+4+4+4)); - data << GetGUID(); // player GUID - data << uint32(received); // 0=looted, 1=from npc - data << uint32(created); // 0=received, 1=created - data << uint32(1); // bool print error to chat - data << uint8(item->GetBagSlot()); // bagslot - // item slot, but when added to stack: 0xFFFFFFFF - data << uint32((item->GetCount() == count) ? item->GetSlot() : -1); - data << uint32(item->GetEntry()); // item id - data << uint32(item->GetItemSuffixFactor()); // SuffixFactor - data << int32(item->GetItemRandomPropertyId()); // random item property id - data << uint32(count); // count of items - data << uint32(GetItemCount(item->GetEntry())); // count of items in inventory + /// @todo: fix 6.x implementation + WorldPackets::Item::ItemPushResult packet; + + packet.PlayerGUID = GetGUID(); + + packet.Slot = item->GetBagSlot(); + packet.SlotInBag = item->GetCount() == quantity ? item->GetSlot() : -1; + + packet.Item.Initialize(item); + + //packet.ReadUInt32("WodUnk"); + packet.Quantity = quantity; + packet.QuantityInInventory = GetItemCount(item->GetEntry()); + //packet.ReadUInt32("BattlePetBreedID"); + //packet.ReadUInt32("BattlePetBreedQuality"); + //packet.ReadUInt32("BattlePetSpeciesID"); + //packet.ReadUInt32("BattlePetLevel"); + + packet.ItemGUID = item->GetGUID(); + + packet.Pushed = pushed; + packet.DisplayText = true; + packet.Created = created; + //packet.ReadBit("IsBonusRoll"); if (broadcast && GetGroup()) - GetGroup()->BroadcastPacket(&data, true); + GetGroup()->BroadcastPacket(packet.Write(), true); else - GetSession()->SendPacket(&data); + GetSession()->SendPacket(packet.Write()); } /*********************************************************/ @@ -14108,48 +14118,7 @@ void Player::SendPreparedQuest(ObjectGuid guid) } } - QEmote qe; - qe._Delay = 0; - qe._Emote = 0; - std::string title = ""; - - // need pet case for some quests - Creature* creature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, guid); - if (creature) - { - uint32 textid = GetGossipTextId(creature); - GossipText const* gossiptext = sObjectMgr->GetGossipText(textid); - if (!gossiptext) - { - qe._Delay = 0; //TEXTEMOTE_MESSAGE; //zyg: player emote - qe._Emote = 0; //TEXTEMOTE_HELLO; //zyg: NPC emote - title.clear(); - } - else - { - qe = gossiptext->Options[0].Emotes[0]; - - if (!gossiptext->Options[0].Text_0.empty()) - { - title = gossiptext->Options[0].Text_0; - - int loc_idx = GetSession()->GetSessionDbLocaleIndex(); - if (loc_idx >= 0) - if (NpcTextLocale const* nl = sObjectMgr->GetNpcTextLocale(textid)) - ObjectMgr::GetLocaleString(nl->Text_0[0], loc_idx, title); - } - else - { - title = gossiptext->Options[0].Text_1; - - int loc_idx = GetSession()->GetSessionDbLocaleIndex(); - if (loc_idx >= 0) - if (NpcTextLocale const* nl = sObjectMgr->GetNpcTextLocale(textid)) - ObjectMgr::GetLocaleString(nl->Text_1[0], loc_idx, title); - } - } - } - PlayerTalkClass->SendQuestGiverQuestList(qe, title, guid); + PlayerTalkClass->SendQuestGiverQuestList(guid); } bool Player::IsActiveQuest(uint32 quest_id) const @@ -14444,13 +14413,16 @@ bool Player::CanRewardQuest(Quest const* quest, uint32 reward, bool msg) ItemPosCountVec dest; if (quest->GetRewChoiceItemsCount() > 0) { - if (quest->RewardChoiceItemId[reward]) + for (uint32 i = 0; i < quest->GetRewChoiceItemsCount(); ++i) { - InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, quest->RewardChoiceItemId[reward], quest->RewardChoiceItemCount[reward]); - if (res != EQUIP_ERR_OK) + if (quest->RewardChoiceItemId[i] && quest->RewardChoiceItemId[i] == reward) { - SendEquipError(res, NULL, NULL, quest->RewardChoiceItemId[reward]); - return false; + InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, quest->RewardChoiceItemId[i], quest->RewardChoiceItemCount[i]); + if (res != EQUIP_ERR_OK) + { + SendEquipError(res, NULL, NULL, quest->RewardChoiceItemId[i]); + return false; + } } } } @@ -14471,6 +14443,32 @@ bool Player::CanRewardQuest(Quest const* quest, uint32 reward, bool msg) } } + // QuestPackageItem.db2 + if (quest->GetQuestPackageID()) + { + if (std::vector<QuestPackageItemEntry const*> const* questPackageItems = sDB2Manager.GetQuestPackageItems(quest->GetQuestPackageID())) + { + for (QuestPackageItemEntry const* questPackageItem : *questPackageItems) + { + if (questPackageItem->ItemID != reward) + continue; + + if (ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(questPackageItem->ItemID)) + { + if (rewardProto->CanWinForPlayer(this)) + { + InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, questPackageItem->ItemID, questPackageItem->ItemCount); + if (res != EQUIP_ERR_OK) + { + SendEquipError(res, NULL, NULL, questPackageItem->ItemID); + return false; + } + } + } + } + } + } + return true; } @@ -14622,7 +14620,8 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, switch (obj.Type) { case QUEST_OBJECTIVE_ITEM: - DestroyItemCount(obj.ObjectID, obj.Amount, true); + if (!(quest->GetFlagsEx() & QUEST_FLAGS_EX_KEEP_ADDITIONAL_ITEMS)) + DestroyItemCount(obj.ObjectID, obj.Amount, true); break; case QUEST_OBJECTIVE_CURRENCY: ModifyCurrency(obj.ObjectID, -int32(obj.Amount)); @@ -14630,12 +14629,15 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, } } - for (uint8 i = 0; i < QUEST_ITEM_DROP_COUNT; ++i) + if (!(quest->GetFlagsEx() & QUEST_FLAGS_EX_KEEP_ADDITIONAL_ITEMS)) { - if (quest->ItemDrop[i]) + for (uint8 i = 0; i < QUEST_ITEM_DROP_COUNT; ++i) { - uint32 count = quest->ItemDropQuantity[i]; - DestroyItemCount(quest->ItemDrop[i], count ? count : 9999, true); + if (quest->ItemDrop[i]) + { + uint32 count = quest->ItemDropQuantity[i]; + DestroyItemCount(quest->ItemDrop[i], count ? count : 9999, true); + } } } @@ -14643,13 +14645,42 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, if (quest->GetRewChoiceItemsCount() > 0) { - if (uint32 itemId = quest->RewardChoiceItemId[reward]) + for (uint32 i = 0; i < quest->GetRewChoiceItemsCount(); ++i) { - ItemPosCountVec dest; - if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, quest->RewardChoiceItemCount[reward]) == EQUIP_ERR_OK) + if (quest->RewardChoiceItemId[i] && quest->RewardChoiceItemId[i] == reward) + { + ItemPosCountVec dest; + if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, reward, quest->RewardChoiceItemCount[i]) == EQUIP_ERR_OK) + { + Item* item = StoreNewItem(dest, reward, true, Item::GenerateItemRandomPropertyId(reward)); + SendNewItem(item, quest->RewardChoiceItemCount[i], true, false); + } + } + } + } + + // QuestPackageItem.db2 + if (quest->GetQuestPackageID()) + { + if (std::vector<QuestPackageItemEntry const*> const* questPackageItems = sDB2Manager.GetQuestPackageItems(quest->GetQuestPackageID())) + { + for (QuestPackageItemEntry const* questPackageItem : *questPackageItems) { - Item* item = StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); - SendNewItem(item, quest->RewardChoiceItemCount[reward], true, false); + if (questPackageItem->ItemID != reward) + continue; + + if (ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(questPackageItem->ItemID)) + { + if (rewardProto->CanWinForPlayer(this)) + { + ItemPosCountVec dest; + if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, questPackageItem->ItemID, questPackageItem->ItemCount) == EQUIP_ERR_OK) + { + Item* item = StoreNewItem(dest, questPackageItem->ItemID, true, Item::GenerateItemRandomPropertyId(questPackageItem->ItemID)); + SendNewItem(item, questPackageItem->ItemCount, true, false); + } + } + } } } } @@ -16223,9 +16254,9 @@ void Player::SendQuestComplete(Quest const* quest) { if (quest) { - WorldPacket data(SMSG_QUEST_UPDATE_COMPLETE, 4); - data << uint32(quest->GetQuestId()); - GetSession()->SendPacket(&data); + WorldPackets::Quest::QuestUpdateComplete data; + data.QuestID = quest->GetQuestId(); + GetSession()->SendPacket(data.Write()); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = %u", quest->GetQuestId()); } } @@ -16298,25 +16329,27 @@ void Player::SendCanTakeQuestResponse(QuestFailedReason msg) const TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_INVALID"); } -void Player::SendQuestConfirmAccept(const Quest* quest, Player* pReceiver) +void Player::SendQuestConfirmAccept(Quest const* quest, Player* receiver) { - if (pReceiver) - { - std::string strTitle = quest->GetLogTitle(); + if (!receiver) + return; - int loc_idx = pReceiver->GetSession()->GetSessionDbLocaleIndex(); - if (loc_idx >= 0) - if (const QuestLocale* pLocale = sObjectMgr->GetQuestLocale(quest->GetQuestId())) - ObjectMgr::GetLocaleString(pLocale->LogTitle, loc_idx, strTitle); + std::string questTitle = quest->GetLogTitle(); + uint32 questID = quest->GetQuestId(); - WorldPacket data(SMSG_QUEST_CONFIRM_ACCEPT, (4 + strTitle.size() + 8)); - data << uint32(quest->GetQuestId()); - data << strTitle; - data << GetGUID(); - pReceiver->GetSession()->SendPacket(&data); + LocaleConstant localeConstant = receiver->GetSession()->GetSessionDbLocaleIndex(); + if (localeConstant >= LOCALE_enUS) + if (QuestTemplateLocale const* questTemplateLocale = sObjectMgr->GetQuestLocale(questID)) + ObjectMgr::GetLocaleString(questTemplateLocale->LogTitle, localeConstant, questTitle); - TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_CONFIRM_ACCEPT"); - } + WorldPackets::Quest::QuestConfirmAccept packet; + packet.QuestID = questID; + packet.InitiatedBy = GetGUID(); + packet.QuestTitle = questTitle; + + receiver->GetSession()->SendPacket(packet.Write()); + + TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_CONFIRM_ACCEPT"); } void Player::SendPushToPartyResponse(Player* player, uint8 msg) @@ -22442,9 +22475,6 @@ void Player::SendInitialPacketsBeforeAddToMap() /// Pass 'this' as argument because we're not stored in ObjectAccessor yet GetSocial()->SendSocialList(this, SOCIAL_FLAG_ALL); - /// SMSG_SPELL_CATEGORY_COOLDOWN - GetSession()->SendSpellCategoryCooldowns(); - /// SMSG_BINDPOINTUPDATE SendBindPointUpdate(); @@ -22475,8 +22505,6 @@ void Player::SendInitialPacketsBeforeAddToMap() /// SMSG_INITIALIZE_FACTIONS m_reputationMgr->SendInitialReputations(); - /// SMSG_SET_FORCED_REACTIONS - m_reputationMgr->SendForceReactions(); /// SMSG_SETUP_CURRENCY SendCurrencies(); /// SMSG_EQUIPMENT_SET_LIST @@ -24602,11 +24630,11 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot) SendEquipError(msg, NULL, NULL, item->itemid); } -bool Player::IsKnowHowFlyIn(uint32 mapid, uint32 zone) const +bool Player::CanFlyInZone(uint32 mapid, uint32 zone) const { // continent checked in SpellInfo::CheckLocation at cast and area update uint32 v_map = GetVirtualMapForMapAndZone(mapid, zone); - return v_map != 571 || HasSpell(54197); // Cold Weather Flying + return v_map != 571 || HasSpell(54197); // 54197 = Cold Weather Flying } void Player::LearnSpellHighestRank(uint32 spellid) @@ -25256,11 +25284,11 @@ void Player::_SaveBGData(SQLTransaction& trans) trans->Append(stmt); } -void Player::DeleteEquipmentSet(uint64 setGuid) +void Player::DeleteEquipmentSet(uint64 id) { for (EquipmentSetContainer::iterator itr = _equipmentSets.begin(); itr != _equipmentSets.end();) { - if (itr->second.Data.Guid == setGuid) + if (itr->second.Data.Guid == id) { if (itr->second.State == EQUIPMENT_SET_NEW) itr = _equipmentSets.erase(itr); @@ -26597,4 +26625,12 @@ bool Player::ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 ha return false; return true; -}
\ No newline at end of file +} + +uint32 Player::GetDefaultSpecId() const +{ + ChrClassesEntry const* entry = sChrClassesStore.LookupEntry(getClass()); + if (entry) + return entry->DefaultSpec; + return 0; +} diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 1a650c509d6..9631f9f2cfe 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1571,7 +1571,7 @@ class Player : public Unit, public GridObject<Player> uint32 GetArmorProficiency() const { return m_ArmorProficiency; } bool IsUseEquipedWeapon(bool mainhand) const; bool IsTwoHandUsed() const; - void SendNewItem(Item* item, uint32 count, bool received, bool created, bool broadcast = false); + void SendNewItem(Item* item, uint32 quantity, bool received, bool created, bool broadcast = false); bool BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot); bool BuyCurrencyFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorSlot, uint32 currency, uint32 count); bool _StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot, int32 price, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore); @@ -1714,7 +1714,7 @@ class Player : public Unit, public GridObject<Player> void SendQuestFailed(uint32 questId, InventoryResult reason = EQUIP_ERR_OK); void SendQuestTimerFailed(uint32 questId); void SendCanTakeQuestResponse(QuestFailedReason msg) const; - void SendQuestConfirmAccept(Quest const* quest, Player* pReceiver); + void SendQuestConfirmAccept(Quest const* quest, Player* receiver); void SendPushToPartyResponse(Player* player, uint8 msg); void SendQuestUpdateAddCredit(Quest const* quest, ObjectGuid guid, QuestObjective const& obj, uint16 count); void SendQuestUpdateAddPlayer(Quest const* quest, uint16 newCount, uint32 required); @@ -1892,6 +1892,7 @@ class Player : public Unit, public GridObject<Player> void SetActiveTalentGroup(uint8 group){ _talentMgr->ActiveGroup = group; } uint8 GetTalentGroupsCount() const { return _talentMgr->GroupsCount; } void SetTalentGroupsCount(uint8 count) { _talentMgr->GroupsCount = count; } + uint32 GetDefaultSpecId() const; bool ResetTalents(bool noCost = false); uint32 GetNextResetTalentsCost() const; @@ -2281,7 +2282,7 @@ class Player : public Unit, public GridObject<Player> void SendEquipmentSetList(); void SetEquipmentSet(EquipmentSetInfo::EquipmentSetData&& newEqSet); - void DeleteEquipmentSet(uint64 setGuid); + void DeleteEquipmentSet(uint64 id); void SendInitWorldStates(uint32 zone, uint32 area); void SendUpdateWorldState(uint32 variable, uint32 value, bool hidden = false); @@ -2395,7 +2396,7 @@ class Player : public Unit, public GridObject<Player> void SetFallInformation(uint32 time, float z); void HandleFall(MovementInfo const& movementInfo); - bool IsKnowHowFlyIn(uint32 mapid, uint32 zone) const; + bool CanFlyInZone(uint32 mapid, uint32 zone) const; void SetClientControl(Unit* target, bool allowMove); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 6a17f4f34c8..0394911d9fe 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3462,6 +3462,77 @@ void Unit::RemoveAura(Aura* aura, AuraRemoveMode mode) RemoveAura(aurApp, mode); } +void Unit::RemoveAppliedAuras(std::function<bool(AuraApplication const*)> const& check) +{ + for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();) + { + if (check(iter->second)) + { + RemoveAura(iter); + continue; + } + ++iter; + } +} + +void Unit::RemoveOwnedAuras(std::function<bool(Aura const*)> const& check) +{ + for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();) + { + if (check(iter->second)) + { + RemoveOwnedAura(iter); + continue; + } + ++iter; + } +} + +void Unit::RemoveAppliedAuras(uint32 spellId, std::function<bool(AuraApplication const*)> const& check) +{ + for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);) + { + if (check(iter->second)) + { + RemoveAura(iter); + continue; + } + ++iter; + } +} + +void Unit::RemoveOwnedAuras(uint32 spellId, std::function<bool(Aura const*)> const& check) +{ + for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);) + { + if (check(iter->second)) + { + RemoveOwnedAura(iter); + continue; + } + ++iter; + } +} + +void Unit::RemoveAurasByType(AuraType auraType, std::function<bool(AuraApplication const*)> const& check) +{ + for (AuraEffectList::iterator iter = m_modAuras[auraType].begin(); iter != m_modAuras[auraType].end();) + { + Aura* aura = (*iter)->GetBase(); + AuraApplication * aurApp = aura->GetApplicationOfTarget(GetGUID()); + ASSERT(aurApp); + + ++iter; + if (check(aurApp)) + { + uint32 removedAuras = m_removedAurasCount; + RemoveAura(aurApp); + if (m_removedAurasCount > removedAuras + 1) + iter = m_modAuras[auraType].begin(); + } + } +} + void Unit::RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID, uint32 reqEffMask, AuraRemoveMode removeMode) { for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);) @@ -13304,9 +13375,9 @@ bool Unit::HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura) void Unit::SendDurabilityLoss(Player* receiver, uint32 percent) { - WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 4); - data << uint32(percent); - receiver->GetSession()->SendPacket(&data); + WorldPackets::Misc::DurabilityDamageDeath packet; + packet.Percent = percent; + receiver->GetSession()->SendPacket(packet.Write()); } void Unit::SetAIAnimKitId(uint16 animKitId) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 87254d230e6..e6f6ff13f37 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1779,6 +1779,16 @@ class Unit : public WorldObject void RemoveAura(AuraApplication * aurApp, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); void RemoveAura(Aura* aur, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + // Convenience methods removing auras by predicate + void RemoveAppliedAuras(std::function<bool(AuraApplication const*)> const& check); + void RemoveOwnedAuras(std::function<bool(Aura const*)> const& check); + + // Optimized overloads taking advantage of map key + void RemoveAppliedAuras(uint32 spellId, std::function<bool(AuraApplication const*)> const& check); + void RemoveOwnedAuras(uint32 spellId, std::function<bool(Aura const*)> const& check); + + void RemoveAurasByType(AuraType auraType, std::function<bool(AuraApplication const*)> const& check); + void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit* dispeller, uint8 chargesRemoved = 1); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 51063666470..43371c5aff8 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -302,14 +302,14 @@ ObjectMgr::~ObjectMgr() delete itr->second; } -void ObjectMgr::AddLocaleString(std::string const& s, LocaleConstant locale, StringVector& data) +void ObjectMgr::AddLocaleString(std::string const& value, LocaleConstant localeConstant, StringVector& data) { - if (!s.empty()) + if (!value.empty()) { - if (data.size() <= size_t(locale)) - data.resize(locale + 1); + if (data.size() <= size_t(localeConstant)) + data.resize(localeConstant + 1); - data[locale] = s; + data[localeConstant] = value; } } @@ -341,7 +341,7 @@ void ObjectMgr::LoadCreatureLocales() CreatureLocale& data = _creatureLocaleStore[entry]; - for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) + for (uint8 i = OLD_TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = (LocaleConstant) i; AddLocaleString(fields[1 + 3 * (i - 1)].GetString(), locale, data.Name); @@ -378,7 +378,7 @@ void ObjectMgr::LoadGossipMenuItemsLocales() GossipMenuItemsLocale& data = _gossipMenuItemsLocaleStore[MAKE_PAIR32(menuId, id)]; - for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) + for (uint8 i = OLD_TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = (LocaleConstant) i; AddLocaleString(fields[2 + 2 * (i - 1)].GetString(), locale, data.OptionText); @@ -394,10 +394,10 @@ void ObjectMgr::LoadPointOfInterestLocales() { uint32 oldMSTime = getMSTime(); - _pointOfInterestLocaleStore.clear(); // need for reload case - - QueryResult result = WorldDatabase.Query("SELECT ID, Name_loc1, Name_loc2, Name_loc3, Name_loc4, Name_loc5, Name_loc6, Name_loc7, Name_loc8 FROM locales_points_of_interest"); + _pointOfInterestLocaleStore.clear(); // need for reload case + // 0 1 2 + QueryResult result = WorldDatabase.Query("SELECT ID, locale, Name FROM points_of_interest_locale"); if (!result) return; @@ -405,12 +405,14 @@ void ObjectMgr::LoadPointOfInterestLocales() { Field* fields = result->Fetch(); - uint32 entry = fields[0].GetUInt32(); + uint32 id = fields[0].GetUInt32(); + std::string localeName = fields[1].GetString(); + std::string name = fields[2].GetString(); - PointOfInterestLocale& data = _pointOfInterestLocaleStore[entry]; + PointOfInterestLocale& data = _pointOfInterestLocaleStore[id]; + LocaleConstant locale = GetLocaleByName(localeName); - for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) - AddLocaleString(fields[i].GetString(), LocaleConstant(i), data.IconName); + AddLocaleString(name, locale, data.Name); } while (result->NextRow()); TC_LOG_INFO("server.loading", ">> Loaded %u points_of_interest locale strings in %u ms", uint32(_pointOfInterestLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); @@ -434,11 +436,8 @@ void ObjectMgr::LoadCreatureTemplates() "spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, " // 64 65 66 67 68 69 70 71 72 "InhabitType, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, " - // 73 74 75 76 77 78 79 - "RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, " - // 80 81 82 83 84 - "movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName " - "FROM creature_template"); + // 73 74 75 76 77 78 + "RacialLeader, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template"); if (!result) { @@ -539,14 +538,11 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields) creatureTemplate.ModExperience = fields[72].GetFloat(); creatureTemplate.RacialLeader = fields[73].GetBool(); - for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) - creatureTemplate.questItems[i] = fields[74 + i].GetUInt32(); - - creatureTemplate.movementId = fields[80].GetUInt32(); - creatureTemplate.RegenHealth = fields[81].GetBool(); - creatureTemplate.MechanicImmuneMask = fields[82].GetUInt32(); - creatureTemplate.flags_extra = fields[83].GetUInt32(); - creatureTemplate.ScriptID = GetScriptId(fields[84].GetCString()); + creatureTemplate.movementId = fields[74].GetUInt32(); + creatureTemplate.RegenHealth = fields[75].GetBool(); + creatureTemplate.MechanicImmuneMask = fields[76].GetUInt32(); + creatureTemplate.flags_extra = fields[77].GetUInt32(); + creatureTemplate.ScriptID = GetScriptId(fields[78].GetCString()); } void ObjectMgr::LoadCreatureTemplateAddons() @@ -2443,6 +2439,32 @@ void ObjectMgr::LoadItemTemplates() itemTemplate.MaxMoneyLoot = 0; itemTemplate.FlagsCu = 0; itemTemplate.SpellPPMRate = 0.0f; + + /*for (uint32 i = 0; i < sItemSpecStore.GetNumRows(); ++i) + { + if (ItemSpecEntry const* spec = sItemSpecStore.LookupEntry(i)) + { + if (itemTemplate.GetBaseItemLevel() >= spec->MinLevel && itemTemplate.GetBaseItemLevel() <= spec->MaxLevel) + { + // have to research what are these! + if (spec->PrimaryStat && spec->SecondaryStat && spec->ItemType) + { + itemTemplate.Specializations.insert(spec->SpecID); + } + } + } + }*/ + + ItemSpecOverridesStore::const_iterator spec = sItemSpecOverridesStore.find(itemTemplate.GetId()); + if (spec != sItemSpecOverridesStore.end()) + { + itemTemplate.Specializations.clear(); + for (ItemSpecOverrideEntry const* over : (*spec).second) + { + itemTemplate.Specializations.insert(over->SpecID); + } + } + ++sparseCount; } @@ -4229,23 +4251,16 @@ void ObjectMgr::LoadQuests() TC_LOG_INFO("server.loading", ">> Loaded %lu quests definitions in %u ms", (unsigned long)_questTemplates.size(), GetMSTimeDiffToNow(oldMSTime)); } -void ObjectMgr::LoadQuestLocales() +void ObjectMgr::LoadQuestTemplateLocale() { uint32 oldMSTime = getMSTime(); - _questLocaleStore.clear(); // need for reload case - - QueryResult result = WorldDatabase.Query("SELECT Id, " - "Title_loc1, Details_loc1, Objectives_loc1, OfferRewardText_loc1, RequestItemsText_loc1, EndText_loc1, CompletedText_loc1, ObjectiveText1_loc1, ObjectiveText2_loc1, ObjectiveText3_loc1, ObjectiveText4_loc1, QuestGiverTextWindow_loc1, QuestGiverTargetName_loc1, QuestTurnTextWindow_loc1, QuestTurnTargetName_loc1," - "Title_loc2, Details_loc2, Objectives_loc2, OfferRewardText_loc2, RequestItemsText_loc2, EndText_loc2, CompletedText_loc2, ObjectiveText1_loc2, ObjectiveText2_loc2, ObjectiveText3_loc2, ObjectiveText4_loc2, QuestGiverTextWindow_loc2, QuestGiverTargetName_loc2, QuestTurnTextWindow_loc2, QuestTurnTargetName_loc2," - "Title_loc3, Details_loc3, Objectives_loc3, OfferRewardText_loc3, RequestItemsText_loc3, EndText_loc3, CompletedText_loc3, ObjectiveText1_loc3, ObjectiveText2_loc3, ObjectiveText3_loc3, ObjectiveText4_loc3, QuestGiverTextWindow_loc3, QuestGiverTargetName_loc3, QuestTurnTextWindow_loc3, QuestTurnTargetName_loc3," - "Title_loc4, Details_loc4, Objectives_loc4, OfferRewardText_loc4, RequestItemsText_loc4, EndText_loc4, CompletedText_loc4, ObjectiveText1_loc4, ObjectiveText2_loc4, ObjectiveText3_loc4, ObjectiveText4_loc4, QuestGiverTextWindow_loc4, QuestGiverTargetName_loc4, QuestTurnTextWindow_loc4, QuestTurnTargetName_loc4," - "Title_loc5, Details_loc5, Objectives_loc5, OfferRewardText_loc5, RequestItemsText_loc5, EndText_loc5, CompletedText_loc5, ObjectiveText1_loc5, ObjectiveText2_loc5, ObjectiveText3_loc5, ObjectiveText4_loc5, QuestGiverTextWindow_loc5, QuestGiverTargetName_loc5, QuestTurnTextWindow_loc5, QuestTurnTargetName_loc5," - "Title_loc6, Details_loc6, Objectives_loc6, OfferRewardText_loc6, RequestItemsText_loc6, EndText_loc6, CompletedText_loc6, ObjectiveText1_loc6, ObjectiveText2_loc6, ObjectiveText3_loc6, ObjectiveText4_loc6, QuestGiverTextWindow_loc6, QuestGiverTargetName_loc6, QuestTurnTextWindow_loc6, QuestTurnTargetName_loc6," - "Title_loc7, Details_loc7, Objectives_loc7, OfferRewardText_loc7, RequestItemsText_loc7, EndText_loc7, CompletedText_loc7, ObjectiveText1_loc7, ObjectiveText2_loc7, ObjectiveText3_loc7, ObjectiveText4_loc7, QuestGiverTextWindow_loc7, QuestGiverTargetName_loc7, QuestTurnTextWindow_loc7, QuestTurnTargetName_loc7," - "Title_loc8, Details_loc8, Objectives_loc8, OfferRewardText_loc8, RequestItemsText_loc8, EndText_loc8, CompletedText_loc8, ObjectiveText1_loc8, ObjectiveText2_loc8, ObjectiveText3_loc8, ObjectiveText4_loc8, QuestGiverTextWindow_loc8, QuestGiverTargetName_loc8, QuestTurnTextWindow_loc8, QuestTurnTargetName_loc8" - " FROM locales_quest"); - + _questTemplateLocaleStore.clear(); // need for reload case + // 0 1 + QueryResult result = WorldDatabase.Query("SELECT Id, locale, " + // 2 3 4 5 6 7 8 9 10 + "LogTitle, LogDescription, QuestDescription, AreaDescription, PortraitGiverText, PortraitGiverName, PortraitTurnInText, PortraitTurnInName, QuestCompletionLog" + " FROM quest_template_locale"); if (!result) return; @@ -4253,34 +4268,63 @@ void ObjectMgr::LoadQuestLocales() { Field* fields = result->Fetch(); - uint32 entry = fields[0].GetUInt32(); + uint32 id = fields[0].GetUInt32(); + std::string localeName = fields[1].GetString(); + + std::string logTitle = fields[2].GetString(); + std::string logDescription = fields[3].GetString(); + std::string questDescription = fields[4].GetString(); + std::string areaDescription = fields[5].GetString(); + std::string portraitGiverText = fields[6].GetString(); + std::string portraitGiverName = fields[7].GetString(); + std::string portraitTurnInText = fields[8].GetString(); + std::string portraitTurnInName = fields[9].GetString(); + std::string questCompletionLog = fields[10].GetString(); + + QuestTemplateLocale& data = _questTemplateLocaleStore[id]; + LocaleConstant locale = GetLocaleByName(localeName); + + AddLocaleString(logTitle, locale, data.LogTitle); + AddLocaleString(logDescription, locale, data.LogDescription); + AddLocaleString(questDescription, locale, data.QuestDescription); + AddLocaleString(areaDescription, locale, data.AreaDescription); + AddLocaleString(portraitGiverText, locale, data.PortraitGiverText); + AddLocaleString(portraitGiverName, locale, data.PortraitGiverName); + AddLocaleString(portraitTurnInText, locale, data.PortraitTurnInText); + AddLocaleString(portraitTurnInName, locale, data.PortraitTurnInName); + AddLocaleString(questCompletionLog, locale, data.QuestCompletionLog); + } while (result->NextRow()); - QuestLocale& data = _questLocaleStore[entry]; + TC_LOG_INFO("server.loading", ">> Loaded %u Quest Tempalate locale strings in %u ms", uint32(_questTemplateLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); +} - for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) - { - LocaleConstant locale = (LocaleConstant) i; +void ObjectMgr::LoadQuestObjectivesLocale() +{ + uint32 oldMSTime = getMSTime(); + + _questObjectivesLocaleStore.clear(); // need for reload case + // 0 1 2 + QueryResult result = WorldDatabase.Query("SELECT Id, locale, Description FROM quest_objectives_locale"); + if (!result) + return; + + do + { + Field* fields = result->Fetch(); - AddLocaleString(fields[1 + 15 * (i - 1)].GetString(), locale, data.LogTitle); - AddLocaleString(fields[1 + 15 * (i - 1) + 1].GetString(), locale, data.LogDescription); - AddLocaleString(fields[1 + 15 * (i - 1) + 2].GetString(), locale, data.QuestDescription); - AddLocaleString(fields[1 + 15 * (i - 1) + 3].GetString(), locale, data.OfferRewardText); - AddLocaleString(fields[1 + 15 * (i - 1) + 4].GetString(), locale, data.RequestItemsText); - AddLocaleString(fields[1 + 15 * (i - 1) + 5].GetString(), locale, data.AreaDescription); - AddLocaleString(fields[1 + 15 * (i - 1) + 6].GetString(), locale, data.QuestCompletionLog); + uint32 id = fields[0].GetUInt32(); + std::string localeName = fields[1].GetString(); - data.ObjectiveDescription.resize(4); - for (uint8 k = 0; k < 4; ++k) - AddLocaleString(fields[1 + 15 * (i - 1) + 7 + k].GetString(), locale, data.ObjectiveDescription[k]); + std::string Description = fields[2].GetString(); - AddLocaleString(fields[1 + 15 * (i - 1) + 11].GetString(), locale, data.PortraitGiverText); - AddLocaleString(fields[1 + 15 * (i - 1) + 12].GetString(), locale, data.PortraitGiverName); - AddLocaleString(fields[1 + 15 * (i - 1) + 13].GetString(), locale, data.PortraitTurnInText); - AddLocaleString(fields[1 + 15 * (i - 1) + 14].GetString(), locale, data.PortraitTurnInName); - } - } while (result->NextRow()); + QuestObjectivesLocale& data = _questObjectivesLocaleStore[id]; + LocaleConstant locale = GetLocaleByName(localeName); - TC_LOG_INFO("server.loading", ">> Loaded %u Quest locale strings in %u ms", uint32(_questLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); + AddLocaleString(Description, locale, data.Description); + } + while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded %u Quest Objectives locale strings in %u ms", uint32(_questObjectivesLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } void ObjectMgr::LoadScripts(ScriptsType type) @@ -4823,7 +4867,6 @@ void ObjectMgr::LoadPageTexts() // 0 1 2 QueryResult result = WorldDatabase.Query("SELECT ID, Text, NextPageID FROM page_text"); - if (!result) { TC_LOG_INFO("server.loading", ">> Loaded 0 page texts. DB table `page_text` is empty!"); @@ -4835,8 +4878,9 @@ void ObjectMgr::LoadPageTexts() { Field* fields = result->Fetch(); - PageText& pageText = _pageTextStore[fields[0].GetUInt32()]; + uint32 id = fields[0].GetUInt32(); + PageText& pageText = _pageTextStore[id]; pageText.Text = fields[1].GetString(); pageText.NextPageID = fields[2].GetUInt32(); @@ -4873,8 +4917,8 @@ void ObjectMgr::LoadPageTextLocales() _pageTextLocaleStore.clear(); // needed for reload case - QueryResult result = WorldDatabase.Query("SELECT ID, Text_loc1, Text_loc2, Text_loc3, Text_loc4, Text_loc5, Text_loc6, Text_loc7, Text_loc8 FROM locales_page_text"); - + // 0 1 2 + QueryResult result = WorldDatabase.Query("SELECT ID, locale, Text FROM page_text_locale"); if (!result) return; @@ -4882,12 +4926,14 @@ void ObjectMgr::LoadPageTextLocales() { Field* fields = result->Fetch(); - uint32 entry = fields[0].GetUInt32(); + uint32 id = fields[0].GetUInt32(); + std::string localeName = fields[1].GetString(); + std::string text = fields[2].GetString(); - PageTextLocale& data = _pageTextLocaleStore[entry]; + PageTextLocale& data = _pageTextLocaleStore[id]; + LocaleConstant locale = GetLocaleByName(localeName); - for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) - AddLocaleString(fields[i].GetString(), LocaleConstant(i), data.Text); + AddLocaleString(text, locale, data.Text); } while (result->NextRow()); TC_LOG_INFO("server.loading", ">> Loaded %u PageText locale strings in %u ms", uint32(_pageTextLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); @@ -5037,80 +5083,63 @@ void ObjectMgr::LoadInstanceEncounters() TC_LOG_INFO("server.loading", ">> Loaded %u instance encounters in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } -GossipText const* ObjectMgr::GetGossipText(uint32 Text_ID) const +NpcText const* ObjectMgr::GetNpcText(uint32 Text_ID) const { - GossipTextContainer::const_iterator itr = _gossipTextStore.find(Text_ID); - if (itr != _gossipTextStore.end()) + NpcTextContainer::const_iterator itr = _npcTextStore.find(Text_ID); + if (itr != _npcTextStore.end()) return &itr->second; return NULL; } -void ObjectMgr::LoadGossipText() +void ObjectMgr::LoadNPCText() { uint32 oldMSTime = getMSTime(); QueryResult result = WorldDatabase.Query("SELECT ID, " - "text0_0, text0_1, BroadcastTextID0, lang0, prob0, em0_0, em0_1, em0_2, em0_3, em0_4, em0_5, " - "text1_0, text1_1, BroadcastTextID1, lang1, prob1, em1_0, em1_1, em1_2, em1_3, em1_4, em1_5, " - "text2_0, text2_1, BroadcastTextID2, lang2, prob2, em2_0, em2_1, em2_2, em2_3, em2_4, em2_5, " - "text3_0, text3_1, BroadcastTextID3, lang3, prob3, em3_0, em3_1, em3_2, em3_3, em3_4, em3_5, " - "text4_0, text4_1, BroadcastTextID4, lang4, prob4, em4_0, em4_1, em4_2, em4_3, em4_4, em4_5, " - "text5_0, text5_1, BroadcastTextID5, lang5, prob5, em5_0, em5_1, em5_2, em5_3, em5_4, em5_5, " - "text6_0, text6_1, BroadcastTextID6, lang6, prob6, em6_0, em6_1, em6_2, em6_3, em6_4, em6_5, " - "text7_0, text7_1, BroadcastTextID7, lang7, prob7, em7_0, em7_1, em7_2, em7_3, em7_4, em7_5 " - "FROM npc_text"); - - + "BroadcastTextID0, Probability0, " + "BroadcastTextID1, Probability1, " + "BroadcastTextID2, Probability2, " + "BroadcastTextID3, Probability3, " + "BroadcastTextID4, Probability4, " + "BroadcastTextID5, Probability5, " + "BroadcastTextID6, Probability6, " + "BroadcastTextID7, Probability7" + " FROM npc_text"); if (!result) { TC_LOG_INFO("server.loading", ">> Loaded 0 npc texts, table is empty!"); return; } - _gossipTextStore.rehash(result->GetRowCount()); - - uint32 count = 0; - uint8 cic; + _npcTextStore.rehash(result->GetRowCount()); do { - ++count; - cic = 0; - Field* fields = result->Fetch(); - uint32 id = fields[cic++].GetUInt32(); - if (!id) + uint32 textID = fields[0].GetUInt32(); + if (!textID) { TC_LOG_ERROR("sql.sql", "Table `npc_text` has record with reserved id 0, ignore."); continue; } - GossipText& gText = _gossipTextStore[id]; + NpcText& npcText = _npcTextStore[textID]; - for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) + for (uint8 i = 0; i < MAX_NPC_TEXT_OPTIONS; ++i) { - gText.Options[i].Text_0 = fields[cic++].GetString(); - gText.Options[i].Text_1 = fields[cic++].GetString(); - gText.Options[i].BroadcastTextID = fields[cic++].GetUInt32(); - gText.Options[i].Language = fields[cic++].GetUInt8(); - gText.Options[i].Probability = fields[cic++].GetFloat(); - - for (uint8 j = 0; j < MAX_GOSSIP_TEXT_EMOTES; ++j) - { - gText.Options[i].Emotes[j]._Delay = fields[cic++].GetUInt16(); - gText.Options[i].Emotes[j]._Emote = fields[cic++].GetUInt16(); - } + npcText.Data[i].BroadcastTextID = fields[1 + i].GetUInt32(); + npcText.Data[i].Probability = fields[1 + i * 2].GetFloat(); } - for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; i++) + for (uint8 i = 0; i < MAX_NPC_TEXT_OPTIONS; i++) { - if (gText.Options[i].BroadcastTextID) + if (npcText.Data[i].BroadcastTextID) { - if (!sBroadcastTextStore.LookupEntry(gText.Options[i].BroadcastTextID)) + if (!sBroadcastTextStore.LookupEntry(npcText.Data[i].BroadcastTextID)) { - TC_LOG_ERROR("sql.sql", "GossipText (Id: %u) in table `npc_text` has non-existing or incompatible BroadcastTextID%u %u.", id, i, gText.Options[i].BroadcastTextID); - gText.Options[i].BroadcastTextID = 0; + TC_LOG_ERROR("sql.sql", "NpcText (Id: %u) in table `npc_text` has non-existing or incompatible Index: %u BroadcastTextID %u.", textID, i, npcText.Data[i].BroadcastTextID); + npcText.Data[i].BroadcastTextID = 0; } } } @@ -5118,49 +5147,7 @@ void ObjectMgr::LoadGossipText() } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %u npc texts in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); -} - -void ObjectMgr::LoadNpcTextLocales() -{ - uint32 oldMSTime = getMSTime(); - - _npcTextLocaleStore.clear(); // need for reload case - - QueryResult result = WorldDatabase.Query("SELECT ID, " - "Text0_0_loc1, Text0_1_loc1, Text1_0_loc1, Text1_1_loc1, Text2_0_loc1, Text2_1_loc1, Text3_0_loc1, Text3_1_loc1, Text4_0_loc1, Text4_1_loc1, Text5_0_loc1, Text5_1_loc1, Text6_0_loc1, Text6_1_loc1, Text7_0_loc1, Text7_1_loc1, " - "Text0_0_loc2, Text0_1_loc2, Text1_0_loc2, Text1_1_loc2, Text2_0_loc2, Text2_1_loc2, Text3_0_loc2, Text3_1_loc1, Text4_0_loc2, Text4_1_loc2, Text5_0_loc2, Text5_1_loc2, Text6_0_loc2, Text6_1_loc2, Text7_0_loc2, Text7_1_loc2, " - "Text0_0_loc3, Text0_1_loc3, Text1_0_loc3, Text1_1_loc3, Text2_0_loc3, Text2_1_loc3, Text3_0_loc3, Text3_1_loc1, Text4_0_loc3, Text4_1_loc3, Text5_0_loc3, Text5_1_loc3, Text6_0_loc3, Text6_1_loc3, Text7_0_loc3, Text7_1_loc3, " - "Text0_0_loc4, Text0_1_loc4, Text1_0_loc4, Text1_1_loc4, Text2_0_loc4, Text2_1_loc4, Text3_0_loc4, Text3_1_loc1, Text4_0_loc4, Text4_1_loc4, Text5_0_loc4, Text5_1_loc4, Text6_0_loc4, Text6_1_loc4, Text7_0_loc4, Text7_1_loc4, " - "Text0_0_loc5, Text0_1_loc5, Text1_0_loc5, Text1_1_loc5, Text2_0_loc5, Text2_1_loc5, Text3_0_loc5, Text3_1_loc1, Text4_0_loc5, Text4_1_loc5, Text5_0_loc5, Text5_1_loc5, Text6_0_loc5, Text6_1_loc5, Text7_0_loc5, Text7_1_loc5, " - "Text0_0_loc6, Text0_1_loc6, Text1_0_loc6, Text1_1_loc6, Text2_0_loc6, Text2_1_loc6, Text3_0_loc6, Text3_1_loc1, Text4_0_loc6, Text4_1_loc6, Text5_0_loc6, Text5_1_loc6, Text6_0_loc6, Text6_1_loc6, Text7_0_loc6, Text7_1_loc6, " - "Text0_0_loc7, Text0_1_loc7, Text1_0_loc7, Text1_1_loc7, Text2_0_loc7, Text2_1_loc7, Text3_0_loc7, Text3_1_loc1, Text4_0_loc7, Text4_1_loc7, Text5_0_loc7, Text5_1_loc7, Text6_0_loc7, Text6_1_loc7, Text7_0_loc7, Text7_1_loc7, " - "Text0_0_loc8, Text0_1_loc8, Text1_0_loc8, Text1_1_loc8, Text2_0_loc8, Text2_1_loc8, Text3_0_loc8, Text3_1_loc1, Text4_0_loc8, Text4_1_loc8, Text5_0_loc8, Text5_1_loc8, Text6_0_loc8, Text6_1_loc8, Text7_0_loc8, Text7_1_loc8 " - " FROM locales_npc_text"); - - if (!result) - return; - - do - { - Field* fields = result->Fetch(); - - uint32 entry = fields[0].GetUInt32(); - - NpcTextLocale& data = _npcTextLocaleStore[entry]; - - for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) - { - LocaleConstant locale = (LocaleConstant) i; - for (uint8 j = 0; j < MAX_GOSSIP_TEXT_OPTIONS; ++j) - { - AddLocaleString(fields[1 + 8 * 2 * (i - 1) + 2 * j].GetString(), locale, data.Text_0[j]); - AddLocaleString(fields[1 + 8 * 2 * (i - 1) + 2 * j + 1].GetString(), locale, data.Text_1[j]); - } - } - } while (result->NextRow()); - - TC_LOG_INFO("server.loading", ">> Loaded %u NpcText locale strings in %u ms", uint32(_npcTextLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u npc texts in %u ms", uint32(_npcTextStore.size()), GetMSTimeDiffToNow(oldMSTime)); } //not very fast function but it is called only once a day, or on starting-up @@ -5349,6 +5336,75 @@ void ObjectMgr::LoadQuestAreaTriggers() TC_LOG_INFO("server.loading", ">> Loaded %u quest trigger points in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } +QuestGreeting const* ObjectMgr::GetQuestGreeting(ObjectGuid guid) const +{ + auto itr = _questGreetingStore.find(guid.GetTypeId()); + if (itr == _questGreetingStore.end()) + return nullptr; + + auto questItr = itr->second.find(guid.GetEntry()); + if (questItr == itr->second.end()) + return nullptr; + + return questItr->second; +} + +void ObjectMgr::LoadQuestGreetings() +{ + uint32 oldMSTime = getMSTime(); + + _questGreetingStore.clear(); // need for reload case + + // 0 1 2 3 + QueryResult result = WorldDatabase.Query("SELECT ID, type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting"); + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 npc texts, table is empty!"); + return; + } + + _questGreetingStore.rehash(result->GetRowCount()); + + do + { + Field* fields = result->Fetch(); + + uint32 id = fields[0].GetUInt32(); + uint8 type = fields[1].GetUInt8(); + // overwrite + switch (type) + { + case 0: // Creature + type = TYPEID_UNIT; + if (!sObjectMgr->GetCreatureTemplate(id)) + { + TC_LOG_ERROR("sql.sql", "Table `quest_greeting`: creature template entry %u does not exist.", id); + continue; + } + break; + case 1: // GameObject + type = TYPEID_GAMEOBJECT; + if (!sObjectMgr->GetGameObjectTemplate(id)) + { + TC_LOG_ERROR("sql.sql", "Table `quest_greeting`: gameobject template entry %u does not exist.", id); + continue; + } + break; + default: + continue; + } + + uint16 greetEmoteType = fields[2].GetUInt32(); + uint32 greetEmoteDelay = fields[3].GetUInt32(); + std::string greeting = fields[4].GetString(); + + _questGreetingStore[type][id] = new QuestGreeting(greetEmoteType, greetEmoteDelay, greeting); + } + while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded %u quest_greeting in %u ms", uint32(_questGreetingStore.size()), GetMSTimeDiffToNow(oldMSTime)); +} + void ObjectMgr::LoadTavernAreaTriggers() { uint32 oldMSTime = getMSTime(); @@ -6121,10 +6177,10 @@ void ObjectMgr::LoadGameObjectLocales() GameObjectLocale& data = _gameObjectLocaleStore[entry]; - for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) + for (uint8 i = OLD_TOTAL_LOCALES - 1; i > 0; --i) { AddLocaleString(fields[i].GetString(), LocaleConstant(i), data.Name); - AddLocaleString(fields[i + (TOTAL_LOCALES - 1)].GetString(), LocaleConstant(i), data.CastBarCaption); + AddLocaleString(fields[i + (OLD_TOTAL_LOCALES - 1)].GetString(), LocaleConstant(i), data.CastBarCaption); } } while (result->NextRow()); @@ -6194,13 +6250,13 @@ void ObjectMgr::LoadGameObjectTemplate() { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 6 7 8 9 10 11 12 - QueryResult result = WorldDatabase.Query("SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, faction, flags, size, questItem1, questItem2, questItem3, " - // 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 - "questItem4, questItem5, questItem6, Data0, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11, Data12, " - // 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 + // 0 1 2 3 4 5 6 7 8 9 + QueryResult result = WorldDatabase.Query("SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, faction, flags, size, " + // 10 11 12 13 14 15 16 17 18 19 20 21 22 + "Data0, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11, Data12, " + // 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 "Data13, Data14, Data15, Data16, Data17, Data18, Data19, Data20, Data21, Data22, Data23, Data24, Data25, Data26, Data27, Data28, " - // 45 46 47 48 49 50 51 + // 39 40 41 42 43 44 45 "Data29, Data30, Data31, Data32, unkInt32, AIName, ScriptName " "FROM gameobject_template"); @@ -6231,15 +6287,12 @@ void ObjectMgr::LoadGameObjectTemplate() got.flags = fields[8].GetUInt32(); got.size = fields[9].GetFloat(); - for (uint8 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i) - got.questItems[i] = fields[10 + i].GetUInt32(); - for (uint8 i = 0; i < MAX_GAMEOBJECT_DATA; ++i) - got.raw.data[i] = fields[16 + i].GetUInt32(); + got.raw.data[i] = fields[10 + i].GetUInt32(); - got.unkInt32 = fields[49].GetInt32(); - got.AIName = fields[50].GetString(); - got.ScriptId = GetScriptId(fields[51].GetCString()); + got.unkInt32 = fields[43].GetInt32(); + got.AIName = fields[44].GetString(); + got.ScriptId = GetScriptId(fields[45].GetCString()); // Checks @@ -6512,7 +6565,7 @@ void ObjectMgr::LoadCorpses() Field* fields = phaseResult->Fetch(); uint32 guid = fields[0].GetUInt32(); uint32 phaseId = fields[1].GetUInt32(); - + phases[guid].push_back(phaseId); } while (phaseResult->NextRow()); @@ -6816,7 +6869,7 @@ void ObjectMgr::LoadPointsOfInterest() { uint32 oldMSTime = getMSTime(); - _pointsOfInterestStore.clear(); // need for reload case + _pointsOfInterestStore.clear(); // need for reload case uint32 count = 0; @@ -6833,24 +6886,24 @@ void ObjectMgr::LoadPointsOfInterest() { Field* fields = result->Fetch(); - uint32 point_id = fields[0].GetUInt32(); + uint32 id = fields[0].GetUInt32(); - PointOfInterest POI; - POI.ID = point_id; - POI.PositionX = fields[1].GetFloat(); - POI.PositionY = fields[2].GetFloat(); - POI.Icon = fields[3].GetUInt32(); - POI.Flags = fields[4].GetUInt32(); - POI.Importance = fields[5].GetUInt32(); - POI.Name = fields[6].GetString(); + PointOfInterest pointOfInterest; + pointOfInterest.ID = id; + pointOfInterest.Pos.x = fields[1].GetFloat(); + pointOfInterest.Pos.y = fields[2].GetFloat(); + pointOfInterest.Icon = fields[3].GetUInt32(); + pointOfInterest.Flags = fields[4].GetUInt32(); + pointOfInterest.Importance = fields[5].GetUInt32(); + pointOfInterest.Name = fields[6].GetString(); - if (!Trinity::IsValidMapCoord(POI.PositionX, POI.PositionY)) + if (!Trinity::IsValidMapCoord(pointOfInterest.Pos.x, pointOfInterest.Pos.y)) { - TC_LOG_ERROR("sql.sql", "Table `points_of_interest` (ID: %u) have invalid coordinates (PositionX: %f PositionY: %f), ignored.", point_id, POI.PositionX, POI.PositionY); + TC_LOG_ERROR("sql.sql", "Table `points_of_interest` (ID: %u) have invalid coordinates (PositionX: %f PositionY: %f), ignored.", id, pointOfInterest.Pos.x, pointOfInterest.Pos.y); continue; } - _pointsOfInterestStore[point_id] = POI; + _pointsOfInterestStore[id] = pointOfInterest; ++count; } while (result->NextRow()); @@ -6895,7 +6948,7 @@ void ObjectMgr::LoadQuestPOI() int32 X = fields[2].GetInt32(); int32 Y = fields[3].GetInt32(); - if (POIs[QuestID].size() <= Idx1 + 1) + if (int32(POIs[QuestID].size()) <= Idx1 + 1) POIs[QuestID].resize(Idx1 + 10); QuestPOIPoint point(X, Y); @@ -6923,7 +6976,7 @@ void ObjectMgr::LoadQuestPOI() int32 WoDUnk1 = fields[13].GetInt32(); QuestPOI POI(BlobIndex, ObjectiveIndex, QuestObjectiveID, QuestObjectID, MapID, WorldMapAreaId, Floor, Priority, Flags, WorldEffectID, PlayerConditionID, WoDUnk1); - if (QuestID < POIs.size() && Idx1 < POIs[QuestID].size()) + if (QuestID < int32(POIs.size()) && Idx1 < int32(POIs[QuestID].size())) { POI.points = POIs[QuestID][Idx1]; _questPOIStore[QuestID].push_back(POI); @@ -7412,7 +7465,7 @@ bool ObjectMgr::LoadTrinityStrings() data.Content.resize(DEFAULT_LOCALE + 1); - for (int8 i = TOTAL_LOCALES - 1; i >= 0; --i) + for (int8 i = OLD_TOTAL_LOCALES - 1; i >= 0; --i) AddLocaleString(fields[i + 1].GetString(), LocaleConstant(i), data.Content); } while (result->NextRow()); @@ -7999,7 +8052,7 @@ void ObjectMgr::LoadGossipMenu() gMenu.entry = fields[0].GetUInt16(); gMenu.text_id = fields[1].GetUInt32(); - if (!GetGossipText(gMenu.text_id)) + if (!GetNpcText(gMenu.text_id)) { TC_LOG_ERROR("sql.sql", "Table gossip_menu entry %u are using non-existing text_id %u", gMenu.entry, gMenu.text_id); continue; @@ -8920,3 +8973,63 @@ std::string ObjectMgr::GetRealmName(uint32 realm) const RealmNameContainer::const_iterator iter = _realmNameStore.find(realm); return iter != _realmNameStore.end() ? iter->second : ""; } + +void ObjectMgr::LoadGameObjectQuestItems() +{ + uint32 oldMSTime = getMSTime(); + + // 0 1 + QueryResult result = WorldDatabase.Query("SELECT GameObjectEntry, ItemId FROM gameobject_questitem ORDER BY Idx ASC"); + + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 gameobject quest items. DB table `gameobject_questitem` is empty."); + return; + } + + uint32 count = 0; + do + { + Field* fields = result->Fetch(); + + uint32 entry = fields[0].GetUInt32(); + uint32 item = fields[1].GetUInt32(); + + _gameObjectQuestItemStore[entry].push_back(item); + + ++count; + } + while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded %u gameobject quest items in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + +void ObjectMgr::LoadCreatureQuestItems() +{ + uint32 oldMSTime = getMSTime(); + + // 0 1 + QueryResult result = WorldDatabase.Query("SELECT CreatureEntry, ItemId FROM creature_questitem ORDER BY Idx ASC"); + + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 creature quest items. DB table `creature_questitem` is empty."); + return; + } + + uint32 count = 0; + do + { + Field* fields = result->Fetch(); + + uint32 entry = fields[0].GetUInt32(); + uint32 item = fields[1].GetUInt32(); + + _creatureQuestItemStore[entry].push_back(item); + + ++count; + } + while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded %u creature quest items in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +}
\ No newline at end of file diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 49d7b024b19..feee679a87b 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -433,8 +433,8 @@ typedef std::unordered_map<ObjectGuid::LowType, GameObjectData> GameObjectDataCo typedef std::map<TempSummonGroupKey, std::vector<TempSummonData> > TempSummonDataContainer; typedef std::unordered_map<uint32, CreatureLocale> CreatureLocaleContainer; typedef std::unordered_map<uint32, GameObjectLocale> GameObjectLocaleContainer; -typedef std::unordered_map<uint32, QuestLocale> QuestLocaleContainer; -typedef std::unordered_map<uint32, NpcTextLocale> NpcTextLocaleContainer; +typedef std::unordered_map<uint32, QuestTemplateLocale> QuestTemplateLocaleContainer; +typedef std::unordered_map<uint32, QuestObjectivesLocale> QuestObjectivesLocaleContainer; typedef std::unordered_map<uint32, PageTextLocale> PageTextLocaleContainer; typedef std::unordered_map<uint32, GossipMenuItemsLocale> GossipMenuItemsLocaleContainer; typedef std::unordered_map<uint32, PointOfInterestLocale> PointOfInterestLocaleContainer; @@ -504,8 +504,7 @@ struct RepSpilloverTemplate struct PointOfInterest { uint32 ID; - float PositionX; - float PositionY; + G3D::Vector2 Pos; uint32 Icon; uint32 Flags; uint32 Importance; @@ -578,6 +577,19 @@ struct QuestPOI typedef std::vector<QuestPOI> QuestPOIVector; typedef std::unordered_map<uint32, QuestPOIVector> QuestPOIContainer; +struct QuestGreeting +{ + uint16 greetEmoteType; + uint32 greetEmoteDelay; + std::string greeting; + + QuestGreeting() : greetEmoteType(0), greetEmoteDelay(0) { } + QuestGreeting(uint16 _greetEmoteType, uint32 _greetEmoteDelay, std::string _greeting) + : greetEmoteType(_greetEmoteType), greetEmoteDelay(_greetEmoteDelay), greeting(_greeting) { } +}; + +typedef std::unordered_map<uint8, std::unordered_map<uint32, QuestGreeting const*>> QuestGreetingContainer; + struct GraveYardData { uint32 safeLocId; @@ -725,6 +737,24 @@ class ObjectMgr static ObjectGuid GetPlayerGUIDByName(std::string const& name); + GameObjectQuestItemList* GetGameObjectQuestItemList(uint32 id) + { + GameObjectQuestItemMap::iterator itr = _gameObjectQuestItemStore.find(id); + if (itr != _gameObjectQuestItemStore.end()) + return &itr->second; + return NULL; + } + GameObjectQuestItemMap const* GetGameObjectQuestItemMap() const { return &_gameObjectQuestItemStore; } + + CreatureQuestItemList* GetCreatureQuestItemList(uint32 id) + { + CreatureQuestItemMap::iterator itr = _creatureQuestItemStore.find(id); + if (itr != _creatureQuestItemStore.end()) + return &itr->second; + return NULL; + } + CreatureQuestItemMap const* GetCreatureQuestItemMap() const { return &_creatureQuestItemStore; } + /** * Retrieves the player name by guid. * @@ -773,7 +803,8 @@ class ObjectMgr return _gameObjectForQuestStore.find(entry) != _gameObjectForQuestStore.end(); } - GossipText const* GetGossipText(uint32 Text_ID) const; + NpcText const* GetNpcText(uint32 textID) const; + QuestGreeting const* GetQuestGreeting(ObjectGuid guid) const; WorldSafeLocsEntry const* GetDefaultGraveYard(uint32 team); WorldSafeLocsEntry const* GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team); @@ -930,6 +961,8 @@ class ObjectMgr void LoadCreatureTemplateAddons(); void LoadCreatureTemplate(Field* fields); void CheckCreatureTemplate(CreatureTemplate const* cInfo); + void LoadGameObjectQuestItems(); + void LoadCreatureQuestItems(); void LoadTempSummons(); void LoadCreatures(); void LoadLinkedRespawn(); @@ -943,8 +976,8 @@ class ObjectMgr void LoadItemTemplates(); void LoadItemTemplateAddon(); void LoadItemScriptNames(); - void LoadQuestLocales(); - void LoadNpcTextLocales(); + void LoadQuestTemplateLocale(); + void LoadQuestObjectivesLocale(); void LoadPageTextLocales(); void LoadGossipMenuItemsLocales(); void LoadPointOfInterestLocales(); @@ -954,11 +987,12 @@ class ObjectMgr void LoadVehicleTemplateAccessories(); void LoadVehicleAccessories(); - void LoadGossipText(); + void LoadNPCText(); void LoadAreaTriggerTeleports(); void LoadAccessRequirements(); void LoadQuestAreaTriggers(); + void LoadQuestGreetings(); void LoadAreaTriggerScripts(); void LoadTavernAreaTriggers(); void LoadGameObjectForQuests(); @@ -1092,16 +1126,16 @@ class ObjectMgr if (itr == _gameObjectLocaleStore.end()) return NULL; return &itr->second; } - QuestLocale const* GetQuestLocale(uint32 entry) const + QuestTemplateLocale const* GetQuestLocale(uint32 entry) const { - QuestLocaleContainer::const_iterator itr = _questLocaleStore.find(entry); - if (itr == _questLocaleStore.end()) return NULL; + QuestTemplateLocaleContainer::const_iterator itr = _questTemplateLocaleStore.find(entry); + if (itr == _questTemplateLocaleStore.end()) return NULL; return &itr->second; } - NpcTextLocale const* GetNpcTextLocale(uint32 entry) const + QuestObjectivesLocale const* GetQuestObjectivesLocale(uint32 entry) const { - NpcTextLocaleContainer::const_iterator itr = _npcTextLocaleStore.find(entry); - if (itr == _npcTextLocaleStore.end()) return NULL; + QuestObjectivesLocaleContainer::const_iterator itr = _questObjectivesLocaleStore.find(entry); + if (itr == _questObjectivesLocaleStore.end()) return NULL; return &itr->second; } PageTextLocale const* GetPageTextLocale(uint32 entry) const @@ -1116,9 +1150,9 @@ class ObjectMgr if (itr == _gossipMenuItemsLocaleStore.end()) return NULL; return &itr->second; } - PointOfInterestLocale const* GetPointOfInterestLocale(uint32 poi_id) const + PointOfInterestLocale const* GetPointOfInterestLocale(uint32 id) const { - PointOfInterestLocaleContainer::const_iterator itr = _pointOfInterestLocaleStore.find(poi_id); + PointOfInterestLocaleContainer::const_iterator itr = _pointOfInterestLocaleStore.find(id); if (itr == _pointOfInterestLocaleStore.end()) return NULL; return &itr->second; } @@ -1239,11 +1273,11 @@ class ObjectMgr // for wintergrasp only GraveYardContainer GraveYardStore; - static void AddLocaleString(std::string const& s, LocaleConstant locale, StringVector& data); - static inline void GetLocaleString(const StringVector& data, int loc_idx, std::string& value) + static void AddLocaleString(std::string const& value, LocaleConstant localeConstant, StringVector& data); + static inline void GetLocaleString(StringVector const& data, LocaleConstant localeConstant, std::string& value) { - if (data.size() > size_t(loc_idx) && !data[loc_idx].empty()) - value = data[loc_idx]; + if (data.size() > size_t(localeConstant) && !data[localeConstant].empty()) + value = data[localeConstant]; } CharacterConversionMap FactionChangeAchievements; @@ -1309,7 +1343,7 @@ class ObjectMgr QuestMap _questTemplates; - typedef std::unordered_map<uint32, GossipText> GossipTextContainer; + typedef std::unordered_map<uint32, NpcText> NpcTextContainer; typedef std::unordered_map<uint32, uint32> QuestAreaTriggerContainer; typedef std::set<uint32> TavernAreaTriggerContainer; typedef std::set<uint32> GameObjectForQuestContainer; @@ -1317,7 +1351,8 @@ class ObjectMgr QuestAreaTriggerContainer _questAreaTriggerStore; TavernAreaTriggerContainer _tavernAreaTriggerStore; GameObjectForQuestContainer _gameObjectForQuestStore; - GossipTextContainer _gossipTextStore; + NpcTextContainer _npcTextStore; + QuestGreetingContainer _questGreetingStore; AreaTriggerContainer _areaTriggerStore; AreaTriggerScriptContainer _areaTriggerScriptStore; AccessRequirementContainer _accessRequirementStore; @@ -1401,6 +1436,8 @@ class ObjectMgr CreatureModelContainer _creatureModelStore; CreatureAddonContainer _creatureAddonStore; GameObjectAddonContainer _gameObjectAddonStore; + GameObjectQuestItemMap _gameObjectQuestItemStore; + CreatureQuestItemMap _creatureQuestItemStore; CreatureTemplateAddonContainer _creatureTemplateAddonStore; EquipmentInfoContainer _equipmentInfoStore; LinkedRespawnContainer _linkedRespawnStore; @@ -1412,8 +1449,8 @@ class ObjectMgr TempSummonDataContainer _tempSummonDataStore; ItemTemplateContainer _itemTemplateStore; - QuestLocaleContainer _questLocaleStore; - NpcTextLocaleContainer _npcTextLocaleStore; + QuestTemplateLocaleContainer _questTemplateLocaleStore; + QuestObjectivesLocaleContainer _questObjectivesLocaleStore; PageTextLocaleContainer _pageTextLocaleStore; GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore; PointOfInterestLocaleContainer _pointOfInterestLocaleStore; diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 8c3ae15cefc..0d9f292c4c2 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -21,7 +21,6 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" - #include "AuctionHouseMgr.h" #include "Log.h" #include "Language.h" @@ -29,7 +28,6 @@ #include "UpdateMask.h" #include "Util.h" #include "AccountMgr.h" - #include "AuctionHousePackets.h" //void called when player click on auctioneer npc @@ -72,88 +70,62 @@ void WorldSession::SendAuctionCommandResult(AuctionEntry* auction, uint32 action { WorldPackets::AuctionHouse::AuctionCommandResult auctionCommandResult; auctionCommandResult.InitializeAuction(auction); - auctionCommandResult.Action = action; + auctionCommandResult.Command = action; auctionCommandResult.ErrorCode = errorCode; SendPacket(auctionCommandResult.Write()); } -//this function sends notification, if bidder is online -void WorldSession::SendAuctionBidderNotification(uint32 /*location*/, uint32 /*auctionId*/, ObjectGuid /*bidder*/, uint32 /*bidSum*/, uint32 /*diff*/, uint32 /*itemEntry*/) +void WorldSession::SendAuctionOutBidNotification(AuctionEntry const* auction, Item const* item) { - //WorldPacket data(SMSG_AUCTION_BIDDER_NOTIFICATION, (8*4)); - //data << uint32(location); - //data << uint32(auctionId); - //data << bidder; - //data << uint64(bidSum); - //data << uint64(diff); - //data << uint32(itemEntry); - //data << uint32(0); - //SendPacket(&data); + WorldPackets::AuctionHouse::AuctionOutBidNotification packet; + packet.BidAmount = auction->bid; + packet.MinIncrement = auction->GetAuctionOutBid(); + packet.Info.Initialize(auction, item); + SendPacket(packet.Write()); } -// this void causes on client to display: "Your auction sold" -void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction) +void WorldSession::SendAuctionClosedNotification(AuctionEntry const* auction, float mailDelay, bool sold, Item const* item) { - WorldPacket data(SMSG_AUCTION_CLOSED_NOTIFICATION, 40); - data << uint32(auction->Id); - data << uint64(auction->bid); - data << uint64(0); //unk - data << uint64(0); //unk - data << uint32(auction->itemEntry); - data << uint32(0); //unk - data << float(0); //unk - SendPacket(&data); + WorldPackets::AuctionHouse::AuctionClosedNotification packet; + packet.Info.Initialize(auction, item); + packet.ProceedsMailDelay = mailDelay; + packet.Sold = sold; + SendPacket(packet.Write()); } -void WorldSession::SendAuctionRemovedNotification(uint32 /*auctionId*/, uint32 /*itemEntry*/, int32 /*randomPropertyId*/) +void WorldSession::SendAuctionWonNotification(AuctionEntry const* auction, Item const* item) { - //WorldPacket data(SMSG_AUCTION_REMOVED_NOTIFICATION, (4+4+4)); - //data << uint32(auctionId); - //data << uint32(itemEntry); - //data << uint32(randomPropertyId); - //SendPacket(&data); + WorldPackets::AuctionHouse::AuctionWonNotification packet; + packet.Info.Initialize(auction, item); + SendPacket(packet.Write()); } -//this void creates new auction and adds auction to some auctionhouse -void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) +void WorldSession::SendAuctionOwnerBidNotification(AuctionEntry const* auction, Item const* item) { - ObjectGuid auctioneer; - uint64 bid, buyout; - uint32 itemsCount, etime; - recvData >> auctioneer; - recvData >> itemsCount; - - ObjectGuid itemGUIDs[MAX_AUCTION_ITEMS]; // 160 slot = 4x 36 slot bag + backpack 16 slot - uint32 count[MAX_AUCTION_ITEMS]; - memset(count, 0, sizeof(count)); + WorldPackets::AuctionHouse::AuctionOwnerBidNotification packet; + packet.Info.Initialize(auction, item); + packet.Bidder = ObjectGuid::Create<HighGuid::Player>(auction->bidder); + packet.MinIncrement = auction->GetAuctionOutBid(); + SendPacket(packet.Write()); +} - if (itemsCount > MAX_AUCTION_ITEMS) +//this void creates new auction and adds auction to some auctionhouse +void WorldSession::HandleAuctionSellItem(WorldPackets::AuctionHouse::AuctionSellItem& packet) +{ + if (packet.Items.size() > MAX_AUCTION_ITEMS) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); - recvData.rfinish(); return; } - for (uint32 i = 0; i < itemsCount; ++i) - { - recvData >> itemGUIDs[i]; - recvData >> count[i]; - - if (!itemGUIDs[i] || !count[i] || count[i] > 1000) - { - recvData.rfinish(); + for (auto const& item : packet.Items) + if (!item.Guid || !item.UseCount || item.UseCount > 1000) return; - } - } - recvData >> bid; - recvData >> buyout; - recvData >> etime; - - if (!bid || !etime) + if (!packet.MinBid || !packet.RunTime) return; - if (bid > MAX_MONEY_AMOUNT || buyout > MAX_MONEY_AMOUNT) + if (packet.MinBid > MAX_MONEY_AMOUNT || packet.BuyoutPrice > MAX_MONEY_AMOUNT) { TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Player %s (%s) attempted to sell item with higher price than max gold amount.", _player->GetName().c_str(), _player->GetGUID().ToString().c_str()); SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); @@ -161,27 +133,27 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) } - Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); + Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(packet.Auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { - TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit (%s) not found or you can't interact with him.", auctioneer.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit (%s) not found or you can't interact with him.", packet.Auctioneer.ToString().c_str()); return; } AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(creature->getFaction()); if (!auctionHouseEntry) { - TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit (%s) has wrong faction.", auctioneer.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit (%s) has wrong faction.", packet.Auctioneer.ToString().c_str()); return; } - etime *= MINUTE; + packet.RunTime *= MINUTE; - switch (etime) + switch (packet.RunTime) { - case 1*MIN_AUCTION_TIME: - case 2*MIN_AUCTION_TIME: - case 4*MIN_AUCTION_TIME: + case 1 * MIN_AUCTION_TIME: + case 2 * MIN_AUCTION_TIME: + case 4 * MIN_AUCTION_TIME: break; default: return; @@ -190,14 +162,10 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - Item* items[MAX_AUCTION_ITEMS]; - uint32 finalCount = 0; - uint32 itemEntry = 0; - - for (uint32 i = 0; i < itemsCount; ++i) + for (auto const& packetItem : packet.Items) { - Item* item = _player->GetItemByGuid(itemGUIDs[i]); + Item* item = _player->GetItemByGuid(packetItem.Guid); if (!item) { @@ -205,19 +173,21 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) return; } - if (itemEntry == 0) - itemEntry = item->GetTemplate()->GetId(); - if (sAuctionMgr->GetAItem(item->GetGUID().GetCounter()) || !item->CanBeTraded() || item->IsNotEmptyBag() || item->GetTemplate()->GetFlags() & ITEM_PROTO_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_DURATION) || - item->GetCount() < count[i] || itemEntry != item->GetTemplate()->GetId()) + item->GetCount() < packetItem.UseCount) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } - items[i] = item; - finalCount += count[i]; + finalCount += packetItem.UseCount; + } + + if (packet.Items.empty()) + { + SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); + return; } if (!finalCount) @@ -227,21 +197,21 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) } // check if there are 2 identical guids, in this case user is most likely cheating - for (uint32 i = 0; i < itemsCount - 1; ++i) + for (uint32 i = 0; i < packet.Items.size() - 1; ++i) { - for (uint32 j = i + 1; j < itemsCount; ++j) + for (uint32 j = i + 1; j < packet.Items.size(); ++j) { - if (itemGUIDs[i] == itemGUIDs[j]) + if (packet.Items[i].Guid == packet.Items[j].Guid) { - SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); + SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } } } - for (uint32 i = 0; i < itemsCount; ++i) + for (auto const& packetItem : packet.Items) { - Item* item = items[i]; + Item* item = _player->GetItemByGuid(packetItem.Guid); if (item->GetMaxStackCount() < finalCount) { @@ -250,12 +220,12 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) } } - Item* item = items[0]; + Item* item = _player->GetItemByGuid(packet.Items[0].Guid); - uint32 auctionTime = uint32(etime * sWorld->getRate(RATE_AUCTION_TIME)); + uint32 auctionTime = uint32(packet.RunTime * sWorld->getRate(RATE_AUCTION_TIME)); AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); - uint32 deposit = sAuctionMgr->GetAuctionDeposit(auctionHouseEntry, etime, item, finalCount); + uint32 deposit = sAuctionMgr->GetAuctionDeposit(auctionHouseEntry, packet.RunTime, item, finalCount); if (!_player->HasEnoughMoney((uint64)deposit)) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_NOT_ENOUGHT_MONEY); @@ -267,10 +237,10 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) AH->auctioneer = UI64LIT(23442); ///@TODO - HARDCODED DB GUID, BAD BAD BAD else - AH->auctioneer = auctioneer.GetCounter(); + AH->auctioneer = packet.Auctioneer.GetCounter(); // Required stack size of auction matches to current item stack size, just move item to auctionhouse - if (itemsCount == 1 && item->GetCount() == count[0]) + if (packet.Items.size() == 1 && item->GetCount() == packet.Items[0].UseCount) { if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { @@ -283,16 +253,16 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) AH->itemEntry = item->GetEntry(); AH->itemCount = item->GetCount(); AH->owner = _player->GetGUID().GetCounter(); - AH->startbid = bid; + AH->startbid = packet.MinBid; AH->bidder = UI64LIT(0); AH->bid = 0; - AH->buyout = buyout; + AH->buyout = packet.BuyoutPrice; AH->expire_time = time(NULL) + auctionTime; AH->deposit = deposit; AH->auctionHouseEntry = auctionHouseEntry; TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: %s %s is selling item %s %s to auctioneer " UI64FMTD " with count %u with initial bid " UI64FMTD " with buyout " UI64FMTD " and with time %u (in sec) in auctionhouse %u", - _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), item->GetGUID().ToString().c_str(), item->GetTemplate()->GetDefaultLocaleName(), AH->auctioneer, item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId()); + _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), item->GetGUID().ToString().c_str(), item->GetTemplate()->GetDefaultLocaleName(), AH->auctioneer, item->GetCount(), packet.MinBid, packet.BuyoutPrice, auctionTime, AH->GetHouseId()); sAuctionMgr->AddAItem(item); auctionHouse->AddAuction(AH); @@ -331,25 +301,25 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) AH->itemEntry = newItem->GetEntry(); AH->itemCount = newItem->GetCount(); AH->owner = _player->GetGUID().GetCounter(); - AH->startbid = bid; + AH->startbid = packet.MinBid; AH->bidder = UI64LIT(0); AH->bid = 0; - AH->buyout = buyout; + AH->buyout = packet.BuyoutPrice; AH->expire_time = time(NULL) + auctionTime; AH->deposit = deposit; AH->auctionHouseEntry = auctionHouseEntry; TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: %s %s is selling %s %s to auctioneer " UI64FMTD " with count %u with initial bid " UI64FMTD " with buyout " UI64FMTD " and with time %u (in sec) in auctionhouse %u", - _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), newItem->GetGUID().ToString().c_str(), newItem->GetTemplate()->GetDefaultLocaleName(), AH->auctioneer, newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId()); + _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), newItem->GetGUID().ToString().c_str(), newItem->GetTemplate()->GetDefaultLocaleName(), AH->auctioneer, newItem->GetCount(), packet.MinBid, packet.BuyoutPrice, auctionTime, AH->GetHouseId()); sAuctionMgr->AddAItem(newItem); auctionHouse->AddAuction(AH); - for (uint32 j = 0; j < itemsCount; ++j) + for (auto const& packetItem : packet.Items) { - Item* item2 = items[j]; + Item* item2 = _player->GetItemByGuid(packetItem.Guid); // Item stack count equals required count, ready to delete item - cloned item will be used for auction - if (item2->GetCount() == count[j]) + if (item2->GetCount() == packetItem.UseCount) { _player->MoveItemFromInventory(item2->GetBagSlot(), item2->GetSlot(), true); @@ -361,9 +331,9 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) } else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction { - item2->SetCount(item2->GetCount() - count[j]); + item2->SetCount(item2->GetCount() - packetItem.UseCount); item2->SetState(ITEM_CHANGED, _player); - _player->ItemRemovedQuestCheck(item2->GetEntry(), count[j]); + _player->ItemRemovedQuestCheck(item2->GetEntry(), packetItem.UseCount); item2->SendUpdateToPlayer(_player); SQLTransaction trans = CharacterDatabase.BeginTransaction(); @@ -387,24 +357,15 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) } // this function is called when client bids or buys out auction -void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) +void WorldSession::HandleAuctionPlaceBid(WorldPackets::AuctionHouse::AuctionPlaceBid& packet) { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_PLACE_BID"); - - ObjectGuid auctioneer; - uint32 auctionId; - uint64 price; - recvData >> auctioneer; - recvData >> auctionId; - recvData >> price; + if (!packet.AuctionItemID || !packet.BidAmount) + return; // check for cheaters - if (!auctionId || !price) - return; // check for cheaters - - Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); + Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(packet.Auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { - TC_LOG_DEBUG("network", "WORLD: HandleAuctionPlaceBid - %s not found or you can't interact with him.", auctioneer.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleAuctionPlaceBid - %s not found or you can't interact with him.", packet.Auctioneer.ToString().c_str()); return; } @@ -414,7 +375,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); - AuctionEntry* auction = auctionHouse->GetAuction(auctionId); + AuctionEntry* auction = auctionHouse->GetAuction(packet.AuctionItemID); Player* player = GetPlayer(); if (!auction || auction->owner == player->GetGUID().GetCounter()) @@ -435,19 +396,19 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) } // cheating - if (price <= auction->bid || price < auction->startbid) + if (packet.BidAmount <= auction->bid || packet.BidAmount < auction->startbid) return; // price too low for next bid if not buyout - if ((price < auction->buyout || auction->buyout == 0) && - price < auction->bid + auction->GetAuctionOutBid()) + if ((packet.BidAmount < auction->buyout || auction->buyout == 0) && + packet.BidAmount < auction->bid + auction->GetAuctionOutBid()) { // client already test it but just in case ... SendAuctionCommandResult(auction, AUCTION_PLACE_BID, ERR_AUCTION_HIGHER_BID); return; } - if (!player->HasEnoughMoney(price)) + if (!player->HasEnoughMoney(packet.BidAmount)) { // client already test it but just in case ... SendAuctionCommandResult(auction, AUCTION_PLACE_BID, ERR_AUCTION_NOT_ENOUGHT_MONEY); @@ -456,25 +417,25 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) SQLTransaction trans = CharacterDatabase.BeginTransaction(); - if (price < auction->buyout || auction->buyout == 0) + if (packet.BidAmount < auction->buyout || auction->buyout == 0) { if (auction->bidder) { if (auction->bidder == player->GetGUID().GetCounter()) - player->ModifyMoney(-int64(price - auction->bid)); + player->ModifyMoney(-int64(packet.BidAmount - auction->bid)); else { // mail to last bidder and return money - sAuctionMgr->SendAuctionOutbiddedMail(auction, price, GetPlayer(), trans); - player->ModifyMoney(-int64(price)); + sAuctionMgr->SendAuctionOutbiddedMail(auction, packet.BidAmount, GetPlayer(), trans); + player->ModifyMoney(-int64(packet.BidAmount)); } } else - player->ModifyMoney(-int64(price)); + player->ModifyMoney(-int64(packet.BidAmount)); auction->bidder = player->GetGUID().GetCounter(); - auction->bid = price; - GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); + auction->bid = packet.BidAmount; + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, packet.BidAmount); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_AUCTION_BID); stmt->setUInt64(0, auction->bidder); @@ -483,6 +444,12 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) trans->Append(stmt); SendAuctionCommandResult(auction, AUCTION_PLACE_BID, ERR_AUCTION_OK); + + // Not sure if we must send this now. + Player* owner = sObjectAccessor->FindConnectedPlayer(ObjectGuid::Create<HighGuid::Player>(auction->owner)); + Item* item = sAuctionMgr->GetAItem(auction->itemGUIDLow); + if (owner && item) + owner->GetSession()->SendAuctionOwnerBidNotification(auction, item); } else { @@ -499,36 +466,30 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) auction->bid = auction->buyout; GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout); + SendAuctionCommandResult(auction, AUCTION_PLACE_BID, ERR_AUCTION_OK); + //- Mails must be under transaction control too to prevent data loss sAuctionMgr->SendAuctionSalePendingMail(auction, trans); sAuctionMgr->SendAuctionSuccessfulMail(auction, trans); sAuctionMgr->SendAuctionWonMail(auction, trans); - SendAuctionCommandResult(auction, AUCTION_PLACE_BID, ERR_AUCTION_OK); - auction->DeleteFromDB(trans); sAuctionMgr->RemoveAItem(auction->itemGUIDLow); auctionHouse->RemoveAuction(auction); } + player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); } //this void is called when auction_owner cancels his auction -void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData) +void WorldSession::HandleAuctionRemoveItem(WorldPackets::AuctionHouse::AuctionRemoveItem& packet) { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_REMOVE_ITEM"); - - ObjectGuid auctioneer; - uint32 auctionId; - recvData >> auctioneer; - recvData >> auctionId; - - Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); + Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(packet.Auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { - TC_LOG_DEBUG("network", "WORLD: HandleAuctionRemoveItem - %s not found or you can't interact with him.", auctioneer.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleAuctionRemoveItem - %s not found or you can't interact with him.", packet.Auctioneer.ToString().c_str()); return; } @@ -538,27 +499,27 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData) AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); - AuctionEntry* auction = auctionHouse->GetAuction(auctionId); + AuctionEntry* auction = auctionHouse->GetAuction(packet.AuctionItemID); Player* player = GetPlayer(); SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (auction && auction->owner == player->GetGUID().GetCounter()) { - Item* pItem = sAuctionMgr->GetAItem(auction->itemGUIDLow); - if (pItem) + Item* item = sAuctionMgr->GetAItem(auction->itemGUIDLow); + if (item) { if (auction->bidder) // If we have a bidder, we have to send him the money he paid { uint32 auctionCut = auction->GetAuctionCut(); if (!player->HasEnoughMoney((uint64)auctionCut)) //player doesn't have enough money, maybe message needed return; - sAuctionMgr->SendAuctionCancelledToBidderMail(auction, trans, pItem); + sAuctionMgr->SendAuctionCancelledToBidderMail(auction, trans); player->ModifyMoney(-int64(auctionCut)); } // item will deleted or added to received mail list MailDraft(auction->BuildAuctionMailSubject(AUCTION_CANCELED), AuctionEntry::BuildAuctionMailBody(0, 0, auction->buyout, auction->deposit, 0)) - .AddItem(pItem) + .AddItem(item) .SendMailTo(trans, player, auction, MAIL_CHECK_MASK_COPIED); } else @@ -572,7 +533,7 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData) { SendAuctionCommandResult(NULL, AUCTION_CANCEL, ERR_AUCTION_DATABASE_ERROR); //this code isn't possible ... maybe there should be assert - TC_LOG_ERROR("network", "CHEATER: %s tried to cancel auction (id: %u) of another player or auction is NULL", player->GetGUID().ToString().c_str(), auctionId); + TC_LOG_ERROR("network", "CHEATER: %s tried to cancel auction (id: %u) of another player or auction is NULL", player->GetGUID().ToString().c_str(), packet.AuctionItemID); return; } @@ -590,28 +551,12 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData) } //called when player lists his bids -void WorldSession::HandleAuctionListBidderItems(WorldPacket& recvData) +void WorldSession::HandleAuctionListBidderItems(WorldPackets::AuctionHouse::AuctionListBidderItems& packet) { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_LIST_BIDDER_ITEMS"); - - ObjectGuid guid; //NPC guid - uint32 listfrom; //page of auctions - uint32 outbiddedCount; //count of outbidded auctions - - recvData >> guid; - recvData >> listfrom; // not used in fact (this list not have page control in client) - recvData >> outbiddedCount; - if (recvData.size() != (16 + outbiddedCount * 4)) - { - TC_LOG_ERROR("network", "Client sent bad opcode!!! with count: %u and size : %lu (must be: %u)", outbiddedCount, (unsigned long)recvData.size(), (16 + outbiddedCount * 4)); - outbiddedCount = 0; - } - - Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_AUCTIONEER); + Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(packet.Auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { - TC_LOG_DEBUG("network", "WORLD: HandleAuctionListBidderItems - %s not found or you can't interact with him.", guid.ToString().c_str()); - recvData.rfinish(); + TC_LOG_DEBUG("network", "WORLD: HandleAuctionListBidderItems - %s not found or you can't interact with him.", packet.Auctioneer.ToString().c_str()); return; } @@ -621,46 +566,21 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket& recvData) AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); - WorldPacket data(SMSG_AUCTION_LIST_BIDDER_ITEMS_RESULT, (4+4+4)); - Player* player = GetPlayer(); - data << uint32(0); //add 0 as count - uint32 count = 0; - uint32 totalcount = 0; - while (outbiddedCount > 0) //add all data, which client requires - { - --outbiddedCount; - uint32 outbiddedAuctionId; - recvData >> outbiddedAuctionId; - AuctionEntry* auction = auctionHouse->GetAuction(outbiddedAuctionId); - if (auction && auction->BuildAuctionInfo(data)) - { - ++totalcount; - ++count; - } - } + WorldPackets::AuctionHouse::AuctionListBidderItemsResult result; - auctionHouse->BuildListBidderItems(data, player, count, totalcount); - data.put<uint32>(0, count); // add count to placeholder - data << totalcount; - data << uint32(300); //unk 2.3.0 - SendPacket(&data); + Player* player = GetPlayer(); + auctionHouse->BuildListBidderItems(result, player, result.TotalCount); + result.DesiredDelay = 300; + SendPacket(result.Write()); } //this void sends player info about his auctions -void WorldSession::HandleAuctionListOwnerItems(WorldPacket& recvData) +void WorldSession::HandleAuctionListOwnerItems(WorldPackets::AuctionHouse::AuctionListOwnerItems& packet) { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_LIST_OWNER_ITEMS"); - - uint32 listfrom; - ObjectGuid guid; - - recvData >> guid; - recvData >> listfrom; // not used in fact (this list not have page control in client) - - Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_AUCTIONEER); + Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(packet.Auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { - TC_LOG_DEBUG("network", "WORLD: HandleAuctionListOwnerItems - %s not found or you can't interact with him.", guid.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleAuctionListOwnerItems - %s not found or you can't interact with him.", packet.Auctioneer.ToString().c_str()); return; } @@ -670,48 +590,20 @@ void WorldSession::HandleAuctionListOwnerItems(WorldPacket& recvData) AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); - WorldPacket data(SMSG_AUCTION_LIST_OWNER_ITEMS_RESULT, (4+4+4)); - data << uint32(0); // amount place holder + WorldPackets::AuctionHouse::AuctionListOwnerItemsResult result; - uint32 count = 0; - uint32 totalcount = 0; - - auctionHouse->BuildListOwnerItems(data, _player, count, totalcount); - data.put<uint32>(0, count); - data << uint32(totalcount); - data << uint32(0); - SendPacket(&data); + auctionHouse->BuildListOwnerItems(result, _player, result.TotalCount); + result.DesiredDelay = 300; + SendPacket(result.Write()); } //this void is called when player clicks on search button -void WorldSession::HandleAuctionListItems(WorldPacket& recvData) +void WorldSession::HandleAuctionListItems(WorldPackets::AuctionHouse::AuctionListItems& packet) { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_LIST_ITEMS"); - - std::string searchedname; - uint8 levelmin, levelmax, usable; - uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality; - ObjectGuid guid; - - recvData >> guid; - recvData >> listfrom; // start, used for page control listing by 50 elements - recvData >> searchedname; - - recvData >> levelmin >> levelmax; - recvData >> auctionSlotID >> auctionMainCategory >> auctionSubCategory; - recvData >> quality >> usable; - - recvData.read_skip<uint8>(); // unk - recvData.read_skip<uint8>(); // unk - - // this block looks like it uses some lame byte packing or similar... - for (uint8 i = 0; i < 15; i++) - recvData.read_skip<uint8>(); - - Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_AUCTIONEER); + Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(packet.Auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { - TC_LOG_DEBUG("network", "WORLD: HandleAuctionListItems - %s not found or you can't interact with him.", guid.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleAuctionListItems - %s not found or you can't interact with him.", packet.Auctioneer.ToString().c_str()); return; } @@ -721,49 +613,42 @@ void WorldSession::HandleAuctionListItems(WorldPacket& recvData) AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); - TC_LOG_DEBUG("auctionHouse", "Auctionhouse search (%s) list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", - guid.ToString().c_str(), listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable); + TC_LOG_DEBUG("auctionHouse", "Auctionhouse search (%s), searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", + packet.Auctioneer.ToString().c_str(), packet.Name.c_str(), packet.MinLevel, packet.MaxLevel , packet.InvType, packet.ItemClass, packet.ItemSubclass, packet.Quality, packet.OnlyUsable); - WorldPacket data(SMSG_AUCTION_LIST_ITEMS_RESULT, (4+4+4)); - uint32 count = 0; - uint32 totalcount = 0; - data << uint32(0); + WorldPackets::AuctionHouse::AuctionListItemsResult result; // converting string that we try to find to lower case std::wstring wsearchedname; - if (!Utf8toWStr(searchedname, wsearchedname)) + if (!Utf8toWStr(packet.Name, wsearchedname)) return; wstrToLower(wsearchedname); - auctionHouse->BuildListAuctionItems(data, _player, - wsearchedname, listfrom, levelmin, levelmax, usable, - auctionSlotID, auctionMainCategory, auctionSubCategory, quality, - count, totalcount); + auctionHouse->BuildListAuctionItems(result, _player, + wsearchedname, packet.Offset, packet.MinLevel, packet.MaxLevel, packet.OnlyUsable, + packet.InvType, packet.ItemClass, packet.ItemSubclass, packet.Quality, result.TotalCount); - data.put<uint32>(0, count); - data << uint32(totalcount); - data << uint32(300); //unk 2.3.0 - SendPacket(&data); + result.DesiredDelay = 300; + result.OnlyUsable = packet.OnlyUsable; + SendPacket(result.Write()); } -void WorldSession::HandleAuctionListPendingSales(WorldPacket& recvData) +void WorldSession::HandleAuctionListPendingSales(WorldPackets::AuctionHouse::AuctionListPendingSales& /*packet*/) { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_LIST_PENDING_SALES"); - - recvData.read_skip<uint64>(); - - uint32 count = 0; + WorldPackets::AuctionHouse::AuctionListPendingSalesResult result; + result.TotalNumRecords = 0; + SendPacket(result.Write()); +} - WorldPacket data(SMSG_AUCTION_LIST_PENDING_SALES_RESULT, 4); - data << uint32(count); // count - /*for (uint32 i = 0; i < count; ++i) - { - data << ""; // string - data << ""; // string - data << uint64(0); - data << uint32(0); - data << float(0); - }*/ - SendPacket(&data); +void WorldSession::HandleReplicateItems(WorldPackets::AuctionHouse::AuctionReplicateItems& packet) +{ + //@todo implement this properly + WorldPackets::AuctionHouse::AuctionReplicateResponse response; + response.ChangeNumberCursor = packet.ChangeNumberCursor; + response.ChangeNumberGlobal = packet.ChangeNumberGlobal; + response.ChangeNumberTombstone = packet.ChangeNumberTombstone; + response.DesiredDelay = 300; + response.Result = 0; + SendPacket(response.Write()); } diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index 54fb8b2f80e..0b9bf2f5d65 100644 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -34,6 +34,9 @@ #include "Opcodes.h" #include "DisableMgr.h" #include "Group.h" +#include "Battlefield.h" +#include "BattlefieldMgr.h" +#include "BattlegroundPackets.h" void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recvData) { @@ -268,8 +271,6 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvData*/) { - TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEGROUND_PLAYER_POSITIONS Message"); - Battleground* bg = _player->GetBattleground(); if (!bg) // can't be received if player not in battleground return; @@ -358,10 +359,8 @@ void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvDa SendPacket(&data); } -void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recvData*/) +void WorldSession::HandlePVPLogDataOpcode(WorldPackets::Battleground::PVPLogDataRequest& /*pvpLogDataRequest*/) { - TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_PVP_LOG_DATA Message"); - Battleground* bg = _player->GetBattleground(); if (!bg) return; @@ -370,17 +369,13 @@ void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recvData*/) if (bg->isArena()) return; - WorldPacket data; - bg->BuildPvPLogDataPacket(data); - SendPacket(&data); - - TC_LOG_DEBUG("network", "WORLD: Sent SMSG_PVP_LOG_DATA Message"); + WorldPackets::Battleground::PVPLogData pvpLogData; + bg->BuildPvPLogDataPacket(pvpLogData); + SendPacket(pvpLogData.Write()); } void WorldSession::HandleBattlefieldListOpcode(WorldPacket& recvData) { - TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_LIST Message"); - uint32 bgTypeId; recvData >> bgTypeId; // id from DBC @@ -398,8 +393,6 @@ void WorldSession::HandleBattlefieldListOpcode(WorldPacket& recvData) void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) { - TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_PORT Message"); - uint32 time; uint32 queueSlot; uint32 unk; @@ -588,8 +581,6 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) void WorldSession::HandleBattlefieldLeaveOpcode(WorldPacket& /*recvData*/) { - TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_LEAVE Message"); - // not allow leave battleground in combat if (_player->IsInCombat()) if (Battleground* bg = _player->GetBattleground()) @@ -601,9 +592,6 @@ void WorldSession::HandleBattlefieldLeaveOpcode(WorldPacket& /*recvData*/) void WorldSession::HandleRequestBattlefieldStatusOpcode(WorldPacket& /*recvData*/) { - // empty opcode - TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_STATUS Message"); - WorldPacket data; // we must update all queues here Battleground* bg = NULL; @@ -666,8 +654,6 @@ void WorldSession::HandleRequestBattlefieldStatusOpcode(WorldPacket& /*recvData* void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) { - TC_LOG_DEBUG("network", "WORLD: CMSG_BATTLEMASTER_JOIN_ARENA"); - uint8 arenaslot; // 2v2, 3v3 or 5v5 recvData >> arenaslot; @@ -790,8 +776,6 @@ void WorldSession::HandleReportPvPAFK(WorldPacket& recvData) void WorldSession::HandleRequestRatedBattlefieldInfo(WorldPacket& recvData) { - TC_LOG_DEBUG("network", "WORLD: CMSG_REQUEST_RATED_BATTLEFIELD_INFO"); - uint8 unk; recvData >> unk; @@ -824,8 +808,6 @@ void WorldSession::HandleRequestRatedBattlefieldInfo(WorldPacket& recvData) void WorldSession::HandleGetPVPOptionsEnabled(WorldPacket& /*recvData*/) { - TC_LOG_DEBUG("network", "WORLD: CMSG_GET_PVP_OPTIONS_ENABLED"); - /// @Todo: perfome research in this case WorldPacket data(SMSG_PVP_OPTIONS_ENABLED, 1); data.WriteBit(1); @@ -841,7 +823,57 @@ void WorldSession::HandleGetPVPOptionsEnabled(WorldPacket& /*recvData*/) void WorldSession::HandleRequestPvpReward(WorldPacket& /*recvData*/) { - TC_LOG_DEBUG("network", "WORLD: CMSG_REQUEST_PVP_REWARDS"); - _player->SendPvpRewards(); } + +void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPackets::Battleground::AreaSpiritHealerQuery& areaSpiritHealerQuery) +{ + Creature* unit = GetPlayer()->GetMap()->GetCreature(areaSpiritHealerQuery.HealerGuid); + if (!unit) + return; + + if (!unit->IsSpiritService()) // it's not spirit service + return; + + if (Battleground* bg = _player->GetBattleground()) + sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, areaSpiritHealerQuery.HealerGuid); + + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId())) + bf->SendAreaSpiritHealerQueryOpcode(_player, areaSpiritHealerQuery.HealerGuid); +} + +void WorldSession::HandleAreaSpiritHealerQueueOpcode(WorldPackets::Battleground::AreaSpiritHealerQueue& areaSpiritHealerQueue) +{ + Creature* unit = GetPlayer()->GetMap()->GetCreature(areaSpiritHealerQueue.HealerGuid); + if (!unit) + return; + + if (!unit->IsSpiritService()) // it's not spirit service + return; + + if (Battleground* bg = _player->GetBattleground()) + bg->AddPlayerToResurrectQueue(areaSpiritHealerQueue.HealerGuid, _player->GetGUID()); + + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId())) + bf->AddPlayerToResurrectQueue(areaSpiritHealerQueue.HealerGuid, _player->GetGUID()); +} + +void WorldSession::HandleHearthAndResurrect(WorldPackets::Battleground::HearthAndResurrect& /*hearthAndResurrect*/) +{ + if (_player->IsInFlight()) + return; + + if (/*Battlefield* bf = */sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId())) + { + // bf->PlayerAskToLeave(_player); FIXME + return; + } + + AreaTableEntry const* atEntry = GetAreaEntryByAreaID(_player->GetAreaId()); + if (!atEntry || !(atEntry->Flags[0] & AREA_FLAG_CAN_HEARTH_AND_RESURRECT)) + return; + + _player->BuildPlayerRepop(); + _player->ResurrectPlayer(1.0f); + _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation()); +} diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 557e31ce74a..cd1497145ef 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1107,6 +1107,8 @@ void WorldSession::SendFeatureSystemStatus() features.TwitterMsTillCanPost = 20; features.CfgRealmID = 2; features.CfgRealmRecID = 0; + features.TokenPollTimeSeconds = 300; + features.TokenRedeemIndex = 0; features.VoiceEnabled = false; features.BrowserEnabled = false; // Has to be false, otherwise client will crash if "Customer Support" is opened @@ -1198,6 +1200,11 @@ void WorldSession::HandleSetFactionInactiveOpcode(WorldPacket& recvData) _player->GetReputationMgr().SetInactive(replistid, inactive != 0); } +void WorldSession::HandleRequestForcedReactionsOpcode(WorldPackets::Reputation::RequestForcedReactions& /*requestForcedReactions*/) +{ + _player->GetReputationMgr().SendForceReactions(); +} + void WorldSession::HandleShowingHelmOpcode(WorldPackets::Character::ShowingHelm& packet) { if (packet.ShowHelm) @@ -1624,43 +1631,35 @@ void WorldSession::HandleEquipmentSetSave(WorldPackets::EquipmentSet::SaveEquipm _player->SetEquipmentSet(std::move(packet.Set)); } -void WorldSession::HandleEquipmentSetDelete(WorldPacket& recvData) +void WorldSession::HandleDeleteEquipmentSet(WorldPackets::EquipmentSet::DeleteEquipmentSet& packet) { - TC_LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_DELETE"); + TC_LOG_DEBUG("network", "CMSG_DELETE_EQUIPMENT_SET"); - uint64 setGuid; - recvData.ReadPackedUInt64(setGuid); - - _player->DeleteEquipmentSet(setGuid); + _player->DeleteEquipmentSet(packet.ID); } -void WorldSession::HandleEquipmentSetUse(WorldPacket& recvData) +void WorldSession::HandleUseEquipmentSet(WorldPackets::EquipmentSet::UseEquipmentSet& packet) { - TC_LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_USE"); + TC_LOG_DEBUG("network", "CMSG_USE_EQUIPMENT_SET"); ObjectGuid ignoredItemGuid; ignoredItemGuid.SetRawValue(0, 1); - for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) - { - ObjectGuid itemGuid; - recvData >> itemGuid.ReadAsPacked(); - - uint8 srcbag, srcslot; - recvData >> srcbag >> srcslot; - TC_LOG_DEBUG("entities.player.items", "%s: srcbag %u, srcslot %u", itemGuid.ToString().c_str(), srcbag, srcslot); + for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) + { + TC_LOG_DEBUG("entities.player.items", "%s: ContainerSlot: %u, Slot: %u", packet.Items[i].Item.ToString().c_str(), packet.Items[i].ContainerSlot, packet.Items[i].Slot); // check if item slot is set to "ignored" (raw value == 1), must not be unequipped then - if (itemGuid == ignoredItemGuid) + if (packet.Items[i].Item == ignoredItemGuid) continue; // Only equip weapons in combat if (_player->IsInCombat() && i != EQUIPMENT_SLOT_MAINHAND && i != EQUIPMENT_SLOT_OFFHAND && i != EQUIPMENT_SLOT_RANGED) continue; - Item* item = _player->GetItemByGuid(itemGuid); + Item* item = _player->GetItemByGuid(packet.Items[i].Item); - uint16 dstpos = i | (INVENTORY_SLOT_BAG_0 << 8); + uint16 dstPos = i | (INVENTORY_SLOT_BAG_0 << 8); if (!item) { @@ -1668,28 +1667,27 @@ void WorldSession::HandleEquipmentSetUse(WorldPacket& recvData) if (!uItem) continue; - ItemPosCountVec sDest; - InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, sDest, uItem, false); - if (msg == EQUIP_ERR_OK) + ItemPosCountVec itemPosCountVec; + InventoryResult inventoryResult = _player->CanStoreItem(NULL_BAG, NULL_SLOT, itemPosCountVec, uItem, false); + if (inventoryResult == EQUIP_ERR_OK) { _player->RemoveItem(INVENTORY_SLOT_BAG_0, i, true); - _player->StoreItem(sDest, uItem, true); + _player->StoreItem(itemPosCountVec, uItem, true); } else - _player->SendEquipError(msg, uItem, NULL); - + _player->SendEquipError(inventoryResult, uItem, NULL); continue; } - if (item->GetPos() == dstpos) + if (item->GetPos() == dstPos) continue; - _player->SwapItem(item->GetPos(), dstpos); + _player->SwapItem(item->GetPos(), dstPos); } - WorldPacket data(SMSG_USE_EQUIPMENT_SET_RESULT, 1); - data << uint8(0); // 4 - equipment swap failed - inventory is full - SendPacket(&data); + WorldPackets::EquipmentSet::UseEquipmentSetResult result; + result.Reason = 0; // 4 - equipment swap failed - inventory is full + SendPacket(result.Write()); } void WorldSession::HandleCharRaceOrFactionChangeOpcode(WorldPackets::Character::CharRaceOrFactionChange& packet) diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index dc91dc4308b..5507887625b 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -41,11 +41,11 @@ #include "AccountMgr.h" #include "ChatPackets.h" -void WorldSession::HandleChatMessageOpcode(WorldPackets::Chat::ChatMessage& packet) +void WorldSession::HandleChatMessageOpcode(WorldPackets::Chat::ChatMessage& chatMessage) { ChatMsg type; - switch (packet.GetOpcode()) + switch (chatMessage.GetOpcode()) { case CMSG_CHAT_MESSAGE_SAY: type = CHAT_MSG_SAY; @@ -68,27 +68,30 @@ void WorldSession::HandleChatMessageOpcode(WorldPackets::Chat::ChatMessage& pack case CMSG_CHAT_MESSAGE_RAID_WARNING: type = CHAT_MSG_RAID_WARNING; break; + case CMSG_CHAT_MESSAGE_INSTANCE_CHAT: + type = CHAT_MSG_INSTANCE_CHAT; + break; default: - TC_LOG_ERROR("network", "HandleMessagechatOpcode : Unknown chat opcode (%u)", packet.GetOpcode()); + TC_LOG_ERROR("network", "HandleMessagechatOpcode : Unknown chat opcode (%u)", chatMessage.GetOpcode()); return; } - HandleChatMessage(type, packet.Language, packet.Text); + HandleChatMessage(type, chatMessage.Language, chatMessage.Text); } -void WorldSession::HandleChatMessageWhisperOpcode(WorldPackets::Chat::ChatMessageWhisper& packet) +void WorldSession::HandleChatMessageWhisperOpcode(WorldPackets::Chat::ChatMessageWhisper& chatMessageWhisper) { - HandleChatMessage(CHAT_MSG_WHISPER, packet.Language, packet.Text, packet.Target); + HandleChatMessage(CHAT_MSG_WHISPER, chatMessageWhisper.Language, chatMessageWhisper.Text, chatMessageWhisper.Target); } -void WorldSession::HandleChatMessageChannelOpcode(WorldPackets::Chat::ChatMessageChannel& packet) +void WorldSession::HandleChatMessageChannelOpcode(WorldPackets::Chat::ChatMessageChannel& chatMessageChannel) { - HandleChatMessage(CHAT_MSG_CHANNEL, packet.Language, packet.Text, packet.Target); + HandleChatMessage(CHAT_MSG_CHANNEL, chatMessageChannel.Language, chatMessageChannel.Text, chatMessageChannel.Target); } -void WorldSession::HandleChatMessageEmoteOpcode(WorldPackets::Chat::ChatMessageEmote& packet) +void WorldSession::HandleChatMessageEmoteOpcode(WorldPackets::Chat::ChatMessageEmote& chatMessageEmote) { - HandleChatMessage(CHAT_MSG_EMOTE, LANG_UNIVERSAL, packet.Text); + HandleChatMessage(CHAT_MSG_EMOTE, LANG_UNIVERSAL, chatMessageEmote.Text); } void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, std::string target /*= ""*/) @@ -366,17 +369,33 @@ void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, } break; } + case CHAT_MSG_INSTANCE_CHAT: + { + Group* group = GetPlayer()->GetGroup(); + if (!group) + return; + + if (group->IsLeader(GetPlayer()->GetGUID())) + type = CHAT_MSG_INSTANCE_CHAT_LEADER; + + sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); + + WorldPackets::Chat::Chat packet; + packet.Initalize(ChatMsg(type), Language(lang), sender, nullptr, msg); + group->BroadcastPacket(packet.Write(), false); + break; + } default: TC_LOG_ERROR("network", "CHAT: unknown message type %u, lang: %u", type, lang); break; } } -void WorldSession::HandleChatAddonMessageOpcode(WorldPackets::Chat::ChatAddonMessage& packet) +void WorldSession::HandleChatAddonMessageOpcode(WorldPackets::Chat::ChatAddonMessage& chatAddonMessage) { ChatMsg type; - switch (packet.GetOpcode()) + switch (chatAddonMessage.GetOpcode()) { case CMSG_CHAT_ADDON_MESSAGE_GUILD: type = CHAT_MSG_GUILD; @@ -390,17 +409,25 @@ void WorldSession::HandleChatAddonMessageOpcode(WorldPackets::Chat::ChatAddonMes case CMSG_CHAT_ADDON_MESSAGE_RAID: type = CHAT_MSG_RAID; break; + case CMSG_CHAT_ADDON_MESSAGE_INSTANCE_CHAT: + type = CHAT_MSG_INSTANCE_CHAT; + break; default: - TC_LOG_ERROR("network", "HandleChatAddonMessageOpcode: Unknown addon chat opcode (%u)", packet.GetOpcode()); + TC_LOG_ERROR("network", "HandleChatAddonMessageOpcode: Unknown addon chat opcode (%u)", chatAddonMessage.GetOpcode()); return; } - HandleChatAddonMessage(type, packet.Prefix, packet.Text); + HandleChatAddonMessage(type, chatAddonMessage.Prefix, chatAddonMessage.Text); +} + +void WorldSession::HandleChatAddonMessageWhisperOpcode(WorldPackets::Chat::ChatAddonMessageWhisper& chatAddonMessageWhisper) +{ + HandleChatAddonMessage(CHAT_MSG_WHISPER, chatAddonMessageWhisper.Prefix, chatAddonMessageWhisper.Text, chatAddonMessageWhisper.Target); } -void WorldSession::HandleChatAddonMessageWhisperOpcode(WorldPackets::Chat::ChatAddonMessageWhisper& packet) +void WorldSession::HandleChatAddonMessageChannelOpcode(WorldPackets::Chat::ChatAddonMessageChannel& chatAddonMessageChannel) { - HandleChatAddonMessage(CHAT_MSG_WHISPER, packet.Prefix, packet.Text, packet.Target); + HandleChatAddonMessage(CHAT_MSG_CHANNEL, chatAddonMessageChannel.Prefix, chatAddonMessageChannel.Text, chatAddonMessageChannel.Target); } void WorldSession::HandleChatAddonMessage(ChatMsg type, std::string prefix, std::string text, std::string target /*= ""*/) @@ -439,15 +466,33 @@ void WorldSession::HandleChatAddonMessage(ChatMsg type, std::string prefix, std: // Messages sent to "RAID" while in a party will get delivered to "PARTY" case CHAT_MSG_PARTY: case CHAT_MSG_RAID: + case CHAT_MSG_INSTANCE_CHAT: { + Group* group = nullptr; + int32 subGroup = -1; + if (type != CHAT_MSG_INSTANCE_CHAT) + group = sender->GetOriginalGroup(); - Group* group = sender->GetGroup(); if (!group) - break; + { + group = sender->GetGroup(); + if (!group) + break; + + if (type == CHAT_MSG_PARTY) + subGroup = sender->GetSubGroup(); + } WorldPackets::Chat::Chat packet; packet.Initalize(type, LANG_ADDON, sender, nullptr, text, 0, "", DEFAULT_LOCALE, prefix); - group->BroadcastAddonMessagePacket(packet.Write(), prefix, true, -1, sender->GetGUID()); + group->BroadcastAddonMessagePacket(packet.Write(), prefix, true, subGroup, sender->GetGUID()); + break; + } + case CHAT_MSG_CHANNEL: + { + if (ChannelMgr* cMgr = ChannelMgr::ForTeam(sender->GetTeam())) + if (Channel* chn = cMgr->GetChannel(target, sender, false)) + chn->Say(sender->GetGUID(), text.c_str(), uint32(LANG_ADDON)); break; } default: @@ -458,7 +503,7 @@ void WorldSession::HandleChatAddonMessage(ChatMsg type, std::string prefix, std: } } -void WorldSession::HandleChatMessageAFKOpcode(WorldPackets::Chat::ChatMessageAFK& packet) +void WorldSession::HandleChatMessageAFKOpcode(WorldPackets::Chat::ChatMessageAFK& chatMessageAFK) { Player* sender = GetPlayer(); @@ -473,14 +518,14 @@ void WorldSession::HandleChatMessageAFKOpcode(WorldPackets::Chat::ChatMessageAFK if (sender->isAFK()) // Already AFK { - if (packet.Text.empty()) + if (chatMessageAFK.Text.empty()) sender->ToggleAFK(); // Remove AFK else - sender->autoReplyMsg = packet.Text; // Update message + sender->autoReplyMsg = chatMessageAFK.Text; // Update message } else // New AFK mode { - sender->autoReplyMsg = packet.Text.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : packet.Text; + sender->autoReplyMsg = chatMessageAFK.Text.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : chatMessageAFK.Text; if (sender->isDND()) sender->ToggleDND(); @@ -488,10 +533,10 @@ void WorldSession::HandleChatMessageAFKOpcode(WorldPackets::Chat::ChatMessageAFK sender->ToggleAFK(); } - sScriptMgr->OnPlayerChat(sender, CHAT_MSG_AFK, LANG_UNIVERSAL, packet.Text); + sScriptMgr->OnPlayerChat(sender, CHAT_MSG_AFK, LANG_UNIVERSAL, chatMessageAFK.Text); } -void WorldSession::HandleChatMessageDNDOpcode(WorldPackets::Chat::ChatMessageDND& packet) +void WorldSession::HandleChatMessageDNDOpcode(WorldPackets::Chat::ChatMessageDND& chatMessageDND) { Player* sender = GetPlayer(); @@ -506,14 +551,14 @@ void WorldSession::HandleChatMessageDNDOpcode(WorldPackets::Chat::ChatMessageDND if (sender->isDND()) // Already DND { - if (packet.Text.empty()) + if (chatMessageDND.Text.empty()) sender->ToggleDND(); // Remove DND else - sender->autoReplyMsg = packet.Text; // Update message + sender->autoReplyMsg = chatMessageDND.Text; // Update message } else // New DND mode { - sender->autoReplyMsg = packet.Text.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : packet.Text; + sender->autoReplyMsg = chatMessageDND.Text.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : chatMessageDND.Text; if (sender->isAFK()) sender->ToggleAFK(); @@ -521,7 +566,7 @@ void WorldSession::HandleChatMessageDNDOpcode(WorldPackets::Chat::ChatMessageDND sender->ToggleDND(); } - sScriptMgr->OnPlayerChat(sender, CHAT_MSG_DND, LANG_UNIVERSAL, packet.Text); + sScriptMgr->OnPlayerChat(sender, CHAT_MSG_DND, LANG_UNIVERSAL, chatMessageDND.Text); } void WorldSession::HandleEmoteOpcode(WorldPackets::Chat::EmoteClient& /* packet */) diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index c03aee9dd5a..335bb9ce48c 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -112,23 +112,20 @@ void WorldSession::HandleSwapInvItemOpcode(WorldPackets::Item::SwapInvItem& swap _player->SwapItem(src, dst); } -void WorldSession::HandleAutoEquipItemSlotOpcode(WorldPacket& recvData) +void WorldSession::HandleAutoEquipItemSlotOpcode(WorldPackets::Item::AutoEquipItemSlot& autoEquipItemSlot) { - ObjectGuid itemguid; - uint8 dstslot; - recvData >> itemguid >> dstslot; - // cheating attempt, client should never send opcode in that case - if (!Player::IsEquipmentPos(INVENTORY_SLOT_BAG_0, dstslot)) + if (autoEquipItemSlot.Inv.Items.size() != 1 || !Player::IsEquipmentPos(INVENTORY_SLOT_BAG_0, autoEquipItemSlot.ItemDstSlot)) return; - Item* item = _player->GetItemByGuid(itemguid); - uint16 dstpos = dstslot | (INVENTORY_SLOT_BAG_0 << 8); + Item* item = _player->GetItemByGuid(autoEquipItemSlot.Item); + uint16 dstPos = autoEquipItemSlot.ItemDstSlot | (INVENTORY_SLOT_BAG_0 << 8); + uint16 srcPos = autoEquipItemSlot.Inv.Items[0].Slot | (uint32(autoEquipItemSlot.Inv.Items[0].ContainerSlot) << 8); - if (!item || item->GetPos() == dstpos) + if (!item || item->GetPos() != srcPos || srcPos == dstPos) return; - _player->SwapItem(item->GetPos(), dstpos); + _player->SwapItem(srcPos, dstPos); } void WorldSession::HandleSwapItem(WorldPackets::Item::SwapItem& swapItem) @@ -313,31 +310,32 @@ void WorldSession::HandleDestroyItemOpcode(WorldPackets::Item::DestroyItem& dest _player->DestroyItem(destroyItem.ContainerId, destroyItem.SlotNum, true); } -void WorldSession::HandleReadItem(WorldPacket& recvData) +void WorldSession::HandleReadItem(WorldPackets::Item::ReadItem& readItem) { - uint8 bag, slot; - recvData >> bag >> slot; - - Item* pItem = _player->GetItemByPos(bag, slot); - - if (pItem && pItem->GetTemplate()->GetPageText()) + Item* item = _player->GetItemByPos(readItem.PackSlot, readItem.Slot); + if (item && item->GetTemplate()->GetPageText()) { - WorldPacket data; - - InventoryResult msg = _player->CanUseItem(pItem); + InventoryResult msg = _player->CanUseItem(item); if (msg == EQUIP_ERR_OK) { - data.Initialize(SMSG_READ_ITEM_RESULT_OK, 8); + WorldPackets::Item::ReadItemResultOK packet; + packet.Item = item->GetGUID(); + SendPacket(packet.Write()); + TC_LOG_INFO("network", "STORAGE: Item page sent"); } else { - data.Initialize(SMSG_READ_ITEM_RESULT_FAILED, 8); + /// @todo: 6.x research new values + /*WorldPackets::Item::ReadItemResultFailed packet; + packet.Item = item->GetGUID(); + packet.Subcode = ??; + packet.Delay = ??; + SendPacket(packet.Write());*/ + TC_LOG_INFO("network", "STORAGE: Unable to read item"); - _player->SendEquipError(msg, pItem, NULL); + _player->SendEquipError(msg, item, NULL); } - data << pItem->GetGUID(); - SendPacket(&data); } else _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index 012df70fab2..c4d3358a333 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -634,10 +634,10 @@ void WorldSession::SendLfgJoinResult(lfg::LfgJoinResultData const& joinData) void WorldSession::SendLfgQueueStatus(lfg::LfgQueueStatusData const& queueData) { - TC_LOG_DEBUG("lfg", "SMSG_LFG_QUEUE_STATUS %s dungeon: %u, waitTime: %d, " + TC_LOG_DEBUG("lfg", "SMSG_LFG_QUEUE_STATUS %s state: %s, dungeon: %u, waitTime: %d, " "avgWaitTime: %d, waitTimeTanks: %d, waitTimeHealer: %d, waitTimeDps: %d, " "queuedTime: %u, tanks: %u, healers: %u, dps: %u", - GetPlayerInfo().c_str(), queueData.dungeonId, queueData.waitTime, queueData.waitTimeAvg, + GetPlayerInfo().c_str(), lfg::GetStateString(sLFGMgr->GetState(GetPlayer()->GetGUID())).c_str(), queueData.dungeonId, queueData.waitTime, queueData.waitTimeAvg, queueData.waitTimeTank, queueData.waitTimeHealer, queueData.waitTimeDps, queueData.queuedTime, queueData.tanks, queueData.healers, queueData.dps); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index c9d94a9fe3b..94b009219d6 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -53,8 +53,6 @@ #include "Spell.h" #include "SpellPackets.h" #include "BattlegroundMgr.h" -#include "Battlefield.h" -#include "BattlefieldMgr.h" #include "DB2Stores.h" #include "CharacterPackets.h" #include "ClientConfigPackets.h" @@ -814,108 +812,6 @@ void WorldSession::HandleNextCinematicCamera(WorldPacket& /*recvData*/) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_NEXT_CINEMATIC_CAMERA"); } - -void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket& recvData) -{ - TC_LOG_DEBUG("network", "WORLD: Received CMSG_MOVE_TIME_SKIPPED"); - - ObjectGuid guid; - uint32 time; - recvData >> time; - - guid[5] = recvData.ReadBit(); - guid[1] = recvData.ReadBit(); - guid[3] = recvData.ReadBit(); - guid[7] = recvData.ReadBit(); - guid[6] = recvData.ReadBit(); - guid[0] = recvData.ReadBit(); - guid[4] = recvData.ReadBit(); - guid[2] = recvData.ReadBit(); - - recvData.ReadByteSeq(guid[7]); - recvData.ReadByteSeq(guid[1]); - recvData.ReadByteSeq(guid[2]); - recvData.ReadByteSeq(guid[4]); - recvData.ReadByteSeq(guid[3]); - recvData.ReadByteSeq(guid[6]); - recvData.ReadByteSeq(guid[0]); - recvData.ReadByteSeq(guid[5]); - - //TODO! - - /* - uint64 guid; - uint32 time_skipped; - recvData >> guid; - recvData >> time_skipped; - TC_LOG_DEBUG("network", "WORLD: CMSG_MOVE_TIME_SKIPPED"); - - //// @todo - must be need use in Trinity - We substract server Lags to move time (AntiLags) - for exmaple - GetPlayer()->ModifyLastMoveTime(-int32(time_skipped)); - */ -} - -void WorldSession::HandleFeatherFallAck(WorldPacket& recvData) -{ - TC_LOG_DEBUG("network", "WORLD: CMSG_MOVE_FEATHER_FALL_ACK"); - - // no used - recvData.rfinish(); // prevent warnings spam -} - -void WorldSession::HandleMoveUnRootAck(WorldPacket& recvData) -{ - // no used - recvData.rfinish(); // prevent warnings spam -/* - uint64 guid; - recvData >> guid; - - // now can skip not our packet - if (_player->GetGUID() != guid) - { - recvData.rfinish(); // prevent warnings spam - return; - } - - TC_LOG_DEBUG("network", "WORLD: CMSG_MOVE_FORCE_UNROOT_ACK"); - - recvData.read_skip<uint32>(); // unk - - MovementInfo movementInfo; - movementInfo.guid = guid; - ValidateMovementInfo(recvData, &movementInfo); - recvData.read_skip<float>(); // unk2 -*/ -} - -void WorldSession::HandleMoveRootAck(WorldPacket& recvData) -{ - // no used - recvData.rfinish(); // prevent warnings spam -/* - uint64 guid; - recvData >> guid; - - // now can skip not our packet - if (_player->GetGUID() != guid) - { - recvData.rfinish(); // prevent warnings spam - return; - } - - TC_LOG_DEBUG("network", "WORLD: CMSG_MOVE_FORCE_ROOT_ACK"); - - recvData.read_skip<uint32>(); // unk - - MovementInfo movementInfo; - ValidateMovementInfo(recvData, &movementInfo); -*/ -} - void WorldSession::HandleSetActionBarToggles(WorldPackets::Character::SetActionBarToggles& packet) { if (!GetPlayer()) // ignore until not logged (check needed because STATUS_AUTHED) @@ -1320,26 +1216,6 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPackets::Misc::SetRaidDiff } } -void WorldSession::HandleCancelMountAuraOpcode(WorldPacket& /*recvData*/) -{ - TC_LOG_DEBUG("network", "WORLD: CMSG_CANCEL_MOUNT_AURA"); - - //If player is not mounted, so go out :) - if (!_player->IsMounted()) // not blizz like; no any messages on blizz - { - ChatHandler(this).SendSysMessage(LANG_CHAR_NON_MOUNTED); - return; - } - - if (_player->IsInFlight()) // not blizz like; no any messages on blizz - { - ChatHandler(this).SendSysMessage(LANG_YOU_IN_FLIGHT); - return; - } - - _player->RemoveAurasByType(SPELL_AURA_MOUNTED); // Calls Dismount() -} - void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket& /*recvData*/) { // fly mode on/off @@ -1395,73 +1271,6 @@ void WorldSession::SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set< SendPacket(phaseShift.Write()); } -// Battlefield and Battleground -void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket& recvData) -{ - TC_LOG_DEBUG("network", "WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY"); - - Battleground* bg = _player->GetBattleground(); - - ObjectGuid guid; - recvData >> guid; - - Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); - if (!unit) - return; - - if (!unit->IsSpiritService()) // it's not spirit service - return; - - if (bg) - sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, guid); - - if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId())) - bf->SendAreaSpiritHealerQueryOpcode(_player, guid); -} - -void WorldSession::HandleAreaSpiritHealerQueueOpcode(WorldPacket& recvData) -{ - TC_LOG_DEBUG("network", "WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE"); - - Battleground* bg = _player->GetBattleground(); - - ObjectGuid guid; - recvData >> guid; - - Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); - if (!unit) - return; - - if (!unit->IsSpiritService()) // it's not spirit service - return; - - if (bg) - bg->AddPlayerToResurrectQueue(guid, _player->GetGUID()); - - if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId())) - bf->AddPlayerToResurrectQueue(guid, _player->GetGUID()); -} - -void WorldSession::HandleHearthAndResurrect(WorldPacket& /*recvData*/) -{ - if (_player->IsInFlight()) - return; - - if (/*Battlefield* bf = */sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId())) - { - // bf->PlayerAskToLeave(_player); FIXME - return; - } - - AreaTableEntry const* atEntry = GetAreaEntryByAreaID(_player->GetAreaId()); - if (!atEntry || !(atEntry->Flags[0] & AREA_FLAG_WINTERGRASP_2)) - return; - - _player->BuildPlayerRepop(); - _player->ResurrectPlayer(1.0f); - _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation()); -} - void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket) { uint8 accept; @@ -1531,39 +1340,28 @@ void WorldSession::HandleViolenceLevel(WorldPackets::Misc::ViolenceLevel& /*viol // do something? } -void WorldSession::HandleObjectUpdateFailedOpcode(WorldPacket& recvPacket) +void WorldSession::HandleObjectUpdateFailedOpcode(WorldPackets::Misc::ObjectUpdateFailed& objectUpdateFailed) { - ObjectGuid guid; - guid[6] = recvPacket.ReadBit(); - guid[7] = recvPacket.ReadBit(); - guid[4] = recvPacket.ReadBit(); - guid[0] = recvPacket.ReadBit(); - guid[1] = recvPacket.ReadBit(); - guid[5] = recvPacket.ReadBit(); - guid[3] = recvPacket.ReadBit(); - guid[2] = recvPacket.ReadBit(); - - recvPacket.ReadByteSeq(guid[6]); - recvPacket.ReadByteSeq(guid[7]); - recvPacket.ReadByteSeq(guid[2]); - recvPacket.ReadByteSeq(guid[3]); - recvPacket.ReadByteSeq(guid[1]); - recvPacket.ReadByteSeq(guid[4]); - recvPacket.ReadByteSeq(guid[0]); - recvPacket.ReadByteSeq(guid[5]); - - WorldObject* obj = ObjectAccessor::GetWorldObject(*GetPlayer(), guid); - TC_LOG_ERROR("network", "Object update failed for %s (%s) for player %s (%s)", guid.ToString().c_str(), obj ? obj->GetName().c_str() : "object-not-found", GetPlayerName().c_str(), _player->GetGUID().ToString().c_str()); + TC_LOG_ERROR("network", "Object update failed for %s for player %s (%s)", objectUpdateFailed.ObjectGUID.ToString().c_str(), GetPlayerName().c_str(), _player->GetGUID().ToString().c_str()); // If create object failed for current player then client will be stuck on loading screen - if (_player->GetGUID() == guid) + if (_player->GetGUID() == objectUpdateFailed.ObjectGUID) { LogoutPlayer(true); return; } // Pretend we've never seen this object - _player->m_clientGUIDs.erase(guid); + _player->m_clientGUIDs.erase(objectUpdateFailed.ObjectGUID); +} + +void WorldSession::HandleObjectUpdateRescuedOpcode(WorldPackets::Misc::ObjectUpdateRescued& objectUpdateRescued) +{ + TC_LOG_ERROR("network", "Object update rescued for %s for player %s (%s)", objectUpdateRescued.ObjectGUID.ToString().c_str(), GetPlayerName().c_str(), _player->GetGUID().ToString().c_str()); + + // Client received values update after destroying object + // re-register object in m_clientGUIDs to send DestroyObject on next visibility update + _player->m_clientGUIDs.insert(objectUpdateRescued.ObjectGUID); } void WorldSession::HandleSaveCUFProfiles(WorldPacket& recvPacket) diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 8fb054f05b6..3835a0642f9 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -491,30 +491,9 @@ void WorldSession::HandleMoveKnockBackAck(WorldPackets::Movement::MovementAckMes _player->SendMessageToSet(updateKnockBack.Write(), false); } -void WorldSession::HandleMoveHoverAck(WorldPacket& recvData) +void WorldSession::HandleMovementAckMessage(WorldPackets::Movement::MovementAckMessage& movementAck) { - ObjectGuid guid; // guid - unused - recvData >> guid.ReadAsPacked(); - - recvData.read_skip<uint32>(); // unk - - MovementInfo movementInfo; - GetPlayer()->ValidateMovementInfo(&movementInfo); - - recvData.read_skip<uint32>(); // unk2 -} - -void WorldSession::HandleMoveWaterWalkAck(WorldPacket& recvData) -{ - ObjectGuid guid; // guid - unused - recvData >> guid.ReadAsPacked(); - - recvData.read_skip<uint32>(); // unk - - MovementInfo movementInfo; - GetPlayer()->ValidateMovementInfo(&movementInfo); - - recvData.read_skip<uint32>(); // unk2 + GetPlayer()->ValidateMovementInfo(&movementAck.Ack.movementInfo); } void WorldSession::HandleSummonResponseOpcode(WorldPacket& recvData) @@ -534,3 +513,7 @@ void WorldSession::HandleSetCollisionHeightAck(WorldPackets::Movement::MoveSetCo { GetPlayer()->ValidateMovementInfo(&setCollisionHeightAck.Data.movementInfo); } + +void WorldSession::HandleMoveTimeSkippedOpcode(WorldPackets::Movement::MoveTimeSkipped& /*moveTimeSkipped*/) +{ +} diff --git a/src/server/game/Handlers/NPCHandler.h b/src/server/game/Handlers/NPCHandler.h index 3b96ae5f937..1a91ecbfc85 100644 --- a/src/server/game/Handlers/NPCHandler.h +++ b/src/server/game/Handlers/NPCHandler.h @@ -19,29 +19,17 @@ #ifndef __NPCHANDLER_H #define __NPCHANDLER_H -struct QEmote +struct NpcTextData { - uint32 _Emote; - uint32 _Delay; -}; - -#define MAX_GOSSIP_TEXT_EMOTES 3 - -struct GossipTextOption -{ - std::string Text_0; - std::string Text_1; - uint32 BroadcastTextID; - uint32 Language; float Probability; - QEmote Emotes[MAX_GOSSIP_TEXT_EMOTES]; + uint32 BroadcastTextID; }; -#define MAX_GOSSIP_TEXT_OPTIONS 8 +#define MAX_NPC_TEXT_OPTIONS 8 -struct GossipText +struct NpcText { - GossipTextOption Options[MAX_GOSSIP_TEXT_OPTIONS]; + NpcTextData Data[MAX_NPC_TEXT_OPTIONS]; }; struct PageTextLocale @@ -49,12 +37,5 @@ struct PageTextLocale StringVector Text; }; -struct NpcTextLocale -{ - NpcTextLocale() { } - - StringVector Text_0[MAX_GOSSIP_TEXT_OPTIONS]; - StringVector Text_1[MAX_GOSSIP_TEXT_OPTIONS]; -}; #endif diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 93ae3873857..55a364b811e 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -89,9 +89,12 @@ void WorldSession::HandleCreatureQuery(WorldPackets::Query::QueryCreature& packe stats.HpMulti = creatureInfo->ModHealth; stats.EnergyMulti = creatureInfo->ModMana; stats.Leader = creatureInfo->RacialLeader; - for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) - if (creatureInfo->questItems[i]) - stats.QuestItems.push_back(creatureInfo->questItems[i]); + + CreatureQuestItemList* items = sObjectMgr->GetCreatureQuestItemList(packet.CreatureID); + if (items) + for (uint32 item : *items) + stats.QuestItems.push_back(item); + stats.CreatureMovementInfoID = creatureInfo->movementId; stats.RequiredExpansion = creatureInfo->expansionUnknown; stats.Flags[0] = creatureInfo->type_flags; @@ -128,9 +131,11 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPackets::Query::QueryGameObj stats.IconName = gameObjectInfo->IconName; stats.Name[0] = gameObjectInfo->name; - for (uint8 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; i++) - if (gameObjectInfo->questItems[i]) - stats.QuestItems.push_back(gameObjectInfo->questItems[i]); + GameObjectQuestItemList* items = sObjectMgr->GetGameObjectQuestItemList(packet.GameObjectID); + if (items) + for (uint32 item : *items) + stats.QuestItems.push_back(item); + for (uint32 i = 0; i < MAX_GAMEOBJECT_DATA; i++) stats.Data[i] = gameObjectInfo->raw.data[i]; @@ -198,35 +203,34 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPackets::Query::QueryNPCText& p { TC_LOG_DEBUG("network", "WORLD: CMSG_NPC_TEXT_QUERY TextId: %u", packet.TextID); - GossipText const* gossip = sObjectMgr->GetGossipText(packet.TextID); + NpcText const* npcText = sObjectMgr->GetNpcText(packet.TextID); WorldPackets::Query::QueryNPCTextResponse response; response.TextID = packet.TextID; - bool hasText = false; - if (gossip) + if (npcText) { - for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) + for (uint8 i = 0; i < MAX_NPC_TEXT_OPTIONS; ++i) { - response.Probabilities[i] = gossip->Options[i].Probability; - response.BroadcastTextID[i] = gossip->Options[i].BroadcastTextID; - if (!hasText && gossip->Options[i].BroadcastTextID) - hasText = true; + response.Probabilities[i] = npcText->Data[i].Probability; + response.BroadcastTextID[i] = npcText->Data[i].BroadcastTextID; + if (!response.Allow && npcText->Data[i].BroadcastTextID) + response.Allow = true; } - - response.Allow = true; } - if (hasText) - SendPacket(response.Write()); - else + + if (!response.Allow) TC_LOG_ERROR("sql.sql", "HandleNpcTextQueryOpcode: no BroadcastTextID found for text %u in `npc_text table`", packet.TextID); + TC_LOG_DEBUG("network", "WORLD: Sent SMSG_NPC_TEXT_UPDATE"); + + SendPacket(response.Write()); } /// Only _static_ data is sent in this packet !!! -void WorldSession::HandlePageTextQueryOpcode(WorldPackets::Query::QueryPageText& packet) +void WorldSession::HandleQueryPageText(WorldPackets::Query::QueryPageText& packet) { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_PAGE_TEXT_QUERY"); + TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUERY_PAGE_TEXT"); uint32 pageID = packet.PageTextID; @@ -246,19 +250,20 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPackets::Query::QueryPageText& { response.Allow = true; response.Info.ID = pageID; + response.Info.NextPageID = pageText->NextPageID; + response.Info.Text = pageText->Text; - int loc_idx = GetSessionDbLocaleIndex(); - if (loc_idx >= 0) - if (PageTextLocale const* player = sObjectMgr->GetPageTextLocale(pageID)) - ObjectMgr::GetLocaleString(player->Text, loc_idx, response.Info.Text); + LocaleConstant localeConstant = GetSessionDbLocaleIndex(); + if (localeConstant >= LOCALE_enUS) + if (PageTextLocale const* pageTextLocale = sObjectMgr->GetPageTextLocale(pageID)) + ObjectMgr::GetLocaleString(pageTextLocale->Text, localeConstant, response.Info.Text); - response.Info.NextPageID = pageText->NextPageID; pageID = pageText->NextPageID; } SendPacket(response.Write()); - TC_LOG_DEBUG("network", "WORLD: Sent SMSG_PAGE_TEXT_QUERY_RESPONSE"); + TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUERY_PAGE_TEXT_RESPONSE"); } } @@ -283,45 +288,34 @@ void WorldSession::HandleQueryCorpseTransport(WorldPackets::Query::QueryCorpseTr SendPacket(response.Write()); } -void WorldSession::HandleQuestNPCQuery(WorldPacket& recvData) +void WorldSession::HandleQueryQuestCompletionNPCs(WorldPackets::Query::QueryQuestCompletionNPCs& queryQuestCompletionNPCs) { - uint32 count = recvData.ReadBits(24); - std::map<uint32, std::vector<uint32>> quests; + WorldPackets::Query::QuestCompletionNPCResponse response; - for (uint32 i = 0; i < count; ++i) + for (int32& questID : queryQuestCompletionNPCs.QuestCompletionNPCs) { - uint32 questId; - recvData >> questId; + WorldPackets::Query::QuestCompletionNPC questCompletionNPC; - if (!sObjectMgr->GetQuestTemplate(questId)) + if (!sObjectMgr->GetQuestTemplate(questID)) { - TC_LOG_DEBUG("network", "WORLD: Unknown quest %u in CMSG_QUERY_QUEST_COMPLETION_NPCS by %s", questId, _player->GetGUID().ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: Unknown quest %u in CMSG_QUERY_QUEST_COMPLETION_NPCS by %s", questID, _player->GetGUID().ToString().c_str()); continue; } - auto creatures = sObjectMgr->GetCreatureQuestInvolvedRelationReverseBounds(questId); + questCompletionNPC.QuestID = questID; + + auto creatures = sObjectMgr->GetCreatureQuestInvolvedRelationReverseBounds(questID); for (auto it = creatures.first; it != creatures.second; ++it) - quests[questId].push_back(it->second); + questCompletionNPC.NPCs.push_back(it->second); - auto gos = sObjectMgr->GetGOQuestInvolvedRelationReverseBounds(questId); + auto gos = sObjectMgr->GetGOQuestInvolvedRelationReverseBounds(questID); for (auto it = gos.first; it != gos.second; ++it) - quests[questId].push_back(it->second | 0x80000000); // GO mask - } + questCompletionNPC.NPCs.push_back(it->second | 0x80000000); // GO mask - WorldPacket data(SMSG_QUEST_COMPLETION_NPC_RESPONSE, 3 + quests.size() * 14); - data.WriteBits(quests.size(), 23); - - for (auto it = quests.begin(); it != quests.end(); ++it) - data.WriteBits(it->second.size(), 24); - - for (auto it = quests.begin(); it != quests.end(); ++it) - { - data << uint32(it->first); - for (const auto& entry : it->second) - data << uint32(entry); + response.QuestCompletionNPCs.push_back(questCompletionNPC); } - SendPacket(&data); + SendPacket(response.Write()); } void WorldSession::HandleQuestPOIQuery(WorldPackets::Query::QuestPOIQuery& packet) @@ -345,7 +339,7 @@ void WorldSession::HandleQuestPOIQuery(WorldPackets::Query::QuestPOIQuery& packe uint16 questSlot = _player->FindQuestSlot(uint32(QuestID)); if (questSlot != MAX_QUEST_LOG_SIZE) - questOk = _player->GetQuestSlotQuestId(questSlot) == QuestID; + questOk = _player->GetQuestSlotQuestId(questSlot) == uint32(QuestID); if (questOk) { @@ -401,7 +395,7 @@ void WorldSession::HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet) DB2StorageBase const* store = sDB2Manager.GetStorage(packet.TableHash); if (!store) { - TC_LOG_ERROR("network", "CMSG_DB_QUERY_BULK: Received unknown hotfix type: %u", packet.TableHash); + TC_LOG_ERROR("network", "CMSG_DB_QUERY_BULK: %s requested unsupported unknown hotfix type: %u", GetPlayerInfo().c_str(), packet.TableHash); return; } @@ -418,7 +412,7 @@ void WorldSession::HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet) } else { - TC_LOG_ERROR("network", "CMSG_DB_QUERY_BULK: Entry %u does not exist in datastore: %u", rec.RecordID, packet.TableHash); + TC_LOG_TRACE("network", "CMSG_DB_QUERY_BULK: %s requested non-existing entry %u in datastore: %u", GetPlayerInfo().c_str(), rec.RecordID, packet.TableHash); response.RecordID = -int32(rec.RecordID); response.Timestamp = time(NULL); } diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index df5fae683fe..d7ad9c71956 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -237,18 +237,60 @@ void WorldSession::HandleQuestQueryOpcode(WorldPackets::Quest::QueryQuestInfo& p void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPackets::Quest::QuestGiverChooseReward& packet) { - if (packet.ItemChoiceID >= QUEST_REWARD_CHOICES_COUNT) - { - TC_LOG_ERROR("network", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (%s) tried to get invalid reward (%u) (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.ItemChoiceID); - return; - } - TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %s, quest = %u, reward = %u", packet.QuestGiverGUID.ToString().c_str(), packet.QuestID, packet.ItemChoiceID); Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestID); if (!quest) return; + // This is Real Item Entry, not slot id as pre 5.x + if (packet.ItemChoiceID) + { + ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(packet.ItemChoiceID); + if (!rewardProto) + { + TC_LOG_ERROR("network", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (%s) tried to get invalid reward item (Item Entry: %u) for quest %u (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.ItemChoiceID, packet.QuestID); + return; + } + + bool itemValid = false; + for (uint32 i = 0; i < quest->GetRewChoiceItemsCount(); ++i) + { + if (quest->RewardChoiceItemId[i] && quest->RewardChoiceItemId[i] == packet.ItemChoiceID) + { + itemValid = true; + break; + } + } + + if (quest->GetQuestPackageID()) + { + if (std::vector<QuestPackageItemEntry const*> const* questPackageItems = sDB2Manager.GetQuestPackageItems(quest->GetQuestPackageID())) + { + for (QuestPackageItemEntry const* questPackageItem : *questPackageItems) + { + if (questPackageItem->ItemID != packet.ItemChoiceID) + continue; + + if (ItemTemplate const* rewardProto = sObjectMgr->GetItemTemplate(questPackageItem->ItemID)) + { + if (rewardProto->CanWinForPlayer(_player)) + { + itemValid = true; + break; + } + } + } + } + } + + if (!itemValid) + { + TC_LOG_ERROR("network", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (%s) tried to get reward item (Item Entry: %u) wich is not a reward for quest %u (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUID().ToString().c_str(), packet.ItemChoiceID, packet.QuestID); + return; + } + } + Object* object = _player; if (!quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE)) diff --git a/src/server/game/Handlers/SceneHandler.cpp b/src/server/game/Handlers/SceneHandler.cpp new file mode 100644 index 00000000000..90965b29929 --- /dev/null +++ b/src/server/game/Handlers/SceneHandler.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * 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 "Common.h" +#include "ScenePackets.h" +#include "WorldSession.h" + +void WorldSession::HandleSceneTriggerEvent(WorldPackets::Scenes::SceneTriggerEvent& sceneTriggerEvent) +{ + TC_LOG_DEBUG("scenes", "HandleSceneTriggerEvent: SceneInstanceID: %u Event: %s", sceneTriggerEvent.SceneInstanceID, sceneTriggerEvent._Event.c_str()); +} + +void WorldSession::HandleScenePlaybackComplete(WorldPackets::Scenes::ScenePlaybackComplete& scenePlaybackComplete) +{ + + TC_LOG_DEBUG("scenes", "HandleScenePlaybackComplete: SceneInstanceID: %u", scenePlaybackComplete.SceneInstanceID); +} + +void WorldSession::HandleScenePlaybackCanceled(WorldPackets::Scenes::ScenePlaybackCanceled& scenePlaybackCanceled) +{ + TC_LOG_DEBUG("scenes", "HandleScenePlaybackCanceled: SceneInstanceID: %u", scenePlaybackCanceled.SceneInstanceID); +} diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index 4c8fd4a674f..824b747b9f8 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -408,7 +408,23 @@ void WorldSession::HandlePetCancelAuraOpcode(WorldPacket& recvPacket) pet->RemoveOwnedAura(spellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_CANCEL); } -void WorldSession::HandleCancelGrowthAuraOpcode(WorldPacket& /*recvPacket*/) { } +void WorldSession::HandleCancelGrowthAuraOpcode(WorldPackets::Spells::CancelGrowthAura& /*cancelGrowthAura*/) +{ + _player->RemoveAurasByType(SPELL_AURA_MOD_SCALE, [](AuraApplication const* aurApp) + { + SpellInfo const* spellInfo = aurApp->GetBase()->GetSpellInfo(); + return !spellInfo->HasAttribute(SPELL_ATTR0_CANT_CANCEL) && spellInfo->IsPositive() && !spellInfo->IsPassive(); + }); +} + +void WorldSession::HandleCancelMountAuraOpcode(WorldPackets::Spells::CancelMountAura& /*cancelMountAura*/) +{ + _player->RemoveAurasByType(SPELL_AURA_MOUNTED, [](AuraApplication const* aurApp) + { + SpellInfo const* spellInfo = aurApp->GetBase()->GetSpellInfo(); + return !spellInfo->HasAttribute(SPELL_ATTR0_CANT_CANCEL) && spellInfo->IsPositive() && !spellInfo->IsPassive(); + }); +} void WorldSession::HandleCancelAutoRepeatSpellOpcode(WorldPacket& /*recvPacket*/) { @@ -616,7 +632,7 @@ void WorldSession::HandleUpdateProjectilePosition(WorldPacket& recvPacket) caster->SendMessageToSet(&data, true); } -void WorldSession::HandleRequestCategoryCooldowns(WorldPacket& /*recvPacket*/) +void WorldSession::HandleRequestCategoryCooldowns(WorldPackets::Spells::RequestCategoryCooldowns& /*requestCategoryCooldowns*/) { SendSpellCategoryCooldowns(); } diff --git a/src/server/game/Handlers/TokenHandler.cpp b/src/server/game/Handlers/TokenHandler.cpp new file mode 100644 index 00000000000..6b2dd06a44b --- /dev/null +++ b/src/server/game/Handlers/TokenHandler.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * 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 "Common.h" +#include "TokenPackets.h" +#include "WorldSession.h" + +void WorldSession::HandleUpdateListedAuctionableTokens(WorldPackets::Token::UpdateListedAuctionableTokens& updateListedAuctionableTokens) +{ + WorldPackets::Token::UpdateListedAuctionableTokensResponse response; + + /// @todo: fix 6.x implementation + response.UnkInt = updateListedAuctionableTokens.UnkInt; + response.Result = TOKEN_RESULT_ERROR_DISABLED; + + SendPacket(response.Write()); +} diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index 517d02f852a..c5258e63e40 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -70,7 +70,7 @@ void WorldSession::SendUpdateTrade(bool trader_data /*= true*/) if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED)) { WorldPackets::Trade::TradeUpdated::UnwrappedTradeItem* unwrappedItem = &tradeItem.Unwrapped.Value; - unwrappedItem->Item.Initalize(item); + unwrappedItem->Item.Initialize(item); unwrappedItem->EnchantID = item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT); unwrappedItem->OnUseEnchantmentID = item->GetEnchantmentId(USE_ENCHANTMENT_SLOT); unwrappedItem->Creator = item->GetGuidValue(ITEM_FIELD_CREATOR); diff --git a/src/server/game/Handlers/VoidStorageHandler.cpp b/src/server/game/Handlers/VoidStorageHandler.cpp index 1e4ba33c910..dcca2f81711 100644 --- a/src/server/game/Handlers/VoidStorageHandler.cpp +++ b/src/server/game/Handlers/VoidStorageHandler.cpp @@ -24,301 +24,128 @@ #include "Log.h" #include "Opcodes.h" #include "Player.h" -#include <list> -#include <vector> -#include <utility> +#include "VoidStoragePackets.h" void WorldSession::SendVoidStorageTransferResult(VoidTransferError result) { - WorldPacket data(SMSG_VOID_TRANSFER_RESULT, 4); - data << uint32(result); - SendPacket(&data); + SendPacket(WorldPackets::VoidStorage::VoidTransferResult(result).Write()); } -void WorldSession::HandleVoidStorageUnlock(WorldPacket& recvData) +void WorldSession::HandleVoidStorageUnlock(WorldPackets::VoidStorage::UnlockVoidStorage& unlockVoidStorage) { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_STORAGE_UNLOCK"); - Player* player = GetPlayer(); - - ObjectGuid npcGuid; - npcGuid[4] = recvData.ReadBit(); - npcGuid[5] = recvData.ReadBit(); - npcGuid[3] = recvData.ReadBit(); - npcGuid[0] = recvData.ReadBit(); - npcGuid[2] = recvData.ReadBit(); - npcGuid[1] = recvData.ReadBit(); - npcGuid[7] = recvData.ReadBit(); - npcGuid[6] = recvData.ReadBit(); - - recvData.ReadByteSeq(npcGuid[7]); - recvData.ReadByteSeq(npcGuid[1]); - recvData.ReadByteSeq(npcGuid[2]); - recvData.ReadByteSeq(npcGuid[3]); - recvData.ReadByteSeq(npcGuid[5]); - recvData.ReadByteSeq(npcGuid[0]); - recvData.ReadByteSeq(npcGuid[6]); - recvData.ReadByteSeq(npcGuid[4]); - - Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER); + Creature* unit = _player->GetNPCIfCanInteractWith(unlockVoidStorage.Npc, UNIT_NPC_FLAG_VAULTKEEPER); if (!unit) { - TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageUnlock - %s not found or player can't interact with it.", npcGuid.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageUnlock - %s not found or player can't interact with it.", unlockVoidStorage.Npc.ToString().c_str()); return; } - if (player->IsVoidStorageUnlocked()) + if (_player->IsVoidStorageUnlocked()) { - TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageUnlock - Player (%s, name: %s) tried to unlock void storage a 2nd time.", player->GetGUID().ToString().c_str(), player->GetName().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageUnlock - Player (%s, name: %s) tried to unlock void storage a 2nd time.", _player->GetGUID().ToString().c_str(), _player->GetName().c_str()); return; } - player->ModifyMoney(-int64(VOID_STORAGE_UNLOCK)); - player->UnlockVoidStorage(); + _player->ModifyMoney(-int64(VOID_STORAGE_UNLOCK_COST)); + _player->UnlockVoidStorage(); } -void WorldSession::HandleVoidStorageQuery(WorldPacket& recvData) +void WorldSession::HandleVoidStorageQuery(WorldPackets::VoidStorage::QueryVoidStorage& queryVoidStorage) { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_STORAGE_QUERY"); - Player* player = GetPlayer(); - - ObjectGuid npcGuid; - npcGuid[4] = recvData.ReadBit(); - npcGuid[0] = recvData.ReadBit(); - npcGuid[5] = recvData.ReadBit(); - npcGuid[7] = recvData.ReadBit(); - npcGuid[6] = recvData.ReadBit(); - npcGuid[3] = recvData.ReadBit(); - npcGuid[1] = recvData.ReadBit(); - npcGuid[2] = recvData.ReadBit(); - - recvData.ReadByteSeq(npcGuid[5]); - recvData.ReadByteSeq(npcGuid[6]); - recvData.ReadByteSeq(npcGuid[3]); - recvData.ReadByteSeq(npcGuid[7]); - recvData.ReadByteSeq(npcGuid[1]); - recvData.ReadByteSeq(npcGuid[0]); - recvData.ReadByteSeq(npcGuid[4]); - recvData.ReadByteSeq(npcGuid[2]); - - Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER); + Creature* unit = _player->GetNPCIfCanInteractWith(queryVoidStorage.Npc, UNIT_NPC_FLAG_VAULTKEEPER); if (!unit) { - TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageQuery - %s not found or player can't interact with it.", npcGuid.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageQuery - %s not found or player can't interact with it.", queryVoidStorage.Npc.ToString().c_str()); + SendPacket(WorldPackets::VoidStorage::VoidStorageFailed().Write()); return; } - if (!player->IsVoidStorageUnlocked()) + if (!_player->IsVoidStorageUnlocked()) { - TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageQuery - Player (%s, name: %s) queried void storage without unlocking it.", player->GetGUID().ToString().c_str(), player->GetName().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageQuery - Player (%s, name: %s) queried void storage without unlocking it.", _player->GetGUID().ToString().c_str(), _player->GetName().c_str()); + SendPacket(WorldPackets::VoidStorage::VoidStorageFailed().Write()); return; } uint8 count = 0; for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) - if (player->GetVoidStorageItem(i)) + if (_player->GetVoidStorageItem(i)) ++count; - WorldPacket data(SMSG_VOID_STORAGE_CONTENTS, 2 * count + (14 + 4 + 4 + 4 + 4) * count); - - data.WriteBits(count, 8); - - ByteBuffer itemData((14 + 4 + 4 + 4 + 4) * count); + WorldPackets::VoidStorage::VoidStorageContents voidStorageContents; + voidStorageContents.Items.reserve(VOID_STORAGE_MAX_SLOT); for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) { - VoidStorageItem* item = player->GetVoidStorageItem(i); + VoidStorageItem* item = _player->GetVoidStorageItem(i); if (!item) continue; - ObjectGuid itemId = ObjectGuid::Create<HighGuid::Item>(item->ItemId); - ObjectGuid creatorGuid = item->CreatorGuid; - - data.WriteBit(creatorGuid[3]); - data.WriteBit(itemId[5]); - data.WriteBit(creatorGuid[6]); - data.WriteBit(creatorGuid[1]); - data.WriteBit(itemId[1]); - data.WriteBit(itemId[3]); - data.WriteBit(itemId[6]); - data.WriteBit(creatorGuid[5]); - data.WriteBit(creatorGuid[2]); - data.WriteBit(itemId[2]); - data.WriteBit(creatorGuid[4]); - data.WriteBit(itemId[0]); - data.WriteBit(itemId[4]); - data.WriteBit(itemId[7]); - data.WriteBit(creatorGuid[0]); - data.WriteBit(creatorGuid[7]); - - itemData.WriteByteSeq(creatorGuid[3]); - - itemData << uint32(item->ItemSuffixFactor); - - itemData.WriteByteSeq(creatorGuid[4]); - - itemData << uint32(i); - - itemData.WriteByteSeq(itemId[0]); - itemData.WriteByteSeq(itemId[6]); - itemData.WriteByteSeq(creatorGuid[0]); - itemData.WriteByteSeq(creatorGuid[1]); - - itemData << uint32(item->ItemRandomPropertyId); - - itemData.WriteByteSeq(itemId[4]); - itemData.WriteByteSeq(itemId[5]); - itemData.WriteByteSeq(itemId[2]); - itemData.WriteByteSeq(creatorGuid[2]); - itemData.WriteByteSeq(creatorGuid[6]); - itemData.WriteByteSeq(itemId[1]); - itemData.WriteByteSeq(itemId[3]); - itemData.WriteByteSeq(creatorGuid[5]); - itemData.WriteByteSeq(creatorGuid[7]); - - itemData << uint32(item->ItemEntry); - - itemData.WriteByteSeq(itemId[7]); - } + WorldPackets::VoidStorage::VoidItem voidItem; + voidItem.Guid = ObjectGuid::Create<HighGuid::Item>(item->ItemId); + voidItem.Creator = item->CreatorGuid; + voidItem.Slot = i; + voidItem.Item.Initialize(item); - data.FlushBits(); - data.append(itemData); + voidStorageContents.Items.push_back(voidItem); + } - SendPacket(&data); + SendPacket(voidStorageContents.Write()); } -void WorldSession::HandleVoidStorageTransfer(WorldPacket& recvData) +void WorldSession::HandleVoidStorageTransfer(WorldPackets::VoidStorage::VoidStorageTransfer& voidStorageTransfer) { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_STORAGE_TRANSFER"); - Player* player = GetPlayer(); - - // Read everything - - ObjectGuid npcGuid; - npcGuid[1] = recvData.ReadBit(); - - uint32 countDeposit = recvData.ReadBits(26); - - if (countDeposit > 9) + if (voidStorageTransfer.DepositsCount > VOID_STORAGE_MAX_DEPOSIT) { - TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (%s, name: %s) wants to deposit more than 9 items (%u).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), countDeposit); + TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (%s, name: %s) wants to deposit more than 9 items (%u).", _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), voidStorageTransfer.DepositsCount); return; } - std::vector<ObjectGuid> itemGuids(countDeposit); - for (uint32 i = 0; i < countDeposit; ++i) + if (voidStorageTransfer.WithdrawalsCount > VOID_STORAGE_MAX_WITHDRAW) { - itemGuids[i][4] = recvData.ReadBit(); - itemGuids[i][6] = recvData.ReadBit(); - itemGuids[i][7] = recvData.ReadBit(); - itemGuids[i][0] = recvData.ReadBit(); - itemGuids[i][1] = recvData.ReadBit(); - itemGuids[i][5] = recvData.ReadBit(); - itemGuids[i][3] = recvData.ReadBit(); - itemGuids[i][2] = recvData.ReadBit(); - } - - npcGuid[2] = recvData.ReadBit(); - npcGuid[0] = recvData.ReadBit(); - npcGuid[3] = recvData.ReadBit(); - npcGuid[5] = recvData.ReadBit(); - npcGuid[6] = recvData.ReadBit(); - npcGuid[4] = recvData.ReadBit(); - - uint32 countWithdraw = recvData.ReadBits(26); - - if (countWithdraw > 9) - { - TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (%s, name: %s) wants to withdraw more than 9 items (%u).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), countWithdraw); + TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (%s, name: %s) wants to withdraw more than 9 items (%u).", _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), voidStorageTransfer.WithdrawalsCount); return; } - std::vector<ObjectGuid> itemIds(countWithdraw); - for (uint32 i = 0; i < countWithdraw; ++i) - { - itemIds[i][4] = recvData.ReadBit(); - itemIds[i][7] = recvData.ReadBit(); - itemIds[i][1] = recvData.ReadBit(); - itemIds[i][0] = recvData.ReadBit(); - itemIds[i][2] = recvData.ReadBit(); - itemIds[i][3] = recvData.ReadBit(); - itemIds[i][5] = recvData.ReadBit(); - itemIds[i][6] = recvData.ReadBit(); - } - - npcGuid[7] = recvData.ReadBit(); - - for (uint32 i = 0; i < countDeposit; ++i) - { - recvData.ReadByteSeq(itemGuids[i][6]); - recvData.ReadByteSeq(itemGuids[i][1]); - recvData.ReadByteSeq(itemGuids[i][0]); - recvData.ReadByteSeq(itemGuids[i][2]); - recvData.ReadByteSeq(itemGuids[i][4]); - recvData.ReadByteSeq(itemGuids[i][5]); - recvData.ReadByteSeq(itemGuids[i][3]); - recvData.ReadByteSeq(itemGuids[i][7]); - } - - recvData.ReadByteSeq(npcGuid[5]); - recvData.ReadByteSeq(npcGuid[6]); - - for (uint32 i = 0; i < countWithdraw; ++i) - { - recvData.ReadByteSeq(itemIds[i][3]); - recvData.ReadByteSeq(itemIds[i][0]); - recvData.ReadByteSeq(itemIds[i][1]); - recvData.ReadByteSeq(itemIds[i][6]); - recvData.ReadByteSeq(itemIds[i][2]); - recvData.ReadByteSeq(itemIds[i][7]); - recvData.ReadByteSeq(itemIds[i][5]); - recvData.ReadByteSeq(itemIds[i][4]); - } - - recvData.ReadByteSeq(npcGuid[1]); - recvData.ReadByteSeq(npcGuid[4]); - recvData.ReadByteSeq(npcGuid[7]); - recvData.ReadByteSeq(npcGuid[3]); - recvData.ReadByteSeq(npcGuid[2]); - recvData.ReadByteSeq(npcGuid[0]); - - Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER); + Creature* unit = _player->GetNPCIfCanInteractWith(voidStorageTransfer.Npc, UNIT_NPC_FLAG_VAULTKEEPER); if (!unit) { - TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s not found or player can't interact with it.", npcGuid.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s not found or player can't interact with it.", voidStorageTransfer.Npc.ToString().c_str()); return; } - if (!player->IsVoidStorageUnlocked()) + if (!_player->IsVoidStorageUnlocked()) { - TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (%s, name: %s) queried void storage without unlocking it.", player->GetGUID().ToString().c_str(), player->GetName().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (%s, name: %s) queried void storage without unlocking it.", _player->GetGUID().ToString().c_str(), _player->GetName().c_str()); return; } - if (itemGuids.size() > player->GetNumOfVoidStorageFreeSlots()) + if (voidStorageTransfer.DepositsCount > _player->GetNumOfVoidStorageFreeSlots()) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_FULL); return; } uint32 freeBagSlots = 0; - if (itemIds.size() != 0) + if (voidStorageTransfer.WithdrawalsCount) { // make this a Player function for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) - if (Bag* bag = player->GetBagByPos(i)) + if (Bag* bag = _player->GetBagByPos(i)) freeBagSlots += bag->GetFreeSlots(); + for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) - if (!player->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + if (!_player->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) ++freeBagSlots; } - if (itemIds.size() > freeBagSlots) + if (voidStorageTransfer.WithdrawalsCount > freeBagSlots) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INVENTORY_FULL); return; } - if (!player->HasEnoughMoney(uint64(itemGuids.size() * VOID_STORAGE_STORE_ITEM))) + if (!_player->HasEnoughMoney(uint64(voidStorageTransfer.DepositsCount * VOID_STORAGE_STORE_ITEM_COST))) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_NOT_ENOUGH_MONEY); return; @@ -326,294 +153,125 @@ void WorldSession::HandleVoidStorageTransfer(WorldPacket& recvData) std::pair<VoidStorageItem, uint8> depositItems[VOID_STORAGE_MAX_DEPOSIT]; uint8 depositCount = 0; - for (std::vector<ObjectGuid>::iterator itr = itemGuids.begin(); itr != itemGuids.end(); ++itr) + for (uint32 i = 0; i < voidStorageTransfer.DepositsCount; ++i) { - Item* item = player->GetItemByGuid(*itr); + Item* item = _player->GetItemByGuid(voidStorageTransfer.Deposits[i]); if (!item) { - TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s %s wants to deposit an invalid item (%s).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), itr->ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s %s wants to deposit an invalid item (%s).", _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), item->GetGUID().ToString().c_str()); continue; } + // TODO: Save these fields to database - for now disallow storing these items to prevent data loss + if (item->GetUInt32Value(ITEM_FIELD_MODIFIERS_MASK) || !item->GetDynamicValues(ITEM_DYNAMIC_FIELD_BONUSLIST_IDS).empty()) + continue; + VoidStorageItem itemVS(sObjectMgr->GenerateVoidStorageItemId(), item->GetEntry(), item->GetGuidValue(ITEM_FIELD_CREATOR), item->GetItemRandomPropertyId(), item->GetItemSuffixFactor()); - uint8 slot = player->AddVoidStorageItem(itemVS); + uint8 slot = _player->AddVoidStorageItem(itemVS); depositItems[depositCount++] = std::make_pair(itemVS, slot); - player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); + _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); } - int64 cost = depositCount * VOID_STORAGE_STORE_ITEM; + int64 cost = depositCount * VOID_STORAGE_STORE_ITEM_COST; - player->ModifyMoney(-cost); + _player->ModifyMoney(-cost); VoidStorageItem withdrawItems[VOID_STORAGE_MAX_WITHDRAW]; uint8 withdrawCount = 0; - for (std::vector<ObjectGuid>::iterator itr = itemIds.begin(); itr != itemIds.end(); ++itr) + for (uint32 i = 0; i < voidStorageTransfer.WithdrawalsCount; ++i) { - uint8 slot; - VoidStorageItem* itemVS = player->GetVoidStorageItem(itr->GetCounter(), slot); + uint8 slot = 0; + VoidStorageItem* itemVS = _player->GetVoidStorageItem(voidStorageTransfer.Withdrawals[i].GetCounter(), slot); if (!itemVS) { - TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s %s tried to withdraw an invalid item (id: %s)", player->GetGUID().ToString().c_str(), player->GetName().c_str(), itr->ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s %s tried to withdraw an invalid item (id: %s)", _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), voidStorageTransfer.Withdrawals[i].ToString().c_str()); continue; } ItemPosCountVec dest; - InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemVS->ItemEntry, 1); + InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemVS->ItemEntry, 1); if (msg != EQUIP_ERR_OK) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INVENTORY_FULL); - TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s %s couldn't withdraw item id %s because inventory was full.", player->GetGUID().ToString().c_str(), player->GetName().c_str(), itr->ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - %s %s couldn't withdraw item id %s because inventory was full.", _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), voidStorageTransfer.Withdrawals[i].ToString().c_str()); return; } - Item* item = player->StoreNewItem(dest, itemVS->ItemEntry, true, itemVS->ItemRandomPropertyId); + Item* item = _player->StoreNewItem(dest, itemVS->ItemEntry, true, itemVS->ItemRandomPropertyId); + item->SetUInt32Value(ITEM_FIELD_PROPERTY_SEED, itemVS->ItemSuffixFactor); item->SetGuidValue(ITEM_FIELD_CREATOR, itemVS->CreatorGuid); item->SetBinding(true); - player->SendNewItem(item, 1, false, false, false); + _player->SendNewItem(item, 1, false, false, false); withdrawItems[withdrawCount++] = *itemVS; - player->DeleteVoidStorageItem(slot); + _player->DeleteVoidStorageItem(slot); } - WorldPacket data(SMSG_VOID_STORAGE_TRANSFER_CHANGES, ((5 + 5 + (7 + 7) * depositCount + - 7 * withdrawCount) / 8) + 7 * withdrawCount + (7 + 7 + 4 * 4) * depositCount); - - data.WriteBits(depositCount, 5); - data.WriteBits(withdrawCount, 5); + WorldPackets::VoidStorage::VoidStorageTransferChanges voidStorageTransferChanges; + voidStorageTransferChanges.AddedItems.resize(depositCount); + voidStorageTransferChanges.RemovedItems.resize(withdrawCount); for (uint8 i = 0; i < depositCount; ++i) { - ObjectGuid itemId = ObjectGuid::Create<HighGuid::Item>(depositItems[i].first.ItemId); - ObjectGuid creatorGuid = depositItems[i].first.CreatorGuid; - data.WriteBit(creatorGuid[7]); - data.WriteBit(itemId[7]); - data.WriteBit(itemId[4]); - data.WriteBit(creatorGuid[6]); - data.WriteBit(creatorGuid[5]); - data.WriteBit(itemId[3]); - data.WriteBit(itemId[5]); - data.WriteBit(creatorGuid[4]); - data.WriteBit(creatorGuid[2]); - data.WriteBit(creatorGuid[0]); - data.WriteBit(creatorGuid[3]); - data.WriteBit(creatorGuid[1]); - data.WriteBit(itemId[2]); - data.WriteBit(itemId[0]); - data.WriteBit(itemId[1]); - data.WriteBit(itemId[6]); + voidStorageTransferChanges.AddedItems[i].Guid = ObjectGuid::Create<HighGuid::Item>(depositItems[i].first.ItemId); + voidStorageTransferChanges.AddedItems[i].Creator = depositItems[i].first.CreatorGuid; + voidStorageTransferChanges.AddedItems[i].Slot = depositItems[i].second; + voidStorageTransferChanges.AddedItems[i].Item.Initialize(&depositItems[i].first); } for (uint8 i = 0; i < withdrawCount; ++i) - { - ObjectGuid itemId = ObjectGuid::Create<HighGuid::Item>(withdrawItems[i].ItemId); - data.WriteBit(itemId[1]); - data.WriteBit(itemId[7]); - data.WriteBit(itemId[3]); - data.WriteBit(itemId[5]); - data.WriteBit(itemId[6]); - data.WriteBit(itemId[2]); - data.WriteBit(itemId[4]); - data.WriteBit(itemId[0]); - } + voidStorageTransferChanges.RemovedItems[i] = ObjectGuid::Create<HighGuid::Item>(withdrawItems[i].ItemId); - data.FlushBits(); - - for (uint8 i = 0; i < withdrawCount; ++i) - { - ObjectGuid itemId = ObjectGuid::Create<HighGuid::Item>(withdrawItems[i].ItemId); - data.WriteByteSeq(itemId[3]); - data.WriteByteSeq(itemId[1]); - data.WriteByteSeq(itemId[0]); - data.WriteByteSeq(itemId[2]); - data.WriteByteSeq(itemId[7]); - data.WriteByteSeq(itemId[5]); - data.WriteByteSeq(itemId[6]); - data.WriteByteSeq(itemId[4]); - } - - for (uint8 i = 0; i < depositCount; ++i) - { - ObjectGuid itemId = ObjectGuid::Create<HighGuid::Item>(depositItems[i].first.ItemId); - ObjectGuid creatorGuid = depositItems[i].first.CreatorGuid; - - data << uint32(depositItems[i].first.ItemSuffixFactor); - - data.WriteByteSeq(itemId[6]); - data.WriteByteSeq(itemId[4]); - data.WriteByteSeq(creatorGuid[4]); - data.WriteByteSeq(itemId[2]); - data.WriteByteSeq(creatorGuid[1]); - data.WriteByteSeq(creatorGuid[3]); - data.WriteByteSeq(itemId[3]); - data.WriteByteSeq(creatorGuid[0]); - data.WriteByteSeq(itemId[0]); - data.WriteByteSeq(creatorGuid[6]); - data.WriteByteSeq(itemId[5]); - data.WriteByteSeq(creatorGuid[5]); - data.WriteByteSeq(creatorGuid[7]); - - data << uint32(depositItems[i].first.ItemEntry); - - data.WriteByteSeq(itemId[1]); - - data << uint32(depositItems[i].second); // slot - - data.WriteByteSeq(creatorGuid[2]); - data.WriteByteSeq(itemId[7]); - - data << uint32(depositItems[i].first.ItemRandomPropertyId); - } - - SendPacket(&data); + SendPacket(voidStorageTransferChanges.Write()); SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_NO_ERROR); } -void WorldSession::HandleVoidSwapItem(WorldPacket& recvData) +void WorldSession::HandleVoidSwapItem(WorldPackets::VoidStorage::SwapVoidItem& swapVoidItem) { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_SWAP_ITEM"); - - Player* player = GetPlayer(); - uint32 newSlot; - ObjectGuid npcGuid; - ObjectGuid itemId; - - recvData >> newSlot; - - npcGuid[2] = recvData.ReadBit(); - npcGuid[4] = recvData.ReadBit(); - npcGuid[0] = recvData.ReadBit(); - itemId[2] = recvData.ReadBit(); - itemId[6] = recvData.ReadBit(); - itemId[5] = recvData.ReadBit(); - npcGuid[1] = recvData.ReadBit(); - npcGuid[7] = recvData.ReadBit(); - itemId[3] = recvData.ReadBit(); - itemId[7] = recvData.ReadBit(); - itemId[0] = recvData.ReadBit(); - npcGuid[6] = recvData.ReadBit(); - npcGuid[5] = recvData.ReadBit(); - npcGuid[3] = recvData.ReadBit(); - itemId[1] = recvData.ReadBit(); - itemId[4] = recvData.ReadBit(); - - recvData.ReadByteSeq(npcGuid[1]); - recvData.ReadByteSeq(itemId[3]); - recvData.ReadByteSeq(itemId[2]); - recvData.ReadByteSeq(itemId[4]); - recvData.ReadByteSeq(npcGuid[3]); - recvData.ReadByteSeq(npcGuid[0]); - recvData.ReadByteSeq(itemId[6]); - recvData.ReadByteSeq(itemId[1]); - recvData.ReadByteSeq(npcGuid[5]); - recvData.ReadByteSeq(itemId[5]); - recvData.ReadByteSeq(npcGuid[6]); - recvData.ReadByteSeq(itemId[0]); - recvData.ReadByteSeq(npcGuid[2]); - recvData.ReadByteSeq(npcGuid[7]); - recvData.ReadByteSeq(npcGuid[4]); - recvData.ReadByteSeq(itemId[7]); - - Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER); + Creature* unit = _player->GetNPCIfCanInteractWith(swapVoidItem.Npc, UNIT_NPC_FLAG_VAULTKEEPER); if (!unit) { - TC_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - %s not found or player can't interact with it.", npcGuid.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - %s not found or player can't interact with it.", swapVoidItem.Npc.ToString().c_str()); return; } - if (!player->IsVoidStorageUnlocked()) + if (!_player->IsVoidStorageUnlocked()) { - TC_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - Player (%s, name: %s) queried void storage without unlocking it.", player->GetGUID().ToString().c_str(), player->GetName().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - Player (%s, name: %s) queried void storage without unlocking it.", _player->GetGUID().ToString().c_str(), _player->GetName().c_str()); return; } uint8 oldSlot; - if (!player->GetVoidStorageItem(itemId.GetCounter(), oldSlot)) + if (!_player->GetVoidStorageItem(swapVoidItem.VoidItemGuid.GetCounter(), oldSlot)) { - TC_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - %s %s requested swapping an invalid item (slot: %u, itemid: %s).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), newSlot, itemId.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - %s %s requested swapping an invalid item (slot: %u, itemid: %s).", _player->GetGUID().ToString().c_str(), _player->GetName().c_str(), swapVoidItem.DstSlot, swapVoidItem.VoidItemGuid.ToString().c_str()); return; } - bool usedSrcSlot = player->GetVoidStorageItem(oldSlot) != NULL; // should be always true - bool usedDestSlot = player->GetVoidStorageItem(newSlot) != NULL; + bool usedDestSlot = _player->GetVoidStorageItem(swapVoidItem.DstSlot) != NULL; ObjectGuid itemIdDest; if (usedDestSlot) - itemIdDest = ObjectGuid::Create<HighGuid::Item>(player->GetVoidStorageItem(newSlot)->ItemId); + itemIdDest = ObjectGuid::Create<HighGuid::Item>(_player->GetVoidStorageItem(swapVoidItem.DstSlot)->ItemId); - if (!player->SwapVoidStorageItem(oldSlot, newSlot)) + if (!_player->SwapVoidStorageItem(oldSlot, swapVoidItem.DstSlot)) { SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INTERNAL_ERROR_1); return; } - WorldPacket data(SMSG_VOID_ITEM_SWAP_RESPONSE, 1 + (usedSrcSlot + usedDestSlot) * (1 + 7 + 4)); - - data.WriteBit(!usedDestSlot); - data.WriteBit(!usedSrcSlot); - - if (usedSrcSlot) - { - data.WriteBit(itemId[5]); - data.WriteBit(itemId[2]); - data.WriteBit(itemId[1]); - data.WriteBit(itemId[4]); - data.WriteBit(itemId[0]); - data.WriteBit(itemId[6]); - data.WriteBit(itemId[7]); - data.WriteBit(itemId[3]); - } - - data.WriteBit(!usedDestSlot); // unk - - if (usedDestSlot) - { - data.WriteBit(itemIdDest[7]); - data.WriteBit(itemIdDest[3]); - data.WriteBit(itemIdDest[4]); - data.WriteBit(itemIdDest[0]); - data.WriteBit(itemIdDest[5]); - data.WriteBit(itemIdDest[1]); - data.WriteBit(itemIdDest[2]); - data.WriteBit(itemIdDest[6]); - } - - data.WriteBit(!usedSrcSlot); // unk - - data.FlushBits(); - + WorldPackets::VoidStorage::VoidItemSwapResponse voidItemSwapResponse; + voidItemSwapResponse.VoidItemA = swapVoidItem.VoidItemGuid; + voidItemSwapResponse.VoidItemSlotA = swapVoidItem.DstSlot; if (usedDestSlot) { - data.WriteByteSeq(itemIdDest[4]); - data.WriteByteSeq(itemIdDest[6]); - data.WriteByteSeq(itemIdDest[5]); - data.WriteByteSeq(itemIdDest[2]); - data.WriteByteSeq(itemIdDest[3]); - data.WriteByteSeq(itemIdDest[1]); - data.WriteByteSeq(itemIdDest[7]); - data.WriteByteSeq(itemIdDest[0]); - } - - if (usedSrcSlot) - { - data.WriteByteSeq(itemId[6]); - data.WriteByteSeq(itemId[3]); - data.WriteByteSeq(itemId[5]); - data.WriteByteSeq(itemId[0]); - data.WriteByteSeq(itemId[1]); - data.WriteByteSeq(itemId[2]); - data.WriteByteSeq(itemId[4]); - data.WriteByteSeq(itemId[7]); + voidItemSwapResponse.VoidItemB = itemIdDest; + voidItemSwapResponse.VoidItemSlotB = oldSlot; } - if (usedDestSlot) - data << uint32(oldSlot); - - if (usedSrcSlot) - data << uint32(newSlot); - - SendPacket(&data); + SendPacket(voidItemSwapResponse.Write()); } diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index ce99d6ed971..efb3810d00c 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -921,7 +921,7 @@ void Loot::BuildLootResponse(WorldPackets::Loot::LootResponse& packet, Player* v lootItem.LootListID = packet.Items.size()+1; lootItem.LootItemType = slot_type; lootItem.Quantity = items[i].count; - lootItem.Loot.Initalize(items[i]); + lootItem.Loot.Initialize(items[i]); packet.Items.push_back(lootItem); } } @@ -941,7 +941,7 @@ void Loot::BuildLootResponse(WorldPackets::Loot::LootResponse& packet, Player* v lootItem.LootListID = packet.Items.size()+1; lootItem.LootItemType = LOOT_SLOT_TYPE_ALLOW_LOOT; lootItem.Quantity = items[i].count; - lootItem.Loot.Initalize(items[i]); + lootItem.Loot.Initialize(items[i]); packet.Items.push_back(lootItem); } } @@ -958,7 +958,7 @@ void Loot::BuildLootResponse(WorldPackets::Loot::LootResponse& packet, Player* v lootItem.LootListID = packet.Items.size()+1; lootItem.LootItemType = LOOT_SLOT_TYPE_ALLOW_LOOT; lootItem.Quantity = items[i].count; - lootItem.Loot.Initalize(items[i]); + lootItem.Loot.Initialize(items[i]); packet.Items.push_back(lootItem); } } @@ -981,7 +981,7 @@ void Loot::BuildLootResponse(WorldPackets::Loot::LootResponse& packet, Player* v WorldPackets::Loot::LootItemData lootItem; lootItem.LootListID = packet.Items.size()+1; lootItem.Quantity = item.count; - lootItem.Loot.Initalize(item); + lootItem.Loot.Initialize(item); if (item.follow_loot_rules) { @@ -1027,7 +1027,7 @@ void Loot::BuildLootResponse(WorldPackets::Loot::LootResponse& packet, Player* v lootItem.LootListID = packet.Items.size()+1; lootItem.LootItemType = LOOT_SLOT_TYPE_ALLOW_LOOT; lootItem.Quantity = item.count; - lootItem.Loot.Initalize(item); + lootItem.Loot.Initialize(item); packet.Items.push_back(lootItem); } } @@ -1046,7 +1046,7 @@ void Loot::BuildLootResponse(WorldPackets::Loot::LootResponse& packet, Player* v WorldPackets::Loot::LootItemData lootItem; lootItem.LootListID = packet.Items.size()+1; lootItem.Quantity = item.count; - lootItem.Loot.Initalize(item); + lootItem.Loot.Initialize(item); if (item.follow_loot_rules) { diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 894e7624ca5..4a024441ed5 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -4264,33 +4264,36 @@ enum ChatMsg CHAT_MSG_RAID_BOSS_EMOTE = 0x29, CHAT_MSG_RAID_BOSS_WHISPER = 0x2A, CHAT_MSG_FILTERED = 0x2B, - CHAT_MSG_BATTLEGROUND = 0x2C, - CHAT_MSG_BATTLEGROUND_LEADER = 0x2D, - CHAT_MSG_RESTRICTED = 0x2E, - CHAT_MSG_BATTLENET = 0x2F, - CHAT_MSG_ACHIEVEMENT = 0x30, - CHAT_MSG_GUILD_ACHIEVEMENT = 0x31, - CHAT_MSG_ARENA_POINTS = 0x32, - CHAT_MSG_PARTY_LEADER = 0x33, - CHAT_MSG_TARGETICONS = 0x34, - CHAT_MSG_BN_WHISPER = 0x35, - CHAT_MSG_BN_WHISPER_INFORM = 0x36, - CHAT_MSG_BN_CONVERSATION = 0x37, - CHAT_MSG_BN_CONVERSATION_NOTICE = 0x38, - CHAT_MSG_BN_CONVERSATION_LIST = 0x39, - CHAT_MSG_BN_INLINE_TOAST_ALERT = 0x3A, - CHAT_MSG_BN_INLINE_TOAST_BROADCAST = 0x3B, - CHAT_MSG_BN_INLINE_TOAST_BROADCAST_INFORM = 0x3C, - CHAT_MSG_BN_INLINE_TOAST_CONVERSATION = 0x3D, - CHAT_MSG_BN_WHISPER_PLAYER_OFFLINE = 0x3E, - CHAT_MSG_COMBAT_GUILD_XP_GAIN = 0x3F, - CHAT_MSG_CURRENCY = 0x40 + CHAT_MSG_RESTRICTED = 0x2C, + CHAT_MSG_BATTLENET = 0x2D, + CHAT_MSG_ACHIEVEMENT = 0x2E, + CHAT_MSG_GUILD_ACHIEVEMENT = 0x2F, + CHAT_MSG_ARENA_POINTS = 0x30, + CHAT_MSG_PARTY_LEADER = 0x31, + CHAT_MSG_TARGETICONS = 0x32, + CHAT_MSG_BN_WHISPER = 0x33, + CHAT_MSG_BN_WHISPER_INFORM = 0x34, + CHAT_MSG_BN_CONVERSATION = 0x35, + CHAT_MSG_BN_CONVERSATION_NOTICE = 0x36, + CHAT_MSG_BN_CONVERSATION_LIST = 0x37, + CHAT_MSG_BN_INLINE_TOAST_ALERT = 0x38, + CHAT_MSG_BN_INLINE_TOAST_BROADCAST = 0x39, + CHAT_MSG_BN_INLINE_TOAST_BROADCAST_INFORM = 0x3A, + CHAT_MSG_BN_INLINE_TOAST_CONVERSATION = 0x3B, + CHAT_MSG_BN_WHISPER_PLAYER_OFFLINE = 0x3C, + CHAT_MSG_COMBAT_GUILD_XP_GAIN = 0x3D, + CHAT_MSG_CURRENCY = 0x3E, + CHAT_MSG_QUEST_BOSS_EMOTE = 0x3F, + CHAT_MSG_PET_BATTLE_COMBAT_LOG = 0x40, + CHAT_MSG_PET_BATTLE_INFO = 0x41, + CHAT_MSG_INSTANCE_CHAT = 0x42, + CHAT_MSG_INSTANCE_CHAT_LEADER = 0x43, + + MAX_CHAT_MSG_TYPE }; #define GM_SILENCE_AURA 1852 -#define MAX_CHAT_MSG_TYPE 0x41 - enum ChatFlags { CHAT_FLAG_NONE = 0x00, @@ -4815,11 +4818,14 @@ enum DungeonStatusFlag RAID_STATUSFLAG_25MAN_HEROIC = 0x08 }; -#define VOID_STORAGE_UNLOCK 100*GOLD -#define VOID_STORAGE_STORE_ITEM 25*GOLD -#define VOID_STORAGE_MAX_DEPOSIT 9 -#define VOID_STORAGE_MAX_WITHDRAW 9 -#define VOID_STORAGE_MAX_SLOT 80 +enum VoidStorageConstants +{ + VOID_STORAGE_UNLOCK_COST = 100 * GOLD, + VOID_STORAGE_STORE_ITEM_COST = 10 * GOLD, + VOID_STORAGE_MAX_DEPOSIT = 9, + VOID_STORAGE_MAX_WITHDRAW = 9, + VOID_STORAGE_MAX_SLOT = 160 +}; enum VoidTransferError { @@ -4831,8 +4837,8 @@ enum VoidTransferError VOID_TRANSFER_ERROR_INTERNAL_ERROR_4 = 5, VOID_TRANSFER_ERROR_NOT_ENOUGH_MONEY = 6, VOID_TRANSFER_ERROR_INVENTORY_FULL = 7, - VOID_TRANSFER_ERROR_INTERNAL_ERROR_5 = 8, - VOID_TRANSFER_ERROR_TRANSFER_UNKNOWN = 9, + VOID_TRANSFER_ERROR_ITEM_INVALID = 8, + VOID_TRANSFER_ERROR_TRANSFER_UNKNOWN = 9 }; #define CURRENCY_PRECISION 100 @@ -4909,4 +4915,17 @@ enum DiminishingLevels DIMINISHING_LEVEL_TAUNT_IMMUNE = 4 }; +enum TokenResult +{ + TOKEN_RESULT_SUCCESS = 1, + TOKEN_RESULT_ERROR_DISABLED = 2, + TOKEN_RESULT_ERROR_OTHER = 3, + TOKEN_RESULT_ERROR_NONE_FOR_SALE = 4, + TOKEN_RESULT_ERROR_TOO_MANY_TOKENS = 5, + TOKEN_RESULT_SUCCESS_NO = 6, + TOKEN_RESULT_ERROR_TRANSACTION_IN_PROGRESS = 7, + TOKEN_RESULT_ERROR_AUCTIONABLE_TOKEN_OWNED = 8, + TOKEN_RESULT_ERROR_TRIAL_RESTRICTED = 9 +}; + #endif diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index da0830734e5..c878287b4ac 100644 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -194,7 +194,7 @@ void Quest::LoadQuestObjective(Field* fields) void Quest::LoadQuestObjectiveVisualEffect(Field* fields) { - uint8 objID = fields[1].GetUInt32(); + uint32 objID = fields[1].GetUInt32(); for (QuestObjective& obj : Objectives) { diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index d893784212e..8433a549c60 100644 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -163,6 +163,33 @@ enum QuestFlags // ... 4.x added flags up to 0x80000000 - all unknown for now }; +// last checked in 19802 +enum QuestFlagsEx +{ + QUEST_FLAGS_EX_NONE = 0X000000, + QUEST_FLAGS_EX_KEEP_ADDITIONAL_ITEMS = 0X000001, + QUEST_FLAGS_EX_SUPPRESS_GOSSIP_COMPLETE = 0X000002, + QUEST_FLAGS_EX_SUPPRESS_GOSSIP_ACCEPT = 0X000004, + QUEST_FLAGS_EX_DISALLOW_PLAYER_AS_QUESTGIVER = 0X000008, + QUEST_FLAGS_EX_DISPLAY_CLASS_CHOICE_REWARDS = 0X000010, + QUEST_FLAGS_EX_DISPLAY_SPEC_CHOICE_REWARDS = 0X000020, + QUEST_FLAGS_EX_REMOVE_FROM_LOG_ON_PERIDOIC_RESET = 0X000040, + QUEST_FLAGS_EX_ACCOUNT_LEVEL_QUEST = 0X000080, + QUEST_FLAGS_EX_LEGENDARY_QUEST = 0X000100, + QUEST_FLAGS_EX_NO_GUILD_XP = 0X000200, + QUEST_FLAGS_EX_RESET_CACHE_ON_ACCEPT = 0X000400, + QUEST_FLAGS_EX_NO_ABANDON_ONCE_ANY_OBJECTIVE_COMPLETE = 0X000800, + QUEST_FLAGS_EX_RECAST_ACCEPT_SPELL_ON_LOGIN = 0X001000, + QUEST_FLAGS_EX_UPDATE_ZONE_AURAS = 0X002000, + QUEST_FLAGS_EX_NO_CREDIT_FOR_PROXY = 0X004000, + QUEST_FLAGS_EX_DISPLAY_AS_DAILY_QUEST = 0X008000, + QUEST_FLAGS_EX_PART_OF_QUEST_LINE = 0X010000, + QUEST_FLAGS_EX_QUEST_FOR_INTERNAL_BUILDS_ONLY = 0X020000, + QUEST_FLAGS_EX_SUPPRESS_SPELL_LEARN_TEXT_LINE = 0X040000, + QUEST_FLAGS_EX_DISPLAY_HEADER_AS_OBJECTIVE_FOR_TASKS = 0X080000, + QUEST_FLAGS_EX_GARRISON_NON_OWNERS_ALLOWED = 0X100000 +}; + enum QuestSpecialFlags { QUEST_SPECIAL_FLAGS_NONE = 0x000, @@ -202,21 +229,26 @@ enum QuestObjectiveType QUEST_OBJECTIVE_WINPVPPETBATTLES = 13 }; -struct QuestLocale +struct QuestTemplateLocale { StringVector LogTitle; StringVector LogDescription; StringVector QuestDescription; StringVector AreaDescription; - StringVector OfferRewardText; - StringVector RequestItemsText; - StringVector QuestCompletionLog; - std::vector< StringVector > ObjectiveDescription; - // new on 4.x StringVector PortraitGiverText; StringVector PortraitGiverName; StringVector PortraitTurnInText; StringVector PortraitTurnInName; + StringVector QuestCompletionLog; + + /// @todo: implemente this in new tables + StringVector OfferRewardText; + StringVector RequestItemsText; +}; + +struct QuestObjectivesLocale +{ + StringVector Description; }; struct QuestObjective diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp index d2fdc9b1da8..48f3bf79088 100644 --- a/src/server/game/Reputation/ReputationMgr.cpp +++ b/src/server/game/Reputation/ReputationMgr.cpp @@ -157,15 +157,18 @@ uint32 ReputationMgr::GetDefaultStateFlags(FactionEntry const* factionEntry) con void ReputationMgr::SendForceReactions() { - WorldPacket data; - data.Initialize(SMSG_SET_FORCED_REACTIONS, 4+_forcedReactions.size()*(4+4)); - data << uint32(_forcedReactions.size()); + WorldPackets::Reputation::SetForcedReactions setForcedReactions; + setForcedReactions.Reactions.resize(_forcedReactions.size()); + + std::size_t i = 0; for (ForcedReactions::const_iterator itr = _forcedReactions.begin(); itr != _forcedReactions.end(); ++itr) { - data << uint32(itr->first); // faction_id (Faction.dbc) - data << uint32(itr->second); // reputation rank + WorldPackets::Reputation::ForcedReaction& forcedReaction = setForcedReactions.Reactions[i++]; + forcedReaction.Faction = int32(itr->first); + forcedReaction.Reaction = int32(itr->second); } - _player->SendDirectMessage(&data); + + _player->SendDirectMessage(setForcedReactions.Write()); } void ReputationMgr::SendState(FactionState const* faction) diff --git a/src/server/game/Server/Packets/AuctionHousePackets.cpp b/src/server/game/Server/Packets/AuctionHousePackets.cpp index 6135e294e4c..65652688823 100644 --- a/src/server/game/Server/Packets/AuctionHousePackets.cpp +++ b/src/server/game/Server/Packets/AuctionHousePackets.cpp @@ -19,6 +19,80 @@ #include "AuctionHouseMgr.h" #include "ObjectGuid.h" +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::AuctionHouse::AuctionItem const& auctionItem) +{ + data << auctionItem.Item; // ItemInstance + data << int32(auctionItem.Count); + data << int32(auctionItem.Charges); + data << int32(auctionItem.Enchantments.size()); + data << int32(auctionItem.Flags); + data << int32(auctionItem.AuctionItemID); + data << auctionItem.Owner; + data << uint64(auctionItem.MinBid); + data << uint64(auctionItem.MinIncrement); + data << uint64(auctionItem.BuyoutPrice); + data << int32(auctionItem.DurationLeft); + data << uint8(auctionItem.DeleteReason); + + for (auto const& enchant : auctionItem.Enchantments) + { + data << int32(enchant.ID); + data << uint32(enchant.Expiration); + data << int32(enchant.Charges); + data << uint8(enchant.Slot); + } + + data.FlushBits(); + + bool censorServerSideInfo = !data.WriteBit(auctionItem.CensorServerSideInfo); + bool censorBidInfo = !data.WriteBit(auctionItem.CensorBidInfo); + + if (censorServerSideInfo) + { + data << auctionItem.ItemGuid; + data << auctionItem.OwnerAccountID; + data << int32(auctionItem.EndTime); + } + + if (censorBidInfo) + { + data << auctionItem.Bidder; + data << uint64(auctionItem.BidAmount); + } + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::AuctionHouse::AuctionOwnerNotification const& ownerNotification) +{ + data << int32(ownerNotification.AuctionItemID); + data << uint64(ownerNotification.BidAmount); + data << ownerNotification.Item; + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::AuctionHouse::AuctionBidderNotification const& bidderNotification) +{ + data << int32(bidderNotification.AuctionItemID); + data << bidderNotification.Bidder; + data << bidderNotification.Item; + return data; +} + +void WorldPackets::AuctionHouse::AuctionOwnerNotification::Initialize(::AuctionEntry const* auction, ::Item const* item) +{ + AuctionItemID = auction->Id; + Item.Initialize(item); + BidAmount = auction->bid; +} + +void WorldPackets::AuctionHouse::AuctionBidderNotification::Initialize(::AuctionEntry const* auction, ::Item const* item) +{ + AuctionItemID = auction->Id; + Item.Initialize(item); + Bidder = ObjectGuid::Create<HighGuid::Player>(auction->bidder); +} + void WorldPackets::AuctionHouse::AuctionHelloRequest::Read() { _worldPacket >> Guid; @@ -36,38 +110,218 @@ WorldPacket const* WorldPackets::AuctionHouse::AuctionHelloResponse::Write() WorldPackets::AuctionHouse::AuctionCommandResult::AuctionCommandResult() : ServerPacket(SMSG_AUCTION_COMMAND_RESULT, 4 + 4 + 4 + 8 + 4 + 8 + 8 + 8) { } -void WorldPackets::AuctionHouse::AuctionCommandResult::InitializeAuction(AuctionEntry* auction) +void WorldPackets::AuctionHouse::AuctionCommandResult::InitializeAuction(::AuctionEntry* auction) { if (auction) { - AuctionId = auction->Id; - Bid = auction->bid; - AuctionOutBid = auction->GetAuctionOutBid(); - Bidder = ObjectGuid::Create<HighGuid::Player>(auction->bidder); + AuctionItemID = auction->Id; + Money = auction->bid == auction->buyout ? 0 : auction->bid; + MinIncrement = auction->bid == auction->buyout ? 0 : auction->GetAuctionOutBid(); + Guid = ObjectGuid::Create<HighGuid::Player>(auction->bidder); } } WorldPacket const* WorldPackets::AuctionHouse::AuctionCommandResult::Write() { - _worldPacket << uint32(AuctionId); - _worldPacket << uint32(Action); - _worldPacket << uint32(ErrorCode); + _worldPacket << uint32(AuctionItemID); + _worldPacket << int32(Command); + _worldPacket << int32(ErrorCode); + _worldPacket << int32(BagResult); + _worldPacket << Guid; + _worldPacket << uint64(MinIncrement); + _worldPacket << uint64(Money); + + return &_worldPacket; +} + +void WorldPackets::AuctionHouse::AuctionSellItem::Read() +{ + _worldPacket >> Auctioneer; + _worldPacket >> MinBid; + _worldPacket >> BuyoutPrice; + _worldPacket >> RunTime; + + uint8 ItemsCount = _worldPacket.ReadBits(5); + _worldPacket.FlushBits(); + + for (uint8 i = 0; i < ItemsCount; i++) + { + WorldPackets::AuctionHouse::AuctionSellItem::AuctionItemForSale item; + _worldPacket >> item.Guid; + _worldPacket >> item.UseCount; + Items.emplace_back(item); + } +} + +void WorldPackets::AuctionHouse::AuctionPlaceBid::Read() +{ + _worldPacket >> Auctioneer; + _worldPacket >> AuctionItemID; + _worldPacket >> BidAmount; +} + +void WorldPackets::AuctionHouse::AuctionListBidderItems::Read() +{ + _worldPacket >> Auctioneer; + _worldPacket >> Offset; + uint8 auctionItemIDsCount = _worldPacket.ReadBits(7); + _worldPacket.FlushBits(); + + for (uint8 i = 0; i < auctionItemIDsCount; i++) + { + uint32 AuctionItemID = 0; + _worldPacket >> AuctionItemID; + AuctionItemIDs.emplace_back(AuctionItemID); + } +} + +void WorldPackets::AuctionHouse::AuctionRemoveItem::Read() +{ + _worldPacket >> Auctioneer; + _worldPacket >> AuctionItemID; +} + +void WorldPackets::AuctionHouse::AuctionReplicateItems::Read() +{ + _worldPacket >> Auctioneer; + _worldPacket >> Count; + _worldPacket >> ChangeNumberGlobal; + _worldPacket >> ChangeNumberCursor; + _worldPacket >> ChangeNumberTombstone; +} + +WorldPacket const* WorldPackets::AuctionHouse::AuctionListItemsResult::Write() +{ + _worldPacket << int32(Items.size()); + _worldPacket << int32(TotalCount); + _worldPacket << int32(DesiredDelay); - switch (ErrorCode) + for (auto const& item : Items) + _worldPacket << item; + + _worldPacket.FlushBits(); + _worldPacket.WriteBit(OnlyUsable); + _worldPacket.FlushBits(); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::AuctionHouse::AuctionListOwnerItemsResult::Write() +{ + _worldPacket << int32(Items.size()); + _worldPacket << uint32(TotalCount); + _worldPacket << uint32(DesiredDelay); + + for (auto const& item : Items) + _worldPacket << item; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::AuctionHouse::AuctionListBidderItemsResult::Write() +{ + _worldPacket << int32(Items.size()); + _worldPacket << uint32(TotalCount); + _worldPacket << uint32(DesiredDelay); + + for (auto const& item : Items) + _worldPacket << item; + + return &_worldPacket; +} + +void WorldPackets::AuctionHouse::AuctionListItems::Read() +{ + _worldPacket >> Offset; + _worldPacket >> Auctioneer; + _worldPacket >> MinLevel; + _worldPacket >> MaxLevel; + _worldPacket >> ItemClass; + _worldPacket >> InvType; + _worldPacket >> ItemSubclass; + _worldPacket >> Quality; + _worldPacket >> SortCount; + + _worldPacket.FlushBits(); + uint32 nameLength = _worldPacket.ReadBits(8); + Name = _worldPacket.ReadString(nameLength); + OnlyUsable = _worldPacket.ReadBit(); + ExactMatch = _worldPacket.ReadBit(); + + _worldPacket.read_skip<uint32>(); // DataSize = (SortCount * 2) + for (int32 i = 0; i < SortCount; i++) { - case ERR_AUCTION_OK: - if (Action == AUCTION_PLACE_BID) - _worldPacket << uint64(Bid ? AuctionOutBid : 0); - break; - case ERR_AUCTION_INVENTORY: - _worldPacket << uint32(BidError); - break; - case ERR_AUCTION_HIGHER_BID: - _worldPacket << Bidder; - _worldPacket << uint64(Bid); - _worldPacket << uint64(Bid ? AuctionOutBid : 0); - break; + WorldPackets::AuctionHouse::AuctionListItems::Sort sort; + _worldPacket >> sort.UnkByte1; + _worldPacket >> sort.UnkByte2; + DataSort.emplace_back(sort); } +} + +void WorldPackets::AuctionHouse::AuctionListOwnerItems::Read() +{ + _worldPacket >> Auctioneer; + _worldPacket >> Offset; +} + +WorldPacket const* WorldPackets::AuctionHouse::AuctionListPendingSalesResult::Write() +{ + _worldPacket << int32(Mails.size()); + _worldPacket << int32(TotalNumRecords); + + for (auto const& mail : Mails) + _worldPacket << mail; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::AuctionHouse::AuctionClosedNotification::Write() +{ + _worldPacket << Info; + _worldPacket << float(ProceedsMailDelay); + _worldPacket.WriteBit(Sold); + _worldPacket.FlushBits(); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::AuctionHouse::AuctionOwnerBidNotification::Write() +{ + _worldPacket << Info; + _worldPacket << uint64(MinIncrement); + _worldPacket << Bidder; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::AuctionHouse::AuctionWonNotification::Write() +{ + _worldPacket << Info; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::AuctionHouse::AuctionOutBidNotification::Write() +{ + _worldPacket << Info; + _worldPacket << uint64(BidAmount); + _worldPacket << uint64(MinIncrement); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::AuctionHouse::AuctionReplicateResponse::Write() +{ + //Todo order + _worldPacket << int32(ChangeNumberCursor); + _worldPacket << int32(ChangeNumberGlobal); + _worldPacket << int32(DesiredDelay); + _worldPacket << int32(ChangeNumberTombstone); + _worldPacket << int32(Result); + _worldPacket << int32(Items.size()); + + for (auto const& item : Items) + _worldPacket << item; return &_worldPacket; } diff --git a/src/server/game/Server/Packets/AuctionHousePackets.h b/src/server/game/Server/Packets/AuctionHousePackets.h index 0af8f488dfd..7b274d3f638 100644 --- a/src/server/game/Server/Packets/AuctionHousePackets.h +++ b/src/server/game/Server/Packets/AuctionHousePackets.h @@ -16,9 +16,12 @@ */ #ifndef AuctionHousePackets_h__ +#define AuctionHousePackets_h__ #include "Packet.h" #include "ObjectGuid.h" +#include "ItemPackets.h" +#include "MailPackets.h" struct AuctionEntry; @@ -26,6 +29,56 @@ namespace WorldPackets { namespace AuctionHouse { + struct AuctionItem + { + struct AuctionItemEnchant + { + AuctionItemEnchant(int32 id, uint32 expiration, int32 charges, uint8 slot) : ID(id), Expiration(expiration), Charges(charges), Slot(slot) { } + int32 ID = 0; + uint32 Expiration = 0; + int32 Charges = 0; + uint8 Slot = 0; + }; + + Item::ItemInstance Item; + int32 Count = 0; + int32 Charges = 0; + std::vector<AuctionItemEnchant> Enchantments; + int32 Flags = 0; + int32 AuctionItemID = 0; + ObjectGuid Owner; + uint64 MinBid = 0; + uint64 MinIncrement = 0; + uint64 BuyoutPrice = 0; + int32 DurationLeft = 0; + uint8 DeleteReason = 0; + bool CensorServerSideInfo = false; + bool CensorBidInfo = false; + ObjectGuid ItemGuid; + ObjectGuid OwnerAccountID; + uint32 EndTime = 0; + ObjectGuid Bidder; + uint64 BidAmount = 0; + }; + + struct AuctionOwnerNotification + { + void Initialize(::AuctionEntry const* auction, ::Item const* item); + + int32 AuctionItemID = 0; + uint64 BidAmount = 0; + Item::ItemInstance Item; + }; + + struct AuctionBidderNotification + { + void Initialize(::AuctionEntry const* auction, ::Item const* item); + + int32 AuctionItemID = 0; + ObjectGuid Bidder; + Item::ItemInstance Item; + }; + class AuctionHelloRequest final : public ClientPacket { public: @@ -58,17 +111,242 @@ namespace WorldPackets * * @param auction The relevant auction object */ - void InitializeAuction(AuctionEntry* auction); + void InitializeAuction(::AuctionEntry* auction); WorldPacket const* Write() override; - uint32 AuctionId = 0; ///< the id of the auction that triggered this notification - uint32 Action = 0; ///< the type of action that triggered this notification. Possible values are @ref AuctionAction - uint32 ErrorCode = 0; ///< the error code that was generated when trying to perform the action. Possible values are @ref AuctionError - uint64 Bid = 0; ///< the amount of money that the player bid in copper - uint32 BidError = 0; ///< the bid error. Possible values are @ref AuctionError - ObjectGuid Bidder; ///< the GUID of the bidder for this auction. - uint64 AuctionOutBid = 0; ///< the sum of outbid is (1% of current bid) * 5, if the bid is too small, then this value is 1 copper. + uint32 AuctionItemID = 0; ///< the id of the auction that triggered this notification + uint32 Command = 0; ///< the type of action that triggered this notification. Possible values are @ref AuctionAction + int32 ErrorCode = 0; ///< the error code that was generated when trying to perform the action. Possible values are @ref AuctionError + uint64 Money = 0; ///< the amount of money that the player bid in copper + int32 BagResult = 0; ///< the bid error. Possible values are @ref AuctionError + ObjectGuid Guid; ///< the GUID of the bidder for this auction. + uint64 MinIncrement = 0; ///< the sum of outbid is (1% of current bid) * 5, if the bid is too small, then this value is 1 copper. + }; + + class AuctionSellItem final : public ClientPacket + { + public: + struct AuctionItemForSale + { + ObjectGuid Guid; + uint32 UseCount = 0; + }; + + AuctionSellItem(WorldPacket&& packet) : ClientPacket(CMSG_AUCTION_SELL_ITEM, std::move(packet)) { } + + void Read() override; + + uint64 BuyoutPrice = 0; + ObjectGuid Auctioneer; + uint64 MinBid = 0; + uint32 RunTime = 0; + std::vector<AuctionItemForSale> Items; + }; + + class AuctionPlaceBid final : public ClientPacket + { + public: + AuctionPlaceBid(WorldPacket&& packet) : ClientPacket(CMSG_AUCTION_PLACE_BID, std::move(packet)) { } + + void Read() override; + + ObjectGuid Auctioneer; + uint64 BidAmount = 0; + int32 AuctionItemID = 0; + }; + + class AuctionListBidderItems final : public ClientPacket + { + public: + AuctionListBidderItems(WorldPacket&& packet) : ClientPacket(CMSG_AUCTION_LIST_BIDDER_ITEMS, std::move(packet)) { } + + void Read() override; + + uint32 Offset = 0; + std::vector<uint32> AuctionItemIDs; + ObjectGuid Auctioneer; + }; + + class AuctionRemoveItem final : public ClientPacket + { + public: + AuctionRemoveItem(WorldPacket&& packet) : ClientPacket(CMSG_AUCTION_REMOVE_ITEM, std::move(packet)) { } + + void Read() override; + + ObjectGuid Auctioneer; + int32 AuctionItemID = 0; + }; + + class AuctionReplicateItems final : public ClientPacket + { + public: + AuctionReplicateItems(WorldPacket&& packet) : ClientPacket(CMSG_AUCTION_REPLICATE_ITEMS, std::move(packet)) { } + + void Read() override; + + ObjectGuid Auctioneer; + int32 Count = 0; + int32 ChangeNumberGlobal = 0; + int32 ChangeNumberCursor = 0; + int32 ChangeNumberTombstone = 0; + }; + + class AuctionListPendingSales final : public ClientPacket + { + public: + AuctionListPendingSales(WorldPacket&& packet) : ClientPacket(CMSG_AUCTION_LIST_PENDING_SALES, std::move(packet)) { } + + void Read() override { } + }; + + class AuctionListItemsResult final : public ServerPacket + { + public: + AuctionListItemsResult() : ServerPacket(SMSG_AUCTION_LIST_ITEMS_RESULT, 150) { } + + WorldPacket const* Write() override; + + uint32 DesiredDelay = 0; + std::vector<AuctionItem> Items; + bool OnlyUsable = true; + uint32 TotalCount = 0; + }; + + class AuctionListOwnerItemsResult final : public ServerPacket + { + public: + AuctionListOwnerItemsResult() : ServerPacket(SMSG_AUCTION_LIST_OWNER_ITEMS_RESULT, 149) { } + + WorldPacket const* Write() override; + + uint32 DesiredDelay = 0; + uint32 TotalCount = 0; + std::vector<AuctionItem> Items; + }; + + class AuctionListBidderItemsResult final : public ServerPacket + { + public: + AuctionListBidderItemsResult() : ServerPacket(SMSG_AUCTION_LIST_BIDDER_ITEMS_RESULT, 149) { } + + WorldPacket const* Write() override; + + uint32 DesiredDelay = 0; + uint32 TotalCount = 0; + std::vector<AuctionItem> Items; + }; + + class AuctionListOwnerItems final : public ClientPacket + { + public: + AuctionListOwnerItems(WorldPacket&& packet) : ClientPacket(CMSG_AUCTION_LIST_OWNER_ITEMS, std::move(packet)) { } + + void Read() override; + + ObjectGuid Auctioneer; + uint32 Offset = 0; + }; + + class AuctionListItems final : public ClientPacket + { + public: + struct Sort + { + uint8 UnkByte1 = 0; + uint8 UnkByte2 = 0; + }; + + AuctionListItems(WorldPacket&& packet) : ClientPacket(CMSG_AUCTION_LIST_ITEMS, std::move(packet)) { } + + void Read() override; + + ObjectGuid Auctioneer; + uint8 SortCount = 0; + uint8 MaxLevel = 100; + uint32 Offset = 0; + int32 ItemClass = 0; + uint8 MinLevel = 1; + int32 InvType = 0; + int32 Quality = 0; + int32 ItemSubclass = 0; + bool ExactMatch = true; + std::string Name; + bool OnlyUsable = false; + std::vector<Sort> DataSort; + }; + + class AuctionListPendingSalesResult final : public ServerPacket + { + public: + AuctionListPendingSalesResult() : ServerPacket(SMSG_AUCTION_LIST_PENDING_SALES_RESULT, 140) { } + + WorldPacket const* Write() override; + + std::vector<Mail::MailListEntry> Mails; + int32 TotalNumRecords = 0; + }; + + class AuctionClosedNotification final : public ServerPacket + { + public: + AuctionClosedNotification() : ServerPacket(SMSG_AUCTION_CLOSED_NOTIFICATION, 45) { } + + WorldPacket const* Write() override; + + AuctionOwnerNotification Info; + float ProceedsMailDelay = 0.0f; + bool Sold = true; + }; + + class AuctionOwnerBidNotification final : public ServerPacket + { + public: + AuctionOwnerBidNotification() : ServerPacket(SMSG_AUCTION_OWNER_BID_NOTIFICATION, 62) { } + + WorldPacket const* Write() override; + + AuctionOwnerNotification Info; + ObjectGuid Bidder; + uint64 MinIncrement = 0; + }; + + class AuctionWonNotification final : public ServerPacket + { + public: + AuctionWonNotification() : ServerPacket(SMSG_AUCTION_WON_NOTIFICATION, 46) { } + + WorldPacket const* Write() override; + + AuctionBidderNotification Info; + }; + + class AuctionOutBidNotification final : public ServerPacket + { + public: + AuctionOutBidNotification() : ServerPacket(SMSG_AUCTION_OUTBID_NOTIFICATION, 62) { } + + WorldPacket const* Write() override; + + AuctionBidderNotification Info; + uint64 BidAmount = 0; + uint64 MinIncrement = 0; + }; + + class AuctionReplicateResponse final : public ServerPacket + { + public: + AuctionReplicateResponse() : ServerPacket(SMSG_AUCTION_REPLICATE_RESPONSE, 165) { } + + WorldPacket const* Write() override; + + uint32 ChangeNumberCursor = 0; + uint32 ChangeNumberGlobal = 0; + uint32 DesiredDelay = 0; + uint32 ChangeNumberTombstone = 0; + uint32 Result = 0; + std::vector<AuctionItem> Items; }; } } diff --git a/src/server/game/Server/Packets/BankPackets.cpp b/src/server/game/Server/Packets/BankPackets.cpp index 0f6af30bed0..b6108d083c7 100644 --- a/src/server/game/Server/Packets/BankPackets.cpp +++ b/src/server/game/Server/Packets/BankPackets.cpp @@ -27,8 +27,8 @@ void WorldPackets::Bank::AutoBankItem::Read() void WorldPackets::Bank::AutoStoreBankItem::Read() { - _worldPacket >> Inv - >> Bag + _worldPacket >> Inv + >> Bag >> Slot; } diff --git a/src/server/game/Server/Packets/BankPackets.h b/src/server/game/Server/Packets/BankPackets.h index dc7883c3643..91599f501b3 100644 --- a/src/server/game/Server/Packets/BankPackets.h +++ b/src/server/game/Server/Packets/BankPackets.h @@ -50,7 +50,7 @@ namespace WorldPackets uint8 Bag = 0; uint8 Slot = 0; }; - + class BuyBankSlot final : public ClientPacket { public: diff --git a/src/server/game/Server/Packets/BattlegroundPackets.cpp b/src/server/game/Server/Packets/BattlegroundPackets.cpp index 47b789d85f0..e11fd9c1ac8 100644 --- a/src/server/game/Server/Packets/BattlegroundPackets.cpp +++ b/src/server/game/Server/Packets/BattlegroundPackets.cpp @@ -24,3 +24,89 @@ WorldPacket const* WorldPackets::Battleground::PVPSeason::Write() return &_worldPacket; } + +void WorldPackets::Battleground::AreaSpiritHealerQuery::Read() +{ + _worldPacket >> HealerGuid; +} + +void WorldPackets::Battleground::AreaSpiritHealerQueue::Read() +{ + _worldPacket >> HealerGuid; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battleground::PVPLogData::RatingData const& ratingData) +{ + data.append(ratingData.Prematch, 2); + data.append(ratingData.Postmatch, 2); + data.append(ratingData.PrematchMMR, 2); + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battleground::PVPLogData::HonorData const& honorData) +{ + data << uint32(honorData.HonorKills); + data << uint32(honorData.Deaths); + data << uint32(honorData.ContributionPoints); + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Battleground::PVPLogData::PlayerData const& playerData) +{ + data << playerData.PlayerGUID; + data << uint32(playerData.Kills); + data << uint32(playerData.DamageDone); + data << uint32(playerData.HealingDone); + data << uint32(playerData.Stats.size()); + data << int32(playerData.PrimaryTalentTree); + data << uint32(playerData.PrimaryTalentTreeNameIndex); + if (!playerData.Stats.empty()) + data.append(playerData.Stats.data(), playerData.Stats.size()); + + data.WriteBit(playerData.Faction); + data.WriteBit(playerData.IsInWorld); + data.WriteBit(playerData.Honor.HasValue); + data.WriteBit(playerData.PreMatchRating.HasValue); + data.WriteBit(playerData.RatingChange.HasValue); + data.WriteBit(playerData.PreMatchMMR.HasValue); + data.WriteBit(playerData.MmrChange.HasValue); + data.FlushBits(); + + if (playerData.Honor.HasValue) + data << playerData.Honor.Value; + + if (playerData.PreMatchRating.HasValue) + data << uint32(playerData.PreMatchRating.Value); + + if (playerData.RatingChange.HasValue) + data << uint32(playerData.RatingChange.Value); + + if (playerData.PreMatchMMR.HasValue) + data << uint32(playerData.PreMatchMMR.Value); + + if (playerData.MmrChange.HasValue) + data << uint32(playerData.MmrChange.Value); + + return data; +} + +WorldPacket const* WorldPackets::Battleground::PVPLogData::Write() +{ + _worldPacket.reserve(Players.size() * sizeof(PlayerData) + sizeof(PVPLogData)); + + _worldPacket.WriteBit(Ratings.HasValue); + _worldPacket.WriteBit(Winner.HasValue); + _worldPacket << uint32(Players.size()); + _worldPacket.append(PlayerCount, 2); + + if (Ratings.HasValue) + _worldPacket << Ratings.Value; + + if (Winner.HasValue) + _worldPacket << uint8(Winner.Value); + + for (PlayerData const& player : Players) + _worldPacket << player; + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/BattlegroundPackets.h b/src/server/game/Server/Packets/BattlegroundPackets.h index b3910fd7676..8620112f548 100644 --- a/src/server/game/Server/Packets/BattlegroundPackets.h +++ b/src/server/game/Server/Packets/BattlegroundPackets.h @@ -18,6 +18,7 @@ #ifndef BattlegroundPackets_h__ #define BattlegroundPackets_h__ +#include "ObjectGuid.h" #include "Packet.h" namespace WorldPackets @@ -34,6 +35,87 @@ namespace WorldPackets uint32 PreviousSeason = 0; uint32 CurrentSeason = 0; }; + + class AreaSpiritHealerQuery final : public ClientPacket + { + public: + AreaSpiritHealerQuery(WorldPacket&& packet) : ClientPacket(CMSG_AREA_SPIRIT_HEALER_QUERY, std::move(packet)) { } + + void Read() override; + + ObjectGuid HealerGuid; + }; + + class AreaSpiritHealerQueue final : public ClientPacket + { + public: + AreaSpiritHealerQueue(WorldPacket&& packet) : ClientPacket(CMSG_AREA_SPIRIT_HEALER_QUEUE, std::move(packet)) { } + + void Read() override; + + ObjectGuid HealerGuid; + }; + + class HearthAndResurrect final : public ClientPacket + { + public: + HearthAndResurrect(WorldPacket&& packet) : ClientPacket(CMSG_HEARTH_AND_RESURRECT, std::move(packet)) { } + + void Read() override { } + }; + + class PVPLogDataRequest final : public ClientPacket + { + public: + PVPLogDataRequest(WorldPacket&& packet) : ClientPacket(CMSG_PVP_LOG_DATA, std::move(packet)) { } + + void Read() override { } + }; + + class PVPLogData final : public ServerPacket + { + public: + PVPLogData() : ServerPacket(SMSG_PVP_LOG_DATA, 0) { } + + WorldPacket const* Write() override; + + struct RatingData + { + int32 Prematch[2] = { }; + int32 Postmatch[2] = { }; + int32 PrematchMMR[2] = { }; + }; + + struct HonorData + { + uint32 HonorKills = 0; + uint32 Deaths = 0; + uint32 ContributionPoints = 0; + }; + + struct PlayerData + { + ObjectGuid PlayerGUID; + uint32 Kills = 0; + uint8 Faction = 0; + bool IsInWorld = false; + Optional<HonorData> Honor; + uint32 DamageDone = 0; + uint32 HealingDone = 0; + Optional<uint32> PreMatchRating; + Optional<int32> RatingChange; + Optional<uint32> PreMatchMMR; + Optional<int32> MmrChange; + std::vector<int32> Stats; + int32 PrimaryTalentTree = 0; + uint32 PrimaryTalentTreeNameIndex = 0; // controls which name field from ChrSpecialization.dbc will be sent to lua + }; + + Optional<uint8> Winner; + std::vector<PlayerData> Players; + Optional<RatingData> Ratings; + int8 PlayerCount[2] = { }; + }; } } diff --git a/src/server/game/Server/Packets/ChatPackets.cpp b/src/server/game/Server/Packets/ChatPackets.cpp index 1b93b401a29..8179ee427c8 100644 --- a/src/server/game/Server/Packets/ChatPackets.cpp +++ b/src/server/game/Server/Packets/ChatPackets.cpp @@ -64,6 +64,16 @@ void WorldPackets::Chat::ChatAddonMessageWhisper::Read() Text = _worldPacket.ReadString(textLen); } +void WorldPackets::Chat::ChatAddonMessageChannel::Read() +{ + uint32 targetLen = _worldPacket.ReadBits(9); + uint32 prefixLen = _worldPacket.ReadBits(5); + uint32 textLen = _worldPacket.ReadBits(8); + Target = _worldPacket.ReadString(targetLen); + Prefix = _worldPacket.ReadString(prefixLen); + Text = _worldPacket.ReadString(textLen); +} + void WorldPackets::Chat::ChatMessageDND::Read() { uint32 len = _worldPacket.ReadBits(8); diff --git a/src/server/game/Server/Packets/ChatPackets.h b/src/server/game/Server/Packets/ChatPackets.h index df87629173c..8cadb88b584 100644 --- a/src/server/game/Server/Packets/ChatPackets.h +++ b/src/server/game/Server/Packets/ChatPackets.h @@ -35,6 +35,7 @@ namespace WorldPackets // CMSG_CHAT_MESSAGE_PARTY // CMSG_CHAT_MESSAGE_RAID // CMSG_CHAT_MESSAGE_RAID_WARNING + // CMSG_CHAT_MESSAGE_INSTANCE_CHAT class ChatMessage final : public ClientPacket { public: @@ -76,6 +77,7 @@ namespace WorldPackets // CMSG_CHAT_ADDON_MESSAGE_OFFICER // CMSG_CHAT_ADDON_MESSAGE_PARTY // CMSG_CHAT_ADDON_MESSAGE_RAID + // CMSG_CHAT_ADDON_MESSAGE_INSTANCE_CHAT class ChatAddonMessage final : public ClientPacket { public: @@ -91,7 +93,7 @@ namespace WorldPackets class ChatAddonMessageWhisper final : public ClientPacket { public: - ChatAddonMessageWhisper(WorldPacket&& packet) : ClientPacket(std::move(packet)) { } + ChatAddonMessageWhisper(WorldPacket&& packet) : ClientPacket(CMSG_CHAT_ADDON_MESSAGE_WHISPER, std::move(packet)) { } void Read() override; @@ -100,6 +102,19 @@ namespace WorldPackets std::string Text; }; + // CMSG_CHAT_ADDON_MESSAGE_CHANNEL + class ChatAddonMessageChannel final : public ClientPacket + { + public: + ChatAddonMessageChannel(WorldPacket&& packet) : ClientPacket(CMSG_CHAT_ADDON_MESSAGE_CHANNEL, std::move(packet)) { } + + void Read() override; + + std::string Text; + std::string Target; + std::string Prefix; + }; + class ChatMessageDND final : public ClientPacket { public: diff --git a/src/server/game/Server/Packets/EquipmentSetPackets.cpp b/src/server/game/Server/Packets/EquipmentSetPackets.cpp index f69e378652e..0dc948f5170 100644 --- a/src/server/game/Server/Packets/EquipmentSetPackets.cpp +++ b/src/server/game/Server/Packets/EquipmentSetPackets.cpp @@ -63,3 +63,27 @@ void WorldPackets::EquipmentSet::SaveEquipmentSet::Read() Set.SetName = _worldPacket.ReadString(setNameLength); Set.SetIcon = _worldPacket.ReadString(setIconLength); } + +void WorldPackets::EquipmentSet::DeleteEquipmentSet::Read() +{ + _worldPacket >> ID; +} + +void WorldPackets::EquipmentSet::UseEquipmentSet::Read() +{ + _worldPacket >> Inv; + + for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) + { + _worldPacket >> Items[i].Item; + _worldPacket >> Items[i].ContainerSlot; + _worldPacket >> Items[i].Slot; + } +} + +WorldPacket const* WorldPackets::EquipmentSet::UseEquipmentSetResult::Write() +{ + _worldPacket << uint8(Reason); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/EquipmentSetPackets.h b/src/server/game/Server/Packets/EquipmentSetPackets.h index 4b1ead24839..a26eee383ae 100644 --- a/src/server/game/Server/Packets/EquipmentSetPackets.h +++ b/src/server/game/Server/Packets/EquipmentSetPackets.h @@ -19,6 +19,7 @@ #include "Packet.h" #include "Player.h" +#include "ItemPackets.h" namespace WorldPackets { @@ -54,5 +55,43 @@ namespace WorldPackets EquipmentSetInfo::EquipmentSetData Set; }; + + class DeleteEquipmentSet final : public ClientPacket + { + public: + DeleteEquipmentSet(WorldPacket&& packet) : ClientPacket(CMSG_DELETE_EQUIPMENT_SET, std::move(packet)) { } + + void Read() override; + + uint64 ID; + }; + + class UseEquipmentSet final : public ClientPacket + { + public: + UseEquipmentSet(WorldPacket&& packet) : ClientPacket(CMSG_USE_EQUIPMENT_SET, std::move(packet)) { } + + void Read() override; + + struct EquipmentSetItem + { + ObjectGuid Item; + uint8 ContainerSlot = 0; + uint8 Slot = 0; + }; + + WorldPackets::Item::InvUpdate Inv; + EquipmentSetItem Items[EQUIPMENT_SLOT_END]; + }; + + class UseEquipmentSetResult final : public ServerPacket + { + public: + UseEquipmentSetResult() : ServerPacket(SMSG_USE_EQUIPMENT_SET_RESULT, 1) { } + + WorldPacket const* Write() override; + + uint8 Reason = 0; + }; } } diff --git a/src/server/game/Server/Packets/GameObjectPackets.cpp b/src/server/game/Server/Packets/GameObjectPackets.cpp index 231b977a63c..c52a1974635 100644 --- a/src/server/game/Server/Packets/GameObjectPackets.cpp +++ b/src/server/game/Server/Packets/GameObjectPackets.cpp @@ -26,3 +26,15 @@ void WorldPackets::GameObject::GameObjReportUse::Read() { _worldPacket >> Guid; } + +WorldPacket const* WorldPackets::GameObject::GameObjectDespawn::Write() +{ + _worldPacket << ObjectGUID; + return &_worldPacket; +} + +WorldPacket const* WorldPackets::GameObject::PageText::Write() +{ + _worldPacket << GameObjectGUID; + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/GameObjectPackets.h b/src/server/game/Server/Packets/GameObjectPackets.h index a18552052a2..6478293a9b7 100644 --- a/src/server/game/Server/Packets/GameObjectPackets.h +++ b/src/server/game/Server/Packets/GameObjectPackets.h @@ -46,6 +46,26 @@ namespace WorldPackets ObjectGuid Guid; }; + + class GameObjectDespawn final : public ServerPacket + { + public: + GameObjectDespawn() : ServerPacket(SMSG_GAME_OBJECT_DESPAWN, 16) { } + + WorldPacket const* Write() override; + + ObjectGuid ObjectGUID; + }; + + class PageText final : public ServerPacket + { + public: + PageText() : ServerPacket(SMSG_PAGE_TEXT, 16) { } + + WorldPacket const* Write() override; + + ObjectGuid GameObjectGUID; + }; } } #endif // GOPackets_h__ diff --git a/src/server/game/Server/Packets/InspectPackets.cpp b/src/server/game/Server/Packets/InspectPackets.cpp index bdfdc4da06b..9d98d30bd74 100644 --- a/src/server/game/Server/Packets/InspectPackets.cpp +++ b/src/server/game/Server/Packets/InspectPackets.cpp @@ -60,7 +60,7 @@ WorldPackets::Inspect::InspectItemData::InspectItemData(::Item const* item, uint { CreatorGUID = item->GetGuidValue(ITEM_FIELD_CREATOR); - Item.Initalize(item); + Item.Initialize(item); Index = index; Usable = true; /// @todo diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp index 57620737190..958a6c9c33a 100644 --- a/src/server/game/Server/Packets/ItemPackets.cpp +++ b/src/server/game/Server/Packets/ItemPackets.cpp @@ -16,6 +16,7 @@ */ #include "ItemPackets.h" +#include "Player.h" void WorldPackets::Item::BuyBackItem::Read() { @@ -165,7 +166,7 @@ ByteBuffer& WorldPackets::Item::operator>>(ByteBuffer& data, InvUpdate& invUpdat return data; } -void WorldPackets::Item::ItemInstance::Initalize(::Item const* item) +void WorldPackets::Item::ItemInstance::Initialize(::Item const* item) { ItemID = item->GetEntry(); RandomPropertiesSeed = item->GetItemSuffixFactor(); @@ -188,7 +189,7 @@ void WorldPackets::Item::ItemInstance::Initalize(::Item const* item) } } -void WorldPackets::Item::ItemInstance::Initalize(::LootItem const& lootItem) +void WorldPackets::Item::ItemInstance::Initialize(::LootItem const& lootItem) { ItemID = lootItem.itemid; RandomPropertiesSeed = lootItem.randomSuffix; @@ -203,6 +204,13 @@ void WorldPackets::Item::ItemInstance::Initalize(::LootItem const& lootItem) /// no Modifications } +void WorldPackets::Item::ItemInstance::Initialize(::VoidStorageItem const* voidItem) +{ + ItemID = voidItem->ItemEntry; + RandomPropertiesID = voidItem->ItemRandomPropertyId; + RandomPropertiesSeed = voidItem->ItemSuffixFactor; +} + WorldPacket const* WorldPackets::Item::InventoryChangeFailure::Write() { _worldPacket << int8(BagResult); @@ -266,6 +274,13 @@ void WorldPackets::Item::AutoEquipItem::Read() >> Slot; } +void WorldPackets::Item::AutoEquipItemSlot::Read() +{ + _worldPacket >> Inv + >> Item + >> ItemDstSlot; +} + void WorldPackets::Item::AutoStoreBagItem::Read() { _worldPacket >> Inv @@ -289,3 +304,56 @@ WorldPacket const* WorldPackets::Item::SellResponse::Write() return &_worldPacket; } + +WorldPacket const* WorldPackets::Item::ItemPushResult::Write() +{ + _worldPacket << PlayerGUID; + + _worldPacket << Slot; + _worldPacket << SlotInBag; + + _worldPacket << Item; + + _worldPacket << WodUnk; + _worldPacket << Quantity; + _worldPacket << QuantityInInventory; + _worldPacket << BattlePetBreedID; + _worldPacket << BattlePetBreedQuality; + _worldPacket << BattlePetSpeciesID; + _worldPacket << BattlePetLevel; + + _worldPacket << ItemGUID; + + _worldPacket.WriteBit(Pushed); + _worldPacket.WriteBit(Created); + _worldPacket.WriteBit(DisplayText); + _worldPacket.WriteBit(IsBonusRoll); + + _worldPacket.FlushBits(); + + return &_worldPacket; +} + +void WorldPackets::Item::ReadItem::Read() +{ + _worldPacket >> PackSlot; + _worldPacket >> Slot; +} + +WorldPacket const* WorldPackets::Item::ReadItemResultFailed::Write() +{ + _worldPacket << Item; + _worldPacket << Delay; + _worldPacket.WriteBits(Subcode, 3); + + _worldPacket.FlushBits(); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Item::ReadItemResultOK::Write() +{ + _worldPacket << Item; + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/ItemPackets.h b/src/server/game/Server/Packets/ItemPackets.h index 45d59144d2f..f9c700b0cb4 100644 --- a/src/server/game/Server/Packets/ItemPackets.h +++ b/src/server/game/Server/Packets/ItemPackets.h @@ -22,6 +22,8 @@ #include "Item.h" #include "PacketUtilities.h" +struct VoidStorageItem; + namespace WorldPackets { namespace Item @@ -34,8 +36,9 @@ namespace WorldPackets struct ItemInstance { - void Initalize(::Item const* item); - void Initalize(::LootItem const& lootItem); + void Initialize(::Item const* item); + void Initialize(::LootItem const& lootItem); + void Initialize(::VoidStorageItem const* voidItem); uint32 ItemID = 0; uint32 RandomPropertiesSeed = 0; @@ -233,6 +236,18 @@ namespace WorldPackets uint8 PackSlot = 0; }; + class AutoEquipItemSlot final : public ClientPacket + { + public: + AutoEquipItemSlot(WorldPacket&& packet) : ClientPacket(CMSG_AUTO_EQUIP_ITEM_SLOT, std::move(packet)) { } + + void Read() override; + + ObjectGuid Item; + uint8 ItemDstSlot = 0; + InvUpdate Inv; + }; + class AutoStoreBagItem final : public ClientPacket { public: @@ -270,6 +285,64 @@ namespace WorldPackets SellResult Reason = SELL_ERR_UNK; }; + class ItemPushResult final : public ServerPacket + { + public: + ItemPushResult() : ServerPacket(SMSG_ITEM_PUSH_RESULT, 16 + 1 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 16 + 1 + 1 + 1 + 1) { } + + WorldPacket const* Write() override; + + ObjectGuid PlayerGUID; + uint8 Slot = 0; + int32 SlotInBag = 0; + ItemInstance Item; + uint32 WodUnk = 0; + int32 Quantity = 0; + int32 QuantityInInventory = 0; + int32 BattlePetBreedID = 0; + uint32 BattlePetBreedQuality = 0; + int32 BattlePetSpeciesID = 0; + int32 BattlePetLevel = 0; + ObjectGuid ItemGUID; + bool Pushed = false; + bool DisplayText = false; + bool Created = false; + bool IsBonusRoll = false; + }; + + class ReadItem final : public ClientPacket + { + public: + ReadItem(WorldPacket&& packet) : ClientPacket(CMSG_READ_ITEM, std::move(packet)) { } + + void Read() override; + + uint8 PackSlot = 0; + uint8 Slot = 0; + }; + + class ReadItemResultFailed final : public ServerPacket + { + public: + ReadItemResultFailed() : ServerPacket(SMSG_READ_ITEM_RESULT_FAILED, 16 + 1 + 4) { } + + WorldPacket const* Write() override; + + ObjectGuid Item; + uint8 Subcode = 0; + uint32 Delay = 0; + }; + + class ReadItemResultOK final : public ServerPacket + { + public: + ReadItemResultOK() : ServerPacket(SMSG_READ_ITEM_RESULT_OK, 16) { } + + WorldPacket const* Write() override; + + ObjectGuid Item; + }; + ByteBuffer& operator>>(ByteBuffer& data, InvUpdate& invUpdate); } } diff --git a/src/server/game/Server/Packets/MailPackets.cpp b/src/server/game/Server/Packets/MailPackets.cpp index 4e3c59a27e6..b1de05aac25 100644 --- a/src/server/game/Server/Packets/MailPackets.cpp +++ b/src/server/game/Server/Packets/MailPackets.cpp @@ -24,7 +24,7 @@ WorldPackets::Mail::MailAttachedItem::MailAttachedItem(::Item const* item, uint8 { Position = pos; AttachID = item->GetGUID().GetCounter(); - Item.Initalize(item); + Item.Initialize(item); Count = item->GetCount(); Charges = item->GetSpellCharges(); MaxDurability = item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY); diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp index a67a0669b35..068b91436b0 100644 --- a/src/server/game/Server/Packets/MiscPackets.cpp +++ b/src/server/game/Server/Packets/MiscPackets.cpp @@ -282,6 +282,7 @@ void WorldPackets::Misc::StandStateChange::Read() WorldPacket const* WorldPackets::Misc::StandStateUpdate::Write() { + _worldPacket << uint32(UnkWoD1); _worldPacket << uint8(State); return &_worldPacket; @@ -413,3 +414,20 @@ WorldPacket const* WorldPackets::Misc::ZoneUnderAttack::Write() return &_worldPacket; } + +WorldPacket const* WorldPackets::Misc::DurabilityDamageDeath::Write() +{ + _worldPacket << int32(Percent); + + return &_worldPacket; +} + +void WorldPackets::Misc::ObjectUpdateFailed::Read() +{ + _worldPacket >> ObjectGUID; +} + +void WorldPackets::Misc::ObjectUpdateRescued::Read() +{ + _worldPacket >> ObjectGUID; +} diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h index 4d21b8a3285..8745ac588e7 100644 --- a/src/server/game/Server/Packets/MiscPackets.h +++ b/src/server/game/Server/Packets/MiscPackets.h @@ -420,11 +420,12 @@ namespace WorldPackets class StandStateUpdate final : public ServerPacket { public: - StandStateUpdate() : ServerPacket(SMSG_STAND_STATE_UPDATE, 1) { } + StandStateUpdate() : ServerPacket(SMSG_STAND_STATE_UPDATE, 4 + 1) { } StandStateUpdate(UnitStandStateType state) : ServerPacket(SMSG_STAND_STATE_UPDATE, 1), State(state) { } WorldPacket const* Write() override; + uint32 UnkWoD1 = 0; /// @todo 6.1.0 resarch new value UnitStandStateType State = UNIT_STAND_STATE_STAND; }; @@ -563,6 +564,36 @@ namespace WorldPackets int32 AreaID = 0; }; + + class DurabilityDamageDeath final : public ServerPacket + { + public: + DurabilityDamageDeath() : ServerPacket(SMSG_DURABILITY_DAMAGE_DEATH, 4) { } + + WorldPacket const* Write() override; + + int32 Percent = 0; + }; + + class ObjectUpdateFailed final : public ClientPacket + { + public: + ObjectUpdateFailed(WorldPacket&& packet) : ClientPacket(CMSG_OBJECT_UPDATE_FAILED, std::move(packet)) { } + + void Read() override; + + ObjectGuid ObjectGUID; + }; + + class ObjectUpdateRescued final : public ClientPacket + { + public: + ObjectUpdateRescued(WorldPacket&& packet) : ClientPacket(CMSG_OBJECT_UPDATE_RESCUED, std::move(packet)) { } + + void Read() override; + + ObjectGuid ObjectGUID; + }; } } diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp index 2f239dfdd63..a42cd0e099c 100644 --- a/src/server/game/Server/Packets/MovementPackets.cpp +++ b/src/server/game/Server/Packets/MovementPackets.cpp @@ -665,3 +665,9 @@ void WorldPackets::Movement::MoveSetCollisionHeightAck::Read() _worldPacket >> MountDisplayID; Reason = UpdateCollisionHeightReason(_worldPacket.ReadBits(2)); } + +void WorldPackets::Movement::MoveTimeSkipped::Read() +{ + _worldPacket >> MoverGUID; + _worldPacket >> TimeSkipped; +} diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h index 9f8ec7bb52b..6803bdf3b95 100644 --- a/src/server/game/Server/Packets/MovementPackets.h +++ b/src/server/game/Server/Packets/MovementPackets.h @@ -389,6 +389,17 @@ namespace WorldPackets uint32 MountDisplayID = 0; float Height = 1.0f; }; + + class MoveTimeSkipped final : public ClientPacket + { + public: + MoveTimeSkipped(WorldPacket&& packet) : ClientPacket(CMSG_MOVE_TIME_SKIPPED, std::move(packet)) { } + + void Read() override; + + ObjectGuid MoverGUID; + uint32 TimeSkipped; + }; } ByteBuffer& operator<<(ByteBuffer& data, Movement::MonsterSplineFilterKey const& monsterSplineFilterKey); diff --git a/src/server/game/Server/Packets/NPCPackets.cpp b/src/server/game/Server/Packets/NPCPackets.cpp index 33e33bece55..2ca1ad7447d 100644 --- a/src/server/game/Server/Packets/NPCPackets.cpp +++ b/src/server/game/Server/Packets/NPCPackets.cpp @@ -150,3 +150,16 @@ WorldPacket const* WorldPackets::NPC::SuppressNPCGreetings::Write() return &_worldPacket; } + +WorldPacket const* WorldPackets::NPC::GossipPOI::Write() +{ + _worldPacket.WriteBits(Flags, 14); + _worldPacket.WriteBits(Name.length(), 6); + _worldPacket << Pos.x; + _worldPacket << Pos.y; + _worldPacket << Icon; + _worldPacket << Importance; + _worldPacket.WriteString(Name); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/NPCPackets.h b/src/server/game/Server/Packets/NPCPackets.h index bc69abc914a..bb38327c463 100644 --- a/src/server/game/Server/Packets/NPCPackets.h +++ b/src/server/game/Server/Packets/NPCPackets.h @@ -22,6 +22,8 @@ #include "ItemPackets.h" #include "Creature.h" +#include "G3D/Vector2.h" + namespace WorldPackets { namespace NPC @@ -179,6 +181,20 @@ namespace WorldPackets ObjectGuid UnitGUID; bool SuppressNPCGreeting = false; }; + + class GossipPOI final : public ServerPacket + { + public: + GossipPOI() : ServerPacket(SMSG_GOSSIP_POI, 2 + 2 * 4 + 4 + 4 + 1) { } + + WorldPacket const* Write() override; + + uint32 Flags = 0; + G3D::Vector2 Pos; + int32 Icon = 0; + int32 Importance = 0; + std::string Name; + }; } } diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp index 2cbd3078f60..59988cbc92e 100644 --- a/src/server/game/Server/Packets/QueryPackets.cpp +++ b/src/server/game/Server/Packets/QueryPackets.cpp @@ -203,6 +203,8 @@ WorldPacket const* WorldPackets::Query::QueryPageTextResponse::Write() _worldPacket << PageTextID; _worldPacket.WriteBit(Allow); + _worldPacket.FlushBits(); + if (Allow) { _worldPacket << Info.ID; @@ -227,10 +229,10 @@ WorldPacket const* WorldPackets::Query::QueryNPCTextResponse::Write() if (Allow) { - _worldPacket << int32(MAX_GOSSIP_TEXT_OPTIONS * (4 + 4)); - for (uint32 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) + _worldPacket << int32(MAX_NPC_TEXT_OPTIONS * (4 + 4)); + for (uint32 i = 0; i < MAX_NPC_TEXT_OPTIONS; ++i) _worldPacket << Probabilities[i]; - for (uint32 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) + for (uint32 i = 0; i < MAX_NPC_TEXT_OPTIONS; ++i) _worldPacket << BroadcastTextID[i]; } @@ -405,3 +407,29 @@ WorldPacket const* WorldPackets::Query::QuestPOIQueryResponse::Write() return &_worldPacket; } + +void WorldPackets::Query::QueryQuestCompletionNPCs::Read() +{ + uint32 questCount = 0; + + _worldPacket >> questCount; + QuestCompletionNPCs.resize(questCount); + + for (int32& QuestID : QuestCompletionNPCs) + _worldPacket >> QuestID; +} + +WorldPacket const* WorldPackets::Query::QuestCompletionNPCResponse::Write() +{ + _worldPacket << uint32(QuestCompletionNPCs.size()); + for (auto& quest : QuestCompletionNPCs) + { + _worldPacket << int32(quest.QuestID); + + _worldPacket << uint32(quest.NPCs.size()); + for (int32 const& npc : quest.NPCs) + _worldPacket << int32(npc); + } + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/QueryPackets.h b/src/server/game/Server/Packets/QueryPackets.h index 1c3310b9621..8e9613019c8 100644 --- a/src/server/game/Server/Packets/QueryPackets.h +++ b/src/server/game/Server/Packets/QueryPackets.h @@ -129,13 +129,6 @@ namespace WorldPackets uint32 PageTextID = 0; }; - struct PageTextInfo - { - uint32 ID = 0; - uint32 NextPageID = 0; - std::string Text; - }; - class QueryPageTextResponse final : public ServerPacket { public: @@ -143,6 +136,13 @@ namespace WorldPackets WorldPacket const* Write() override; + struct PageTextInfo + { + uint32 ID = 0; + uint32 NextPageID = 0; + std::string Text; + }; + bool Allow = false; PageTextInfo Info; uint32 PageTextID = 0; @@ -168,8 +168,8 @@ namespace WorldPackets uint32 TextID = 0; bool Allow = false; - float Probabilities[MAX_GOSSIP_TEXT_OPTIONS]; - uint32 BroadcastTextID[MAX_GOSSIP_TEXT_OPTIONS]; + float Probabilities[MAX_NPC_TEXT_OPTIONS]; + uint32 BroadcastTextID[MAX_NPC_TEXT_OPTIONS]; }; class DBQueryBulk final : public ClientPacket @@ -366,6 +366,32 @@ namespace WorldPackets std::vector<QuestPOIData> QuestPOIDataStats; }; + + class QueryQuestCompletionNPCs final : public ClientPacket + { + public: + QueryQuestCompletionNPCs(WorldPacket&& packet) : ClientPacket(CMSG_QUERY_QUEST_COMPLETION_NPCS, std::move(packet)) { } + + void Read() override; + + std::vector<int32> QuestCompletionNPCs; + }; + + struct QuestCompletionNPC + { + int32 QuestID = 0; + std::vector<int32> NPCs; + }; + + class QuestCompletionNPCResponse final : public ServerPacket + { + public: + QuestCompletionNPCResponse() : ServerPacket(SMSG_QUEST_COMPLETION_NPC_RESPONSE, 4) { } + + WorldPacket const* Write() override; + + std::vector<QuestCompletionNPC> QuestCompletionNPCs; + }; } } diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp index ce3f9115772..aeeb9f3b8b1 100644 --- a/src/server/game/Server/Packets/QuestPackets.cpp +++ b/src/server/game/Server/Packets/QuestPackets.cpp @@ -138,22 +138,22 @@ WorldPacket const* WorldPackets::Quest::QueryQuestInfoResponse::Write() _worldPacket << int32(Info.Objectives.size()); _worldPacket << int32(Info.AllowableRaces); - for (uint32 i = 0; i < Info.Objectives.size(); ++i) + for (QuestObjective const& questObjective : Info.Objectives) { - _worldPacket << Info.Objectives[i].ID; - _worldPacket << Info.Objectives[i].Type; - _worldPacket << Info.Objectives[i].StorageIndex; - _worldPacket << Info.Objectives[i].ObjectID; - _worldPacket << Info.Objectives[i].Amount; - _worldPacket << Info.Objectives[i].Flags; - _worldPacket << Info.Objectives[i].UnkFloat; - - _worldPacket << int32(Info.Objectives[i].VisualEffects.size()); - for (uint32 j = 0; j < Info.Objectives[i].VisualEffects.size(); ++j) - _worldPacket << Info.Objectives[i].VisualEffects[i]; - - _worldPacket.WriteBits(Info.Objectives[i].Description.size(), 8); - _worldPacket.WriteString(Info.Objectives[i].Description); + _worldPacket << questObjective.ID; + _worldPacket << questObjective.Type; + _worldPacket << questObjective.StorageIndex; + _worldPacket << questObjective.ObjectID; + _worldPacket << questObjective.Amount; + _worldPacket << questObjective.Flags; + _worldPacket << questObjective.UnkFloat; + + _worldPacket << int32(questObjective.VisualEffects.size()); + for (auto& visualEffect : questObjective.VisualEffects) + _worldPacket << visualEffect; + + _worldPacket.WriteBits(questObjective.Description.size(), 8); + _worldPacket.WriteString(questObjective.Description); } _worldPacket.WriteBits(Info.LogTitle.size(), 9); @@ -165,7 +165,6 @@ WorldPacket const* WorldPackets::Quest::QueryQuestInfoResponse::Write() _worldPacket.WriteBits(Info.PortraitTurnInText.size(), 10); _worldPacket.WriteBits(Info.PortraitTurnInName.size(), 8); _worldPacket.WriteBits(Info.QuestCompletionLog.size(), 11); - _worldPacket.FlushBits(); _worldPacket.WriteString(Info.LogTitle); _worldPacket.WriteString(Info.LogDescription); @@ -463,3 +462,21 @@ WorldPacket const* WorldPackets::Quest::QuestGiverQuestList::Write() return &_worldPacket; } + +WorldPacket const* WorldPackets::Quest::QuestUpdateComplete::Write() +{ + _worldPacket << int32(QuestID); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Quest::QuestConfirmAccept::Write() +{ + _worldPacket << uint32(QuestID); + _worldPacket << InitiatedBy; + + _worldPacket.WriteBits(QuestTitle.size(), 10); + _worldPacket.WriteString(QuestTitle); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h index fd6def07977..0943c482158 100644 --- a/src/server/game/Server/Packets/QuestPackets.h +++ b/src/server/game/Server/Packets/QuestPackets.h @@ -427,10 +427,10 @@ namespace WorldPackets uint8 Entry = 0; }; - + struct GossipTextData { - GossipTextData(uint32 questID, uint32 questType, uint32 questLevel, uint32 questFlags, uint32 questFlagsEx, bool repeatable, std::string questTitle) : + GossipTextData(uint32 questID, uint32 questType, uint32 questLevel, uint32 questFlags, uint32 questFlagsEx, bool repeatable, std::string questTitle) : QuestID(questID), QuestType(questType), QuestLevel(questLevel), QuestFlags(questFlags), QuestFlagsEx(questFlagsEx), Repeatable(repeatable), QuestTitle(questTitle) { } uint32 QuestID; uint32 QuestType; @@ -454,6 +454,28 @@ namespace WorldPackets std::vector<GossipTextData> GossipTexts; std::string Greeting; }; + + class QuestUpdateComplete final : public ServerPacket + { + public: + QuestUpdateComplete() : ServerPacket(SMSG_QUEST_UPDATE_COMPLETE, 4) { } + + WorldPacket const* Write() override; + + int32 QuestID = 0; + }; + + class QuestConfirmAccept final : public ServerPacket + { + public: + QuestConfirmAccept() : ServerPacket(SMSG_QUEST_CONFIRM_ACCEPT, 21) { } + + WorldPacket const* Write() override; + + ObjectGuid InitiatedBy; + int32 QuestID = 0; + std::string QuestTitle; + }; } } diff --git a/src/server/game/Server/Packets/ReputationPackets.cpp b/src/server/game/Server/Packets/ReputationPackets.cpp index 8dce2936835..edcef8da40d 100644 --- a/src/server/game/Server/Packets/ReputationPackets.cpp +++ b/src/server/game/Server/Packets/ReputationPackets.cpp @@ -32,3 +32,21 @@ WorldPacket const* WorldPackets::Reputation::InitializeFactions::Write() return &_worldPacket; } + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Reputation::ForcedReaction const& forcedReaction) +{ + data << int32(forcedReaction.Faction); + data << int32(forcedReaction.Reaction); + return data; +} + +WorldPacket const* WorldPackets::Reputation::SetForcedReactions::Write() +{ + _worldPacket.WriteBits(Reactions.size(), 6); + for (ForcedReaction const& reaction : Reactions) + _worldPacket << reaction; + + _worldPacket.FlushBits(); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/ReputationPackets.h b/src/server/game/Server/Packets/ReputationPackets.h index 578e6e35911..59245544c02 100644 --- a/src/server/game/Server/Packets/ReputationPackets.h +++ b/src/server/game/Server/Packets/ReputationPackets.h @@ -15,7 +15,8 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#pragma once +#ifndef ReputationPackets_h__ +#define ReputationPackets_h__ #include "Packet.h" @@ -44,5 +45,31 @@ namespace WorldPackets bool FactionHasBonus[FactionCount]; ///< @todo: implement faction bonus uint8 FactionFlags[FactionCount]; ///< @see enum FactionFlags }; + + class RequestForcedReactions final : public ClientPacket + { + public: + RequestForcedReactions(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_FORCED_REACTIONS, std::move(packet)) { } + + void Read() override { } + }; + + struct ForcedReaction + { + int32 Faction = 0; + int32 Reaction = 0; + }; + + class SetForcedReactions final : public ServerPacket + { + public: + SetForcedReactions() : ServerPacket(SMSG_SET_FORCED_REACTIONS) { } + + WorldPacket const* Write() override; + + std::vector<ForcedReaction> Reactions; + }; } } + +#endif // ReputationPackets_h__ diff --git a/src/server/game/Server/Packets/ScenePackets.cpp b/src/server/game/Server/Packets/ScenePackets.cpp new file mode 100644 index 00000000000..df37156d9dd --- /dev/null +++ b/src/server/game/Server/Packets/ScenePackets.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * 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 "ScenePackets.h" + +WorldPacket const* WorldPackets::Scenes::PlayScene::Write() +{ + _worldPacket << SceneID; + _worldPacket << PlaybackFlags; + _worldPacket << SceneInstanceID; + _worldPacket << SceneScriptPackageID; + _worldPacket << TransportGUID; + _worldPacket << Location.PositionXYZOStream(); + + return &_worldPacket; +} + +void WorldPackets::Scenes::SceneTriggerEvent::Read() +{ + uint32 len = _worldPacket.ReadBits(6); + _worldPacket >> SceneInstanceID; + _Event = _worldPacket.ReadString(len); +} + +void WorldPackets::Scenes::ScenePlaybackComplete::Read() +{ + _worldPacket >> SceneInstanceID; +} + +void WorldPackets::Scenes::ScenePlaybackCanceled::Read() +{ + _worldPacket >> SceneInstanceID; +} diff --git a/src/server/game/Server/Packets/ScenePackets.h b/src/server/game/Server/Packets/ScenePackets.h new file mode 100644 index 00000000000..50aed92615a --- /dev/null +++ b/src/server/game/Server/Packets/ScenePackets.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * 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 ScenePackets_h__ +#define ScenePackets_h__ + +#include "Packet.h" +#include "Object.h" + +namespace WorldPackets +{ + namespace Scenes + { + class PlayScene final : public ServerPacket + { + public: + PlayScene() : ServerPacket(SMSG_PLAY_SCENE, 34) { } + + WorldPacket const* Write() override; + + int32 SceneID = 0; + int32 PlaybackFlags = 0; + int32 SceneInstanceID = 0; + int32 SceneScriptPackageID = 0; + ObjectGuid TransportGUID; + Position Location; + }; + + class SceneTriggerEvent final : public ClientPacket + { + public: + SceneTriggerEvent(WorldPacket&& packet) : ClientPacket(CMSG_SCENE_TRIGGER_EVENT, std::move(packet)) { } + + void Read() override; + + uint32 SceneInstanceID = 0; + std::string _Event; + }; + + class ScenePlaybackComplete final : public ClientPacket + { + public: + ScenePlaybackComplete(WorldPacket&& packet) : ClientPacket(CMSG_SCENE_PLAYBACK_COMPLETE, std::move(packet)) { } + + void Read() override; + + uint32 SceneInstanceID = 0; + }; + + class ScenePlaybackCanceled final : public ClientPacket + { + public: + ScenePlaybackCanceled(WorldPacket&& packet) : ClientPacket(CMSG_SCENE_PLAYBACK_CANCELED, std::move(packet)) { } + + void Read() override; + + uint32 SceneInstanceID = 0; + }; + } +} + +#endif // ScenePackets_h__ diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h index 86bbf76b0c0..1f7cdd0b93a 100644 --- a/src/server/game/Server/Packets/SpellPackets.h +++ b/src/server/game/Server/Packets/SpellPackets.h @@ -38,6 +38,30 @@ namespace WorldPackets int32 SpellID = 0; }; + class CancelGrowthAura final : public ClientPacket + { + public: + CancelGrowthAura(WorldPacket&& packet) : ClientPacket(CMSG_CANCEL_GROWTH_AURA, std::move(packet)) { } + + void Read() override { } + }; + + class CancelMountAura final : public ClientPacket + { + public: + CancelMountAura(WorldPacket&& packet) : ClientPacket(CMSG_CANCEL_MOUNT_AURA, std::move(packet)) { } + + void Read() override { } + }; + + class RequestCategoryCooldowns final : public ClientPacket + { + public: + RequestCategoryCooldowns(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_CATEGORY_COOLDOWNS, std::move(packet)) { } + + void Read() override { } + }; + class CategoryCooldown final : public ServerPacket { public: diff --git a/src/server/game/Server/Packets/TicketPackets.cpp b/src/server/game/Server/Packets/TicketPackets.cpp index 70ef53551da..ba5725bfe23 100644 --- a/src/server/game/Server/Packets/TicketPackets.cpp +++ b/src/server/game/Server/Packets/TicketPackets.cpp @@ -113,7 +113,7 @@ void WorldPackets::Ticket::GMTicketCreate::Read() _worldPacket >> ChatHistoryData.TextCount; for (uint8 i = 0; i < ChatHistoryData.TextCount; ++i) ChatHistoryData.Sent.push_back(_worldPacket.read<uint32>()); - + _worldPacket >> ChatHistoryData.DecompressedSize; //Note: don't ask why, but it works... @@ -184,7 +184,7 @@ void WorldPackets::Ticket::GMSurveySubmit::Read() } void WorldPackets::Ticket::SupportTicketSubmitBug::Read() -{ +{ _worldPacket >> Header; Note = _worldPacket.ReadString(_worldPacket.ReadBits(10)); } @@ -313,7 +313,7 @@ void WorldPackets::Ticket::SupportTicketSubmitComplaint::Read() _worldPacket >> ChatLog; _worldPacket >> TargetCharacterGUID; ComplaintType = _worldPacket.ReadBits(5); - + uint16 noteLength = _worldPacket.ReadBits(10); bool hasMailInfo = _worldPacket.ReadBit(); bool hasCalendarInfo = _worldPacket.ReadBit(); diff --git a/src/server/game/Server/Packets/TokenPackets.cpp b/src/server/game/Server/Packets/TokenPackets.cpp new file mode 100644 index 00000000000..af186a1cf4b --- /dev/null +++ b/src/server/game/Server/Packets/TokenPackets.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * 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 "TokenPackets.h" + +void WorldPackets::Token::UpdateListedAuctionableTokens::Read() +{ + _worldPacket >> UnkInt; +} + +WorldPacket const* WorldPackets::Token::UpdateListedAuctionableTokensResponse::Write() +{ + _worldPacket << UnkInt; + _worldPacket << Result; + _worldPacket << uint32(AuctionableTokenAuctionableList.size()); + for (AuctionableTokenAuctionable const& auctionableTokenAuctionable : AuctionableTokenAuctionableList) + { + _worldPacket << auctionableTokenAuctionable.UnkInt1; + _worldPacket << auctionableTokenAuctionable.UnkInt2; + _worldPacket << auctionableTokenAuctionable.UnkInt3; + _worldPacket << auctionableTokenAuctionable.UnkInt4; + _worldPacket << auctionableTokenAuctionable.UnkInt5; + } + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/TokenPackets.h b/src/server/game/Server/Packets/TokenPackets.h new file mode 100644 index 00000000000..126fbe59982 --- /dev/null +++ b/src/server/game/Server/Packets/TokenPackets.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * 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 TokenPackets_h__ +#define TokenPackets_h__ + +#include "Packet.h" + +namespace WorldPackets +{ + namespace Token + { + class UpdateListedAuctionableTokens final : public ClientPacket + { + public: + UpdateListedAuctionableTokens(WorldPacket&& packet) : ClientPacket(CMSG_UPDATE_WOW_TOKEN_AUCTIONABLE_LIST, std::move(packet)) { } + + void Read() override; + + uint32 UnkInt = 0; + }; + + class UpdateListedAuctionableTokensResponse final : public ServerPacket + { + public: + UpdateListedAuctionableTokensResponse() : ServerPacket(SMSG_UPDATE_WOW_TOKEN_AUCTIONABLE_LIST_RESPONSE, 12) { } + + WorldPacket const* Write() override; + + struct AuctionableTokenAuctionable + { + uint64 UnkInt1 = 0; + uint32 UnkInt2 = 0; + uint32 UnkInt3 = 0; + uint64 UnkInt4 = 0; + uint32 UnkInt5 = 0; + }; + + uint32 UnkInt = 0; // send CMSG_UPDATE_WOW_TOKEN_AUCTIONABLE_LIST + uint32 Result = 0; + std::vector<AuctionableTokenAuctionable> AuctionableTokenAuctionableList; + }; + } +} + +#endif // TokenPackets_h__ diff --git a/src/server/game/Server/Packets/VoidStoragePackets.cpp b/src/server/game/Server/Packets/VoidStoragePackets.cpp new file mode 100644 index 00000000000..a635d57666d --- /dev/null +++ b/src/server/game/Server/Packets/VoidStoragePackets.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * 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 "VoidStoragePackets.h" +#include "SharedDefines.h" + +WorldPacket const* WorldPackets::VoidStorage::VoidTransferResult::Write() +{ + _worldPacket << int32(Result); + return &_worldPacket; +} + +void WorldPackets::VoidStorage::UnlockVoidStorage::Read() +{ + _worldPacket >> Npc; +} + +void WorldPackets::VoidStorage::QueryVoidStorage::Read() +{ + _worldPacket >> Npc; +} + +WorldPacket const* WorldPackets::VoidStorage::VoidStorageFailed::Write() +{ + _worldPacket << uint8(Reason); + return &_worldPacket; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::VoidStorage::VoidItem const& voidItem) +{ + data << voidItem.Guid; + data << voidItem.Creator; + data << uint32(voidItem.Slot); + data << voidItem.Item; + return data; +} + +WorldPacket const* WorldPackets::VoidStorage::VoidStorageContents::Write() +{ + _worldPacket.reserve(1 + Items.size() * sizeof(VoidItem)); + + _worldPacket.WriteBits(Items.size(), 8); + _worldPacket.FlushBits(); + + for (VoidItem const& voidItem : Items) + _worldPacket << voidItem; + + return &_worldPacket; +} + +void WorldPackets::VoidStorage::VoidStorageTransfer::Read() +{ + _worldPacket >> Npc; + _worldPacket >> DepositsCount; + _worldPacket >> WithdrawalsCount; + + if (WithdrawalsCount > VOID_STORAGE_MAX_WITHDRAW || DepositsCount > VOID_STORAGE_MAX_DEPOSIT) + return; + + for (uint32 i = 0; i < DepositsCount; ++i) + _worldPacket >> Deposits[i]; + + for (uint32 i = 0; i < WithdrawalsCount; ++i) + _worldPacket >> Withdrawals[i]; +} + +WorldPacket const* WorldPackets::VoidStorage::VoidStorageTransferChanges::Write() +{ + _worldPacket.reserve(1 + AddedItems.size() * sizeof(VoidItem) + RemovedItems.size() * 16); + + _worldPacket.WriteBits(AddedItems.size(), 4); + _worldPacket.WriteBits(RemovedItems.size(), 4); + _worldPacket.FlushBits(); + + for (VoidItem const& addedItem : AddedItems) + _worldPacket << addedItem; + + for (ObjectGuid const& removedItem : RemovedItems) + _worldPacket << removedItem; + + return &_worldPacket; +} + +void WorldPackets::VoidStorage::SwapVoidItem::Read() +{ + _worldPacket >> Npc; + _worldPacket >> VoidItemGuid; + _worldPacket >> DstSlot; +} + +WorldPacket const* WorldPackets::VoidStorage::VoidItemSwapResponse::Write() +{ + _worldPacket << VoidItemA << uint32(VoidItemSlotA); + _worldPacket << VoidItemB << uint32(VoidItemSlotB); + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/VoidStoragePackets.h b/src/server/game/Server/Packets/VoidStoragePackets.h new file mode 100644 index 00000000000..9790b328e72 --- /dev/null +++ b/src/server/game/Server/Packets/VoidStoragePackets.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * 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 VoidStoragePackets_h__ +#define VoidStoragePackets_h__ + +#include "Packet.h" +#include "ItemPackets.h" + +namespace WorldPackets +{ + namespace VoidStorage + { + class VoidTransferResult final : public ServerPacket + { + public: + VoidTransferResult(int32 result) : ServerPacket(SMSG_VOID_TRANSFER_RESULT, 4), Result(result) { } + + WorldPacket const* Write() override; + + int32 Result; + }; + + class UnlockVoidStorage final : public ClientPacket + { + public: + UnlockVoidStorage(WorldPacket&& packet) : ClientPacket(CMSG_UNLOCK_VOID_STORAGE, std::move(packet)) { } + + void Read() override; + + ObjectGuid Npc; + }; + + class QueryVoidStorage final : public ClientPacket + { + public: + QueryVoidStorage(WorldPacket&& packet) : ClientPacket(CMSG_QUERY_VOID_STORAGE, std::move(packet)) { } + + void Read() override; + + ObjectGuid Npc; + }; + + class VoidStorageFailed final : public ServerPacket + { + public: + VoidStorageFailed() : ServerPacket(SMSG_VOID_STORAGE_FAILED, 1) { } + + WorldPacket const* Write() override; + + uint8 Reason = 0; + }; + + struct VoidItem + { + ObjectGuid Guid; + ObjectGuid Creator; + uint32 Slot = 0; + WorldPackets::Item::ItemInstance Item; + }; + + class VoidStorageContents final : public ServerPacket + { + public: + VoidStorageContents() : ServerPacket(SMSG_VOID_STORAGE_CONTENTS, 0) { } + + WorldPacket const* Write() override; + + std::vector<VoidItem> Items; + }; + + class VoidStorageTransfer final : public ClientPacket + { + public: + VoidStorageTransfer(WorldPacket&& packet) : ClientPacket(CMSG_VOID_STORAGE_TRANSFER, std::move(packet)) { } + + void Read() override; + + std::array<ObjectGuid, VOID_STORAGE_MAX_WITHDRAW> Withdrawals; + uint32 WithdrawalsCount = 0; + std::array<ObjectGuid, VOID_STORAGE_MAX_DEPOSIT> Deposits; + uint32 DepositsCount = 0; + ObjectGuid Npc; + }; + + class VoidStorageTransferChanges final : public ServerPacket + { + public: + VoidStorageTransferChanges() : ServerPacket(SMSG_VOID_STORAGE_TRANSFER_CHANGES, 0) { } + + WorldPacket const* Write() override; + + std::vector<ObjectGuid> RemovedItems; + std::vector<VoidItem> AddedItems; + }; + + class SwapVoidItem final : public ClientPacket + { + public: + SwapVoidItem(WorldPacket&& packet) : ClientPacket(CMSG_SWAP_VOID_ITEM, std::move(packet)) { } + + void Read() override; + + ObjectGuid Npc; + ObjectGuid VoidItemGuid; + uint32 DstSlot = 0; + }; + + class VoidItemSwapResponse final : public ServerPacket + { + public: + VoidItemSwapResponse() : ServerPacket(SMSG_VOID_ITEM_SWAP_RESPONSE, 16 + 16 + 4 + 4) { } + + WorldPacket const* Write() override; + + ObjectGuid VoidItemA; + ObjectGuid VoidItemB; + uint32 VoidItemSlotA = 0; + uint32 VoidItemSlotB = 0; + }; + } +} + +#endif // VoidStoragePackets_h__ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index d1dcd5521ef..d1f68da912c 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -21,6 +21,7 @@ #include "Packets/AchievementPackets.h" #include "Packets/AuctionHousePackets.h" #include "Packets/BankPackets.h" +#include "Packets/BattlegroundPackets.h" #include "Packets/BlackMarketPackets.h" #include "Packets/CharacterPackets.h" #include "Packets/ChannelPackets.h" @@ -42,11 +43,15 @@ #include "Packets/QueryPackets.h" #include "Packets/QuestPackets.h" #include "Packets/ReferAFriendPackets.h" +#include "Packets/ReputationPackets.h" +#include "Packets/ScenePackets.h" #include "Packets/SocialPackets.h" #include "Packets/TalentPackets.h" +#include "Packets/TokenPackets.h" #include "Packets/TradePackets.h" #include "Packets/TicketPackets.h" #include "Packets/VehiclePackets.h" +#include "Packets/VoidStoragePackets.h" #include "Packets/WhoPackets.h" template<class PacketClass, void(WorldSession::*HandlerFunction)(PacketClass&)> @@ -145,8 +150,8 @@ void OpcodeTable::Initialize() #define DEFINE_OPCODE_HANDLER_OLD(opcode, status, processing, handler) \ DEFINE_HANDLER(opcode, status, processing, WorldPacket, handler); - DEFINE_HANDLER(CMSG_ACCEPT_GUILD_INVITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::AcceptGuildInvite, &WorldSession::HandleGuildAcceptInvite); - DEFINE_HANDLER(CMSG_ACCEPT_LEVEL_GRANT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::RaF::AcceptLevelGrant, &WorldSession::HandleAcceptGrantLevel ); + DEFINE_HANDLER(CMSG_ACCEPT_GUILD_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::AcceptGuildInvite, &WorldSession::HandleGuildAcceptInvite); + DEFINE_HANDLER(CMSG_ACCEPT_LEVEL_GRANT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::RaF::AcceptLevelGrant, &WorldSession::HandleAcceptGrantLevel); DEFINE_HANDLER(CMSG_ACCEPT_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::AcceptTrade, &WorldSession::HandleAcceptTradeOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_ACCEPT_WARGAME_INVITE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_ACTIVATE_TAXI, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleActivateTaxiOpcode ); @@ -155,20 +160,20 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_ADD_IGNORE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Social::AddIgnore, &WorldSession::HandleAddIgnoreOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_ADD_TOY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_ALTER_APPEARANCE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::AlterApperance, &WorldSession::HandleAlterAppearance); - DEFINE_OPCODE_HANDLER_OLD(CMSG_AREA_SPIRIT_HEALER_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaSpiritHealerQueryOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_AREA_SPIRIT_HEALER_QUEUE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaSpiritHealerQueueOpcode); + DEFINE_HANDLER(CMSG_AREA_SPIRIT_HEALER_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Battleground::AreaSpiritHealerQuery, &WorldSession::HandleAreaSpiritHealerQueryOpcode); + DEFINE_HANDLER(CMSG_AREA_SPIRIT_HEALER_QUEUE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Battleground::AreaSpiritHealerQueue, &WorldSession::HandleAreaSpiritHealerQueueOpcode); DEFINE_HANDLER(CMSG_AREA_TRIGGER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::AreaTrigger, &WorldSession::HandleAreaTriggerOpcode); DEFINE_HANDLER(CMSG_ATTACK_STOP, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Combat::AttackStop, &WorldSession::HandleAttackStopOpcode); DEFINE_HANDLER(CMSG_ATTACK_SWING, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Combat::AttackSwing, &WorldSession::HandleAttackSwingOpcode); - DEFINE_HANDLER(CMSG_AUCTION_HELLO_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionHelloRequest, &WorldSession::HandleAuctionHelloOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_LIST_BIDDER_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListBidderItems ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_LIST_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListItems ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_LIST_OWNER_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListOwnerItems ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_LIST_PENDING_SALES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListPendingSales ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_PLACE_BID, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionPlaceBid ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_REMOVE_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionRemoveItem ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_REPLICATE_ITEMS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_AUCTION_SELL_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionSellItem ); + DEFINE_HANDLER(CMSG_AUCTION_HELLO_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionHelloRequest, &WorldSession::HandleAuctionHelloOpcode); + DEFINE_HANDLER(CMSG_AUCTION_LIST_BIDDER_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionListBidderItems, &WorldSession::HandleAuctionListBidderItems); + DEFINE_HANDLER(CMSG_AUCTION_LIST_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionListItems, &WorldSession::HandleAuctionListItems); + DEFINE_HANDLER(CMSG_AUCTION_LIST_OWNER_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionListOwnerItems, &WorldSession::HandleAuctionListOwnerItems); + DEFINE_HANDLER(CMSG_AUCTION_LIST_PENDING_SALES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionListPendingSales, &WorldSession::HandleAuctionListPendingSales); + DEFINE_HANDLER(CMSG_AUCTION_PLACE_BID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionPlaceBid, &WorldSession::HandleAuctionPlaceBid); + DEFINE_HANDLER(CMSG_AUCTION_REMOVE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionRemoveItem, &WorldSession::HandleAuctionRemoveItem); + DEFINE_HANDLER(CMSG_AUCTION_REPLICATE_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionReplicateItems, &WorldSession::HandleReplicateItems); + DEFINE_HANDLER(CMSG_AUCTION_SELL_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionSellItem, &WorldSession::HandleAuctionSellItem); DEFINE_HANDLER(CMSG_AUTH_CONTINUED_SESSION, STATUS_NEVER, PROCESS_INPLACE, WorldPacket, &WorldSession::Handle_EarlyProccess); DEFINE_HANDLER(CMSG_AUTH_SESSION, STATUS_NEVER, PROCESS_INPLACE, WorldPacket, &WorldSession::Handle_EarlyProccess); DEFINE_HANDLER(CMSG_AUTOBANK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Bank::AutoBankItem, &WorldSession::HandleAutoBankItemOpcode); @@ -176,8 +181,8 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_AUTOSTORE_BANK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Bank::AutoStoreBankItem, &WorldSession::HandleAutoStoreBankItemOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOSTORE_BANK_REAGENT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_AUTO_EQUIP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::AutoEquipItem, &WorldSession::HandleAutoEquipItemOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTO_EQUIP_ITEM_SLOT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemSlotOpcode ); - DEFINE_HANDLER(CMSG_AUTO_STORE_BAG_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Item::AutoStoreBagItem, &WorldSession::HandleAutoStoreBagItemOpcode); + DEFINE_HANDLER(CMSG_AUTO_EQUIP_ITEM_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::AutoEquipItemSlot, &WorldSession::HandleAutoEquipItemSlotOpcode); + DEFINE_HANDLER(CMSG_AUTO_STORE_BAG_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::AutoStoreBagItem, &WorldSession::HandleAutoStoreBagItemOpcode); DEFINE_HANDLER(CMSG_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleBankerActivateOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_LEAVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBattlefieldLeaveOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldListOpcode ); @@ -202,14 +207,14 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_SET_FLAGS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_SUMMON, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_UPDATE_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_BEGIN_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::BeginTrade, &WorldSession::HandleBeginTradeOpcode ); + DEFINE_HANDLER(CMSG_BEGIN_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::BeginTrade, &WorldSession::HandleBeginTradeOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_BF_MGR_ENTRY_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBfEntryInviteResponse ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BF_MGR_QUEUE_EXIT_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBfExitRequest); DEFINE_OPCODE_HANDLER_OLD(CMSG_BF_MGR_QUEUE_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBfQueueInviteResponse ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BF_MGR_QUEUE_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_BINDER_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleBinderActivateOpcode); + DEFINE_HANDLER(CMSG_BINDER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleBinderActivateOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_BLACK_MARKET_BID_ON_ITEM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_BLACK_MARKET_OPEN, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::BlackMarket::BlackMarketOpen, &WorldSession::HandleBlackMarketOpen); + DEFINE_HANDLER(CMSG_BLACK_MARKET_OPEN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::BlackMarket::BlackMarketOpen, &WorldSession::HandleBlackMarketOpen); DEFINE_OPCODE_HANDLER_OLD(CMSG_BLACK_MARKET_REQUEST_ITEMS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BUG_REPORT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBugReportOpcode ); DEFINE_HANDLER(CMSG_BUSY_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::BusyTrade, &WorldSession::HandleBusyTradeOpcode); @@ -233,16 +238,16 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_GET_NUM_PENDING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetNumPending ); DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_GUILD_FILTER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGuildFilter ); DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_REMOVE_EVENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarRemoveEvent ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_REMOVE_INVITE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleCalendarEventRemoveInvite ); + DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_REMOVE_INVITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventRemoveInvite ); DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_UPDATE_EVENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarUpdateEvent ); DEFINE_HANDLER(CMSG_CANCEL_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::CancelAura, &WorldSession::HandleCancelAuraOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_AUTO_REPEAT_SPELL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAutoRepeatSpellOpcode); DEFINE_HANDLER(CMSG_CANCEL_CAST, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Spells::CancelCast, &WorldSession::HandleCancelCastOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_CHANNELLING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelChanneling ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_GROWTH_AURA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelGrowthAuraOpcode ); + DEFINE_HANDLER(CMSG_CANCEL_GROWTH_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::CancelGrowthAura, &WorldSession::HandleCancelGrowthAuraOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_MASTER_LOOT_ROLL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_MOD_SPEED_NO_CONTROL_AURAS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_MOUNT_AURA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelMountAuraOpcode ); + DEFINE_HANDLER(CMSG_CANCEL_MOUNT_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::CancelMountAura, &WorldSession::HandleCancelMountAuraOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_QUEUED_SPELL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_TEMP_ENCHANTMENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTempEnchantmentOpcode); DEFINE_HANDLER(CMSG_CANCEL_TRADE, STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, PROCESS_THREADUNSAFE, WorldPackets::Trade::CancelTrade, &WorldSession::HandleCancelTradeOpcode); @@ -257,9 +262,9 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_CHAR_CUSTOMIZE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharCustomize, &WorldSession::HandleCharCustomizeOpcode); DEFINE_HANDLER(CMSG_CHAR_DELETE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharDelete, &WorldSession::HandleCharDeleteOpcode); DEFINE_HANDLER(CMSG_CHAR_RACE_OR_FACTION_CHANGE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharRaceOrFactionChange, &WorldSession::HandleCharRaceOrFactionChangeOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_CHAT_ADDON_MESSAGE_CHANNEL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_HANDLER(CMSG_CHAT_ADDON_MESSAGE_CHANNEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessageChannel, &WorldSession::HandleChatAddonMessageChannelOpcode); DEFINE_HANDLER(CMSG_CHAT_ADDON_MESSAGE_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessage, &WorldSession::HandleChatAddonMessageOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_CHAT_ADDON_MESSAGE_INSTANCE_CHAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_HANDLER(CMSG_CHAT_ADDON_MESSAGE_INSTANCE_CHAT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessage, &WorldSession::HandleChatAddonMessageOpcode); DEFINE_HANDLER(CMSG_CHAT_ADDON_MESSAGE_OFFICER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessage, &WorldSession::HandleChatAddonMessageOpcode); DEFINE_HANDLER(CMSG_CHAT_ADDON_MESSAGE_PARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessage, &WorldSession::HandleChatAddonMessageOpcode); DEFINE_HANDLER(CMSG_CHAT_ADDON_MESSAGE_RAID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessage, &WorldSession::HandleChatAddonMessageOpcode); @@ -293,7 +298,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_CHAT_MESSAGE_DND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessageDND, &WorldSession::HandleChatMessageDNDOpcode); DEFINE_HANDLER(CMSG_CHAT_MESSAGE_EMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessageEmote, &WorldSession::HandleChatMessageEmoteOpcode); DEFINE_HANDLER(CMSG_CHAT_MESSAGE_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_CHAT_MESSAGE_INSTANCE_CHAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_HANDLER(CMSG_CHAT_MESSAGE_INSTANCE_CHAT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode); DEFINE_HANDLER(CMSG_CHAT_MESSAGE_OFFICER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode); DEFINE_HANDLER(CMSG_CHAT_MESSAGE_PARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode); DEFINE_HANDLER(CMSG_CHAT_MESSAGE_RAID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode); @@ -328,9 +333,9 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_CREATE_CHARACTER, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CreateCharacter, &WorldSession::HandleCharCreateOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_CREATE_SHIPMENT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_DB_QUERY_BULK, STATUS_AUTHED, PROCESS_INPLACE, WorldPackets::Query::DBQueryBulk, &WorldSession::HandleDBQueryBulk); - DEFINE_HANDLER(CMSG_DECLINE_GUILD_INVITES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::DeclineGuildInvites, &WorldSession::HandleDeclineGuildInvites); - DEFINE_HANDLER(CMSG_DECLINE_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Petition::DeclinePetition, &WorldSession::HandleDeclinePetition); - DEFINE_OPCODE_HANDLER_OLD(CMSG_DELETE_EQUIPMENT_SET, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetDelete ); + DEFINE_HANDLER(CMSG_DECLINE_GUILD_INVITES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::DeclineGuildInvites, &WorldSession::HandleDeclineGuildInvites); + DEFINE_HANDLER(CMSG_DECLINE_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::DeclinePetition, &WorldSession::HandleDeclinePetition); + DEFINE_HANDLER(CMSG_DELETE_EQUIPMENT_SET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::EquipmentSet::DeleteEquipmentSet, &WorldSession::HandleDeleteEquipmentSet); DEFINE_HANDLER(CMSG_DEL_FRIEND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Social::DelFriend, &WorldSession::HandleDelFriendOpcode); DEFINE_HANDLER(CMSG_DEL_IGNORE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Social::DelIgnore, &WorldSession::HandleDelIgnoreOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_DEPOSIT_REAGENT_BANK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -385,14 +390,14 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_GENERATE_RANDOM_CHARACTER_NAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::GenerateRandomCharacterName, &WorldSession::HandleRandomizeCharNameOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_GET_CHALLENGE_MODE_REWARDS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GET_GARRISON_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_GET_ITEM_PURCHASE_DATA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Item::GetItemPurchaseData, &WorldSession::HandleGetItemPurchaseData); + DEFINE_HANDLER(CMSG_GET_ITEM_PURCHASE_DATA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::GetItemPurchaseData, &WorldSession::HandleGetItemPurchaseData); DEFINE_OPCODE_HANDLER_OLD(CMSG_GET_MIRROR_IMAGE_DATA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMirrorImageDataRequest ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GET_PVP_OPTIONS_ENABLED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGetPVPOptionsEnabled ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GET_REMAINING_GAME_TIME, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GET_TROPHY_LIST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_GET_UNDELETE_CHARACTER_COOLDOWN_STATUS, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::GetUndeleteCharacterCooldownStatus, &WorldSession::HandleGetUndeleteCooldownStatus); DEFINE_OPCODE_HANDLER_OLD(CMSG_GM_LAG_REPORT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_GM_SURVEY_SUBMIT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Ticket::GMSurveySubmit, &WorldSession::HandleGMSurveySubmit); + DEFINE_HANDLER(CMSG_GM_SURVEY_SUBMIT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Ticket::GMSurveySubmit, &WorldSession::HandleGMSurveySubmit); DEFINE_OPCODE_HANDLER_OLD(CMSG_GM_TICKET_ACKNOWLEDGE_SURVEY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_GM_TICKET_CREATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Ticket::GMTicketCreate, &WorldSession::HandleGMTicketCreateOpcode); DEFINE_HANDLER(CMSG_GM_TICKET_DELETE_TICKET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Ticket::GMTicketDelete, &WorldSession::HandleGMTicketDeleteOpcode); @@ -402,59 +407,59 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_GM_TICKET_RESPONSE_RESOLVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Ticket::GMTicketResponseResolve, &WorldSession::HandleGMResponseResolve); DEFINE_HANDLER(CMSG_GM_TICKET_UPDATE_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Ticket::GMTicketUpdateText, &WorldSession::HandleGMTicketUpdateTextOpcode); DEFINE_HANDLER(CMSG_GOSSIP_SELECT_OPTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::GossipSelectOption, &WorldSession::HandleGossipSelectOptionOpcode); - DEFINE_HANDLER(CMSG_GRANT_LEVEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::RaF::GrantLevel, &WorldSession::HandleGrantLevel ); + DEFINE_HANDLER(CMSG_GRANT_LEVEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::RaF::GrantLevel, &WorldSession::HandleGrantLevel); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_ADD_BATTLENET_FRIEND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_GUILD_ADD_RANK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildAddRank, &WorldSession::HandleGuildAddRank); - DEFINE_HANDLER(CMSG_GUILD_ASSIGN_MEMBER_RANK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildAssignMemberRank, &WorldSession::HandleGuildAssignRank); + DEFINE_HANDLER(CMSG_GUILD_ADD_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildAddRank, &WorldSession::HandleGuildAddRank); + DEFINE_HANDLER(CMSG_GUILD_ASSIGN_MEMBER_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildAssignMemberRank, &WorldSession::HandleGuildAssignRank); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_AUTO_DECLINE_INVITATION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_GUILD_BANK_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankActivate, &WorldSession::HandleGuildBankActivate); - DEFINE_HANDLER(CMSG_GUILD_BANK_BUY_TAB, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankBuyTab, &WorldSession::HandleGuildBankBuyTab); - DEFINE_HANDLER(CMSG_GUILD_BANK_DEPOSIT_MONEY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankDepositMoney, &WorldSession::HandleGuildBankDepositMoney); - DEFINE_HANDLER(CMSG_GUILD_BANK_LOG_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankLogQuery, &WorldSession::HandleGuildBankLogQuery); - DEFINE_HANDLER(CMSG_GUILD_BANK_QUERY_TAB, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankQueryTab, &WorldSession::HandleGuildBankQueryTab); - DEFINE_HANDLER(CMSG_GUILD_BANK_REMAINING_WITHDRAW_MONEY_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankRemainingWithdrawMoneyQuery, &WorldSession::HandleGuildBankMoneyWithdrawn); - DEFINE_HANDLER(CMSG_GUILD_BANK_SET_TAB_TEXT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankSetTabText, &WorldSession::HandleGuildBankSetTabText); - DEFINE_HANDLER(CMSG_GUILD_BANK_SWAP_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankSwapItems, &WorldSession::HandleGuildBankSwapItems); - DEFINE_HANDLER(CMSG_GUILD_BANK_TEXT_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankTextQuery, &WorldSession::HandleGuildBankTextQuery); - DEFINE_HANDLER(CMSG_GUILD_BANK_UPDATE_TAB, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankUpdateTab, &WorldSession::HandleGuildBankUpdateTab); - DEFINE_HANDLER(CMSG_GUILD_BANK_WITHDRAW_MONEY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankWithdrawMoney, &WorldSession::HandleGuildBankWithdrawMoney); - DEFINE_HANDLER(CMSG_GUILD_CHALLENGE_UPDATE_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildChallengeUpdateRequest, &WorldSession::HandleGuildChallengeUpdateRequest); + DEFINE_HANDLER(CMSG_GUILD_BANK_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankActivate, &WorldSession::HandleGuildBankActivate); + DEFINE_HANDLER(CMSG_GUILD_BANK_BUY_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankBuyTab, &WorldSession::HandleGuildBankBuyTab); + DEFINE_HANDLER(CMSG_GUILD_BANK_DEPOSIT_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankDepositMoney, &WorldSession::HandleGuildBankDepositMoney); + DEFINE_HANDLER(CMSG_GUILD_BANK_LOG_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankLogQuery, &WorldSession::HandleGuildBankLogQuery); + DEFINE_HANDLER(CMSG_GUILD_BANK_QUERY_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankQueryTab, &WorldSession::HandleGuildBankQueryTab); + DEFINE_HANDLER(CMSG_GUILD_BANK_REMAINING_WITHDRAW_MONEY_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankRemainingWithdrawMoneyQuery, &WorldSession::HandleGuildBankMoneyWithdrawn); + DEFINE_HANDLER(CMSG_GUILD_BANK_SET_TAB_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankSetTabText, &WorldSession::HandleGuildBankSetTabText); + DEFINE_HANDLER(CMSG_GUILD_BANK_SWAP_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankSwapItems, &WorldSession::HandleGuildBankSwapItems); + DEFINE_HANDLER(CMSG_GUILD_BANK_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankTextQuery, &WorldSession::HandleGuildBankTextQuery); + DEFINE_HANDLER(CMSG_GUILD_BANK_UPDATE_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankUpdateTab, &WorldSession::HandleGuildBankUpdateTab); + DEFINE_HANDLER(CMSG_GUILD_BANK_WITHDRAW_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildBankWithdrawMoney, &WorldSession::HandleGuildBankWithdrawMoney); + DEFINE_HANDLER(CMSG_GUILD_CHALLENGE_UPDATE_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildChallengeUpdateRequest, &WorldSession::HandleGuildChallengeUpdateRequest); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_CHANGE_NAME_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_GUILD_DECLINE_INVITATION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDeclineInvitation, &WorldSession::HandleGuildDeclineInvitation); - DEFINE_HANDLER(CMSG_GUILD_DELETE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDelete, &WorldSession::HandleGuildDelete); - DEFINE_HANDLER(CMSG_GUILD_DELETE_RANK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDeleteRank, &WorldSession::HandleGuildDeleteRank); - DEFINE_HANDLER(CMSG_GUILD_DEMOTE_MEMBER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDemoteMember, &WorldSession::HandleGuildDemoteMember); - DEFINE_HANDLER(CMSG_GUILD_EVENT_LOG_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildEventLogQuery, &WorldSession::HandleGuildEventLogQuery); + DEFINE_HANDLER(CMSG_GUILD_DECLINE_INVITATION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDeclineInvitation, &WorldSession::HandleGuildDeclineInvitation); + DEFINE_HANDLER(CMSG_GUILD_DELETE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDelete, &WorldSession::HandleGuildDelete); + DEFINE_HANDLER(CMSG_GUILD_DELETE_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDeleteRank, &WorldSession::HandleGuildDeleteRank); + DEFINE_HANDLER(CMSG_GUILD_DEMOTE_MEMBER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildDemoteMember, &WorldSession::HandleGuildDemoteMember); + DEFINE_HANDLER(CMSG_GUILD_EVENT_LOG_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildEventLogQuery, &WorldSession::HandleGuildEventLogQuery); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_GET_ACHIEVEMENT_MEMBERS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_GUILD_GET_RANKS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildGetRanks, &WorldSession::HandleGuildGetRanks); - DEFINE_HANDLER(CMSG_GUILD_GET_ROSTER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildGetRoster, &WorldSession::HandleGuildGetRoster); - DEFINE_HANDLER(CMSG_GUILD_INVITE_BY_NAME, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildInviteByName, &WorldSession::HandleGuildInviteByName); - DEFINE_HANDLER(CMSG_GUILD_LEAVE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildLeave, &WorldSession::HandleGuildLeave); + DEFINE_HANDLER(CMSG_GUILD_GET_RANKS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildGetRanks, &WorldSession::HandleGuildGetRanks); + DEFINE_HANDLER(CMSG_GUILD_GET_ROSTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildGetRoster, &WorldSession::HandleGuildGetRoster); + DEFINE_HANDLER(CMSG_GUILD_INVITE_BY_NAME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildInviteByName, &WorldSession::HandleGuildInviteByName); + DEFINE_HANDLER(CMSG_GUILD_LEAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildLeave, &WorldSession::HandleGuildLeave); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_MEMBER_SEND_SOR_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_GUILD_NEWS_UPDATE_STICKY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Guild::GuildNewsUpdateSticky, &WorldSession::HandleGuildNewsUpdateSticky); - DEFINE_HANDLER(CMSG_GUILD_OFFICER_REMOVE_MEMBER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildOfficerRemoveMember, &WorldSession::HandleGuildOfficerRemoveMember); - DEFINE_HANDLER(CMSG_GUILD_PERMISSIONS_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildPermissionsQuery, &WorldSession::HandleGuildPermissionsQuery); - DEFINE_HANDLER(CMSG_GUILD_PROMOTE_MEMBER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildPromoteMember, &WorldSession::HandleGuildPromoteMember); + DEFINE_HANDLER(CMSG_GUILD_NEWS_UPDATE_STICKY, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Guild::GuildNewsUpdateSticky, &WorldSession::HandleGuildNewsUpdateSticky); + DEFINE_HANDLER(CMSG_GUILD_OFFICER_REMOVE_MEMBER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildOfficerRemoveMember, &WorldSession::HandleGuildOfficerRemoveMember); + DEFINE_HANDLER(CMSG_GUILD_PERMISSIONS_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildPermissionsQuery, &WorldSession::HandleGuildPermissionsQuery); + DEFINE_HANDLER(CMSG_GUILD_PROMOTE_MEMBER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildPromoteMember, &WorldSession::HandleGuildPromoteMember); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_QUERY_MEMBERS_FOR_RECIPE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_QUERY_MEMBER_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_GUILD_QUERY_NEWS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Guild::GuildQueryNews, &WorldSession::HandleGuildQueryNews); + DEFINE_HANDLER(CMSG_GUILD_QUERY_NEWS, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Guild::GuildQueryNews, &WorldSession::HandleGuildQueryNews); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_QUERY_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_REPLACE_GUILD_MASTER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_SET_ACHIEVEMENT_TRACKING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetAchievementTracking); - DEFINE_HANDLER(CMSG_GUILD_SET_FOCUSED_ACHIEVEMENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Achievement::GuildSetFocusedAchievement, &WorldSession::HandleGuildSetFocusedAchievement); - DEFINE_HANDLER(CMSG_GUILD_SET_GUILD_MASTER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildSetGuildMaster, &WorldSession::HandleGuildSetGuildMaster); - DEFINE_HANDLER(CMSG_GUILD_SET_MEMBER_NOTE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildSetMemberNote, &WorldSession::HandleGuildSetMemberNote); - DEFINE_HANDLER(CMSG_GUILD_SET_RANK_PERMISSIONS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildSetRankPermissions, &WorldSession::HandleGuildSetRankPermissions); + DEFINE_HANDLER(CMSG_GUILD_SET_FOCUSED_ACHIEVEMENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Achievement::GuildSetFocusedAchievement, &WorldSession::HandleGuildSetFocusedAchievement); + DEFINE_HANDLER(CMSG_GUILD_SET_GUILD_MASTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildSetGuildMaster, &WorldSession::HandleGuildSetGuildMaster); + DEFINE_HANDLER(CMSG_GUILD_SET_MEMBER_NOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildSetMemberNote, &WorldSession::HandleGuildSetMemberNote); + DEFINE_HANDLER(CMSG_GUILD_SET_RANK_PERMISSIONS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildSetRankPermissions, &WorldSession::HandleGuildSetRankPermissions); DEFINE_OPCODE_HANDLER_OLD(CMSG_GUILD_SHIFT_RANK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_GUILD_UPDATE_INFO_TEXT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildUpdateInfoText, &WorldSession::HandleGuildUpdateInfoText); - DEFINE_HANDLER(CMSG_GUILD_UPDATE_MOTD_TEXT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildUpdateMotdText, &WorldSession::HandleGuildUpdateMotdText); - DEFINE_OPCODE_HANDLER_OLD(CMSG_HEARTH_AND_RESURRECT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleHearthAndResurrect ); + DEFINE_HANDLER(CMSG_GUILD_UPDATE_INFO_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildUpdateInfoText, &WorldSession::HandleGuildUpdateInfoText); + DEFINE_HANDLER(CMSG_GUILD_UPDATE_MOTD_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::GuildUpdateMotdText, &WorldSession::HandleGuildUpdateMotdText); + DEFINE_HANDLER(CMSG_HEARTH_AND_RESURRECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Battleground::HearthAndResurrect, &WorldSession::HandleHearthAndResurrect); DEFINE_HANDLER(CMSG_IGNORE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::IgnoreTrade, &WorldSession::HandleIgnoreTradeOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_INCREASE_CAST_TIME_FOR_SPELL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_INITIATE_ROLE_POLL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRolePollBeginOpcode); DEFINE_HANDLER(CMSG_INITIATE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::InitiateTrade, &WorldSession::HandleInitiateTradeOpcode); - DEFINE_HANDLER(CMSG_INSPECT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Inspect::Inspect, &WorldSession::HandleInspectOpcode); - DEFINE_HANDLER(CMSG_INSPECT_PVP, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Inspect::InspectPVPRequest, &WorldSession::HandleInspectPVP); + DEFINE_HANDLER(CMSG_INSPECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Inspect::Inspect, &WorldSession::HandleInspectOpcode); + DEFINE_HANDLER(CMSG_INSPECT_PVP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Inspect::InspectPVPRequest, &WorldSession::HandleInspectPVP); DEFINE_OPCODE_HANDLER_OLD(CMSG_INSTANCE_LOCK_RESPONSE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleInstanceLockResponse); DEFINE_OPCODE_HANDLER_OLD(CMSG_ITEM_PURCHASE_REFUND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefund ); DEFINE_OPCODE_HANDLER_OLD(CMSG_ITEM_TEXT_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleItemTextQuery ); @@ -516,35 +521,35 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_MOVE_CHANGE_VEHICLE_SEATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Vehicle::MoveChangeVehicleSeats, &WorldSession::HandleMoveChangeVehicleSeats); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_CHARM_TELEPORT_CHEAT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_MOVE_DISMISS_VEHICLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Vehicle::MoveDismissVehicle, &WorldSession::HandleMoveDismissVehicle); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_ENABLE_SWIM_TO_FLY_TRANS_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_HANDLER(CMSG_MOVE_ENABLE_SWIM_TO_FLY_TRANS_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementAckMessage, &WorldSession::HandleMovementAckMessage); DEFINE_HANDLER(CMSG_MOVE_FALL_LAND, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); DEFINE_HANDLER(CMSG_MOVE_FALL_RESET, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FEATHER_FALL_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleFeatherFallAck ); + DEFINE_HANDLER(CMSG_MOVE_FEATHER_FALL_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementAckMessage, &WorldSession::HandleMovementAckMessage); DEFINE_HANDLER(CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); DEFINE_HANDLER(CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); DEFINE_HANDLER(CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FORCE_ROOT_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveRootAck ); + DEFINE_HANDLER(CMSG_MOVE_FORCE_ROOT_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementAckMessage, &WorldSession::HandleMovementAckMessage); DEFINE_HANDLER(CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); DEFINE_HANDLER(CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); DEFINE_HANDLER(CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); DEFINE_HANDLER(CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); DEFINE_HANDLER(CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_FORCE_UNROOT_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveUnRootAck ); + DEFINE_HANDLER(CMSG_MOVE_FORCE_UNROOT_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementAckMessage, &WorldSession::HandleMovementAckMessage); DEFINE_HANDLER(CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementSpeedAck, &WorldSession::HandleForceSpeedChangeAck); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_GRAVITY_DISABLE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_GRAVITY_ENABLE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::Handle_NULL ); + DEFINE_HANDLER(CMSG_MOVE_GRAVITY_DISABLE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementAckMessage, &WorldSession::HandleMovementAckMessage); + DEFINE_HANDLER(CMSG_MOVE_GRAVITY_ENABLE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementAckMessage, &WorldSession::HandleMovementAckMessage); DEFINE_HANDLER(CMSG_MOVE_HEARTBEAT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_HOVER_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveHoverAck ); + DEFINE_HANDLER(CMSG_MOVE_HOVER_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementAckMessage, &WorldSession::HandleMovementAckMessage); DEFINE_HANDLER(CMSG_MOVE_JUMP, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); DEFINE_HANDLER(CMSG_MOVE_KNOCK_BACK_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementAckMessage, &WorldSession::HandleMoveKnockBackAck); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_REMOVE_MOVEMENT_FORCES, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_REMOVE_MOVEMENT_FORCE_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_SET_CAN_FLY_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveSetCanFlyAckOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_SET_CAN_TURN_WHILE_FALLING_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::Handle_NULL ); + DEFINE_HANDLER(CMSG_MOVE_SET_CAN_FLY_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementAckMessage, &WorldSession::HandleMovementAckMessage); + DEFINE_HANDLER(CMSG_MOVE_SET_CAN_TURN_WHILE_FALLING_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementAckMessage, &WorldSession::HandleMovementAckMessage); DEFINE_HANDLER(CMSG_MOVE_SET_COLLISION_HEIGHT_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MoveSetCollisionHeightAck, &WorldSession::HandleSetCollisionHeightAck); DEFINE_HANDLER(CMSG_MOVE_SET_FACING, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); DEFINE_HANDLER(CMSG_MOVE_SET_FLY, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_SET_IGNORE_MOVEMENT_FORCES_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::Handle_NULL ); + DEFINE_HANDLER(CMSG_MOVE_SET_IGNORE_MOVEMENT_FORCES_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementAckMessage, &WorldSession::HandleMovementAckMessage); DEFINE_HANDLER(CMSG_MOVE_SET_PITCH, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_SET_RELATIVE_POSITION, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_MOVE_SET_RUN_MODE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); @@ -570,16 +575,16 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_MOVE_STOP_TURN, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes); DEFINE_HANDLER(CMSG_MOVE_TELEPORT_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MoveTeleportAck, &WorldSession::HandleMoveTeleportAck); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_TELEPORT_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_TIME_SKIPPED, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleMoveTimeSkippedOpcode ); + DEFINE_HANDLER(CMSG_MOVE_TIME_SKIPPED, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Movement::MoveTimeSkipped, &WorldSession::HandleMoveTimeSkippedOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_TOGGLE_COLLISION_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_WATER_WALK_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveWaterWalkAck ); + DEFINE_HANDLER(CMSG_MOVE_WATER_WALK_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MovementAckMessage, &WorldSession::HandleMovementAckMessage); DEFINE_OPCODE_HANDLER_OLD(CMSG_NEUTRAL_PLAYER_SELECT_FACTION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_NEXT_CINEMATIC_CAMERA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleNextCinematicCamera ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_OBJECT_UPDATE_FAILED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleObjectUpdateFailedOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_OBJECT_UPDATE_RESCUED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_OFFER_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Petition::OfferPetition, &WorldSession::HandleOfferPetition); + DEFINE_HANDLER(CMSG_OBJECT_UPDATE_FAILED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::ObjectUpdateFailed, &WorldSession::HandleObjectUpdateFailedOpcode); + DEFINE_HANDLER(CMSG_OBJECT_UPDATE_RESCUED, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Misc::ObjectUpdateRescued, &WorldSession::HandleObjectUpdateRescuedOpcode); + DEFINE_HANDLER(CMSG_OFFER_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::OfferPetition, &WorldSession::HandleOfferPetition); DEFINE_OPCODE_HANDLER_OLD(CMSG_OPENING_CINEMATIC, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOpeningCinematic ); - DEFINE_HANDLER(CMSG_OPEN_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::OpenItem, &WorldSession::HandleOpenItemOpcode ); + DEFINE_HANDLER(CMSG_OPEN_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::OpenItem, &WorldSession::HandleOpenItemOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_OPEN_MISSION_NPC, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_OPEN_SHIPMENT_NPC, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_OPEN_TRADESKILL_NPC, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -587,10 +592,10 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_INVITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteResponseOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_UNINVITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteOpcode ); - DEFINE_HANDLER(CMSG_PETITION_BUY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionBuy, &WorldSession::HandlePetitionBuy); - DEFINE_HANDLER(CMSG_PETITION_RENAME_GUILD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionRenameGuild, &WorldSession::HandlePetitionRenameGuild); - DEFINE_HANDLER(CMSG_PETITION_SHOW_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionShowList, &WorldSession::HandlePetitionShowList); - DEFINE_HANDLER(CMSG_PETITION_SHOW_SIGNATURES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionShowSignatures, &WorldSession::HandlePetitionShowSignatures); + DEFINE_HANDLER(CMSG_PETITION_BUY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionBuy, &WorldSession::HandlePetitionBuy); + DEFINE_HANDLER(CMSG_PETITION_RENAME_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionRenameGuild, &WorldSession::HandlePetitionRenameGuild); + DEFINE_HANDLER(CMSG_PETITION_SHOW_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionShowList, &WorldSession::HandlePetitionShowList); + DEFINE_HANDLER(CMSG_PETITION_SHOW_SIGNATURES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionShowSignatures, &WorldSession::HandlePetitionShowSignatures); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_ABANDON, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAbandon ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_ACTION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAction ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_BATTLE_FINAL_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -603,7 +608,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_BATTLE_REQUEST_WILD, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_BATTLE_SCRIPT_ERROR_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_CANCEL_AURA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCancelAuraOpcode ); - DEFINE_HANDLER(CMSG_PET_CAST_SPELL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Spells::PetCastSpell, &WorldSession::HandlePetCastSpellOpcode); + DEFINE_HANDLER(CMSG_PET_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::PetCastSpell, &WorldSession::HandlePetCastSpellOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_RENAME, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetRename ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_SET_ACTION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetSetAction ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_SPELL_AUTOCAST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetSpellAutocastOpcode ); @@ -612,28 +617,28 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_PLAYER_LOGIN, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::PlayerLogin, &WorldSession::HandlePlayerLoginOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_PROTOCOL_MISMATCH, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_PUSH_QUEST_TO_PARTY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePushQuestToParty ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PVP_LOG_DATA, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandlePVPLogDataOpcode ); + DEFINE_HANDLER(CMSG_PVP_LOG_DATA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Battleground::PVPLogDataRequest, &WorldSession::HandlePVPLogDataOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_BATTLE_PET_NAME, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_QUERY_CORPSE_LOCATION_FROM_CLIENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryCorpseLocationFromClient, &WorldSession::HandleQueryCorpseLocation); - DEFINE_HANDLER(CMSG_QUERY_CORPSE_TRANSPORT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryCorpseTransport, &WorldSession::HandleQueryCorpseTransport); + DEFINE_HANDLER(CMSG_QUERY_CORPSE_LOCATION_FROM_CLIENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryCorpseLocationFromClient, &WorldSession::HandleQueryCorpseLocation); + DEFINE_HANDLER(CMSG_QUERY_CORPSE_TRANSPORT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryCorpseTransport, &WorldSession::HandleQueryCorpseTransport); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_COUNTDOWN_TIMER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_QUERY_CREATURE, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Query::QueryCreature, &WorldSession::HandleCreatureQuery); DEFINE_HANDLER(CMSG_QUERY_GAME_OBJECT, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Query::QueryGameObject, &WorldSession::HandleGameObjectQueryOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_GARRISON_CREATURE_NAME, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_QUERY_GUILD_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::QueryGuildInfo, &WorldSession::HandleGuildQueryOpcode); - DEFINE_HANDLER(CMSG_QUERY_INSPECT_ACHIEVEMENTS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Inspect::QueryInspectAchievements, &WorldSession::HandleQueryInspectAchievements); + DEFINE_HANDLER(CMSG_QUERY_GUILD_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::QueryGuildInfo, &WorldSession::HandleGuildQueryOpcode); + DEFINE_HANDLER(CMSG_QUERY_INSPECT_ACHIEVEMENTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Inspect::QueryInspectAchievements, &WorldSession::HandleQueryInspectAchievements); DEFINE_HANDLER(CMSG_QUERY_NEXT_MAIL_TIME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailQueryNextMailTime, &WorldSession::HandleQueryNextMailTime); DEFINE_HANDLER(CMSG_QUERY_NPC_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryNPCText, &WorldSession::HandleNpcTextQueryOpcode); - DEFINE_HANDLER(CMSG_QUERY_PAGE_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryPageText, &WorldSession::HandlePageTextQueryOpcode); - DEFINE_HANDLER(CMSG_QUERY_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Petition::QueryPetition, &WorldSession::HandleQueryPetition); + DEFINE_HANDLER(CMSG_QUERY_PAGE_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryPageText, &WorldSession::HandleQueryPageText); + DEFINE_HANDLER(CMSG_QUERY_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::QueryPetition, &WorldSession::HandleQueryPetition); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_PET_NAME, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetNameQuery ); DEFINE_HANDLER(CMSG_QUERY_PLAYER_NAME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryPlayerName, &WorldSession::HandleNameQueryOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_QUEST_COMPLETION_NPCS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestNPCQuery ); + DEFINE_HANDLER(CMSG_QUERY_QUEST_COMPLETION_NPCS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryQuestCompletionNPCs, &WorldSession::HandleQueryQuestCompletionNPCs); DEFINE_HANDLER(CMSG_QUERY_QUEST_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QueryQuestInfo, &WorldSession::HandleQuestQueryOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_REALM_NAME, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_SCENARIO_POI, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_QUERY_TIME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryTime, &WorldSession::HandleQueryTimeOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_QUERY_VOID_STORAGE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleVoidStorageQuery ); + DEFINE_HANDLER(CMSG_QUERY_VOID_STORAGE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::VoidStorage::QueryVoidStorage, &WorldSession::HandleVoidStorageQuery); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_CONFIRM_ACCEPT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestConfirmAccept ); DEFINE_HANDLER(CMSG_QUEST_GIVER_ACCEPT_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverAcceptQuest, &WorldSession::HandleQuestgiverAcceptQuestOpcode); DEFINE_HANDLER(CMSG_QUEST_GIVER_CHOOSE_REWARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverChooseReward, &WorldSession::HandleQuestgiverChooseRewardOpcode); @@ -649,7 +654,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEUED_MESSAGES_END, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_RANDOM_ROLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::RandomRollClient, &WorldSession::HandleRandomRollOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_READY_CHECK_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_READ_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleReadItem ); + DEFINE_HANDLER(CMSG_READ_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::ReadItem, &WorldSession::HandleReadItem); DEFINE_HANDLER(CMSG_RECLAIM_CORPSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::ReclaimCorpse, &WorldSession::HandleReclaimCorpse); DEFINE_OPCODE_HANDLER_OLD(CMSG_RECRUIT_A_FRIEND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REDEEM_WOW_TOKEN_CONFIRM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -661,13 +666,13 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_REPORT_PVP_PLAYER_AFK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleReportPvPAFK ); DEFINE_HANDLER(CMSG_REQUEST_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::ClientConfig::RequestAccountData, &WorldSession::HandleRequestAccountData); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_BATTLEFIELD_STATUS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestBattlefieldStatusOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_CATEGORY_COOLDOWNS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleRequestCategoryCooldowns ); + DEFINE_HANDLER(CMSG_REQUEST_CATEGORY_COOLDOWNS, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Spells::RequestCategoryCooldowns, &WorldSession::HandleRequestCategoryCooldowns); DEFINE_HANDLER(CMSG_REQUEST_CEMETERY_LIST, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Misc::RequestCemeteryList, &WorldSession::HandleRequestCemeteryList); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_CONQUEST_FORMULA_CONSTANTS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_FORCED_REACTIONS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_REQUEST_GUILD_PARTY_STATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::RequestGuildPartyState, &WorldSession::HandleGuildRequestPartyState); - DEFINE_HANDLER(CMSG_REQUEST_GUILD_REWARDS_LIST, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Guild::RequestGuildRewardsList, &WorldSession::HandleRequestGuildRewardsList); - DEFINE_HANDLER(CMSG_REQUEST_HONOR_STATS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Inspect::RequestHonorStats, &WorldSession::HandleRequestHonorStatsOpcode); + DEFINE_HANDLER(CMSG_REQUEST_FORCED_REACTIONS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Reputation::RequestForcedReactions, &WorldSession::HandleRequestForcedReactionsOpcode); + DEFINE_HANDLER(CMSG_REQUEST_GUILD_PARTY_STATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::RequestGuildPartyState, &WorldSession::HandleGuildRequestPartyState); + DEFINE_HANDLER(CMSG_REQUEST_GUILD_REWARDS_LIST, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Guild::RequestGuildRewardsList, &WorldSession::HandleRequestGuildRewardsList); + DEFINE_HANDLER(CMSG_REQUEST_HONOR_STATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Inspect::RequestHonorStats, &WorldSession::HandleRequestHonorStatsOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_LFG_LIST_BLACKLIST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PARTY_JOIN_UPDATES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupRequestJoinUpdates); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PARTY_MEMBER_STATS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPartyMemberStatsOpcode); @@ -689,11 +694,11 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_REVERT_MONUMENT_APPEARANCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_RIDE_VEHICLE_INTERACT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Vehicle::RideVehicleInteract, &WorldSession::HandleRideVehicleInteract); DEFINE_OPCODE_HANDLER_OLD(CMSG_SAVE_CUF_PROFILES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleSaveCUFProfiles ); - DEFINE_HANDLER(CMSG_SAVE_EQUIPMENT_SET, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::EquipmentSet::SaveEquipmentSet, &WorldSession::HandleEquipmentSetSave); - DEFINE_HANDLER(CMSG_SAVE_GUILD_EMBLEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Guild::SaveGuildEmblem, &WorldSession::HandleSaveGuildEmblem); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SCENE_PLAYBACK_CANCELED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SCENE_PLAYBACK_COMPLETE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SCENE_TRIGGER_EVENT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_HANDLER(CMSG_SAVE_EQUIPMENT_SET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::EquipmentSet::SaveEquipmentSet, &WorldSession::HandleEquipmentSetSave); + DEFINE_HANDLER(CMSG_SAVE_GUILD_EMBLEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::SaveGuildEmblem, &WorldSession::HandleSaveGuildEmblem); + DEFINE_HANDLER(CMSG_SCENE_PLAYBACK_CANCELED, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Scenes::ScenePlaybackCanceled, &WorldSession::HandleScenePlaybackCanceled); + DEFINE_HANDLER(CMSG_SCENE_PLAYBACK_COMPLETE, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Scenes::ScenePlaybackComplete, &WorldSession::HandleScenePlaybackComplete); + DEFINE_HANDLER(CMSG_SCENE_TRIGGER_EVENT, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Scenes::SceneTriggerEvent, &WorldSession::HandleSceneTriggerEvent); DEFINE_OPCODE_HANDLER_OLD(CMSG_SELF_RES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSelfResOpcode ); DEFINE_HANDLER(CMSG_SELL_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::SellItem, &WorldSession::HandleSellItemOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_SELL_WOW_TOKEN_CONFIRM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -745,10 +750,10 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_SET_TRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::SetTradeItem, &WorldSession::HandleSetTradeItemOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_USING_PARTY_GARRISON, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_WATCHED_FACTION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetWatchedFactionOpcode ); - DEFINE_HANDLER(CMSG_SHOWING_CLOAK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Character::ShowingCloak, &WorldSession::HandleShowingCloakOpcode); - DEFINE_HANDLER(CMSG_SHOWING_HELM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Character::ShowingHelm, &WorldSession::HandleShowingHelmOpcode); + DEFINE_HANDLER(CMSG_SHOWING_CLOAK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::ShowingCloak, &WorldSession::HandleShowingCloakOpcode); + DEFINE_HANDLER(CMSG_SHOWING_HELM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::ShowingHelm, &WorldSession::HandleShowingHelmOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_SHOW_TRADE_SKILL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_HANDLER(CMSG_SIGN_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Petition::SignPetition, &WorldSession::HandleSignPetition); + DEFINE_HANDLER(CMSG_SIGN_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::SignPetition, &WorldSession::HandleSignPetition); DEFINE_OPCODE_HANDLER_OLD(CMSG_SILENCE_PARTY_TALKER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_SOCKET_GEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSocketOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_SORT_BAGS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -769,8 +774,8 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_SWAP_INV_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::SwapInvItem, &WorldSession::HandleSwapInvItemOpcode); DEFINE_HANDLER(CMSG_SWAP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::SwapItem, &WorldSession::HandleSwapItem); DEFINE_OPCODE_HANDLER_OLD(CMSG_SWAP_SUB_GROUPS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupSwapSubGroupOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SWAP_VOID_ITEM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleVoidSwapItem ); - DEFINE_HANDLER(CMSG_TABARD_VENDOR_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleTabardVendorActivateOpcode); + DEFINE_HANDLER(CMSG_SWAP_VOID_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::VoidStorage::SwapVoidItem, &WorldSession::HandleVoidSwapItem); + DEFINE_HANDLER(CMSG_TABARD_VENDOR_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleTabardVendorActivateOpcode); DEFINE_HANDLER(CMSG_TALK_TO_GOSSIP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleGossipHelloOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_TAXI_NODE_STATUS_QUERY, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleTaxiNodeStatusQueryOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_TAXI_QUERY_AVAILABLE_NODES, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleTaxiQueryAvailableNodes ); @@ -787,36 +792,36 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_TRAINER_BUY_SPELL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerBuySpellOpcode ); DEFINE_HANDLER(CMSG_TRAINER_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleTrainerListOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_TRANSMOGRIFY_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTransmogrifyItems ); - DEFINE_HANDLER(CMSG_TURN_IN_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Petition::TurnInPetition, &WorldSession::HandleTurnInPetition); + DEFINE_HANDLER(CMSG_TURN_IN_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::TurnInPetition, &WorldSession::HandleTurnInPetition); DEFINE_HANDLER(CMSG_TUTORIAL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::TutorialSetFlag, &WorldSession::HandleTutorialFlag); DEFINE_OPCODE_HANDLER_OLD(CMSG_TWITTER_CHECK_STATUS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_TWITTER_CONNECT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_TWITTER_DISCONNECT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_TWITTER_POST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_UI_TIME_REQUEST, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Misc::UITimeRequest, &WorldSession::HandleUITimeRequest); - DEFINE_HANDLER(CMSG_UNACCEPT_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Trade::UnacceptTrade, &WorldSession::HandleUnacceptTradeOpcode); + DEFINE_HANDLER(CMSG_UNACCEPT_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::UnacceptTrade, &WorldSession::HandleUnacceptTradeOpcode); DEFINE_HANDLER(CMSG_UNDELETE_CHARACTER, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::UndeleteCharacter, &WorldSession::HandleCharUndeleteOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_UNLEARN_SKILL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUnlearnSkillOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_UNLEARN_SPECIALIZATION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_UNLOCK_VOID_STORAGE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleVoidStorageUnlock ); + DEFINE_HANDLER(CMSG_UNLOCK_VOID_STORAGE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::VoidStorage::UnlockVoidStorage, &WorldSession::HandleVoidStorageUnlock); DEFINE_HANDLER(CMSG_UPDATE_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::ClientConfig::UserClientUpdateAccountData, &WorldSession::HandleUpdateAccountData); DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_CLIENT_SETTINGS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_MISSILE_TRAJECTORY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateMissileTrajectory ); DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_RAID_TARGET, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidTargetUpdateOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_WOW_TOKEN_AUCTIONABLE_LIST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_HANDLER(CMSG_UPDATE_WOW_TOKEN_AUCTIONABLE_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Token::UpdateListedAuctionableTokens, &WorldSession::HandleUpdateListedAuctionableTokens); DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_WOW_TOKEN_COUNT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_UPGRADE_GARRISON, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_UPGRADE_ITEM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_USED_FOLLOW, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_USE_CRITTER_ITEM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_USE_EQUIPMENT_SET, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetUse ); + DEFINE_HANDLER(CMSG_USE_EQUIPMENT_SET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::EquipmentSet::UseEquipmentSet, &WorldSession::HandleUseEquipmentSet); DEFINE_HANDLER(CMSG_USE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::UseItem, &WorldSession::HandleUseItemOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_USE_TOY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_HANDLER(CMSG_VIOLENCE_LEVEL, STATUS_AUTHED, PROCESS_INPLACE, WorldPackets::Misc::ViolenceLevel, &WorldSession::HandleViolenceLevel); DEFINE_OPCODE_HANDLER_OLD(CMSG_VOICE_ADD_IGNORE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_VOICE_DEL_IGNORE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_VOICE_SESSION_ENABLE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleVoiceSessionEnableOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_VOID_STORAGE_TRANSFER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleVoidStorageTransfer ); + DEFINE_HANDLER(CMSG_VOID_STORAGE_TRANSFER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::VoidStorage::VoidStorageTransfer, &WorldSession::HandleVoidStorageTransfer); DEFINE_OPCODE_HANDLER_OLD(CMSG_WARDEN_DATA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleWardenDataOpcode ); DEFINE_HANDLER(CMSG_WHO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Who::WhoRequestPkt, &WorldSession::HandleWhoOpcode); DEFINE_HANDLER(CMSG_WHO_IS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Who::WhoIsRequest, &WorldSession::HandleWhoIsOpcode); @@ -828,6 +833,7 @@ void OpcodeTable::Initialize() #undef DEFINE_HANDLER #define DEFINE_SERVER_OPCODE_HANDLER(opcode, status, con) \ + static_assert(status == STATUS_NEVER || status == STATUS_UNHANDLED, "Invalid status for server opcode"); \ ValidateAndSetServerOpcode(opcode, #opcode, status, con) DEFINE_SERVER_OPCODE_HANDLER(SMSG_ABORT_NEW_WORLD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -835,8 +841,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_DATA_TIMES, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_MOUNT_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_TOYS_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_EARNED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_DELETED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_EARNED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACTIVATE_TAXI_REPLY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADDON_INFO, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADD_BATTLENET_FRIEND_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -849,7 +855,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_AI_REACTION, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_ACCOUNT_CRITERIA, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_ACHIEVEMENT_DATA, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_GUILD_ACHIEVEMENTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_GUILD_ACHIEVEMENTS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARCHAEOLOGY_SURVERY_CAST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_SPIRIT_HEALER_TIME, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_DENIED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -863,17 +869,17 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACK_STOP, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACK_SWING_ERROR, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACK_SWING_LANDED_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_CLOSED_NOTIFICATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_COMMAND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_HELLO_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_BIDDER_ITEMS_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_ITEMS_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_OWNER_ITEMS_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_PENDING_SALES_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OUTBID_NOTIFICATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OWNER_BID_NOTIFICATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_REPLICATE_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_WON_NOTIFICATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_CLOSED_NOTIFICATION, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_COMMAND_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_HELLO_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_BIDDER_ITEMS_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_ITEMS_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_OWNER_ITEMS_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_PENDING_SALES_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OUTBID_NOTIFICATION, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OWNER_BID_NOTIFICATION, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_REPLICATE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_WON_NOTIFICATION, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AURA_POINTS_DEPLETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AURA_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUTH_CHALLENGE, STATUS_NEVER, CONNECTION_TYPE_REALM); @@ -1037,7 +1043,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_TRANSPORT_QUERY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CREATE_CHAR, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CREATE_SHIPMENT_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_CRITERIA_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_CRITERIA_DELETED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CRITERIA_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CROSSED_INEBRIATION_THRESHOLD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CUSTOM_LOAD_SCREEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1068,7 +1074,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_OUT_OF_BOUNDS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_REQUESTED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_WINNER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_DURABILITY_DAMAGE_DEATH, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_DURABILITY_DAMAGE_DEATH, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_EMOTE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENABLE_BARBER_SHOP, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENCHANTMENT_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1076,7 +1082,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENCOUNTER_START, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENUM_CHARACTERS_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENVIRONMENTAL_DAMAGE_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_ID, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_ID, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_EXPECTED_SPAM_RECORDS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_EXPLORATION_EXPERIENCE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_FACTION_BONUS_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1094,7 +1100,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_FRIEND_STATUS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_ACTIVATE_ANIM_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_CUSTOM_ANIM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_DESPAWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_DESPAWN, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_PLAY_SPELL_VISUAL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_PLAY_SPELL_VISUAL_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_RESET_STATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1105,9 +1111,11 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_ADD_MISSION_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_ASSIGN_FOLLOWER_TO_BUILDING_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_BUILDING_ACTIVATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_BUILDING_LANDMARKS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_BUILDING_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_BUILDING_SET_ACTIVE_SPECIALIZATION_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_COMPLETE_MISSION_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_CREATE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_DELETE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_FOLLOWER_CHANGED_ITEM_LEVEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_FOLLOWER_CHANGED_ITEM_LEVEL2, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1126,6 +1134,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_PLACE_BUILDING_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_PLOT_PLACED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_PLOT_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_RECALL_PORTAL_LAST_USED_TIME, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_RECALL_PORTAL_USED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_RECRUITMENT_FOLLOWERS_GENERATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_RECRUIT_FOLLOWER_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_REMOTE_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1155,63 +1165,63 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOD_MODE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_COMPLETE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_MESSAGE, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_POI, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_POI, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_ACTION_THROTTLED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_DECLINE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_DESTROYED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_NEW_LEADER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_UNINVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_EARNED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DELETED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_EARNED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_MEMBERS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_LOG_QUERY_RESULTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_QUERY_RESULTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_REMAINING_WITHDRAW_MONEY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_TEXT_QUERY_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_LOG_QUERY_RESULTS, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_QUERY_RESULTS, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_REMAINING_WITHDRAW_MONEY, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_TEXT_QUERY_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_COMPLETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHANGE_NAME_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DELETED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_BANK_CONTENTS_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_BANK_MONEY_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_DISBANDED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_LOG_QUERY_RESULTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_MOTD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_NEW_LEADER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PLAYER_JOINED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PLAYER_LEFT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PRESENCE_CHANGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_RANKS_UPDATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_RANK_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_TAB_ADDED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_BANK_MONEY_CHANGED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_DISBANDED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_LOG_QUERY_RESULTS, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_MOTD, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_NEW_LEADER, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PLAYER_JOINED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PLAYER_LEFT, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PRESENCE_CHANGE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_RANKS_UPDATED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_RANK_CHANGED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_TAB_ADDED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_TAB_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_TAB_MODIFIED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_TAB_TEXT_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_FLAGGED_FOR_RENAME, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_TAB_MODIFIED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_TAB_TEXT_CHANGED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_FLAGGED_FOR_RENAME, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_INVITE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_INVITE_DECLINED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_INVITE_EXPIRED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_KNOWN_RECIPES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBERS_WITH_RECIPE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_DAILY_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_DAILY_RESET, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_RECIPES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_UPDATE_NOTE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_UPDATE_NOTE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MOVE_STARTING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NAME_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PARTY_STATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RANKS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PARTY_STATE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RANKS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_REACTION_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REWARD_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ROSTER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ROSTER_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_SEND_RANK_CHANGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REWARD_LIST, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ROSTER, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ROSTER_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_SEND_RANK_CHANGE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_HEALTH_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_HIGHEST_THREAT_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_NOTIFY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1220,9 +1230,9 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIALIZE_FACTIONS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SETUP, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INIT_WORLD_STATES, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_HONOR_STATS, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_PVP, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_HONOR_STATS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_PVP, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_RESULT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_CHANGE_PRIORITY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_DISENGAGE_UNIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_END, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1249,7 +1259,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_ENCHANT_TIME_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_EXPIRE_PURCHASE_REFUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_PURCHASE_REFUND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_PUSH_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_PUSH_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_TIME_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_KICK_REASON, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LEARNED_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); @@ -1418,7 +1428,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_OPEN_SHIPMENT_NPC_FROM_GOSSIP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_OPEN_SHIPMENT_NPC_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_OVERRIDE_LIGHT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PAGE_TEXT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PAGE_TEXT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_COMMAND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_KILL_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1427,10 +1437,10 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_PAUSE_MIRROR_TIMER, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PENDING_RAID_LOCK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_ALREADY_SIGNED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_RENAME_GUILD_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOW_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOW_SIGNATURES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SIGN_RESULTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_RENAME_GUILD_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOW_LIST, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOW_SIGNATURES, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SIGN_RESULTS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_ACTION_FEEDBACK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_ACTION_SOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_ADDED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1466,9 +1476,9 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_PHASE_SHIFT_CHANGE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYED_TIME, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_BOUND, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_SAVE_GUILD_EMBLEM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_SAVE_GUILD_EMBLEM, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_SKINNED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_TABARD_VENDOR_ACTIVATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_TABARD_VENDOR_ACTIVATE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_MUSIC, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_OBJECT_SOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_ONE_SHOT_ANIM_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1486,23 +1496,24 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_PROC_RESIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PROPOSE_LEVEL_GRANT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_CREDIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_LOG_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_LOG_DATA, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_OPTIONS_ENABLED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_SEASON, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_BATTLE_PET_NAME_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_CREATURE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_GAME_OBJECT_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_GUILD_INFO_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_GARRISON_CREATURE_NAME_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_GUILD_INFO_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_ITEM_TEXT_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_NPC_TEXT_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_PAGE_TEXT_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_PETITION_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_PETITION_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_PET_NAME_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_PLAYER_NAME_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_QUEST_INFO_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_TIME_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_COMPLETION_NPC_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_CONFIRM_ACCEPT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_COMPLETION_NPC_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_CONFIRM_ACCEPT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_FORCE_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_INVALID_QUEST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_OFFER_REWARD_MESSAGE, STATUS_NEVER, CONNECTION_TYPE_REALM); @@ -1519,7 +1530,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_ADD_CREDIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_ADD_CREDIT_SIMPLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_ADD_PVP_CREDIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_COMPLETE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_UPDATE_FAILED_TIMER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAF_EMAIL_ENABLED_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1532,8 +1543,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_COMPLETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_STARTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_READ_ITEM_RESULT_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_READ_ITEM_RESULT_OK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_READ_ITEM_RESULT_FAILED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_READ_ITEM_RESULT_OK, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REALM_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REALM_SPLIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RECRUIT_A_FRIEND_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1553,7 +1564,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_RANGED_COMBAT_TIMER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_WEEKLY_CURRENCY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESPEC_WIPE_CONFIRM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_CAST_BAR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_COMMS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_TOKEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1585,7 +1596,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_CHARGES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_HISTORY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_UNLEARN_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_FIRST_ACHIEVEMENT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_FIRST_ACHIEVEMENT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_FIRST_ACHIEVEMENTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_TIME, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SETUP_CURRENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); @@ -1601,7 +1612,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_STANDING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_VISIBLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FLAT_SPELL_MODIFIER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FORCED_REACTIONS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FORCED_REACTIONS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_ITEM_PURCHASE_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_LFG_TIME_WALKER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_LOOT_METHOD_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1685,7 +1696,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRANSFER_PENDING, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_CINEMATIC, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_MOVIE, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_TURN_IN_PETITION_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_TURN_IN_PETITION_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TUTORIAL_FLAGS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TWITTER_STATUS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UI_TIME, STATUS_NEVER, CONNECTION_TYPE_REALM); @@ -1704,21 +1715,22 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_TASK_PROGRESS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_WEEKLY_SPELL_USAGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_WORLD_STATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_WOW_TOKEN_AUCTIONABLE_LIST_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_ADD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_REMOVE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_USE_EQUIPMENT_SET_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_USE_EQUIPMENT_SET_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_VENDOR_INVENTORY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_VIGNETTE_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_CHAT_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_PARENTAL_CONTROLS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_SESSION_LEAVE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_SESSION_ROSTER_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_ITEM_SWAP_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_STORAGE_CONTENTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_STORAGE_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_STORAGE_TRANSFER_CHANGES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_TRANSFER_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_ITEM_SWAP_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_STORAGE_CONTENTS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_STORAGE_FAILED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_STORAGE_TRANSFER_CHANGES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_TRANSFER_RESULT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_WAIT_QUEUE_FINISH, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_WAIT_QUEUE_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_WARDEN_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index f180734403d..ab59edf68c0 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -1008,6 +1008,7 @@ enum OpcodeServer : uint32 SMSG_GARRISON_BUILDING_REMOVED = 0x08F7, SMSG_GARRISON_BUILDING_SET_ACTIVE_SPECIALIZATION_RESULT = 0x00F8, SMSG_GARRISON_COMPLETE_MISSION_RESULT = 0x00F7, + SMSG_GARRISON_CREATE_RESULT = 0x01BB, SMSG_GARRISON_DELETE_RESULT = 0x01FC, SMSG_GARRISON_FOLLOWER_CHANGED_ITEM_LEVEL = 0x01B4, SMSG_GARRISON_FOLLOWER_CHANGED_ITEM_LEVEL2 = 0x0093, @@ -1026,6 +1027,8 @@ enum OpcodeServer : uint32 SMSG_GARRISON_PLACE_BUILDING_RESULT = 0x08A4, SMSG_GARRISON_PLOT_PLACED = 0x00E7, SMSG_GARRISON_PLOT_REMOVED = 0x01AB, + SMSG_GARRISON_RECALL_PORTAL_LAST_USED_TIME = 0x089B, + SMSG_GARRISON_RECALL_PORTAL_USED = 0x0197, SMSG_GARRISON_RECRUITMENT_FOLLOWERS_GENERATED = 0x0088, SMSG_GARRISON_RECRUIT_FOLLOWER_RESULT = 0x01EC, SMSG_GARRISON_REMOTE_INFO = 0x01B0, @@ -1605,6 +1608,7 @@ enum OpcodeServer : uint32 SMSG_UPDATE_TASK_PROGRESS = 0x1317, SMSG_UPDATE_WEEKLY_SPELL_USAGE = 0x103A, SMSG_UPDATE_WORLD_STATE = 0x1DF1, + SMSG_UPDATE_WOW_TOKEN_AUCTIONABLE_LIST_RESPONSE = 0x1836, SMSG_USERLIST_ADD = 0x15F0, SMSG_USERLIST_REMOVE = 0x10E4, SMSG_USERLIST_UPDATE = 0x18EF, diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index df35141dc5a..8ed6403918b 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -834,7 +834,7 @@ void WorldSession::ReadAddonsInfo(ByteBuffer& data) if (size > 0xFFFFF) { - TC_LOG_ERROR("misc", "WorldSession::ReadAddonsInfo addon info too big, size %u", size); + TC_LOG_DEBUG("addon", "WorldSession::ReadAddonsInfo: AddOnInfo too big, size %u", size); return; } @@ -866,7 +866,7 @@ void WorldSession::ReadAddonsInfo(ByteBuffer& data) addonInfo >> enabled >> crc >> unk1; - TC_LOG_DEBUG("misc", "ADDON: Name: %s, Enabled: 0x%x, CRC: 0x%x, Unknown2: 0x%x", addonName.c_str(), enabled, crc, unk1); + TC_LOG_DEBUG("addon", "AddOn: %s (CRC: 0x%x) - enabled: 0x%x - Unknown2: 0x%x", addonName.c_str(), crc, enabled, unk1); AddonInfo addon(addonName, enabled, crc, 2, true); @@ -874,15 +874,14 @@ void WorldSession::ReadAddonsInfo(ByteBuffer& data) if (savedAddon) { if (addon.CRC != savedAddon->CRC) - TC_LOG_ERROR("misc", "ADDON: %s was known, but didn't match known CRC (0x%x)!", addon.Name.c_str(), savedAddon->CRC); + TC_LOG_WARN("addon", " Addon: %s: modified (CRC: 0x%x) - accountID %d)", addon.Name.c_str(), savedAddon->CRC, GetAccountId()); else - TC_LOG_DEBUG("misc", "ADDON: %s was known, CRC is correct (0x%x)", addon.Name.c_str(), savedAddon->CRC); + TC_LOG_DEBUG("addon", "Addon: %s: validated (CRC: 0x%x) - accountID %d", addon.Name.c_str(), savedAddon->CRC, GetAccountId()); } else { AddonMgr::SaveAddon(addon); - - TC_LOG_DEBUG("misc", "ADDON: %s (0x%x) was not known, saving...", addon.Name.c_str(), addon.CRC); + TC_LOG_WARN("addon", "Addon: %s: unknown (CRC: 0x%x) - accountId %d (storing addon name and checksum to database)", addon.Name.c_str(), addon.CRC, GetAccountId()); } /// @todo Find out when to not use CRC/pubkey, and other possible states. @@ -891,10 +890,10 @@ void WorldSession::ReadAddonsInfo(ByteBuffer& data) uint32 currentTime; addonInfo >> currentTime; - TC_LOG_DEBUG("network", "ADDON: CurrentTime: %u", currentTime); + TC_LOG_DEBUG("addon", "AddOn: CurrentTime: %u", currentTime); } else - TC_LOG_ERROR("misc", "Addon packet uncompress error!"); + TC_LOG_DEBUG("addon", "AddOn: Addon packet uncompress error!"); } void WorldSession::SendAddonsInfo() @@ -919,7 +918,6 @@ bool WorldSession::IsAddonRegistered(const std::string& prefix) const void WorldSession::HandleUnregisterAddonPrefixesOpcode(WorldPacket& /*recvPacket*/) // empty packet { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_UNREGISTER_ALL_ADDON_PREFIXES"); _registeredAddonPrefixes.clear(); } diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 03909497370..ce525420710 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -82,6 +82,14 @@ namespace WorldPackets namespace AuctionHouse { class AuctionHelloRequest; + class AuctionListBidderItems; + class AuctionListItems; + class AuctionListOwnerItems; + class AuctionListPendingSales; + class AuctionPlaceBid; + class AuctionRemoveItem; + class AuctionReplicateItems; + class AuctionSellItem; } namespace Auth @@ -96,6 +104,14 @@ namespace WorldPackets class BuyBankSlot; } + namespace Battleground + { + class AreaSpiritHealerQuery; + class AreaSpiritHealerQueue; + class HearthAndResurrect; + class PVPLogDataRequest; + } + namespace BlackMarket { class BlackMarketOpen; @@ -153,6 +169,7 @@ namespace WorldPackets class ChatMessageChannel; class ChatAddonMessage; class ChatAddonMessageWhisper; + class ChatAddonMessageChannel; class ChatMessageAFK; class ChatMessageDND; class ChatMessageEmote; @@ -176,6 +193,8 @@ namespace WorldPackets namespace EquipmentSet { class SaveEquipmentSet; + class DeleteEquipmentSet; + class UseEquipmentSet; } namespace GameObject @@ -238,12 +257,14 @@ namespace WorldPackets namespace Item { class AutoEquipItem; + class AutoEquipItemSlot; class AutoStoreBagItem; class BuyItem; class BuyBackItem; class DestroyItem; class GetItemPurchaseData; class RepairItem; + class ReadItem; class SellItem; class SplitItem; class SwapInvItem; @@ -289,6 +310,8 @@ namespace WorldPackets class StandStateChange; class UITimeRequest; class RandomRollClient; + class ObjectUpdateFailed; + class ObjectUpdateRescued; } namespace Movement @@ -300,6 +323,7 @@ namespace WorldPackets class MovementSpeedAck; class SetActiveMover; class MoveSetCollisionHeightAck; + class MoveTimeSkipped; } namespace NPC @@ -333,6 +357,7 @@ namespace WorldPackets class QueryCorpseTransport; class QueryTime; class QuestPOIQuery; + class QueryQuestCompletionNPCs; } namespace Quest @@ -355,6 +380,18 @@ namespace WorldPackets class GrantLevel; } + namespace Reputation + { + class RequestForcedReactions; + } + + namespace Scenes + { + class SceneTriggerEvent; + class ScenePlaybackComplete; + class ScenePlaybackCanceled; + } + namespace Social { class AddFriend; @@ -368,6 +405,9 @@ namespace WorldPackets namespace Spells { class CancelAura; + class CancelGrowthAura; + class CancelMountAura; + class RequestCategoryCooldowns; class CancelCast; class CastSpell; class PetCastSpell; @@ -398,6 +438,11 @@ namespace WorldPackets class SupportTicketSubmitComplaint; } + namespace Token + { + class UpdateListedAuctionableTokens; + } + namespace Trade { class AcceptTrade; @@ -427,6 +472,14 @@ namespace WorldPackets class MoveSetVehicleRecIdAck; } + namespace VoidStorage + { + class UnlockVoidStorage; + class QueryVoidStorage; + class VoidStorageTransfer; + class SwapVoidItem; + } + namespace Who { class WhoIsRequest; @@ -725,7 +778,7 @@ class WorldSession } //used with item_page table bool SendItemInfo(uint32 itemid, WorldPacket data); - //auction + // Auction void SendAuctionHello(ObjectGuid guid, Creature* unit); /** @@ -739,10 +792,10 @@ class WorldSession * @param bidError (Optional) the bid error. */ void SendAuctionCommandResult(AuctionEntry* auction, uint32 Action, uint32 ErrorCode, uint32 bidError = 0); - - void SendAuctionBidderNotification(uint32 location, uint32 auctionId, ObjectGuid bidder, uint32 bidSum, uint32 diff, uint32 item_template); - void SendAuctionOwnerNotification(AuctionEntry* auction); - void SendAuctionRemovedNotification(uint32 auctionId, uint32 itemEntry, int32 randomPropertyId); + void SendAuctionOutBidNotification(AuctionEntry const* auction, Item const* item); + void SendAuctionClosedNotification(AuctionEntry const* auction, float mailDelay, bool sold, Item const* item); + void SendAuctionWonNotification(AuctionEntry const* auction, Item const* item); + void SendAuctionOwnerBidNotification(AuctionEntry const* auction, Item const* item); // Black Market void SendBlackMarketOpenResult(ObjectGuid guid, Creature* auctioneer); @@ -849,8 +902,6 @@ class WorldSession void HandlePlayedTime(WorldPackets::Character::RequestPlayedTime& packet); // new - void HandleMoveUnRootAck(WorldPacket& recvPacket); - void HandleMoveRootAck(WorldPacket& recvPacket); void HandleLookingForGroup(WorldPacket& recvPacket); // cemetery/graveyard related @@ -863,11 +914,6 @@ class WorldSession void HandleInspectPVP(WorldPackets::Inspect::InspectPVPRequest& request); void HandleQueryInspectAchievements(WorldPackets::Inspect::QueryInspectAchievements& inspect); - void HandleMoveWaterWalkAck(WorldPacket& recvPacket); - void HandleFeatherFallAck(WorldPacket& recvData); - - void HandleMoveHoverAck(WorldPacket& recvData); - void HandleMountSpecialAnimOpcode(WorldPacket& recvdata); // character view @@ -932,6 +978,7 @@ class WorldSession void HandleSetFactionCheat(WorldPacket& recvData); void HandleSetWatchedFactionOpcode(WorldPacket& recvData); void HandleSetFactionInactiveOpcode(WorldPacket& recvData); + void HandleRequestForcedReactionsOpcode(WorldPackets::Reputation::RequestForcedReactions& requestForcedReactions); void HandleUpdateAccountData(WorldPackets::ClientConfig::UserClientUpdateAccountData& packet); void HandleRequestAccountData(WorldPackets::ClientConfig::RequestAccountData& request); @@ -962,7 +1009,8 @@ class WorldSession void HandleEjectPassenger(WorldPackets::Vehicle::EjectPassenger& ejectPassenger); void HandleRequestVehicleExit(WorldPackets::Vehicle::RequestVehicleExit& requestVehicleExit); void HandleMoveSetVehicleRecAck(WorldPackets::Vehicle::MoveSetVehicleRecIdAck& setVehicleRecIdAck); - void HandleMoveTimeSkippedOpcode(WorldPacket& recvData); + void HandleMoveTimeSkippedOpcode(WorldPackets::Movement::MoveTimeSkipped& moveTimeSkipped); + void HandleMovementAckMessage(WorldPackets::Movement::MovementAckMessage& movementAck); void HandleRequestRaidInfoOpcode(WorldPacket& recvData); @@ -1083,13 +1131,14 @@ class WorldSession void HandleUnacceptTradeOpcode(WorldPackets::Trade::UnacceptTrade& unacceptTrade); void HandleAuctionHelloOpcode(WorldPackets::AuctionHouse::AuctionHelloRequest& packet); - void HandleAuctionListItems(WorldPacket& recvData); - void HandleAuctionListBidderItems(WorldPacket& recvData); - void HandleAuctionSellItem(WorldPacket& recvData); - void HandleAuctionRemoveItem(WorldPacket& recvData); - void HandleAuctionListOwnerItems(WorldPacket& recvData); - void HandleAuctionPlaceBid(WorldPacket& recvData); - void HandleAuctionListPendingSales(WorldPacket& recvData); + void HandleAuctionListItems(WorldPackets::AuctionHouse::AuctionListItems& packet); + void HandleAuctionListBidderItems(WorldPackets::AuctionHouse::AuctionListBidderItems& packet); + void HandleAuctionSellItem(WorldPackets::AuctionHouse::AuctionSellItem& packet); + void HandleAuctionRemoveItem(WorldPackets::AuctionHouse::AuctionRemoveItem& packet); + void HandleAuctionListOwnerItems(WorldPackets::AuctionHouse::AuctionListOwnerItems& packet); + void HandleAuctionPlaceBid(WorldPackets::AuctionHouse::AuctionPlaceBid& packet); + void HandleAuctionListPendingSales(WorldPackets::AuctionHouse::AuctionListPendingSales& packet); + void HandleReplicateItems(WorldPackets::AuctionHouse::AuctionReplicateItems& packet); // Bank void HandleAutoBankItemOpcode(WorldPackets::Bank::AutoBankItem& packet); @@ -1121,8 +1170,8 @@ class WorldSession void HandleBuyItemOpcode(WorldPackets::Item::BuyItem& packet); void HandleListInventoryOpcode(WorldPackets::NPC::Hello& packet); void HandleAutoStoreBagItemOpcode(WorldPackets::Item::AutoStoreBagItem& packet); - void HandleReadItem(WorldPacket& recvPacket); - void HandleAutoEquipItemSlotOpcode(WorldPacket& recvPacket); + void HandleReadItem(WorldPackets::Item::ReadItem& readItem); + void HandleAutoEquipItemSlotOpcode(WorldPackets::Item::AutoEquipItemSlot& autoEquipItemSlot); void HandleSwapItem(WorldPackets::Item::SwapItem& swapItem); void HandleBuybackItem(WorldPackets::Item::BuyBackItem& packet); void HandleWrapItemOpcode(WorldPacket& recvPacket); @@ -1136,7 +1185,8 @@ class WorldSession void HandleCastSpellOpcode(WorldPackets::Spells::CastSpell& castRequest); void HandleCancelCastOpcode(WorldPackets::Spells::CancelCast& packet); void HandleCancelAuraOpcode(WorldPackets::Spells::CancelAura& cancelAura); - void HandleCancelGrowthAuraOpcode(WorldPacket& recvPacket); + void HandleCancelGrowthAuraOpcode(WorldPackets::Spells::CancelGrowthAura& cancelGrowthAura); + void HandleCancelMountAuraOpcode(WorldPackets::Spells::CancelMountAura& cancelMountAura); void HandleCancelAutoRepeatSpellOpcode(WorldPacket& recvPacket); void HandleLearnTalentsOpcode(WorldPackets::Talent::LearnTalents& packet); @@ -1161,16 +1211,17 @@ class WorldSession void HandlePushQuestToParty(WorldPacket& recvPacket); void HandleQuestPushResult(WorldPacket& recvPacket); - void HandleChatMessageOpcode(WorldPackets::Chat::ChatMessage& packet); - void HandleChatMessageWhisperOpcode(WorldPackets::Chat::ChatMessageWhisper& packet); - void HandleChatMessageChannelOpcode(WorldPackets::Chat::ChatMessageChannel& packet); + void HandleChatMessageOpcode(WorldPackets::Chat::ChatMessage& chatMessage); + void HandleChatMessageWhisperOpcode(WorldPackets::Chat::ChatMessageWhisper& chatMessageWhisper); + void HandleChatMessageChannelOpcode(WorldPackets::Chat::ChatMessageChannel& chatMessageChannel); void HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, std::string target = ""); - void HandleChatAddonMessageOpcode(WorldPackets::Chat::ChatAddonMessage& packet); - void HandleChatAddonMessageWhisperOpcode(WorldPackets::Chat::ChatAddonMessageWhisper& packet); + void HandleChatAddonMessageOpcode(WorldPackets::Chat::ChatAddonMessage& chatAddonMessage); + void HandleChatAddonMessageWhisperOpcode(WorldPackets::Chat::ChatAddonMessageWhisper& chatAddonMessageWhisper); + void HandleChatAddonMessageChannelOpcode(WorldPackets::Chat::ChatAddonMessageChannel& chatAddonMessageChannel); void HandleChatAddonMessage(ChatMsg type, std::string prefix, std::string text, std::string target = ""); - void HandleChatMessageAFKOpcode(WorldPackets::Chat::ChatMessageAFK& packet); - void HandleChatMessageDNDOpcode(WorldPackets::Chat::ChatMessageDND& packet); - void HandleChatMessageEmoteOpcode(WorldPackets::Chat::ChatMessageEmote& packet); + void HandleChatMessageAFKOpcode(WorldPackets::Chat::ChatMessageAFK& chatMessageAFK); + void HandleChatMessageDNDOpcode(WorldPackets::Chat::ChatMessageDND& chatMessageDND); + void HandleChatMessageEmoteOpcode(WorldPackets::Chat::ChatMessageEmote& chatMessageEmote); void SendPlayerNotFoundNotice(std::string const& name); void SendPlayerAmbiguousNotice(std::string const& name); void SendChatRestrictedNotice(ChatRestrictionType restriction); @@ -1201,7 +1252,7 @@ class WorldSession void HandleCompleteCinematic(WorldPacket& recvPacket); void HandleNextCinematicCamera(WorldPacket& recvPacket); - void HandlePageTextQueryOpcode(WorldPackets::Query::QueryPageText& packet); + void HandleQueryPageText(WorldPackets::Query::QueryPageText& packet); void HandleTutorialFlag(WorldPackets::Misc::TutorialSetFlag& packet); @@ -1226,7 +1277,7 @@ class WorldSession void HandleBattlemasterHelloOpcode(WorldPacket& recvData); void HandleBattlemasterJoinOpcode(WorldPacket& recvData); void HandleBattlegroundPlayerPositionsOpcode(WorldPacket& recvData); - void HandlePVPLogDataOpcode(WorldPacket& recvData); + void HandlePVPLogDataOpcode(WorldPackets::Battleground::PVPLogDataRequest& pvpLogDataRequest); void HandleBattleFieldPortOpcode(WorldPacket& recvData); void HandleBattlefieldListOpcode(WorldPacket& recvData); void HandleBattlefieldLeaveOpcode(WorldPacket& recvData); @@ -1235,6 +1286,9 @@ class WorldSession void HandleRequestRatedBattlefieldInfo(WorldPacket& recvData); void HandleGetPVPOptionsEnabled(WorldPacket& recvData); void HandleRequestPvpReward(WorldPacket& recvData); + void HandleAreaSpiritHealerQueryOpcode(WorldPackets::Battleground::AreaSpiritHealerQuery& areaSpiritHealerQuery); + void HandleAreaSpiritHealerQueueOpcode(WorldPackets::Battleground::AreaSpiritHealerQueue& areaSpiritHealerQueue); + void HandleHearthAndResurrect(WorldPackets::Battleground::HearthAndResurrect& hearthAndResurrect); // Battlefield void SendBfInvitePlayerToWar(ObjectGuid guid, uint32 zoneId, uint32 time); @@ -1259,7 +1313,6 @@ class WorldSession void HandleTimeSyncResponse(WorldPackets::Misc::TimeSyncResponse& packet); void HandleWhoIsOpcode(WorldPackets::Who::WhoIsRequest& packet); void HandleResetInstancesOpcode(WorldPacket& recvData); - void HandleHearthAndResurrect(WorldPacket& recvData); void HandleInstanceLockResponse(WorldPacket& recvPacket); // Looking for Dungeon/Raid @@ -1290,9 +1343,6 @@ class WorldSession void SendLfgOfferContinue(uint32 dungeonEntry); void SendLfgTeleportError(uint8 err); - void HandleAreaSpiritHealerQueryOpcode(WorldPacket& recvData); - void HandleAreaSpiritHealerQueueOpcode(WorldPacket& recvData); - void HandleCancelMountAuraOpcode(WorldPacket& recvData); void HandleSelfResOpcode(WorldPacket& recvData); void HandleComplainOpcode(WorldPacket& recvData); void HandleRequestPetInfoOpcode(WorldPacket& recvData); @@ -1348,10 +1398,10 @@ class WorldSession void HandleSetSavedInstanceExtend(WorldPacket& recvData); // Void Storage - void HandleVoidStorageUnlock(WorldPacket& recvData); - void HandleVoidStorageQuery(WorldPacket& recvData); - void HandleVoidStorageTransfer(WorldPacket& recvData); - void HandleVoidSwapItem(WorldPacket& recvData); + void HandleVoidStorageUnlock(WorldPackets::VoidStorage::UnlockVoidStorage& unlockVoidStorage); + void HandleVoidStorageQuery(WorldPackets::VoidStorage::QueryVoidStorage& queryVoidStorage); + void HandleVoidStorageTransfer(WorldPackets::VoidStorage::VoidStorageTransfer& voidStorageTransfer); + void HandleVoidSwapItem(WorldPackets::VoidStorage::SwapVoidItem& swapVoidItem); void SendVoidStorageTransferResult(VoidTransferError result); // Transmogrification @@ -1363,16 +1413,25 @@ class WorldSession void HandleRemoveGlyph(WorldPacket& recvData); void HandleGuildSetFocusedAchievement(WorldPackets::Achievement::GuildSetFocusedAchievement& setFocusedAchievement); void HandleEquipmentSetSave(WorldPackets::EquipmentSet::SaveEquipmentSet& packet); - void HandleEquipmentSetDelete(WorldPacket& recvData); - void HandleEquipmentSetUse(WorldPacket& recvData); + void HandleDeleteEquipmentSet(WorldPackets::EquipmentSet::DeleteEquipmentSet& packet); + void HandleUseEquipmentSet(WorldPackets::EquipmentSet::UseEquipmentSet& packet); void HandleUITimeRequest(WorldPackets::Misc::UITimeRequest& /*request*/); - void HandleQuestNPCQuery(WorldPacket& recvData); + void HandleQueryQuestCompletionNPCs(WorldPackets::Query::QueryQuestCompletionNPCs& queryQuestCompletionNPCs); void HandleQuestPOIQuery(WorldPackets::Query::QuestPOIQuery& packet); void HandleUpdateProjectilePosition(WorldPacket& recvPacket); void HandleUpdateMissileTrajectory(WorldPacket& recvPacket); void HandleViolenceLevel(WorldPackets::Misc::ViolenceLevel& violenceLevel); - void HandleObjectUpdateFailedOpcode(WorldPacket& recvPacket); - void HandleRequestCategoryCooldowns(WorldPacket& recvPacket); + void HandleObjectUpdateFailedOpcode(WorldPackets::Misc::ObjectUpdateFailed& objectUpdateFailed); + void HandleObjectUpdateRescuedOpcode(WorldPackets::Misc::ObjectUpdateRescued& objectUpdateRescued); + void HandleRequestCategoryCooldowns(WorldPackets::Spells::RequestCategoryCooldowns& requestCategoryCooldowns); + + // Scenes + void HandleSceneTriggerEvent(WorldPackets::Scenes::SceneTriggerEvent& sceneTriggerEvent); + void HandleScenePlaybackComplete(WorldPackets::Scenes::ScenePlaybackComplete& scenePlaybackComplete); + void HandleScenePlaybackCanceled(WorldPackets::Scenes::ScenePlaybackCanceled& scenePlaybackCanceled); + + // Token + void HandleUpdateListedAuctionableTokens(WorldPackets::Token::UpdateListedAuctionableTokens& updateListedAuctionableTokens); void SendSpellCategoryCooldowns(); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index e1dd5505eab..543b818597e 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -401,7 +401,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]= &AuraEffect::HandleNoImmediateEffect, //338 SPELL_AURA_MOD_DURABILITY_LOSS &AuraEffect::HandleNULL, //339 SPELL_AURA_INCREASE_SKILL_GAIN_CHANCE &AuraEffect::HandleNULL, //340 SPELL_AURA_MOD_RESURRECTED_HEALTH_BY_GUILD_MEMBER - &AuraEffect::HandleNULL, //341 SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN + &AuraEffect::HandleModSpellCategoryCooldown, //341 SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN &AuraEffect::HandleModMeleeRangedSpeedPct, //342 SPELL_AURA_MOD_MELEE_RANGED_HASTE_2 &AuraEffect::HandleNULL, //343 SPELL_AURA_MOD_MELEE_DAMAGE_FROM_CASTER &AuraEffect::HandleNULL, //344 SPELL_AURA_MOD_AUTOATTACK_DAMAGE @@ -6634,3 +6634,12 @@ void AuraEffect::HandleEnableAltPower(AuraApplication const* aurApp, uint8 mode, else aurApp->GetTarget()->SetMaxPower(POWER_ALTERNATE_POWER, 0); } + +void AuraEffect::HandleModSpellCategoryCooldown(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const +{ + if (!(mode & AURA_EFFECT_HANDLE_REAL)) + return; + + if (aurApp->GetTarget()->GetTypeId() == TYPEID_PLAYER) + aurApp->GetTarget()->ToPlayer()->GetSession()->SendSpellCategoryCooldowns(); +} diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h index 41eb2ab91ed..e8431e202ba 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.h +++ b/src/server/game/Spells/Auras/SpellAuraEffects.h @@ -300,6 +300,7 @@ class AuraEffect void HandleMastery(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleAuraForceWeather(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleEnableAltPower(AuraApplication const* aurApp, uint8 mode, bool apply) const; + void HandleModSpellCategoryCooldown(AuraApplication const* aurApp, uint8 mode, bool apply) const; // aura effect periodic tick handlers void HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 6063a97d2ca..3106ac4bc5a 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5796,10 +5796,8 @@ void Spell::EffectDestroyItem(SpellEffIndex effIndex) return; Player* player = unitTarget->ToPlayer(); - if (SpellEffectInfo const* effect = GetEffect(effIndex)) - { - uint32 itemId = effect->ItemType; - if (Item* item = player->GetItemByEntry(itemId)) - player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); - } + SpellEffectInfo const* effect = GetEffect(effIndex); + uint32 itemId = effect->ItemType; + if (Item* item = player->GetItemByEntry(itemId)) + player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); } diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index 40d5d75ba6f..54e33078622 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -783,7 +783,7 @@ bool SpellHistory::HasCharge(SpellCategoryEntry const* chargeCategoryEntry) cons return true; auto itr = _categoryCharges.find(chargeCategoryEntry->ID); - return itr == _categoryCharges.end() || itr->second.size() < maxCharges; + return itr == _categoryCharges.end() || int32(itr->second.size()) < maxCharges; } int32 SpellHistory::GetMaxCharges(SpellCategoryEntry const* chargeCategoryEntry) const diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index eb09cc60a1f..1334f5840ab 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1815,9 +1815,13 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a { case SPELL_AURA_FLY: { - if (!player->IsKnowHowFlyIn(map_id, zone_id)) - return SPELL_FAILED_INCORRECT_AREA; - break; + SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(Id); + for (SkillLineAbilityMap::const_iterator skillIter = bounds.first; skillIter != bounds.second; ++skillIter) + { + if (skillIter->second->SkillLine == SKILL_MOUNTS) + if (!player->CanFlyInZone(map_id, zone_id)) + return SPELL_FAILED_INCORRECT_AREA; + } } case SPELL_AURA_MOUNTED: { diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 518463a9539..b31090496ee 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3070,6 +3070,10 @@ void SpellMgr::LoadSpellInfoCorrections() const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TriggerSpell = 36325; // They Must Burn Bomb Drop (DND) break; case 49838: // Stop Time + case 69438: // Sample Satisfaction + case 69445: // Perfume Spritz + case 69489: // Chocolate Sample + case 69563: // Cologne Spritz spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO; break; case 61407: // Energize Cores diff --git a/src/server/game/Support/SupportMgr.h b/src/server/game/Support/SupportMgr.h index fbaf75753d5..b3a7b2e24f0 100644 --- a/src/server/game/Support/SupportMgr.h +++ b/src/server/game/Support/SupportMgr.h @@ -110,7 +110,7 @@ public: virtual void SetAssignedTo(ObjectGuid guid) { _assignedTo = guid; } virtual void SetAssignedTo(ObjectGuid /*guid*/, bool /*isAdmin*/) { } virtual void SetUnassigned() { _assignedTo.Clear(); } - void SetClosedBy(ObjectGuid value) { _closedBy = value; } + void SetClosedBy(ObjectGuid value) { _closedBy = value; } void SetComment(std::string const& comment) { _comment = comment; } void SetPosition(uint32 mapId, G3D::Vector3& pos) { @@ -137,7 +137,7 @@ protected: ObjectGuid _assignedTo; std::string _comment; }; - + class GmTicket : public Ticket { @@ -206,7 +206,7 @@ public: BugTicket(); BugTicket(Player* player); ~BugTicket(); - + std::string const& GetNote() const { return _note; } void SetFacing(float facing) { _facing = facing; } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index dc40e5f3c2b..cdbb15bf539 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1506,8 +1506,9 @@ void World::SetInitialWorldSettings() uint32 oldMSTime = getMSTime(); sObjectMgr->LoadCreatureLocales(); sObjectMgr->LoadGameObjectLocales(); - sObjectMgr->LoadQuestLocales(); - sObjectMgr->LoadNpcTextLocales(); + sObjectMgr->LoadQuestTemplateLocale(); + sObjectMgr->LoadQuestObjectivesLocale(); + sObjectMgr->LoadQuestGreetings(); sObjectMgr->LoadPageTextLocales(); sObjectMgr->LoadGossipMenuItemsLocales(); sObjectMgr->LoadPointOfInterestLocales(); @@ -1555,7 +1556,7 @@ void World::SetInitialWorldSettings() sSpellMgr->LoadSpellGroupStackRules(); TC_LOG_INFO("server.loading", "Loading NPC Texts..."); - sObjectMgr->LoadGossipText(); + sObjectMgr->LoadNPCText(); TC_LOG_INFO("server.loading", "Loading Enchant Spells Proc datas..."); sSpellMgr->LoadSpellEnchantProcData(); @@ -1619,10 +1620,16 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading Gameobject Data..."); sObjectMgr->LoadGameobjects(); - + TC_LOG_INFO("server.loading", "Loading GameObject Addon Data..."); sObjectMgr->LoadGameObjectAddons(); // must be after LoadGameObjectTemplate() and LoadGameobjects() + TC_LOG_INFO("server.loading", "Loading GameObject Quest Items..."); + sObjectMgr->LoadGameObjectQuestItems(); + + TC_LOG_INFO("server.loading", "Loading Creature Quest Items..."); + sObjectMgr->LoadCreatureQuestItems(); + TC_LOG_INFO("server.loading", "Loading Creature Linked Respawn..."); sObjectMgr->LoadLinkedRespawn(); // must be after LoadCreatures(), LoadGameObjects() diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp index c5f1fe114f6..2e08b53bffd 100644 --- a/src/server/scripts/Commands/cs_account.cpp +++ b/src/server/scripts/Commands/cs_account.cpp @@ -666,7 +666,7 @@ public: if (isAccountNameGiven) { targetAccountName = arg1; - if (!Utf8ToUpperOnlyLatin(targetAccountName)) + if (!Utf8ToUpperOnlyLatin(targetAccountName) || !AccountMgr::GetId(targetAccountName)) { handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, targetAccountName.c_str()); handler->SetSentErrorMessage(true); diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 84e3cf4c23c..bfc61ad9f78 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -34,6 +34,7 @@ EndScriptData */ #include "Transport.h" #include "Language.h" #include "MovementPackets.h" +#include "ScenePackets.h" #include <fstream> @@ -64,6 +65,7 @@ public: { "sellerror", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_SELLERROR, false, &HandleDebugSendSellErrorCommand, "", NULL }, { "setphaseshift", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_SETPHASESHIFT, false, &HandleDebugSendSetPhaseShiftCommand, "", NULL }, { "spellfail", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_SPELLFAIL, false, &HandleDebugSendSpellFailCommand, "", NULL }, + { "playscene", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_PLAYSCENE, false, &HandleDebugSendPlaySceneCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand debugCommandTable[] = @@ -1429,6 +1431,49 @@ public: handler->SendSysMessage("Target is not phased"); return true; } + + static bool HandleDebugSendPlaySceneCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + int32 sceneID = 0; + int32 playbackFlags = 0; + int32 sceneInstanceID = 0; + int32 sceneScriptPackageID = 0; + + char* a = strtok((char*)args, " "); + char* b = strtok(NULL, " "); + char* c = strtok(NULL, " "); + char* d = strtok(NULL, " "); + + if (!a || !b || !c || !d) + return false; + + if (a) + sceneID = atoi(a); + if (b) + playbackFlags = atoi(b); + if (c) + sceneInstanceID = atoi(c); + if (d) + sceneScriptPackageID = atoi(d); + + Player* me = handler->GetSession()->GetPlayer(); + + WorldPackets::Scenes::PlayScene packet; + packet.SceneID = sceneID; + packet.PlaybackFlags = playbackFlags; + packet.SceneInstanceID = sceneInstanceID; + packet.SceneScriptPackageID = sceneScriptPackageID; + packet.TransportGUID = me->GetTransGUID(); + packet.Location = me->GetPosition(); + handler->GetSession()->SendPacket(packet.Write(), true); + + TC_LOG_DEBUG("network", "Sent SMSG_PLAY_SCENE to %s, SceneID: %d, PlaybackFlags: %d, SceneInstanceID: %d, SceneScriptPackageID: %d", me->GetName().c_str(), sceneID, playbackFlags, sceneInstanceID, sceneScriptPackageID); + + return true; + } }; void AddSC_debug_commandscript() diff --git a/src/server/scripts/Commands/cs_lfg.cpp b/src/server/scripts/Commands/cs_lfg.cpp index 308a841df2a..747d84de9c5 100644 --- a/src/server/scripts/Commands/cs_lfg.cpp +++ b/src/server/scripts/Commands/cs_lfg.cpp @@ -47,15 +47,15 @@ public: { { "player", rbac::RBAC_PERM_COMMAND_LFG_PLAYER, false, &HandleLfgPlayerInfoCommand, "", NULL }, { "group", rbac::RBAC_PERM_COMMAND_LFG_GROUP, false, &HandleLfgGroupInfoCommand, "", NULL }, - { "queue", rbac::RBAC_PERM_COMMAND_LFG_QUEUE, false, &HandleLfgQueueInfoCommand, "", NULL }, - { "clean", rbac::RBAC_PERM_COMMAND_LFG_CLEAN, false, &HandleLfgCleanCommand, "", NULL }, - { "options", rbac::RBAC_PERM_COMMAND_LFG_OPTIONS, false, &HandleLfgOptionsCommand, "", NULL }, + { "queue", rbac::RBAC_PERM_COMMAND_LFG_QUEUE, true, &HandleLfgQueueInfoCommand, "", NULL }, + { "clean", rbac::RBAC_PERM_COMMAND_LFG_CLEAN, true, &HandleLfgCleanCommand, "", NULL }, + { "options", rbac::RBAC_PERM_COMMAND_LFG_OPTIONS, true, &HandleLfgOptionsCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand commandTable[] = { - { "lfg", rbac::RBAC_PERM_COMMAND_LFG, false, NULL, "", lfgCommandTable }, + { "lfg", rbac::RBAC_PERM_COMMAND_LFG, true, NULL, "", lfgCommandTable }, { NULL, 0, false, NULL, "", NULL } }; return commandTable; @@ -118,7 +118,7 @@ public: static bool HandleLfgQueueInfoCommand(ChatHandler* handler, char const* args) { - handler->SendSysMessage(sLFGMgr->DumpQueueInfo(atoi(args) != 0).c_str()); + handler->SendSysMessage(sLFGMgr->DumpQueueInfo(*args != '\0').c_str()); return true; } diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp index 8666e38b84b..d8f98e90275 100644 --- a/src/server/scripts/Commands/cs_lookup.cpp +++ b/src/server/scripts/Commands/cs_lookup.cpp @@ -565,7 +565,7 @@ public: if (localeIndex >= 0) { uint8 ulocaleIndex = uint8(localeIndex); - if (QuestLocale const* questLocale = sObjectMgr->GetQuestLocale(qInfo->GetQuestId())) + if (QuestTemplateLocale const* questLocale = sObjectMgr->GetQuestLocale(qInfo->GetQuestId())) { if (questLocale->LogTitle.size() > ulocaleIndex && !questLocale->LogTitle[ulocaleIndex].empty()) { diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index b57efc07a74..a63c300f685 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -248,7 +248,7 @@ public: if (status) handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status); - + if (!object->GetTerrainSwaps().empty()) { std::stringstream ss; diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index c1f90c7ac96..48a514fd0db 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -1281,7 +1281,7 @@ public: Unit* target = handler->getSelectedUnit(); if (!target) target = handler->GetSession()->GetPlayer(); - + target->SetInPhase(phase, true, !target->IsInPhase(phase)); if (target->GetTypeId() == TYPEID_PLAYER) diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 78f23ceab25..c8066ee92e9 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -106,10 +106,8 @@ public: { "locales_creature_text", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_CRETURE_TEXT, true, &HandleReloadLocalesCreatureTextCommand, "", NULL }, { "locales_gameobject", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_GAMEOBJECT, true, &HandleReloadLocalesGameobjectCommand, "", NULL }, { "locales_gossip_menu_option", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_GOSSIP_MENU_OPTION, true, &HandleReloadLocalesGossipMenuOptionCommand, "", NULL }, - { "locales_npc_text", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_NPC_TEXT, true, &HandleReloadLocalesNpcTextCommand, "", NULL }, { "locales_page_text", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_PAGE_TEXT, true, &HandleReloadLocalesPageTextCommand, "", NULL }, { "locales_points_of_interest", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_POINTS_OF_INTEREST, true, &HandleReloadLocalesPointsOfInterestCommand, "", NULL }, - { "locales_quest", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_QUEST, true, &HandleReloadLocalesQuestCommand, "", NULL }, { "mail_level_reward", rbac::RBAC_PERM_COMMAND_RELOAD_MAIL_LEVEL_REWARD, true, &HandleReloadMailLevelRewardCommand, "", NULL }, { "mail_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_MAIL_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesMailCommand, "", NULL }, { "milling_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_MILLING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesMillingCommand, "", NULL }, @@ -120,6 +118,8 @@ public: { "pickpocketing_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_PICKPOCKETING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesPickpocketingCommand, "", NULL }, { "points_of_interest", rbac::RBAC_PERM_COMMAND_RELOAD_POINTS_OF_INTEREST, true, &HandleReloadPointsOfInterestCommand, "", NULL }, { "prospecting_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_PROSPECTING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesProspectingCommand, "", NULL }, + { "quest_greeting", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_GREETING, true, &HandleReloadQuestGreetingCommand, "", NULL }, + { "quest_locale", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_LOCALE, true, &HandleReloadQuestLocaleCommand, "", NULL }, { "quest_poi", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_POI, true, &HandleReloadQuestPOICommand, "", NULL }, { "quest_template", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_TEMPLATE, true, &HandleReloadQuestTemplateCommand, "", NULL }, { "rbac", rbac::RBAC_PERM_COMMAND_RELOAD_RBAC, true, &HandleReloadRBACCommand, "", NULL }, @@ -243,6 +243,7 @@ public: static bool HandleReloadAllQuestCommand(ChatHandler* handler, const char* /*args*/) { HandleReloadQuestAreaTriggersCommand(handler, "a"); + HandleReloadQuestGreetingCommand(handler, "a"); HandleReloadQuestPOICommand(handler, "a"); HandleReloadQuestTemplateCommand(handler, "a"); @@ -311,10 +312,9 @@ public: HandleReloadLocalesCreatureTextCommand(handler, "a"); HandleReloadLocalesGameobjectCommand(handler, "a"); HandleReloadLocalesGossipMenuOptionCommand(handler, "a"); - HandleReloadLocalesNpcTextCommand(handler, "a"); HandleReloadLocalesPageTextCommand(handler, "a"); HandleReloadLocalesPointsOfInterestCommand(handler, "a"); - HandleReloadLocalesQuestCommand(handler, "a"); + HandleReloadQuestLocaleCommand(handler, "a"); return true; } @@ -511,6 +511,14 @@ public: return true; } + static bool HandleReloadQuestGreetingCommand(ChatHandler* handler, const char* /*args*/) + { + TC_LOG_INFO("misc", "Re-Loading Quest Greeting ... "); + sObjectMgr->LoadQuestGreetings(); + handler->SendGlobalGMSysMessage("DB table `quest_greeting` reloaded."); + return true; + } + static bool HandleReloadQuestTemplateCommand(ChatHandler* handler, const char* /*args*/) { TC_LOG_INFO("misc", "Re-Loading Quest Templates..."); @@ -1011,14 +1019,6 @@ public: return true; } - static bool HandleReloadLocalesNpcTextCommand(ChatHandler* handler, const char* /*args*/) - { - TC_LOG_INFO("misc", "Re-Loading Locales NPC Text ... "); - sObjectMgr->LoadNpcTextLocales(); - handler->SendGlobalGMSysMessage("DB table `locales_npc_text` reloaded."); - return true; - } - static bool HandleReloadLocalesPageTextCommand(ChatHandler* handler, const char* /*args*/) { TC_LOG_INFO("misc", "Re-Loading Locales Page Text ... "); @@ -1035,11 +1035,13 @@ public: return true; } - static bool HandleReloadLocalesQuestCommand(ChatHandler* handler, const char* /*args*/) + static bool HandleReloadQuestLocaleCommand(ChatHandler* handler, const char* /*args*/) { - TC_LOG_INFO("misc", "Re-Loading Locales Quest ... "); - sObjectMgr->LoadQuestLocales(); - handler->SendGlobalGMSysMessage("DB table `locales_quest` reloaded."); + TC_LOG_INFO("misc", "Re-Loading Quest Locale ... "); + sObjectMgr->LoadQuestTemplateLocale(); + sObjectMgr->LoadQuestObjectivesLocale(); + handler->SendGlobalGMSysMessage("DB table `quest_template_locale` reloaded."); + handler->SendGlobalGMSysMessage("DB table `quest_objectives_locale` reloaded."); return true; } diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp index 7af67902711..b97c2657d30 100644 --- a/src/server/scripts/Commands/cs_ticket.cpp +++ b/src/server/scripts/Commands/cs_ticket.cpp @@ -126,7 +126,7 @@ public: static bool HandleTicketResetAllCommand(ChatHandler* handler, char const* /*args*/) { - if (sSupportMgr->GetOpenTicketCount<GmTicket>() || sSupportMgr->GetOpenTicketCount<BugTicket>() + if (sSupportMgr->GetOpenTicketCount<GmTicket>() || sSupportMgr->GetOpenTicketCount<BugTicket>() || sSupportMgr->GetOpenTicketCount<ComplaintTicket>() || sSupportMgr->GetOpenTicketCount<SuggestionTicket>()) { handler->SendSysMessage(LANG_COMMAND_TICKETPENDING); diff --git a/src/server/scripts/EasternKingdoms/zone_undercity.cpp b/src/server/scripts/EasternKingdoms/zone_undercity.cpp index ca281bab60a..d7d06a2e3ab 100644 --- a/src/server/scripts/EasternKingdoms/zone_undercity.cpp +++ b/src/server/scripts/EasternKingdoms/zone_undercity.cpp @@ -50,7 +50,7 @@ enum Sylvanas SAY_SUNSORROW_WHISPER = 0, SOUND_CREDIT = 10896, - + NPC_HIGHBORNE_LAMENTER = 21628, NPC_HIGHBORNE_BUNNY = 21641, NPC_AMBASSADOR_SUNSORROW = 16287, diff --git a/src/server/scripts/Kalimdor/zone_ashenvale.cpp b/src/server/scripts/Kalimdor/zone_ashenvale.cpp index e3357a5d62b..b8e6bfb85e8 100644 --- a/src/server/scripts/Kalimdor/zone_ashenvale.cpp +++ b/src/server/scripts/Kalimdor/zone_ashenvale.cpp @@ -24,7 +24,6 @@ SDCategory: Ashenvale Forest EndScriptData */ /* ContentData -npc_torek npc_ruul_snowhoof EndContentData */ @@ -34,132 +33,6 @@ EndContentData */ #include "Player.h" /*#### -# npc_torek -####*/ - -enum Torek -{ - SAY_READY = 0, - SAY_MOVE = 1, - SAY_PREPARE = 2, - SAY_WIN = 3, - SAY_END = 4, - SPELL_REND = 11977, - SPELL_THUNDERCLAP = 8078, - QUEST_TOREK_ASSULT = 6544, - NPC_SPLINTERTREE_RAIDER = 12859, - NPC_DURIEL = 12860, - NPC_SILVERWING_SENTINEL = 12896, - NPC_SILVERWING_WARRIOR = 12897, - FACTION_QUEST = 113 -}; - -class npc_torek : public CreatureScript -{ -public: - npc_torek() : CreatureScript("npc_torek") { } - - struct npc_torekAI : public npc_escortAI - { - npc_torekAI(Creature* creature) : npc_escortAI(creature) - { - Initialize(); - } - - void Initialize() - { - rend_Timer = 5000; - thunderclap_Timer = 8000; - _completed = false; - } - - void Reset() override - { - Initialize(); - } - - void EnterCombat(Unit* /*who*/) override { } - - void JustSummoned(Creature* summoned) override - { - summoned->AI()->AttackStart(me); - } - - void sQuestAccept(Player* player, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_TOREK_ASSULT) - { - /// @todo find companions, make them follow Torek, at any time (possibly done by core/database in future?) - Talk(SAY_READY, player); - me->setFaction(FACTION_QUEST); - npc_escortAI::Start(true, true, player->GetGUID()); - } - } - - void WaypointReached(uint32 waypointId) override - { - if (Player* player = GetPlayerForEscort()) - { - switch (waypointId) - { - case 1: - Talk(SAY_MOVE, player); - break; - case 8: - Talk(SAY_PREPARE, player); - break; - case 19: - /// @todo verify location and creatures amount. - me->SummonCreature(NPC_DURIEL, 1776.73f, -2049.06f, 109.83f, 1.54f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(NPC_SILVERWING_SENTINEL, 1774.64f, -2049.41f, 109.83f, 1.40f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(NPC_SILVERWING_WARRIOR, 1778.73f, -2049.50f, 109.83f, 1.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - break; - case 20: - Talk(SAY_WIN, player); - _completed = true; - player->GroupEventHappens(QUEST_TOREK_ASSULT, me); - break; - case 21: - Talk(SAY_END, player); - break; - } - } - } - - void UpdateAI(uint32 diff) override - { - npc_escortAI::UpdateAI(diff); - - if (!UpdateVictim()) - return; - - if (rend_Timer <= diff) - { - DoCastVictim(SPELL_REND); - rend_Timer = 20000; - } else rend_Timer -= diff; - - if (thunderclap_Timer <= diff) - { - DoCast(me, SPELL_THUNDERCLAP); - thunderclap_Timer = 30000; - } else thunderclap_Timer -= diff; - } - - private: - uint32 rend_Timer; - uint32 thunderclap_Timer; - bool _completed; - - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_torekAI(creature); - } -}; - -/*#### # npc_ruul_snowhoof ####*/ @@ -169,6 +42,7 @@ enum RuulSnowhoof NPC_THISTLEFUR_TOTEMIC = 3922, NPC_THISTLEFUR_PATHFINDER = 3926, QUEST_FREEDOM_TO_RUUL = 6482, + FACTION_QUEST = 113, GO_CAGE = 178147 }; @@ -472,7 +346,6 @@ class go_naga_brazier : public GameObjectScript void AddSC_ashenvale() { - new npc_torek(); new npc_ruul_snowhoof(); new npc_muglash(); new go_naga_brazier(); diff --git a/src/server/scripts/Kalimdor/zone_desolace.cpp b/src/server/scripts/Kalimdor/zone_desolace.cpp index 09d0ac1ee92..c128d5dd434 100644 --- a/src/server/scripts/Kalimdor/zone_desolace.cpp +++ b/src/server/scripts/Kalimdor/zone_desolace.cpp @@ -85,12 +85,20 @@ public: DoCast(me, SPELL_KODO_KOMBO_DESPAWN_BUFF, true); me->UpdateEntry(NPC_TAMED_KODO); + me->CombatStop(); + me->DeleteThreatList(); + me->SetSpeed(MOVE_RUN, 0.6f, true); me->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, me->GetFollowAngle()); + me->setActive(true); } } else if (spell->Id == SPELL_KODO_KOMBO_GOSSIP) { me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveIdle(); + me->setActive(false); me->DespawnOrUnsummon(60000); } } diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp index e967f4aa8c5..2da131615e7 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp @@ -89,7 +89,7 @@ class boss_volkhan : public CreatureScript { public: boss_volkhan() : CreatureScript("boss_volkhan") { } - + struct boss_volkhanAI : public BossAI { boss_volkhanAI(Creature* creature) : BossAI(creature, DATA_VOLKHAN) @@ -104,7 +104,7 @@ public: m_bCanShatterGolem = false; m_uiDelay_Timer = 1000; m_uiSummonPhase = 0; - GolemsShattered = 0; + GolemsShattered = 0; m_uiHealthAmountModifier = 1; } diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index b58d9419e95..74614ae7c13 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -1703,7 +1703,7 @@ public: break; } creature->SetStandState(UNIT_STAND_STATE_STAND); - creature->AI()->Talk(SAY_1); + creature->AI()->Talk(SAY_1, player); ENSURE_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); } return true; diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp index c329e6212cc..af0c824006a 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp @@ -60,7 +60,7 @@ void OutdoorPvPTF::FillInitialWorldStates(WorldPackets::WorldState::InitWorldSta packet.Worldstates.emplace_back(uint32(TF_UI_LOCKED_TIME_MINUTES_FIRST_DIGIT), int32(first_digit)); packet.Worldstates.emplace_back(uint32(TF_UI_LOCKED_TIME_MINUTES_SECOND_DIGIT), int32(second_digit)); packet.Worldstates.emplace_back(uint32(TF_UI_LOCKED_TIME_HOURS), int32(hours_left)); - + packet.Worldstates.emplace_back(uint32(TF_UI_LOCKED_DISPLAY_NEUTRAL), int32(m_IsLocked && !m_HordeTowersControlled && !m_AllianceTowersControlled)); packet.Worldstates.emplace_back(uint32(TF_UI_LOCKED_DISPLAY_HORDE), int32(m_IsLocked && (m_HordeTowersControlled > m_AllianceTowersControlled))); packet.Worldstates.emplace_back(uint32(TF_UI_LOCKED_DISPLAY_ALLIANCE), int32(m_IsLocked && (m_HordeTowersControlled < m_AllianceTowersControlled))); diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_harbinger_skyriss.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_harbinger_skyriss.cpp index 213f31b280f..03e2154792b 100644 --- a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_harbinger_skyriss.cpp +++ b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_harbinger_skyriss.cpp @@ -283,7 +283,7 @@ class boss_harbinger_skyriss_illusion : public CreatureScript { boss_harbinger_skyriss_illusionAI(Creature* creature) : ScriptedAI(creature) { } - void Reset() override + void Reset() override { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } diff --git a/src/server/scripts/Outland/zone_blades_edge_mountains.cpp b/src/server/scripts/Outland/zone_blades_edge_mountains.cpp index 0fa5b44e09b..a2652031ef2 100644 --- a/src/server/scripts/Outland/zone_blades_edge_mountains.cpp +++ b/src/server/scripts/Outland/zone_blades_edge_mountains.cpp @@ -24,12 +24,9 @@ SDCategory: Blade's Edge Mountains EndScriptData */ /* ContentData -npc_bloodmaul_brutebane -npc_bloodmaul_brute npc_nether_drake npc_daranelle go_legion_obelisk -go_thunderspike EndContentData */ #include "ScriptMgr.h" @@ -45,171 +42,6 @@ EndContentData */ #include "SpellAuraEffects.h" /*###### -## npc_bloodmaul_brutebane -######*/ - -enum Bloodmaul -{ - NPC_OGRE_BRUTE = 19995, - NPC_QUEST_CREDIT = 21241, - GO_KEG = 184315, - QUEST_GETTING_THE_BLADESPIRE_TANKED = 10512, - QUEST_BLADESPIRE_KEGGER = 10545 -}; - -class npc_bloodmaul_brutebane : public CreatureScript -{ -public: - npc_bloodmaul_brutebane() : CreatureScript("npc_bloodmaul_brutebane") { } - - struct npc_bloodmaul_brutebaneAI : public ScriptedAI - { - npc_bloodmaul_brutebaneAI(Creature* creature) : ScriptedAI(creature) - { - if (Creature* Ogre = me->FindNearestCreature(NPC_OGRE_BRUTE, 50, true)) - { - Ogre->SetReactState(REACT_DEFENSIVE); - Ogre->GetMotionMaster()->MovePoint(1, me->GetPositionX()-1, me->GetPositionY()+1, me->GetPositionZ()); - } - } - - void UpdateAI(uint32 /*diff*/) override { } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_bloodmaul_brutebaneAI(creature); - } -}; - -/*###### -## npc_bloodmaul_brute -######*/ - -enum BloodmaulBrute -{ - EVENT_CLEAVE = 1, - EVENT_DEBILITATING_STRIKE = 2, - SAY_AGGRO = 0, - SAY_DEATH = 1, - SAY_ENRAGE = 2, - SPELL_CLEAVE = 15496, - SPELL_DEBILITATING_STRIKE = 37577, - SPELL_ENRAGE = 8599, - QUEST_INTO_THE_SOULGRINDER = 11000 -}; - -class npc_bloodmaul_brute : public CreatureScript -{ -public: - npc_bloodmaul_brute() : CreatureScript("npc_bloodmaul_brute") { } - - struct npc_bloodmaul_bruteAI : public ScriptedAI - { - npc_bloodmaul_bruteAI(Creature* creature) : ScriptedAI(creature) - { - hp30 = false; - } - - void Reset() override - { - PlayerGUID.Clear(); - hp30 = false; - } - - void EnterCombat(Unit* /*who*/) override - { - if (urand (0, 100) < 35) - Talk(SAY_AGGRO); - - events.ScheduleEvent(EVENT_CLEAVE, urand(9000,12000)); - events.ScheduleEvent(EVENT_DEBILITATING_STRIKE, 15000); - } - - void JustDied(Unit* killer) override - { - if (killer->GetTypeId() == TYPEID_PLAYER) - if (killer->ToPlayer()->GetQuestRewardStatus(QUEST_INTO_THE_SOULGRINDER)) - Talk(SAY_DEATH); - } - - void MoveInLineOfSight(Unit* who) override - { - if (!who || (!who->IsAlive())) - return; - - if (me->IsWithinDistInMap(who, 50.0f)) - { - if (who->GetTypeId() == TYPEID_PLAYER) - if (who->ToPlayer()->GetQuestStatus(QUEST_GETTING_THE_BLADESPIRE_TANKED) == QUEST_STATUS_INCOMPLETE - || who->ToPlayer()->GetQuestStatus(QUEST_BLADESPIRE_KEGGER) == QUEST_STATUS_INCOMPLETE) - PlayerGUID = who->GetGUID(); - } - } - - void MovementInform(uint32 /*type*/, uint32 id) override - { - if (id == 1) - { - if (GameObject* Keg = me->FindNearestGameObject(GO_KEG, 20)) - Keg->Delete(); - - me->HandleEmoteCommand(7); - me->SetReactState(REACT_AGGRESSIVE); - me->GetMotionMaster()->MoveTargetedHome(); - - Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID); - Creature* Credit = me->FindNearestCreature(NPC_QUEST_CREDIT, 50, true); - if (player && Credit) - player->KilledMonster(Credit->GetCreatureTemplate(), Credit->GetGUID()); - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_CLEAVE: - DoCast(me, SPELL_CLEAVE); - events.ScheduleEvent(EVENT_CLEAVE, urand(9000,12000)); - break; - case EVENT_DEBILITATING_STRIKE: - DoCastVictim(SPELL_DEBILITATING_STRIKE); - events.ScheduleEvent(EVENT_DEBILITATING_STRIKE, urand(18000,22000)); - break; - } - } - - if (!hp30 && HealthBelowPct(30)) - { - hp30 = true; - Talk(SAY_ENRAGE); - DoCast(me, SPELL_ENRAGE); - } - - DoMeleeAttackIfReady(); - } - - private: - EventMap events; - ObjectGuid PlayerGUID; - bool hp30; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_bloodmaul_bruteAI(creature); - } -}; - -/*###### ## npc_nether_drake ######*/ @@ -507,31 +339,6 @@ public: } }; -/*###### -## go_thunderspike -######*/ - -enum TheThunderspike -{ - NPC_GOR_GRIMGUT = 21319, - QUEST_THUNDERSPIKE = 10526, -}; - -class go_thunderspike : public GameObjectScript -{ - public: - go_thunderspike() : GameObjectScript("go_thunderspike") { } - - bool OnGossipHello(Player* player, GameObject* go) override - { - if (player->GetQuestStatus(QUEST_THUNDERSPIKE) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_GOR_GRIMGUT, 25.0f, true)) - if (Creature* gorGrimgut = go->SummonCreature(NPC_GOR_GRIMGUT, -2413.4f, 6914.48f, 25.01f, 3.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000)) - gorGrimgut->AI()->AttackStart(player); - - return true; - } -}; - enum SimonGame { NPC_SIMON_BUNNY = 22923, @@ -1219,12 +1026,9 @@ class spell_oscillating_field : public SpellScriptLoader void AddSC_blades_edge_mountains() { - new npc_bloodmaul_brutebane(); - new npc_bloodmaul_brute(); new npc_nether_drake(); new npc_daranelle(); new go_legion_obelisk(); - new go_thunderspike(); new npc_simon_bunny(); new go_simon_cluster(); new go_apexis_relic(); diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp index 96244ee5aae..b2000230347 100644 --- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp +++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp @@ -31,7 +31,6 @@ npc_enslaved_netherwing_drake npc_drake_dealer_hurlunk npcs_flanis_swiftwing_and_kagrosh npc_karynaku -npc_overlord_morghor npc_earthmender_wilda npc_torloth_the_magnificent npc_illidari_spawn @@ -677,331 +676,6 @@ class npc_karynaku : public CreatureScript }; /*#### -# npc_overlord_morghor -# this whole script is wrong and needs a rewrite.even the illidan npc used is the wrong one.npc id 23467 may be the correct one -####*/ -enum OverlordData -{ - QUEST_LORD_ILLIDAN_STORMRAGE = 11108, - - C_ILLIDAN = 22083, - C_YARZILL = 23141, - - SPELL_ONE = 39990, // Red Lightning Bolt - SPELL_TWO = 41528, // Mark of Stormrage - SPELL_THREE = 40216, // Dragonaw Faction - SPELL_FOUR = 42016, // Dragonaw Trasform - - OVERLORD_SAY_1 = 0, - OVERLORD_SAY_2 = 1, - //OVERLORD_SAY_3 = 2, - OVERLORD_SAY_4 = 3, - OVERLORD_SAY_5 = 4, - OVERLORD_SAY_6 = 5, - - OVERLORD_YELL_1 = 6, - OVERLORD_YELL_2 = 7, - - LORD_ILLIDAN_SAY_1 = 0, - LORD_ILLIDAN_SAY_2 = 1, - LORD_ILLIDAN_SAY_3 = 2, - LORD_ILLIDAN_SAY_4 = 3, - LORD_ILLIDAN_SAY_5 = 4, - LORD_ILLIDAN_SAY_6 = 5, - LORD_ILLIDAN_SAY_7 = 6, - - YARZILL_THE_MERC_SAY = 0 -}; - -class npc_overlord_morghor : public CreatureScript -{ -public: - npc_overlord_morghor() : CreatureScript("npc_overlord_morghor") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest *_Quest) override - { - if (_Quest->GetQuestId() == QUEST_LORD_ILLIDAN_STORMRAGE) - { - ENSURE_AI(npc_overlord_morghor::npc_overlord_morghorAI, creature->AI())->PlayerGUID = player->GetGUID(); - ENSURE_AI(npc_overlord_morghor::npc_overlord_morghorAI, creature->AI())->StartEvent(); - return true; - } - return false; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_overlord_morghorAI(creature); - } - - struct npc_overlord_morghorAI : public ScriptedAI - { - npc_overlord_morghorAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - PlayerGUID.Clear(); - IllidanGUID.Clear(); - - ConversationTimer = 0; - Step = 0; - - Event = false; - } - - ObjectGuid PlayerGUID; - ObjectGuid IllidanGUID; - - uint32 ConversationTimer; - uint32 Step; - - bool Event; - - void Reset() override - { - Initialize(); - me->SetUInt32Value(UNIT_NPC_FLAGS, 2); - } - - void StartEvent() - { - me->SetUInt32Value(UNIT_NPC_FLAGS, 0); - me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - Unit* Illidan = me->SummonCreature(C_ILLIDAN, -5107.83f, 602.584f, 85.2393f, 4.92598f, TEMPSUMMON_CORPSE_DESPAWN, 0); - if (Illidan) - { - IllidanGUID = Illidan->GetGUID(); - Illidan->SetVisible(false); - } - if (!PlayerGUID.IsEmpty()) - { - Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID); - if (player) - Talk(OVERLORD_SAY_1, player); - } - ConversationTimer = 4200; - Step = 0; - Event = true; - } - - uint32 NextStep(uint32 Step) - { - Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID); - Creature* Illi = ObjectAccessor::GetCreature(*me, IllidanGUID); - - if (!player) - { - EnterEvadeMode(); - return 0; - } - - switch (Step) - { - case 0: - return 0; - break; - case 1: - me->GetMotionMaster()->MovePoint(0, -5104.41f, 595.297f, 85.6838f); - return 9000; - break; - case 2: - Talk(OVERLORD_YELL_1, player); - return 4500; - break; - case 3: - me->SetInFront(player); - return 3200; - break; - case 4: - Talk(OVERLORD_SAY_2, player); - return 2000; - break; - case 5: - if (Illi) - { - Illi->SetVisible(true); - Illi->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - Illi->SetDisplayId(21526); - } - return 350; - break; - case 6: - if (Illi) - { - Illi->CastSpell(Illi, SPELL_ONE, true); - Illi->SetTarget(me->GetGUID()); - me->SetTarget(IllidanGUID); - } - return 2000; - break; - case 7: - Talk(OVERLORD_YELL_2); - return 4500; - break; - case 8: - me->SetUInt32Value(UNIT_FIELD_BYTES_1, 8); - return 2500; - break; - case 9: - // missing text "Lord Illidan, this is the Dragonmaw that I, and others, have told you about. He will lead us to victory!" - return 5000; - break; - case 10: - if (Illi) - Illi->AI()->Talk(LORD_ILLIDAN_SAY_1); - return 5000; - break; - case 11: - Talk(OVERLORD_SAY_4, player); - return 6000; - break; - case 12: - if (Illi) - Illi->AI()->Talk(LORD_ILLIDAN_SAY_2); - return 5500; - break; - case 13: - if (Illi) - Illi->AI()->Talk(LORD_ILLIDAN_SAY_3); - return 4000; - break; - case 14: - if (Illi) - Illi->SetTarget(PlayerGUID); - return 1500; - break; - case 15: - if (Illi) - Illi->AI()->Talk(LORD_ILLIDAN_SAY_4); - return 1500; - break; - case 16: - if (Illi) - Illi->CastSpell(player, SPELL_TWO, true); - player->RemoveAurasDueToSpell(SPELL_THREE); - player->RemoveAurasDueToSpell(SPELL_FOUR); - return 5000; - break; - case 17: - if (Illi) - Illi->AI()->Talk(LORD_ILLIDAN_SAY_5); - return 5000; - break; - case 18: - if (Illi) - Illi->AI()->Talk(LORD_ILLIDAN_SAY_6); - return 5000; - break; - case 19: - if (Illi) - Illi->AI()->Talk(LORD_ILLIDAN_SAY_7); - return 5000; - break; - case 20: - if (Illi) - { - Illi->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - Illi->SetDisableGravity(true); - } - return 500; - break; - case 21: - Talk(OVERLORD_SAY_5); - return 500; - break; - case 22: - if (Illi) - { - Illi->SetVisible(false); - Illi->setDeathState(JUST_DIED); - } - return 1000; - break; - case 23: - me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - return 2000; - break; - case 24: - me->SetTarget(PlayerGUID); - return 5000; - break; - case 25: - Talk(OVERLORD_SAY_6); - return 2000; - break; - case 26: - player->GroupEventHappens(QUEST_LORD_ILLIDAN_STORMRAGE, me); - return 6000; - break; - case 27: - { - Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50.0f); - if (Yarzill) - Yarzill->SetTarget(PlayerGUID); - return 500; - } - break; - case 28: - player->RemoveAurasDueToSpell(SPELL_TWO); - player->RemoveAurasDueToSpell(41519); - player->CastSpell(player, SPELL_THREE, true); - player->CastSpell(player, SPELL_FOUR, true); - return 1000; - break; - case 29: - { - if (Creature* Yarzill = me->FindNearestCreature(C_YARZILL, 50.0f)) - Yarzill->AI()->Talk(YARZILL_THE_MERC_SAY, player); - return 5000; - } - break; - case 30: - { - if (Creature* Yarzill = me->FindNearestCreature(C_YARZILL, 50.0f)) - Yarzill->SetTarget(ObjectGuid::Empty); - return 5000; - } - break; - case 31: - { - if (Creature* Yarzill = me->FindNearestCreature(C_YARZILL, 50.0f)) - Yarzill->CastSpell(player, 41540, true); - return 1000; - } - break; - case 32: - me->GetMotionMaster()->MovePoint(0, -5085.77f, 577.231f, 86.6719f); - return 5000; - break; - case 33: - me->SetTarget(ObjectGuid::Empty); - Reset(); - return 100; - break; - default : - return 0; - break; - } - } - - void UpdateAI(uint32 diff) override - { - if (!ConversationTimer) - return; - - if (ConversationTimer <= diff) - { - if (Event && !PlayerGUID.IsEmpty()) - ConversationTimer = NextStep(++Step); - } else ConversationTimer -= diff; - } - }; -}; - -/*#### # npc_earthmender_wilda ####*/ @@ -2026,7 +1700,6 @@ void AddSC_shadowmoon_valley() new npc_drake_dealer_hurlunk(); new npcs_flanis_swiftwing_and_kagrosh(); new npc_karynaku(); - new npc_overlord_morghor(); new npc_earthmender_wilda(); new npc_lord_illidan_stormrage(); new go_crystal_prison(); diff --git a/src/server/scripts/World/chat_log.cpp b/src/server/scripts/World/chat_log.cpp index 87dba586678..c11d2a0ac14 100644 --- a/src/server/scripts/World/chat_log.cpp +++ b/src/server/scripts/World/chat_log.cpp @@ -95,17 +95,17 @@ class ChatLogScript : public PlayerScript player->GetName().c_str(), msg.c_str()); break; - case CHAT_MSG_BATTLEGROUND: + case CHAT_MSG_INSTANCE_CHAT: if (lang != LANG_ADDON) - TC_LOG_DEBUG("chat.log.bg", "Player %s tells battleground with leader %s: %s", + TC_LOG_DEBUG("chat.log.bg", "Player %s tells instance with leader %s: %s", player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str()); else - TC_LOG_DEBUG("chat.log.addon.bg", "Player %s tells battleground with leader %s: %s", + TC_LOG_DEBUG("chat.log.addon.bg", "Player %s tells instance with leader %s: %s", player->GetName().c_str(), group ? group->GetLeaderName() : "<unknown>", msg.c_str()); break; - case CHAT_MSG_BATTLEGROUND_LEADER: - TC_LOG_DEBUG("chat.log.bg", "Leader player %s tells battleground: %s", + case CHAT_MSG_INSTANCE_CHAT_LEADER: + TC_LOG_DEBUG("chat.log.bg", "Leader player %s tells instance: %s", player->GetName().c_str(), msg.c_str()); break; } diff --git a/src/server/shared/Common.cpp b/src/server/shared/Common.cpp index 56e3c4faaf5..22560012b49 100644 --- a/src/server/shared/Common.cpp +++ b/src/server/shared/Common.cpp @@ -18,7 +18,8 @@ #include "Common.h" -char const* localeNames[TOTAL_LOCALES] = { +char const* localeNames[TOTAL_LOCALES] = +{ "enUS", "koKR", "frFR", @@ -27,13 +28,16 @@ char const* localeNames[TOTAL_LOCALES] = { "zhTW", "esES", "esMX", - "ruRU" + "ruRU", + "none", + "ptBR", + "itIT" }; LocaleConstant GetLocaleByName(const std::string& name) { for (uint32 i = 0; i < TOTAL_LOCALES; ++i) - if (name==localeNames[i]) + if (name == localeNames[i]) return LocaleConstant(i); return LOCALE_enUS; // including enGB case diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h index 4c5773d5eb5..11c9ad3b27f 100644 --- a/src/server/shared/Common.h +++ b/src/server/shared/Common.h @@ -114,13 +114,18 @@ enum LocaleConstant LOCALE_zhTW = 5, LOCALE_esES = 6, LOCALE_esMX = 7, - LOCALE_ruRU = 8 + LOCALE_ruRU = 8, + LOCALE_none = 9, + LOCALE_ptBR = 10, + LOCALE_itIT = 11, + + TOTAL_LOCALES }; -const uint8 TOTAL_LOCALES = 9; +const uint8 OLD_TOTAL_LOCALES = 9; /// @todo convert in simple system #define DEFAULT_LOCALE LOCALE_enUS -#define MAX_LOCALES 8 +#define MAX_LOCALES 11 extern char const* localeNames[TOTAL_LOCALES]; diff --git a/src/server/shared/Database/Implementation/HotfixDatabase.cpp b/src/server/shared/Database/Implementation/HotfixDatabase.cpp index 7f148f95e00..e13863d9326 100644 --- a/src/server/shared/Database/Implementation/HotfixDatabase.cpp +++ b/src/server/shared/Database/Implementation/HotfixDatabase.cpp @@ -118,6 +118,9 @@ void HotfixDatabaseConnection::DoPrepareStatements() // PhaseGroup.db2 PrepareStatement(HOTFIX_SEL_PHASE_GROUP, "SELECT ID, PhaseID, PhaseGroupID FROM phase_group ORDER BY ID DESC", CONNECTION_SYNCH); + // QuestPackageItem.db2 + PrepareStatement(HOTFIX_SEL_QUEST_PACKAGE_ITEM, "SELECT ID, QuestPackageID, ItemID, ItemCount, FilterType FROM quest_package_item ORDER BY ID DESC", CONNECTION_SYNCH); + // SoundEntries.db2 PrepareStatement(HOTFIX_SEL_SOUND_ENTRIES, "SELECT ID, SoundType, Name, FileDataID1, FileDataID2, FileDataID3, FileDataID4, FileDataID5, " "FileDataID6, FileDataID7, FileDataID8, FileDataID9, FileDataID10, FileDataID11, FileDataID12, FileDataID13, FileDataID14, FileDataID15, " diff --git a/src/server/shared/Database/Implementation/HotfixDatabase.h b/src/server/shared/Database/Implementation/HotfixDatabase.h index 70472537510..3d8e528cd98 100644 --- a/src/server/shared/Database/Implementation/HotfixDatabase.h +++ b/src/server/shared/Database/Implementation/HotfixDatabase.h @@ -86,6 +86,8 @@ enum HotfixDatabaseStatements HOTFIX_SEL_OVERRIDE_SPELL_DATA, HOTFIX_SEL_PHASE_GROUP, + + HOTFIX_SEL_QUEST_PACKAGE_ITEM, HOTFIX_SEL_SOUND_ENTRIES, HOTFIX_SEL_SOUND_ENTRIES_LOCALE, diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index ad3eb2c577f..70350f3136c 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -24,8 +24,10 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_REALMLIST, "SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild, Region, Battlegroup FROM realmlist WHERE flag <> 3 ORDER BY name", CONNECTION_SYNCH); PrepareStatement(LOGIN_DEL_EXPIRED_IP_BANS, "DELETE FROM ip_banned WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_IP_BANNED, "SELECT * FROM ip_banned WHERE ip = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC); + PrepareStatement(LOGIN_SEL_IP_INFO, "(SELECT unbandate > UNIX_TIMESTAMP() OR unbandate = bandate AS banned, NULL as country FROM ip_banned WHERE ip = ?) " + "UNION " + "(SELECT NULL AS banned, country FROM ip2nation WHERE INET_NTOA(ip) = ?)", CONNECTION_ASYNC); PrepareStatement(LOGIN_INS_IP_AUTO_BANNED, "INSERT INTO ip_banned (ip, bandate, unbandate, bannedby, banreason) VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity Auth', 'Failed login autoban')", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_IP_BANNED_ALL, "SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned WHERE (bandate = unbandate OR unbandate > UNIX_TIMESTAMP()) ORDER BY unbandate", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_IP_BANNED_BY_IP, "SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned WHERE (bandate = unbandate OR unbandate > UNIX_TIMESTAMP()) AND ip LIKE CONCAT('%%', ?, '%%') ORDER BY unbandate", CONNECTION_SYNCH); @@ -108,19 +110,16 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_INS_ACCOUNT_MUTE, "INSERT INTO account_muted VALUES (?, UNIX_TIMESTAMP(), ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_ACCOUNT_MUTE_INFO, "SELECT mutedate, mutetime, mutereason, mutedby FROM account_muted WHERE guid = ? ORDER BY mutedate ASC", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_INFO, "SELECT sha_pass_hash, id, locked, lock_country, last_ip, v, s FROM battlenet_accounts WHERE email = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_DEL_BNET_EXPIRED_BANS, "UPDATE battlenet_account_bans SET active = 0 WHERE active = 1 AND unbandate <> bandate AND unbandate <= UNIX_TIMESTAMP()", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_BNET_ACTIVE_ACCOUNT_BAN, "SELECT bandate, unbandate FROM battlenet_account_bans WHERE id = ? AND active = 1", CONNECTION_SYNCH); +#define BnetAccountInfo "ba.id, UPPER(ba.email), ba.locked, ba.lock_country, ba.last_ip, ba.failed_logins, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, bab.unbandate = bab.bandate" +#define BnetGameAccountInfo "a.id, a.username, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, ab.unbandate = ab.bandate, aa.gmlevel" + + PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_INFO, "SELECT " BnetAccountInfo ", ba.sha_pass_hash, ba.v, ba.s, " BnetGameAccountInfo " FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account a ON ba.id = a.battlenet_account LEFT JOIN account_banned ab ON a.id = ab.id LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID = -1 WHERE ba.email = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_BNET_VS_FIELDS, "UPDATE battlenet_accounts SET v = ?, s = ? WHERE email = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_BNET_SESSION_KEY, "UPDATE battlenet_accounts SET sessionKey = ?, online = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_BNET_RECONNECT_INFO, "SELECT ba.id, ba.sessionKey, a.id FROM battlenet_accounts ba LEFT JOIN account a ON ba.id = a.battlenet_account WHERE ba.email = ? AND a.username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNTS, "SELECT a.id, a.username, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE battlenet_account = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNT, "SELECT a.id, a.username, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE username = ? AND battlenet_account = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNT_UNNAMED, "SELECT a.id, a.username, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE battlenet_index = ? AND battlenet_account = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_BNET_FAILED_LOGINS, "SELECT failed_logins FROM battlenet_accounts WHERE id = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_BNET_RECONNECT_INFO, "SELECT " BnetAccountInfo ", ba.sessionKey, " BnetGameAccountInfo " FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account a ON ba.id = a.battlenet_account LEFT JOIN account_banned ab ON a.id = ab.id LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID = -1 WHERE ba.email = ? AND a.username = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_BNET_FAILED_LOGINS, "UPDATE battlenet_accounts SET failed_logins = failed_logins + 1 WHERE email = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO, "UPDATE battlenet_accounts SET last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS, "SELECT rc.numchars, r.id, r.Region, r.Battlegroup, r.gamebuild FROM realmcharacters rc INNER JOIN realmlist r ON rc.realmid = r.id WHERE rc.acctid = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS, "SELECT rc.numchars, r.id, r.Region, r.Battlegroup, r.gamebuild FROM realmcharacters rc INNER JOIN realmlist r ON rc.realmid = r.id WHERE rc.acctid = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_INS_BNET_ACCOUNT, "INSERT INTO battlenet_accounts (`email`,`sha_pass_hash`) VALUES (?, ?)", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_EMAIL_BY_ID, "SELECT email FROM battlenet_accounts WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_ID_BY_EMAIL, "SELECT id FROM battlenet_accounts WHERE email = ?", CONNECTION_SYNCH); diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index 727482ff533..c0aa178f199 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -45,7 +45,7 @@ enum LoginDatabaseStatements LOGIN_SEL_REALMLIST, LOGIN_DEL_EXPIRED_IP_BANS, LOGIN_UPD_EXPIRED_ACCOUNT_BANS, - LOGIN_SEL_IP_BANNED, + LOGIN_SEL_IP_INFO, LOGIN_INS_IP_AUTO_BANNED, LOGIN_SEL_ACCOUNT_BANNED_ALL, LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME, @@ -125,15 +125,9 @@ enum LoginDatabaseStatements LOGIN_SEL_ACCOUNT_MUTE_INFO, LOGIN_SEL_BNET_ACCOUNT_INFO, - LOGIN_DEL_BNET_EXPIRED_BANS, - LOGIN_SEL_BNET_ACTIVE_ACCOUNT_BAN, LOGIN_UPD_BNET_VS_FIELDS, LOGIN_UPD_BNET_SESSION_KEY, LOGIN_SEL_BNET_RECONNECT_INFO, - LOGIN_SEL_BNET_GAME_ACCOUNTS, - LOGIN_SEL_BNET_GAME_ACCOUNT, - LOGIN_SEL_BNET_GAME_ACCOUNT_UNNAMED, - LOGIN_SEL_BNET_FAILED_LOGINS, LOGIN_UPD_BNET_FAILED_LOGINS, LOGIN_UPD_BNET_LAST_LOGIN_INFO, LOGIN_SEL_BNET_CHARACTER_COUNTS, diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp index eeecc563854..28c4f43b1ea 100644 --- a/src/server/shared/Database/Implementation/WorldDatabase.cpp +++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp @@ -76,7 +76,7 @@ void WorldDatabaseConnection::DoPrepareStatements() PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_DEL_CREATURE, "DELETE FROM creature WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, permission, help FROM command", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, scale, rank, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_class, trainer_race, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); + PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, scale, rank, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_class, trainer_race, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_GAMEOBJECT_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM gameobject WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_", CONNECTION_SYNCH); diff --git a/src/server/shared/Networking/AsyncAcceptor.h b/src/server/shared/Networking/AsyncAcceptor.h index d22d553965b..2c50a38dd59 100644 --- a/src/server/shared/Networking/AsyncAcceptor.h +++ b/src/server/shared/Networking/AsyncAcceptor.h @@ -30,7 +30,7 @@ public: AsyncAcceptor(boost::asio::io_service& ioService, std::string const& bindIp, uint16 port) : _acceptor(ioService, tcp::endpoint(boost::asio::ip::address::from_string(bindIp), port)), - _socket(ioService) + _socket(ioService), _closed(false) { } @@ -55,13 +55,24 @@ public: } } - AsyncAcceptManaged(mgrHandler); + if (!_closed) + AsyncAcceptManaged(mgrHandler); }); } + void Close() + { + if (_closed.exchange(true)) + return; + + boost::system::error_code err; + _acceptor.close(err); + } + private: tcp::acceptor _acceptor; tcp::socket _socket; + std::atomic<bool> _closed; }; template<class T> @@ -83,7 +94,8 @@ void AsyncAcceptor::AsyncAccept() } // lets slap some more this-> on this so we can fix this bug with gcc 4.7.2 throwing internals in yo face - this->AsyncAccept<T>(); + if (!_closed) + this->AsyncAccept<T>(); }); } diff --git a/src/server/shared/Networking/NetworkThread.h b/src/server/shared/Networking/NetworkThread.h index 05ca99ea6a6..219bcb07fbb 100644 --- a/src/server/shared/Networking/NetworkThread.h +++ b/src/server/shared/Networking/NetworkThread.h @@ -147,6 +147,8 @@ protected: } TC_LOG_DEBUG("misc", "Network Thread exits"); + _newSockets.clear(); + _Sockets.clear(); } private: diff --git a/src/server/shared/Networking/SocketMgr.h b/src/server/shared/Networking/SocketMgr.h index e18a2077288..c7689ec8395 100644 --- a/src/server/shared/Networking/SocketMgr.h +++ b/src/server/shared/Networking/SocketMgr.h @@ -33,8 +33,7 @@ class SocketMgr public: virtual ~SocketMgr() { - delete _acceptor; - delete[] _threads; + ASSERT(!_threads && !_acceptor && !_threadCount, "StopNetwork must be called prior to SocketMgr destruction"); } virtual bool StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port) @@ -69,11 +68,19 @@ public: virtual void StopNetwork() { + _acceptor->Close(); + if (_threadCount != 0) for (int32 i = 0; i < _threadCount; ++i) _threads[i].Stop(); Wait(); + + delete _acceptor; + _acceptor = nullptr; + delete[] _threads; + _threads = nullptr; + _threadCount = 0; } void Wait() diff --git a/src/server/shared/Updater/UpdateFetcher.cpp b/src/server/shared/Updater/UpdateFetcher.cpp index 2b12f39780c..a4bdd193743 100644 --- a/src/server/shared/Updater/UpdateFetcher.cpp +++ b/src/server/shared/Updater/UpdateFetcher.cpp @@ -158,7 +158,7 @@ uint32 UpdateFetcher::Update(bool const redundancyChecks, bool const allowRehash { LocaleFileStorage const available = GetFileList(); AppliedFileStorage applied = ReceiveAppliedFiles(); - + // Fill hash to name cache HashToFileNameStorage hashToName; for (auto entry : applied) diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index ba4bcd765e7..e00a9cbd8c9 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -3315,6 +3315,7 @@ Logger.sql.sql=5,Console DBErrors Logger.sql.updates=3,Console Server #Logger.achievement=3,Console Server +#Logger.addon=3,Console Server #Logger.ahbot=3,Console Server #Logger.auctionHouse=3,Console Server #Logger.bg.arena=3,Console Server @@ -3350,6 +3351,7 @@ Logger.sql.updates=3,Console Server #Logger.phase=3,Console Server #Logger.pool=3,Console Server #Logger.rbac=3,Console Server +#Logger.scenes=3,Console Server #Logger.scripts=3,Console Server #Logger.scripts.ai=3,Console Server #Logger.server.bnetserver=3,Console Server |
