don't reload serverlist when switching between lan and global. Closes #1281

This commit is contained in:
oy 2015-11-01 20:05:26 +01:00
parent ee567f7769
commit fae0115bd8
5 changed files with 182 additions and 113 deletions

View file

@ -33,13 +33,27 @@ inline int GetNewToken()
return random_int() & 0x7FFFFFFF;
}
//
void CServerBrowser::CServerlist::Clear()
{
m_ServerlistHeap.Reset();
m_NumServers = 0;
m_NumPlayers = 0;
mem_zero(m_aServerlistIp, sizeof(m_aServerlistIp));
}
//
CServerBrowser::CServerBrowser()
{
m_pMasterServer = 0;
//
mem_zero(m_aServerlistIp, sizeof(m_aServerlistIp));
for(int i = 0; i < NUM_TYPES; ++i)
{
m_aServerlist[i].Clear();
m_aServerlist[i].m_NumServerCapacity = 0;
m_aServerlist[i].m_ppServerlist = 0;
}
m_pFirstReqServer = 0; // request list
m_pLastReqServer = 0;
@ -47,15 +61,10 @@ CServerBrowser::CServerBrowser()
m_NeedRefresh = 0;
m_NumServers = 0;
m_NumServerCapacity = 0;
m_NumPlayers = 0;
// the token is to keep server refresh separated from each other
m_CurrentLanToken = 1;
m_ServerlistType = 0;
m_ActServerlistType = 0;
m_BroadcastTime = 0;
}
@ -69,20 +78,23 @@ void CServerBrowser::Init(class CNetClient *pNetClient, const char *pNetVersion)
m_ServerBrowserFilter.Init(Kernel()->RequestInterface<IFriends>(), pNetVersion);
}
void CServerBrowser::Set(const NETADDR &Addr, int Type, int Token, const CServerInfo *pInfo)
void CServerBrowser::Set(const NETADDR &Addr, int SetType, int Token, const CServerInfo *pInfo)
{
CServerEntry *pEntry = 0;
if(Type == SET_MASTER_ADD)
switch(SetType)
{
if(m_ServerlistType != IServerBrowser::TYPE_INTERNET)
case SET_MASTER_ADD:
{
if(!(m_RefreshFlags&IServerBrowser::REFRESHFLAG_INTERNET))
return;
if(!Find(Addr))
if(!Find(IServerBrowser::TYPE_INTERNET, Addr))
{
pEntry = Add(Addr);
pEntry = Add(IServerBrowser::TYPE_INTERNET, Addr);
QueueRequest(pEntry);
}
}
break;
/*else if(Type == SET_FAV_ADD)
{
if(m_ServerlistType != IServerBrowser::TYPE_FAVORITES)
@ -94,26 +106,41 @@ void CServerBrowser::Set(const NETADDR &Addr, int Type, int Token, const CServer
QueueRequest(pEntry);
}
}*/
else if(Type == SET_TOKEN)
case SET_TOKEN:
{
if(m_ServerlistType == IServerBrowser::TYPE_LAN && Token != m_CurrentLanToken)
return;
int Type;
pEntry = Find(Addr);
if(!pEntry && m_ServerlistType == IServerBrowser::TYPE_LAN && m_BroadcastTime+time_freq() >= time_get())
pEntry = Add(Addr);
if(pEntry && ((pEntry->m_InfoState == CServerEntry::STATE_PENDING && Token == pEntry->m_CurrentToken) || m_ServerlistType == IServerBrowser::TYPE_LAN))
// internet entry
if(m_RefreshFlags&IServerBrowser::REFRESHFLAG_INTERNET)
{
SetInfo(pEntry, *pInfo);
if(m_ServerlistType == IServerBrowser::TYPE_LAN)
Type = IServerBrowser::TYPE_INTERNET;
pEntry = Find(Type, Addr);
if(pEntry && (pEntry->m_InfoState != CServerEntry::STATE_PENDING || Token != pEntry->m_CurrentToken))
pEntry = 0;
}
// lan entry
if(!pEntry && (m_RefreshFlags&IServerBrowser::REFRESHFLAG_LAN) && m_BroadcastTime+time_freq() >= time_get())
{
Type = IServerBrowser::TYPE_LAN;
pEntry = Add(Type, Addr);
}
// set info
if(pEntry)
{
SetInfo(Type, pEntry, *pInfo);
if(Type == IServerBrowser::TYPE_LAN)
pEntry->m_Info.m_Latency = min(static_cast<int>((time_get()-m_BroadcastTime)*1000/time_freq()), 999);
else
pEntry->m_Info.m_Latency = min(static_cast<int>((time_get()-pEntry->m_RequestTime)*1000/time_freq()), 999);
RemoveRequest(pEntry);
}
}
}
m_ServerBrowserFilter.Sort(m_ppServerlist, m_NumServers, CServerBrowserFilter::RESORT_FLAG_FORCE);
if(pEntry)
m_ServerBrowserFilter.Sort(m_aServerlist[m_ActServerlistType].m_ppServerlist, m_aServerlist[m_ActServerlistType].m_NumServers, CServerBrowserFilter::RESORT_FLAG_FORCE);
}
void CServerBrowser::Update(bool ForceResort)
@ -190,35 +217,44 @@ void CServerBrowser::Update(bool ForceResort)
const NETADDR *pFavAddr = m_ServerBrowserFavorites.UpdateFavorites();
if(pFavAddr)
{
CServerEntry *pEntry = Find(*pFavAddr);
for(int i = 0; i < NUM_TYPES; ++i)
{
CServerEntry *pEntry = Find(i, *pFavAddr);
if(pEntry)
pEntry->m_Info.m_Favorite = 1;
if(i == m_ActServerlistType)
ForceResort = true;
}
}
m_ServerBrowserFilter.Sort(m_ppServerlist, m_NumServers, ForceResort ? CServerBrowserFilter::RESORT_FLAG_FORCE : 0);
m_ServerBrowserFilter.Sort(m_aServerlist[m_ActServerlistType].m_ppServerlist, m_aServerlist[m_ActServerlistType].m_NumServers, ForceResort ? CServerBrowserFilter::RESORT_FLAG_FORCE : 0);
}
// interface functions
void CServerBrowser::Refresh(int Type)
void CServerBrowser::SetType(int Type)
{
if(Type < 0 || Type >= NUM_TYPES && Type != m_ActServerlistType)
return;
m_ActServerlistType = Type;
m_ServerBrowserFilter.Sort(m_aServerlist[m_ActServerlistType].m_ppServerlist, m_aServerlist[m_ActServerlistType].m_NumServers, CServerBrowserFilter::RESORT_FLAG_FORCE);
}
void CServerBrowser::Refresh(int RefreshFlags)
{
m_RefreshFlags = RefreshFlags;
if(RefreshFlags&IServerBrowser::REFRESHFLAG_LAN)
{
// clear out everything
m_ServerlistHeap.Reset();
m_NumServers = 0;
m_NumPlayers = 0;
m_aServerlist[IServerBrowser::TYPE_LAN].Clear();
if(m_ActServerlistType == IServerBrowser::TYPE_LAN)
m_ServerBrowserFilter.Clear();
mem_zero(m_aServerlistIp, sizeof(m_aServerlistIp));
m_pFirstReqServer = 0;
m_pLastReqServer = 0;
m_NumRequests = 0;
// next token
m_CurrentLanToken = GetNewToken();
//
m_ServerlistType = Type;
if(Type == IServerBrowser::TYPE_LAN)
{
CPacker Packer;
Packer.Reset();
Packer.AddRaw(SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO));
@ -243,8 +279,19 @@ void CServerBrowser::Refresh(int Type)
if(g_Config.m_Debug)
m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", "broadcasting for servers");
}
else if(Type == IServerBrowser::TYPE_INTERNET)
if(RefreshFlags&IServerBrowser::REFRESHFLAG_INTERNET)
{
// clear out everything
m_aServerlist[IServerBrowser::TYPE_INTERNET].Clear();
if(m_ActServerlistType == IServerBrowser::TYPE_INTERNET)
m_ServerBrowserFilter.Clear();
m_pFirstReqServer = 0;
m_pLastReqServer = 0;
m_NumRequests = 0;
m_NeedRefresh = 1;
}
/*else if(Type == IServerBrowser::TYPE_FAVORITES)
{
for(int i = 0; i < m_NumFavoriteServers; i++)
@ -255,11 +302,11 @@ void CServerBrowser::Refresh(int Type)
int CServerBrowser::LoadingProgression() const
{
if(m_NumServers == 0)
if(m_aServerlist[m_ActServerlistType].m_NumServers == 0)
return 0;
int Servers = m_NumServers;
int Loaded = m_NumServers-m_NumRequests;
int Servers = m_aServerlist[m_ActServerlistType].m_NumServers;
int Loaded = m_aServerlist[m_ActServerlistType].m_NumServers-m_NumRequests;
return 100.0f * Loaded/Servers;
}
@ -267,12 +314,18 @@ void CServerBrowser::AddFavorite(const CServerInfo *pInfo)
{
if(m_ServerBrowserFavorites.AddFavoriteEx(pInfo->m_aHostname, &pInfo->m_NetAddr, true))
{
CServerEntry *pEntry = Find(pInfo->m_NetAddr);
for(int i = 0; i < NUM_TYPES; ++i)
{
CServerEntry *pEntry = Find(i, pInfo->m_NetAddr);
if(pEntry)
{
pEntry->m_Info.m_Favorite = 1;
// refresh servers in all filters where favorites are filtered
m_ServerBrowserFilter.Sort(m_ppServerlist, m_NumServers, CServerBrowserFilter::RESORT_FLAG_FAV);
if(i == m_ActServerlistType)
m_ServerBrowserFilter.Sort(m_aServerlist[m_ActServerlistType].m_ppServerlist, m_aServerlist[m_ActServerlistType].m_NumServers, CServerBrowserFilter::RESORT_FLAG_FAV);
}
}
}
}
@ -280,20 +333,26 @@ void CServerBrowser::RemoveFavorite(const CServerInfo *pInfo)
{
if(m_ServerBrowserFavorites.RemoveFavoriteEx(pInfo->m_aHostname, &pInfo->m_NetAddr))
{
CServerEntry *pEntry = Find(pInfo->m_NetAddr);
for(int i = 0; i < NUM_TYPES; ++i)
{
CServerEntry *pEntry = Find(i, pInfo->m_NetAddr);
if(pEntry)
{
pEntry->m_Info.m_Favorite = 0;
// refresh servers in all filters where favorites are filtered
m_ServerBrowserFilter.Sort(m_ppServerlist, m_NumServers, CServerBrowserFilter::RESORT_FLAG_FAV);
if(i == m_ActServerlistType)
m_ServerBrowserFilter.Sort(m_aServerlist[m_ActServerlistType].m_ppServerlist, m_aServerlist[m_ActServerlistType].m_NumServers, CServerBrowserFilter::RESORT_FLAG_FAV);
}
}
}
}
// manipulate entries
CServerEntry *CServerBrowser::Add(const NETADDR &Addr)
CServerEntry *CServerBrowser::Add(int ServerlistType, const NETADDR &Addr)
{
// create new pEntry
CServerEntry *pEntry = (CServerEntry *)m_ServerlistHeap.Allocate(sizeof(CServerEntry));
CServerEntry *pEntry = (CServerEntry *)m_aServerlist[ServerlistType].m_ServerlistHeap.Allocate(sizeof(CServerEntry));
mem_zero(pEntry, sizeof(CServerEntry));
// set the info
@ -313,39 +372,39 @@ CServerEntry *CServerBrowser::Add(const NETADDR &Addr)
// add to the hash list
int Hash = AddrHash(&Addr);
pEntry->m_pNextIp = m_aServerlistIp[Hash];
m_aServerlistIp[Hash] = pEntry;
pEntry->m_pNextIp = m_aServerlist[ServerlistType].m_aServerlistIp[Hash];
m_aServerlist[ServerlistType].m_aServerlistIp[Hash] = pEntry;
if(m_NumServers == m_NumServerCapacity)
if(m_aServerlist[ServerlistType].m_NumServers == m_aServerlist[ServerlistType].m_NumServerCapacity)
{
if(m_NumServerCapacity == 0)
if(m_aServerlist[ServerlistType].m_NumServerCapacity == 0)
{
// alloc start size
m_NumServerCapacity = 1000;
m_ppServerlist = (CServerEntry **)mem_alloc(m_NumServerCapacity*sizeof(CServerEntry*), 1);
m_aServerlist[ServerlistType].m_NumServerCapacity = 1000;
m_aServerlist[ServerlistType].m_ppServerlist = (CServerEntry **)mem_alloc(m_aServerlist[ServerlistType].m_NumServerCapacity*sizeof(CServerEntry*), 1);
}
else
{
// increase size
m_NumServerCapacity += 100;
CServerEntry **ppNewlist = (CServerEntry **)mem_alloc(m_NumServerCapacity*sizeof(CServerEntry*), 1);
mem_copy(ppNewlist, m_ppServerlist, m_NumServers*sizeof(CServerEntry*));
mem_free(m_ppServerlist);
m_ppServerlist = ppNewlist;
m_aServerlist[ServerlistType].m_NumServerCapacity += 100;
CServerEntry **ppNewlist = (CServerEntry **)mem_alloc(m_aServerlist[ServerlistType].m_NumServerCapacity*sizeof(CServerEntry*), 1);
mem_copy(ppNewlist, m_aServerlist[ServerlistType].m_ppServerlist, m_aServerlist[ServerlistType].m_NumServers*sizeof(CServerEntry*));
mem_free(m_aServerlist[ServerlistType].m_ppServerlist);
m_aServerlist[ServerlistType].m_ppServerlist = ppNewlist;
}
}
// add to list
m_ppServerlist[m_NumServers] = pEntry;
pEntry->m_Info.m_ServerIndex = m_NumServers;
m_NumServers++;
m_aServerlist[ServerlistType].m_ppServerlist[m_aServerlist[ServerlistType].m_NumServers] = pEntry;
pEntry->m_Info.m_ServerIndex = m_aServerlist[ServerlistType].m_NumServers;
m_aServerlist[ServerlistType].m_NumServers++;
return pEntry;
}
CServerEntry *CServerBrowser::Find(const NETADDR &Addr)
CServerEntry *CServerBrowser::Find(int ServerlistType, const NETADDR &Addr)
{
for(CServerEntry *pEntry = m_aServerlistIp[AddrHash(&Addr)]; pEntry; pEntry = pEntry->m_pNextIp)
for(CServerEntry *pEntry = m_aServerlist[ServerlistType].m_aServerlistIp[AddrHash(&Addr)]; pEntry; pEntry = pEntry->m_pNextIp)
{
if(net_addr_comp(&pEntry->m_Addr, &Addr) == 0)
return pEntry;
@ -418,7 +477,7 @@ void CServerBrowser::RequestImpl(const NETADDR &Addr, CServerEntry *pEntry) cons
}
}
void CServerBrowser::SetInfo(CServerEntry *pEntry, const CServerInfo &Info)
void CServerBrowser::SetInfo(int ServerlistType, CServerEntry *pEntry, const CServerInfo &Info)
{
int Fav = pEntry->m_Info.m_Favorite;
pEntry->m_Info = Info;
@ -435,7 +494,7 @@ void CServerBrowser::SetInfo(CServerEntry *pEntry, const CServerInfo &Info)
pEntry->m_Info.m_Favorite = Fav;
pEntry->m_Info.m_NetAddr = pEntry->m_Addr;
m_NumPlayers += pEntry->m_Info.m_NumPlayers;
m_aServerlist[ServerlistType].m_NumPlayers += pEntry->m_Info.m_NumPlayers;
pEntry->m_InfoState = CServerEntry::STATE_READY;
}

View file

@ -20,21 +20,22 @@ public:
CServerBrowser();
void Init(class CNetClient *pClient, const char *pNetVersion);
void Set(const NETADDR &Addr, int Type, int Token, const CServerInfo *pInfo);
void Set(const NETADDR &Addr, int SetType, int Token, const CServerInfo *pInfo);
void Update(bool ForceResort);
// interface functions
void Refresh(int Type);
void SetType(int Type);
void Refresh(int RefreshFlags);
bool IsRefreshing() const { return m_pFirstReqServer != 0; }
bool IsRefreshingMasters() const { return m_pMasterServer->IsRefreshing(); }
int LoadingProgression() const;
int NumServers() const { return m_NumServers; }
int NumPlayers() const { return m_NumPlayers; }
int NumServers() const { return m_aServerlist[m_ActServerlistType].m_NumServers; }
int NumPlayers() const { return m_aServerlist[m_ActServerlistType].m_NumPlayers; }
int NumSortedServers(int Index) const { return m_ServerBrowserFilter.GetNumSortedServers(Index); }
int NumSortedPlayers(int Index) const { return m_ServerBrowserFilter.GetNumSortedPlayers(Index); }
const CServerInfo *SortedGet(int FilterIndex, int Index) const { return &m_ppServerlist[m_ServerBrowserFilter.GetIndex(FilterIndex, Index)]->m_Info; };
const CServerInfo *SortedGet(int FilterIndex, int Index) const { return &m_aServerlist[m_ActServerlistType].m_ppServerlist[m_ServerBrowserFilter.GetIndex(FilterIndex, Index)]->m_Info; };
const void *GetID(int FilterIndex, int Index) const { return m_ServerBrowserFilter.GetID(FilterIndex, Index); };
bool IsFavorite(const NETADDR &Addr) { return m_ServerBrowserFavorites.FindFavoriteByAddr(Addr, 0) != 0; }
@ -53,36 +54,42 @@ private:
class CServerBrowserFavorites m_ServerBrowserFavorites;
class CServerBrowserFilter m_ServerBrowserFilter;
// serverlist
int m_ActServerlistType;
class CServerlist
{
public:
class CHeap m_ServerlistHeap;
//
CServerEntry *m_aServerlistIp[256]; // ip hash list
int m_NumPlayers;
int m_NumServers;
int m_NumServerCapacity;
CServerEntry *m_aServerlistIp[256]; // ip hash list
CServerEntry **m_ppServerlist;
void Clear();
} m_aServerlist[NUM_TYPES];
CServerEntry *m_pFirstReqServer; // request list
CServerEntry *m_pLastReqServer;
int m_NumRequests;
int m_NeedRefresh;
int m_NumServers;
int m_NumServerCapacity;
int m_NumPlayers;
// the token is to keep server refresh separated from each other
int m_CurrentLanToken;
int m_ServerlistType;
int m_RefreshFlags;
int64 m_BroadcastTime;
CServerEntry *Add(const NETADDR &Addr);
CServerEntry *Find(const NETADDR &Addr);
CServerEntry *Add(int ServerlistType, const NETADDR &Addr);
CServerEntry *Find(int ServerlistType, const NETADDR &Addr);
void QueueRequest(CServerEntry *pEntry);
void RemoveRequest(CServerEntry *pEntry);
void RequestImpl(const NETADDR &Addr, CServerEntry *pEntry) const;
void SetInfo(CServerEntry *pEntry, const CServerInfo &Info);
void SetInfo(int ServerlistType, CServerEntry *pEntry, const CServerInfo &Info);
};
#endif

View file

@ -87,7 +87,11 @@ public:
QUICK_MAPNAME=4,
TYPE_INTERNET = 0,
TYPE_LAN = 1,
TYPE_LAN,
NUM_TYPES,
REFRESHFLAG_INTERNET=1,
REFRESHFLAG_LAN=2,
FLAG_PASSWORD =1,
FLAG_PURE =2,
@ -107,7 +111,8 @@ public:
FILTER_PING=65536,
};
virtual void Refresh(int Type) = 0;
virtual void SetType(int Type) = 0;
virtual void Refresh(int RefreshFlags) = 0;
virtual bool IsRefreshing() const = 0;
virtual bool IsRefreshingMasters() const = 0;
virtual int LoadingProgression() const = 0;

View file

@ -1154,7 +1154,7 @@ void CMenus::RenderMenubar(CUIRect r)
if(DoButton_MenuTabTop(&s_InternetButton, Localize("Global"), m_ActivePage==PAGE_INTERNET, &Button))
{
m_pClient->m_pCamera->ChangePosition(CCamera::POS_INTERNET);
ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET);
ServerBrowser()->SetType(IServerBrowser::TYPE_INTERNET);
NewPage = PAGE_INTERNET;
g_Config.m_UiBrowserPage = PAGE_INTERNET;
}
@ -1165,7 +1165,7 @@ void CMenus::RenderMenubar(CUIRect r)
if(DoButton_MenuTabTop(&s_LanButton, Localize("Local"), m_ActivePage==PAGE_LAN, &Button))
{
m_pClient->m_pCamera->ChangePosition(CCamera::POS_LAN);
ServerBrowser()->Refresh(IServerBrowser::TYPE_LAN);
ServerBrowser()->SetType(IServerBrowser::TYPE_LAN);
NewPage = PAGE_LAN;
g_Config.m_UiBrowserPage = PAGE_LAN;
}
@ -1598,10 +1598,8 @@ int CMenus::Render()
{
// refresh server browser before we are in browser menu to save time
m_pClient->m_pCamera->ChangePosition(CCamera::POS_START);
if(g_Config.m_UiBrowserPage == PAGE_LAN)
ServerBrowser()->Refresh(IServerBrowser::TYPE_LAN);
else
ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET);
ServerBrowser()->Refresh(IServerBrowser::REFRESHFLAG_INTERNET|IServerBrowser::REFRESHFLAG_LAN);
ServerBrowser()->SetType(g_Config.m_UiBrowserPage == PAGE_LAN ? IServerBrowser::TYPE_LAN : IServerBrowser::TYPE_INTERNET);
m_pClient->m_pSounds->Enqueue(CSounds::CHN_MUSIC, SOUND_MENU);
s_First = false;

View file

@ -1596,9 +1596,9 @@ void CMenus::RenderServerbrowserBottomBox(CUIRect MainView)
if(DoButton_Menu(&s_RefreshButton, Localize("Refresh"), 0, &Button))
{
if(m_MenuPage == PAGE_INTERNET)
ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET);
ServerBrowser()->Refresh(IServerBrowser::REFRESHFLAG_INTERNET);
else if(m_MenuPage == PAGE_LAN)
ServerBrowser()->Refresh(IServerBrowser::TYPE_LAN);
ServerBrowser()->Refresh(IServerBrowser::REFRESHFLAG_LAN);
}
MainView.VSplitLeft(Spacing, 0, &MainView); // little space