aboutsummaryrefslogtreecommitdiff
path: root/src/server/bnetserver/Server
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2014-10-11 15:13:30 +0200
committerShauren <shauren.trinity@gmail.com>2014-10-11 15:13:30 +0200
commit56cf7ff2a8f1e0a710544ec6300a21cfa44c0f73 (patch)
treeccad474a9cfad3df6528ebde146164a40738e73f /src/server/bnetserver/Server
parent35b14f15e171b303a6306db745762ca5be7cb4e4 (diff)
Core/Battle.net: Implemented updating realm list after initial login
Diffstat (limited to 'src/server/bnetserver/Server')
-rw-r--r--src/server/bnetserver/Server/Session.cpp110
-rw-r--r--src/server/bnetserver/Server/Session.h15
-rw-r--r--src/server/bnetserver/Server/SessionManager.cpp12
-rw-r--r--src/server/bnetserver/Server/SessionManager.h20
4 files changed, 109 insertions, 48 deletions
diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp
index 1d8e0136af3..301a6b9bae1 100644
--- a/src/server/bnetserver/Server/Session.cpp
+++ b/src/server/bnetserver/Server/Session.cpp
@@ -38,7 +38,7 @@ Battlenet::Session::ModuleHandler const Battlenet::Session::ModuleHandlers[MODUL
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(),
- _reconnectProof(), _crypt(), _authed(false)
+ _reconnectProof(), _crypt(), _authed(false), _subscribedToRealmListUpdates(false)
{
static uint8 const N_Bytes[] =
{
@@ -398,8 +398,6 @@ void Battlenet::Session::HandleLogoutRequest(Connection::LogoutRequest const& /*
void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& /*listSubscribeRequest*/)
{
- sRealmList->UpdateIfNeed();
-
WoWRealm::ListSubscribeResponse* listSubscribeResponse = new WoWRealm::ListSubscribeResponse();
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS);
@@ -411,58 +409,29 @@ void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeReque
{
Field* fields = countResult->Fetch();
uint32 build = fields[4].GetUInt32();
- listSubscribeResponse->CharacterCounts.push_back({ { fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32(), (_build != build ? build : 0) }, fields[0].GetUInt8() });
+ listSubscribeResponse->CharacterCounts.push_back({ RealmId(fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32(), (_build != build ? build : 0)), fields[0].GetUInt8() });
} while (countResult->NextRow());
}
- for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i)
- {
- Realm const& realm = i->second;
-
- uint32 flag = realm.flag & ~REALM_FLAG_SPECIFYBUILD;
- RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.gamebuild);
- if (realm.gamebuild != _build)
- {
- flag |= REALM_FLAG_INVALID;
- if (buildInfo)
- flag |= REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for
- }
-
- WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate();
- listUpdate->Timezone = realm.timezone;
- listUpdate->Population = realm.populationLevel;
- listUpdate->Lock = (realm.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0;
- listUpdate->Type = realm.icon;
- listUpdate->Name = realm.name;
-
- if (flag & REALM_FLAG_SPECIFYBUILD)
- {
- std::ostringstream version;
- version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build;
-
- listUpdate->Version = version.str();
- listUpdate->Address = realm.GetAddressForClient(GetRemoteIpAddress());
- listUpdate->Build = buildInfo->Build;
- }
-
- listUpdate->Flags = flag;
- listUpdate->Region = realm.Region;
- listUpdate->Battlegroup = realm.Battlegroup;
- listUpdate->Index = realm.m_ID;
-
- listSubscribeResponse->RealmData.push_back(listUpdate);
- }
+ for (RealmList::RealmMap::value_type const& i : sRealmList->GetRealms())
+ listSubscribeResponse->RealmData.push_back(BuildListUpdate(&i.second));
listSubscribeResponse->RealmData.push_back(new WoWRealm::ListComplete());
AsyncWrite(listSubscribeResponse);
+ _subscribedToRealmListUpdates = true;
+}
+
+void Battlenet::Session::HandleListUnsubscribe(WoWRealm::ListUnsubscribe const& /*listUnsubscribe*/)
+{
+ _subscribedToRealmListUpdates = false;
}
void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest)
{
WoWRealm::JoinResponseV2* joinResponse = new WoWRealm::JoinResponseV2();
Realm const* realm = sRealmList->GetRealm(joinRequest.Realm);
- if (!realm || realm->flag & (REALM_FLAG_INVALID | REALM_FLAG_OFFLINE))
+ if (!realm || realm->Flags & (REALM_FLAG_INVALID | REALM_FLAG_OFFLINE))
{
joinResponse->Response = WoWRealm::JoinResponseV2::FAILURE;
AsyncWrite(joinResponse);
@@ -491,13 +460,20 @@ void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& join
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);
- joinResponse->IPv4.emplace_back(realm->ExternalAddress, realm->port);
+ joinResponse->IPv4.emplace_back(realm->ExternalAddress, realm->Port);
if (realm->ExternalAddress != realm->LocalAddress)
- joinResponse->IPv4.emplace_back(realm->LocalAddress, realm->port);
+ joinResponse->IPv4.emplace_back(realm->LocalAddress, realm->Port);
AsyncWrite(joinResponse);
}
+void Battlenet::Session::HandleSocialNetworkCheckConnected(Friends::SocialNetworkCheckConnected const& socialNetworkCheckConnected)
+{
+ Friends::SocialNetworkCheckConnectedResult* socialNetworkCheckConnectedResult = new Friends::SocialNetworkCheckConnectedResult();
+ socialNetworkCheckConnectedResult->SocialNetworkId = socialNetworkCheckConnected.SocialNetworkId;
+ AsyncWrite(socialNetworkCheckConnectedResult);
+}
+
void Battlenet::Session::ReadHandler()
{
BitStream stream(std::move(GetReadBuffer()));
@@ -998,3 +974,49 @@ bool Battlenet::Session::UnhandledModule(BitStream* /*dataStream*/, ServerPacket
ReplaceResponse(response, logonResponse);
return false;
}
+
+void Battlenet::Session::UpdateRealms(std::vector<Realm const*>& realms, std::vector<RealmId>& deletedRealms)
+{
+ for (Realm const* realm : realms)
+ AsyncWrite(BuildListUpdate(realm));
+
+ for (RealmId& deleted : deletedRealms)
+ {
+ WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate();
+ listUpdate->UpdateState = WoWRealm::ListUpdate::DELETED;
+ listUpdate->Id = deleted;
+ AsyncWrite(listUpdate);
+ }
+}
+
+Battlenet::WoWRealm::ListUpdate* Battlenet::Session::BuildListUpdate(Realm const* realm) const
+{
+ uint32 flag = realm->Flags & ~REALM_FLAG_SPECIFYBUILD;
+ RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm->Id.Build);
+ if (realm->Id.Build != _build)
+ {
+ flag |= REALM_FLAG_INVALID;
+ if (buildInfo)
+ flag |= REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for
+ }
+
+ WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate();
+ listUpdate->Timezone = realm->Timezone;
+ listUpdate->Population = realm->PopulationLevel;
+ listUpdate->Lock = (realm->AllowedSecurityLevel > _accountSecurityLevel) ? 1 : 0;
+ listUpdate->Type = realm->Type;
+ listUpdate->Name = realm->Name;
+
+ if (flag & REALM_FLAG_SPECIFYBUILD)
+ {
+ std::ostringstream version;
+ version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build;
+
+ listUpdate->Version = version.str();
+ listUpdate->Address = realm->GetAddressForClient(GetRemoteIpAddress());
+ }
+
+ listUpdate->Flags = flag;
+ listUpdate->Id = realm->Id;
+ return listUpdate;
+}
diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h
index 41caadbab3f..7def3c70460 100644
--- a/src/server/bnetserver/Server/Session.h
+++ b/src/server/bnetserver/Server/Session.h
@@ -25,6 +25,7 @@
#include <memory>
#include <boost/asio/ip/tcp.hpp>
+struct Realm;
using boost::asio::ip::tcp;
namespace Battlenet
@@ -73,12 +74,23 @@ namespace Battlenet
// WoWRealm
void HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& listSubscribeRequest);
+ void HandleListUnsubscribe(WoWRealm::ListUnsubscribe const& listUnsubscribe);
void HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest);
+ // Friends
+ void HandleSocialNetworkCheckConnected(Friends::SocialNetworkCheckConnected const& socialNetworkCheckConnected);
+
void Start() override;
+ void UpdateRealms(std::vector<Realm const*>& realms, std::vector<RealmId>& deletedRealms);
+
void AsyncWrite(ServerPacket* packet);
+ uint32 GetAccountId() const { return _accountId; }
+ uint32 GetGameAccountId() const { return _gameAccountId; }
+
+ bool IsSubscribedToRealmListUpdates() const { return _subscribedToRealmListUpdates; }
+
protected:
void ReadHandler() override;
@@ -94,6 +106,8 @@ namespace Battlenet
bool HandleResumeModule(BitStream* dataStream, ServerPacket** response);
bool UnhandledModule(BitStream* dataStream, ServerPacket** response);
+ WoWRealm::ListUpdate* BuildListUpdate(Realm const* realm) const;
+
uint32 _accountId;
std::string _accountName;
std::string _locale;
@@ -121,6 +135,7 @@ namespace Battlenet
PacketCrypt _crypt;
bool _authed;
+ bool _subscribedToRealmListUpdates;
};
}
diff --git a/src/server/bnetserver/Server/SessionManager.cpp b/src/server/bnetserver/Server/SessionManager.cpp
index d8b6bfca8d1..caa17364038 100644
--- a/src/server/bnetserver/Server/SessionManager.cpp
+++ b/src/server/bnetserver/Server/SessionManager.cpp
@@ -35,3 +35,15 @@ void Battlenet::SessionManager::OnSocketAccept(tcp::socket&& sock)
{
sSessionMgr.OnSocketOpen(std::forward<tcp::socket>(sock));
}
+
+void Battlenet::SessionManager::AddSession(Session* session)
+{
+ std::unique_lock<boost::shared_mutex> lock(_sessionMutex);
+ _sessions[{ session->GetAccountId(), session->GetGameAccountId() }] = session;
+}
+
+void Battlenet::SessionManager::RemoveSession(Session* session)
+{
+ std::unique_lock<boost::shared_mutex> lock(_sessionMutex);
+ _sessions.erase({ session->GetAccountId(), session->GetGameAccountId() });
+}
diff --git a/src/server/bnetserver/Server/SessionManager.h b/src/server/bnetserver/Server/SessionManager.h
index 10e7196e4d8..4f8e0d9fa97 100644
--- a/src/server/bnetserver/Server/SessionManager.h
+++ b/src/server/bnetserver/Server/SessionManager.h
@@ -20,6 +20,8 @@
#include "Session.h"
#include "SocketMgr.h"
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
namespace Battlenet
{
@@ -28,7 +30,7 @@ namespace Battlenet
struct SessionInfo
{
uint32 AccountId;
- uint32 GameAccountIndex;
+ uint32 GameAccountId;
bool operator<(SessionInfo const& right) const
{
@@ -41,6 +43,7 @@ namespace Battlenet
class SessionManager : SocketMgr<Session>
{
typedef SocketMgr<Session> BaseSocketMgr;
+ typedef std::map<SessionInfo, Session*> SessionMap;
public:
static SessionManager& Instance()
@@ -52,9 +55,17 @@ namespace Battlenet
bool StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port) override;
// noop for now, will be needed later to broadcast realmlist updates for example
- void AddSession(Session* /*session*/) { }
+ void AddSession(Session* /*session*/);
- void RemoveSession(Session* /*session*/) { }
+ void RemoveSession(Session* /*session*/);
+
+ template<typename Iterator>
+ void LockedForEach(Iterator iterator)
+ {
+ boost::shared_lock<boost::shared_mutex> lock(_sessionMutex);
+ for (SessionMap::value_type const& pair : _sessions)
+ iterator(pair.second);
+ }
protected:
NetworkThread<Session>* CreateThreads() const override;
@@ -62,7 +73,8 @@ namespace Battlenet
private:
static void OnSocketAccept(tcp::socket&& sock);
- std::map<SessionInfo, Session> _sessions;
+ SessionMap _sessions;
+ boost::shared_mutex _sessionMutex;
};
}