diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 87e2a1cce..82049dca5 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -508,7 +508,7 @@ void CClient::Connect(const char *pAddress) ServerInfoRequest(); - if(net_host_lookup(m_aServerAddressStr, &m_ServerAddress, m_NetClient.NetType()) != 0) + if(net_addr_from_str(&m_ServerAddress, m_aServerAddressStr) != 0 && net_host_lookup(m_aServerAddressStr, &m_ServerAddress, m_NetClient.NetType()) != 0) { char aBufMsg[256]; str_format(aBufMsg, sizeof(aBufMsg), "could not find the address of %s, connecting to localhost", aBuf); @@ -947,7 +947,7 @@ void CClient::ProcessConnlessPacket(CNetChunk *pPacket) } Addr.port = (pAddrs[i].m_aPort[0]<<8) | pAddrs[i].m_aPort[1]; - m_ServerBrowser.Set(Addr, IServerBrowser::SET_MASTER_ADD, -1, 0x0); + m_ServerBrowser.Set(Addr, CServerBrowser::SET_MASTER_ADD, -1, 0x0); } } @@ -962,6 +962,7 @@ void CClient::ProcessConnlessPacket(CNetChunk *pPacket) int Token = Up.GetInt(); str_copy(Info.m_aVersion, Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), sizeof(Info.m_aVersion)); str_copy(Info.m_aName, Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), sizeof(Info.m_aName)); + str_copy(Info.m_aHostname, Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), sizeof(Info.m_aHostname)); str_copy(Info.m_aMap, Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), sizeof(Info.m_aMap)); str_copy(Info.m_aGameType, Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), sizeof(Info.m_aGameType)); Info.m_Flags = (Up.GetInt()&SERVERINFO_FLAG_PASSWORD) ? IServerBrowser::FLAG_PASSWORD : 0; @@ -977,6 +978,8 @@ void CClient::ProcessConnlessPacket(CNetChunk *pPacket) return; net_addr_str(&pPacket->m_Address, Info.m_aAddress, sizeof(Info.m_aAddress), true); + if(Info.m_aHostname[0] == 0) + str_copy(Info.m_aHostname, Info.m_aAddress, sizeof(Info.m_aHostname)); for(int i = 0; i < Info.m_NumClients; i++) { @@ -999,7 +1002,7 @@ void CClient::ProcessConnlessPacket(CNetChunk *pPacket) m_CurrentServerInfoRequestTime = -1; } else - m_ServerBrowser.Set(pPacket->m_Address, IServerBrowser::SET_TOKEN, Token, &Info); + m_ServerBrowser.Set(pPacket->m_Address, CServerBrowser::SET_TOKEN, Token, &Info); } } } @@ -2067,22 +2070,6 @@ void CClient::Con_RconAuth(IConsole::IResult *pResult, void *pUserData) pSelf->RconAuth("", pResult->GetString(0)); } -void CClient::Con_AddFavorite(IConsole::IResult *pResult, void *pUserData) -{ - CClient *pSelf = (CClient *)pUserData; - NETADDR Addr; - if(net_addr_from_str(&Addr, pResult->GetString(0)) == 0) - pSelf->m_ServerBrowser.AddFavorite(Addr); -} - -void CClient::Con_RemoveFavorite(IConsole::IResult *pResult, void *pUserData) -{ - CClient *pSelf = (CClient *)pUserData; - NETADDR Addr; - if(net_addr_from_str(&Addr, pResult->GetString(0)) == 0) - pSelf->m_ServerBrowser.RemoveFavorite(Addr); -} - const char *CClient::DemoPlayer_Play(const char *pFilename, int StorageType) { int Crc; @@ -2236,8 +2223,6 @@ void CClient::RegisterCommands() m_pConsole->Register("record", "?s", CFGFLAG_CLIENT, Con_Record, this, "Record to the file"); m_pConsole->Register("stoprecord", "", CFGFLAG_CLIENT, Con_StopRecord, this, "Stop recording"); m_pConsole->Register("add_demomarker", "", CFGFLAG_CLIENT, Con_AddDemoMarker, this, "Add demo timeline marker"); - m_pConsole->Register("add_favorite", "s", CFGFLAG_CLIENT, Con_AddFavorite, this, "Add a server as a favorite"); - m_pConsole->Register("remove_favorite", "s", CFGFLAG_CLIENT, Con_RemoveFavorite, this, "Remove a server from favorites"); // used for server browser update m_pConsole->Chain("br_filter_string", ConchainServerBrowserUpdate, this); diff --git a/src/engine/client/serverbrowser.cpp b/src/engine/client/serverbrowser.cpp index 152181cf3..bda9c9b8f 100644 --- a/src/engine/client/serverbrowser.cpp +++ b/src/engine/client/serverbrowser.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -33,8 +34,12 @@ CServerBrowser::CServerBrowser() { m_pMasterServer = 0; + // favorites m_NumFavoriteServers = 0; + m_FavLookup.m_LookupCount = 0; + m_FavLookup.m_Active = false; + // mem_zero(m_aServerlistIp, sizeof(m_aServerlistIp)); m_pFirstReqServer = 0; // request list @@ -106,10 +111,14 @@ void CServerBrowser::SetBaseInfo(class CNetClient *pClient, const char *pNetVers str_copy(m_aNetVersion, pNetVersion, sizeof(m_aNetVersion)); m_pMasterServer = Kernel()->RequestInterface(); m_pConsole = Kernel()->RequestInterface(); + m_pEngine = Kernel()->RequestInterface(); m_pFriends = Kernel()->RequestInterface(); IConfig *pConfig = Kernel()->RequestInterface(); if(pConfig) pConfig->RegisterCallback(ConfigSaveCallback, this); + + m_pConsole->Register("add_favorite", "s", CFGFLAG_CLIENT, ConAddFavorite, this, "Add a server as a favorite"); + m_pConsole->Register("remove_favorite", "s", CFGFLAG_CLIENT, ConRemoveFavorite, this, "Remove a server from favorites"); } const CServerInfo *CServerBrowser::SortedGet(int FilterIndex, int Index) const @@ -179,7 +188,6 @@ bool CServerBrowser::CServerFilter::SortCompareNumClients(int Index1, int Index2 void CServerBrowser::CServerFilter::Filter() { - int i = 0, p = 0; int NumServers = m_pServerBrowser->m_NumServers; m_NumSortedServers = 0; m_NumPlayers = 0; @@ -189,12 +197,12 @@ void CServerBrowser::CServerFilter::Filter() { if(m_pSortedServerlist) mem_free(m_pSortedServerlist); - m_NumSortedServersCapacity = NumServers; + m_NumSortedServersCapacity = max(1000, NumServers+NumServers/2); m_pSortedServerlist = (int *)mem_alloc(m_NumSortedServersCapacity*sizeof(int), 1); } // filter the servers - for(i = 0; i < NumServers; i++) + for(int i = 0; i < NumServers; i++) { int Filtered = 0; @@ -227,7 +235,7 @@ void CServerBrowser::CServerFilter::Filter() { Filtered = 1; // match against player country - for(p = 0; p < m_pServerBrowser->m_ppServerlist[i]->m_Info.m_NumClients; p++) + for(int p = 0; p < m_pServerBrowser->m_ppServerlist[i]->m_Info.m_NumClients; p++) { if(m_pServerBrowser->m_ppServerlist[i]->m_Info.m_aClients[p].m_Country == m_Country) { @@ -251,7 +259,7 @@ void CServerBrowser::CServerFilter::Filter() } // match against players - for(p = 0; p < m_pServerBrowser->m_ppServerlist[i]->m_Info.m_NumClients; p++) + for(int p = 0; p < m_pServerBrowser->m_ppServerlist[i]->m_Info.m_NumClients; p++) { if(str_find_nocase(m_pServerBrowser->m_ppServerlist[i]->m_Info.m_aClients[p].m_aName, g_Config.m_BrFilterString) || str_find_nocase(m_pServerBrowser->m_ppServerlist[i]->m_Info.m_aClients[p].m_aClan, g_Config.m_BrFilterString)) @@ -278,7 +286,7 @@ void CServerBrowser::CServerFilter::Filter() { // check for friend m_pServerBrowser->m_ppServerlist[i]->m_Info.m_FriendState = IFriends::FRIEND_NO; - for(p = 0; p < m_pServerBrowser->m_ppServerlist[i]->m_Info.m_NumClients; p++) + for(int p = 0; p < m_pServerBrowser->m_ppServerlist[i]->m_Info.m_NumClients; p++) { m_pServerBrowser->m_ppServerlist[i]->m_Info.m_aClients[p].m_FriendState = m_pServerBrowser->m_pFriends->GetFriendState(m_pServerBrowser->m_ppServerlist[i]->m_Info.m_aClients[p].m_aName, m_pServerBrowser->m_ppServerlist[i]->m_Info.m_aClients[p].m_aClan); @@ -319,17 +327,24 @@ void CServerBrowser::CServerFilter::Sort() Filter(); // sort - if(g_Config.m_BrSort == IServerBrowser::SORT_NAME) + switch(g_Config.m_BrSort) + { + case IServerBrowser::SORT_NAME: std::stable_sort(m_pSortedServerlist, m_pSortedServerlist+m_NumSortedServers, SortWrap(this, &CServerBrowser::CServerFilter::SortCompareName)); - else if(g_Config.m_BrSort == IServerBrowser::SORT_PING) + break; + case IServerBrowser::SORT_PING: std::stable_sort(m_pSortedServerlist, m_pSortedServerlist+m_NumSortedServers, SortWrap(this, &CServerBrowser::CServerFilter::SortComparePing)); - else if(g_Config.m_BrSort == IServerBrowser::SORT_MAP) + break; + case IServerBrowser::SORT_MAP: std::stable_sort(m_pSortedServerlist, m_pSortedServerlist+m_NumSortedServers, SortWrap(this, &CServerBrowser::CServerFilter::SortCompareMap)); - else if(g_Config.m_BrSort == IServerBrowser::SORT_NUMPLAYERS) + break; + case IServerBrowser::SORT_NUMPLAYERS: std::stable_sort(m_pSortedServerlist, m_pSortedServerlist+m_NumSortedServers, SortWrap(this, g_Config.m_BrFilterSpectators ? &CServerBrowser::CServerFilter::SortCompareNumPlayers : &CServerBrowser::CServerFilter::SortCompareNumClients)); - else if(g_Config.m_BrSort == IServerBrowser::SORT_GAMETYPE) + break; + case IServerBrowser::SORT_GAMETYPE: std::stable_sort(m_pSortedServerlist, m_pSortedServerlist+m_NumSortedServers, SortWrap(this, &CServerBrowser::CServerFilter::SortCompareGametype)); + } // set indexes /*for(i = 0; i < m_NumSortedServers; i++) @@ -358,9 +373,18 @@ void CServerBrowser::RemoveRequest(CServerEntry *pEntry) } } +inline int AddrHash(const NETADDR *pAddr) +{ + if(pAddr->type==NETTYPE_IPV4) + return (pAddr->ip[0]+pAddr->ip[1]+pAddr->ip[2]+pAddr->ip[3])&0xFF; + else + return (pAddr->ip[0]+pAddr->ip[1]+pAddr->ip[2]+pAddr->ip[3]+pAddr->ip[4]+pAddr->ip[5]+pAddr->ip[6]+pAddr->ip[7]+ + pAddr->ip[8]+pAddr->ip[9]+pAddr->ip[10]+pAddr->ip[11]+pAddr->ip[12]+pAddr->ip[13]+pAddr->ip[14]+pAddr->ip[15])&0xFF; +} + CServerBrowser::CServerEntry *CServerBrowser::Find(const NETADDR &Addr) { - CServerEntry *pEntry = m_aServerlistIp[Addr.ip[0]]; + CServerEntry *pEntry = m_aServerlistIp[AddrHash(&Addr)]; for(; pEntry; pEntry = pEntry->m_pNextIp) { @@ -407,12 +431,8 @@ void CServerBrowser::SetInfo(CServerEntry *pEntry, const CServerInfo &Info) CServerBrowser::CServerEntry *CServerBrowser::Add(const NETADDR &Addr) { - int Hash = Addr.ip[0]; - CServerEntry *pEntry = 0; - int i; - // create new pEntry - pEntry = (CServerEntry *)m_ServerlistHeap.Allocate(sizeof(CServerEntry)); + CServerEntry *pEntry = (CServerEntry *)m_ServerlistHeap.Allocate(sizeof(CServerEntry)); mem_zero(pEntry, sizeof(CServerEntry)); // set the info @@ -422,26 +442,37 @@ CServerBrowser::CServerEntry *CServerBrowser::Add(const NETADDR &Addr) pEntry->m_Info.m_Latency = 999; net_addr_str(&Addr, pEntry->m_Info.m_aAddress, sizeof(pEntry->m_Info.m_aAddress), true); str_copy(pEntry->m_Info.m_aName, pEntry->m_Info.m_aAddress, sizeof(pEntry->m_Info.m_aName)); + str_copy(pEntry->m_Info.m_aHostname, pEntry->m_Info.m_aAddress, sizeof(pEntry->m_Info.m_aHostname)); // check if it's a favorite - for(i = 0; i < m_NumFavoriteServers; i++) + for(int i = 0; i < m_NumFavoriteServers; i++) { - if(net_addr_comp(&Addr, &m_aFavoriteServers[i]) == 0) + if(m_aFavoriteServers[i].m_State >= FAVSTATE_ADDR && net_addr_comp(&Addr, &m_aFavoriteServers[i].m_Addr) == 0) pEntry->m_Info.m_Favorite = 1; } // add to the hash list + int Hash = AddrHash(&Addr); pEntry->m_pNextIp = m_aServerlistIp[Hash]; m_aServerlistIp[Hash] = pEntry; if(m_NumServers == m_NumServerCapacity) { - CServerEntry **ppNewlist; - m_NumServerCapacity += 100; - 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; + if(m_NumServerCapacity == 0) + { + // alloc start size + m_NumServerCapacity = 1000; + m_ppServerlist = (CServerEntry **)mem_alloc(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; + } } // add to list @@ -455,7 +486,7 @@ CServerBrowser::CServerEntry *CServerBrowser::Add(const NETADDR &Addr) void CServerBrowser::Set(const NETADDR &Addr, int Type, int Token, const CServerInfo *pInfo) { CServerEntry *pEntry = 0; - if(Type == IServerBrowser::SET_MASTER_ADD) + if(Type == SET_MASTER_ADD) { if(m_ServerlistType != IServerBrowser::TYPE_INTERNET) return; @@ -466,7 +497,7 @@ void CServerBrowser::Set(const NETADDR &Addr, int Type, int Token, const CServer QueueRequest(pEntry); } } - /*else if(Type == IServerBrowser::SET_FAV_ADD) + /*else if(Type == SET_FAV_ADD) { if(m_ServerlistType != IServerBrowser::TYPE_FAVORITES) return; @@ -477,7 +508,7 @@ void CServerBrowser::Set(const NETADDR &Addr, int Type, int Token, const CServer QueueRequest(pEntry); } }*/ - else if(Type == IServerBrowser::SET_TOKEN) + else if(Type == SET_TOKEN) { if(Token != m_CurrentToken) return; @@ -554,7 +585,8 @@ void CServerBrowser::Refresh(int Type) /*else if(Type == IServerBrowser::TYPE_FAVORITES) { for(int i = 0; i < m_NumFavoriteServers; i++) - Set(m_aFavoriteServers[i], IServerBrowser::SET_FAV_ADD, -1, 0); + if(m_aFavoriteServers[i].m_State >= FAVSTATE_ADDR) + Set(m_aFavoriteServers[i].m_Addr, SET_FAV_ADD, -1, 0); }*/ } @@ -666,6 +698,9 @@ void CServerBrowser::Update(bool ForceResort) pEntry = pEntry->m_pNextReq; } + // update favorites + UpdateFavorites(); + // check if we need to resort for(int i = 0; i < m_lFilters.size(); i++) { @@ -676,44 +711,162 @@ void CServerBrowser::Update(bool ForceResort) } -bool CServerBrowser::IsFavorite(const NETADDR &Addr) const +void CServerBrowser::UpdateFavorites() { - // search for the address - int i; - for(i = 0; i < m_NumFavoriteServers; i++) + // check if hostname lookup for favourites is done + if(m_FavLookup.m_Active && m_FavLookup.m_HostLookup.m_Job.Status() == CJob::STATE_DONE) { - if(net_addr_comp(&Addr, &m_aFavoriteServers[i]) == 0) - return true; + // check if favourite has not been removed in the meanwhile + if(m_FavLookup.m_FavoriteIndex != -1) + { + if(m_FavLookup.m_HostLookup.m_Job.Result() == 0) + { + CFavoriteServer *pEntry = FindFavoriteByAddr(m_FavLookup.m_HostLookup.m_Addr, 0); + if(pEntry) + { + // address is already in the list -> acquire hostname if existing entry lacks it and drop multiple address entry + if(pEntry->m_State != FAVSTATE_HOST) + { + str_copy(pEntry->m_aHostname, m_aFavoriteServers[m_FavLookup.m_FavoriteIndex].m_aHostname, sizeof(pEntry->m_aHostname)); + pEntry->m_State = FAVSTATE_HOST; + dbg_msg("test", "fav aquired hostname, %s", m_aFavoriteServers[m_FavLookup.m_FavoriteIndex].m_aHostname); + } + RemoveFavoriteEntry(m_FavLookup.m_FavoriteIndex); + dbg_msg("test", "fav removed multiple entry"); + } + else + { + // address wasn't in the list yet -> add it (optional check if hostname matches given address -> drop entry on fail) + if(m_aFavoriteServers[m_FavLookup.m_FavoriteIndex].m_State == FAVSTATE_LOOKUP || + net_addr_comp(&m_aFavoriteServers[m_NumFavoriteServers].m_Addr, &m_FavLookup.m_HostLookup.m_Addr) == 0) + { + m_aFavoriteServers[m_FavLookup.m_FavoriteIndex].m_Addr = m_FavLookup.m_HostLookup.m_Addr; + m_aFavoriteServers[m_FavLookup.m_FavoriteIndex].m_State = FAVSTATE_HOST; + CServerEntry *pEntry = Find(m_aFavoriteServers[m_FavLookup.m_FavoriteIndex].m_Addr); + if(pEntry) + pEntry->m_Info.m_Favorite = 1; + dbg_msg("test", "fav added, %s", m_aFavoriteServers[m_FavLookup.m_FavoriteIndex].m_aHostname); + } + else + { + RemoveFavoriteEntry(m_FavLookup.m_FavoriteIndex); + dbg_msg("test", "fav removed entry that failed hostname-address check"); + } + } + } + else + { + // hostname lookup failed + if(m_aFavoriteServers[m_FavLookup.m_FavoriteIndex].m_State == FAVSTATE_LOOKUP) + { + m_aFavoriteServers[m_FavLookup.m_FavoriteIndex].m_State = FAVSTATE_INVALID; + dbg_msg("test", "fav invalid, %s", m_aFavoriteServers[m_FavLookup.m_FavoriteIndex].m_aHostname); + } + else + { + RemoveFavoriteEntry(m_FavLookup.m_FavoriteIndex); + dbg_msg("test", "fav removed invalid check-based entry"); + } + } + } + m_FavLookup.m_Active = false; + } + + // add hostname lookup for favourites + if(m_FavLookup.m_LookupCount > 0 && !m_FavLookup.m_Active) + { + for(int i = 0; i < m_NumFavoriteServers; i++) + { + if(m_aFavoriteServers[i].m_State <= FAVSTATE_LOOKUPCHECK) + { + m_pEngine->HostLookup(&m_FavLookup.m_HostLookup, m_aFavoriteServers[i].m_aHostname, m_pNetClient->NetType()); + m_FavLookup.m_FavoriteIndex = i; + --m_FavLookup.m_LookupCount; + m_FavLookup.m_Active = true; + break; + } + } } - return false; } -void CServerBrowser::AddFavorite(const NETADDR &Addr) +CServerBrowser::CFavoriteServer *CServerBrowser::FindFavoriteByAddr(const NETADDR &Addr, int *Index) { - CServerEntry *pEntry; - - if(m_NumFavoriteServers == MAX_FAVORITES) - return; - - // make sure that we don't already have the server in our list for(int i = 0; i < m_NumFavoriteServers; i++) { - if(net_addr_comp(&Addr, &m_aFavoriteServers[i]) == 0) - return; + if(net_addr_comp(&Addr, &m_aFavoriteServers[i].m_Addr) == 0) + { + if(Index) + *Index = i; + return &m_aFavoriteServers[i]; + } } - // add the server to the list - m_aFavoriteServers[m_NumFavoriteServers++] = Addr; - pEntry = Find(Addr); - if(pEntry) - pEntry->m_Info.m_Favorite = 1; + return 0; +} + +CServerBrowser::CFavoriteServer *CServerBrowser::FindFavoriteByHostname(const char *pHostname, int *Index) +{ + for(int i = 0; i < m_NumFavoriteServers; i++) + { + if(str_comp(pHostname, m_aFavoriteServers[i].m_aHostname) == 0) + { + if(Index) + *Index = i; + return &m_aFavoriteServers[i]; + } + } + + return 0; +} + +void CServerBrowser::RemoveFavoriteEntry(int Index) +{ + mem_move(&m_aFavoriteServers[Index], &m_aFavoriteServers[Index+1], sizeof(CFavoriteServer)*(m_NumFavoriteServers-(Index+1))); + m_NumFavoriteServers--; +} + +void CServerBrowser::AddFavoriteEx(const char *pHostname, const NETADDR *pAddr, bool DoCheck) +{ + if(m_NumFavoriteServers == MAX_FAVORITES || FindFavoriteByHostname(pHostname, 0)) + return; + + // check if hostname is a net address string + if(net_addr_from_str(&m_aFavoriteServers[m_NumFavoriteServers].m_Addr, pHostname) == 0) + { + // make sure that we don't already have the server in our list + if(FindFavoriteByAddr(m_aFavoriteServers[m_NumFavoriteServers].m_Addr, 0) != 0) + return; + + // check if hostname does not match given address + if(DoCheck && net_addr_comp(&m_aFavoriteServers[m_NumFavoriteServers].m_Addr, pAddr) != 0) + return; + + // add the server to the list + m_aFavoriteServers[m_NumFavoriteServers].m_State = FAVSTATE_ADDR; + CServerEntry *pEntry = Find(m_aFavoriteServers[m_NumFavoriteServers].m_Addr); + if(pEntry) + pEntry->m_Info.m_Favorite = 1; + } + else + { + // prepare for hostname lookup + if(DoCheck) + { + m_aFavoriteServers[m_NumFavoriteServers].m_State = FAVSTATE_LOOKUPCHECK; + m_aFavoriteServers[m_NumFavoriteServers].m_Addr = *pAddr; + } + else + m_aFavoriteServers[m_NumFavoriteServers].m_State = FAVSTATE_LOOKUP; + ++m_FavLookup.m_LookupCount; + } + + str_copy(m_aFavoriteServers[m_NumFavoriteServers].m_aHostname, pHostname, sizeof(m_aFavoriteServers[m_NumFavoriteServers].m_aHostname)); + ++m_NumFavoriteServers; if(g_Config.m_Debug) { - char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr), true); char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "added fav, %s", aAddrStr); + str_format(aBuf, sizeof(aBuf), "added fav '%s' (%s)", pHostname); m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", aBuf); } @@ -726,24 +879,32 @@ void CServerBrowser::AddFavorite(const NETADDR &Addr) } } -void CServerBrowser::RemoveFavorite(const NETADDR &Addr) +void CServerBrowser::RemoveFavoriteEx(const char *pHostname, const NETADDR *pAddr) { - int i; - CServerEntry *pEntry; - - for(i = 0; i < m_NumFavoriteServers; i++) + // find favorite entry + int Index = 0; + CFavoriteServer *pFavEntry = FindFavoriteByHostname(pHostname, &Index); + if(pFavEntry == 0 && pAddr) + pFavEntry = FindFavoriteByAddr(*pAddr, &Index); + if(pFavEntry) { - if(net_addr_comp(&Addr, &m_aFavoriteServers[i]) == 0) + if(pFavEntry->m_State >= FAVSTATE_ADDR) { - mem_move(&m_aFavoriteServers[i], &m_aFavoriteServers[i+1], sizeof(NETADDR)*(m_NumFavoriteServers-(i+1))); - m_NumFavoriteServers--; - - pEntry = Find(Addr); + // invalidate favorite state for server entry + CServerEntry *pEntry = Find(pFavEntry->m_Addr); if(pEntry) - pEntry->m_Info.m_Favorite = 0; - - break; + pEntry->m_Info.m_Favorite = 0; } + else if(pFavEntry->m_State <= FAVSTATE_LOOKUPCHECK && m_FavLookup.m_FavoriteIndex == Index) + { + // skip result on favorite hostname lookup + m_FavLookup.m_FavoriteIndex = -1; + } + + // remove favorite + RemoveFavoriteEntry(Index); + if(m_FavLookup.m_FavoriteIndex > Index) + --m_FavLookup.m_FavoriteIndex; } // refresh servers in all filters where favorites are filtered @@ -755,16 +916,6 @@ void CServerBrowser::RemoveFavorite(const NETADDR &Addr) } } -bool CServerBrowser::IsRefreshing() const -{ - return m_pFirstReqServer != 0; -} - -bool CServerBrowser::IsRefreshingMasters() const -{ - return m_pMasterServer->IsRefreshing(); -} - int CServerBrowser::LoadingProgression() const { @@ -777,16 +928,26 @@ int CServerBrowser::LoadingProgression() const } +void CServerBrowser::ConAddFavorite(IConsole::IResult *pResult, void *pUserData) +{ + CServerBrowser *pSelf = static_cast(pUserData); + pSelf->AddFavoriteEx(pResult->GetString(0), 0, false); +} + +void CServerBrowser::ConRemoveFavorite(IConsole::IResult *pResult, void *pUserData) +{ + CServerBrowser *pSelf = static_cast(pUserData); + pSelf->RemoveFavoriteEx(pResult->GetString(0), 0); +} + void CServerBrowser::ConfigSaveCallback(IConfig *pConfig, void *pUserData) { CServerBrowser *pSelf = (CServerBrowser *)pUserData; - char aAddrStr[128]; char aBuffer[256]; for(int i = 0; i < pSelf->m_NumFavoriteServers; i++) { - net_addr_str(&pSelf->m_aFavoriteServers[i], aAddrStr, sizeof(aAddrStr), true); - str_format(aBuffer, sizeof(aBuffer), "add_favorite %s", aAddrStr); + str_format(aBuffer, sizeof(aBuffer), "add_favorite %s", pSelf->m_aFavoriteServers[i].m_aHostname); pConfig->WriteLine(aBuffer); } } diff --git a/src/engine/client/serverbrowser.h b/src/engine/client/serverbrowser.h index 1595179fc..b34a58317 100644 --- a/src/engine/client/serverbrowser.h +++ b/src/engine/client/serverbrowser.h @@ -9,6 +9,13 @@ class CServerBrowser : public IServerBrowser { public: + enum + { + SET_MASTER_ADD=1, + SET_FAV_ADD, + SET_TOKEN, + }; + class CServerEntry { public: @@ -23,11 +30,6 @@ public: CServerEntry *m_pNextReq; }; - enum - { - MAX_FAVORITES=256 - }; - class CServerFilter { public: @@ -72,8 +74,8 @@ public: // interface functions void Refresh(int Type); - bool IsRefreshing() const; - bool IsRefreshingMasters() const; + bool IsRefreshing() const { return m_pFirstReqServer != 0; } + bool IsRefreshingMasters() const { return m_pMasterServer->IsRefreshing(); } int LoadingProgression() const; int NumServers() const { return m_NumServers; } @@ -84,9 +86,9 @@ public: const CServerInfo *SortedGet(int FilterIndex, int Index) const; const void *GetID(int FilterIndex, int Index) const; - bool IsFavorite(const NETADDR &Addr) const; - void AddFavorite(const NETADDR &Addr); - void RemoveFavorite(const NETADDR &Addr); + bool IsFavorite(const NETADDR &Addr) { return FindFavoriteByAddr(Addr, 0) != 0; } + void AddFavorite(const CServerInfo *pEntry) { AddFavoriteEx(pEntry->m_aHostname, &pEntry->m_NetAddr, true); } + void RemoveFavorite(const CServerInfo *pEntry) { RemoveFavoriteEx(pEntry->m_aHostname, &pEntry->m_NetAddr); } // void Update(bool ForceResort); @@ -99,14 +101,49 @@ private: CNetClient *m_pNetClient; IMasterServer *m_pMasterServer; class IConsole *m_pConsole; + class IEngine *m_pEngine; class IFriends *m_pFriends; char m_aNetVersion[128]; CHeap m_ServerlistHeap; - NETADDR m_aFavoriteServers[MAX_FAVORITES]; + // favourite + enum + { + FAVSTATE_LOOKUP=0, + FAVSTATE_LOOKUPCHECK, + FAVSTATE_INVALID, + FAVSTATE_ADDR, + FAVSTATE_HOST, + + MAX_FAVORITES=256, + }; + + struct CFavoriteServer + { + char m_aHostname[128]; + NETADDR m_Addr; + int m_State; + } m_aFavoriteServers[MAX_FAVORITES]; + int m_NumFavoriteServers; + struct CFavoriteLookup + { + class CHostLookup m_HostLookup; + int m_FavoriteIndex; + int m_LookupCount; + bool m_Active; + } m_FavLookup; + + void UpdateFavorites(); + CFavoriteServer *FindFavoriteByAddr(const NETADDR &Addr, int *Index); + CFavoriteServer *FindFavoriteByHostname(const char *pHostname, int *Index); + void RemoveFavoriteEntry(int Index); + void AddFavoriteEx(const char *pHostname, const NETADDR *pAddr, bool DoCheck); + void RemoveFavoriteEx(const char *pHostname, const NETADDR *Addr); + + // CServerEntry *m_aServerlistIp[256]; // ip hash list CServerEntry **m_ppServerlist; @@ -138,6 +175,8 @@ private: void SetInfo(CServerEntry *pEntry, const CServerInfo &Info); + static void ConAddFavorite(IConsole::IResult *pResult, void *pUserData); + static void ConRemoveFavorite(IConsole::IResult *pResult, void *pUserData); static void ConfigSaveCallback(IConfig *pConfig, void *pUserData); }; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 65e864662..4e45da44a 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1089,6 +1089,7 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token) Packer.AddString(GameServer()->Version(), 32); Packer.AddString(g_Config.m_SvName, 64); + Packer.AddString(g_Config.m_SvHostname, 128); Packer.AddString(GetMapName(), 32); // gametype diff --git a/src/engine/serverbrowser.h b/src/engine/serverbrowser.h index 24544f3da..95fcb9587 100644 --- a/src/engine/serverbrowser.h +++ b/src/engine/serverbrowser.h @@ -46,6 +46,7 @@ public: int m_Latency; // in ms char m_aGameType[16]; char m_aName[64]; + char m_aHostname[128]; char m_aMap[32]; char m_aVersion[32]; char m_aAddress[NETADDR_MAXSTRSIZE]; @@ -78,10 +79,6 @@ public: TYPE_INTERNET = 0, TYPE_LAN = 1, - SET_MASTER_ADD=1, - SET_FAV_ADD, - SET_TOKEN, - FLAG_PASSWORD =1, FLAG_PURE =2, FLAG_PUREMAP =4, @@ -113,9 +110,9 @@ public: virtual const CServerInfo *SortedGet(int FilterIndex, int Index) const = 0; virtual const void *GetID(int FilterIndex, int Index) const = 0; - virtual bool IsFavorite(const NETADDR &Addr) const = 0; - virtual void AddFavorite(const NETADDR &Addr) = 0; - virtual void RemoveFavorite(const NETADDR &Addr) = 0; + virtual bool IsFavorite(const NETADDR &Addr) = 0; // todo: remove this + virtual void AddFavorite(const CServerInfo *pEntry) = 0; + virtual void RemoveFavorite(const CServerInfo *pEntry) = 0; virtual int AddFilter(int Flag, int Ping, int Country, const char* pGametype, const char* pServerAddress) = 0; virtual void SetFilter(int Index, int SortHash, int Ping, int Country, const char* pGametype, const char* pServerAddress) = 0; diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index 6329cf2fc..7c75461ff 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -76,6 +76,7 @@ MACRO_CONFIG_INT(GfxAsyncRender, gfx_asyncrender, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_ MACRO_CONFIG_INT(InpMousesens, inp_mousesens, 100, 5, 100000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Mouse sensitivity") MACRO_CONFIG_STR(SvName, sv_name, 128, "unnamed server", CFGFLAG_SERVER, "Server name") +MACRO_CONFIG_STR(SvHostname, sv_hostname, 128, "", CFGFLAG_SERVER, "Server hostname") MACRO_CONFIG_STR(Bindaddr, bindaddr, 128, "", CFGFLAG_CLIENT|CFGFLAG_SERVER|CFGFLAG_MASTER, "Address to bind the client/server to") MACRO_CONFIG_INT(SvPort, sv_port, 8303, 0, 0, CFGFLAG_SERVER, "Port to use for the server") MACRO_CONFIG_INT(SvExternalPort, sv_external_port, 0, 0, 0, CFGFLAG_SERVER, "External port to report to the master servers") diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index 1fd551e1d..e494fc29b 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -341,9 +341,9 @@ int CMenus::DoBrowserEntry(const void *pID, CUIRect *pRect, const CServerInfo *p if(DoButton_SpriteClean(IMAGE_BROWSERICONS, pEntry->m_Favorite ? SPRITE_BROWSERICON_STAR_ACTIVE : SPRITE_BROWSERICON_STAR_INACTIVE, &Button)) { if(!pEntry->m_Favorite) - ServerBrowser()->AddFavorite(pEntry->m_NetAddr); + ServerBrowser()->AddFavorite(pEntry); else - ServerBrowser()->RemoveFavorite(pEntry->m_NetAddr); + ServerBrowser()->RemoveFavorite(pEntry); } } else if(ID == COL_INFO) diff --git a/src/game/client/components/menus_ingame.cpp b/src/game/client/components/menus_ingame.cpp index de82cb2bd..04f1e6ee6 100644 --- a/src/game/client/components/menus_ingame.cpp +++ b/src/game/client/components/menus_ingame.cpp @@ -294,15 +294,15 @@ void CMenus::RenderServerInfo(CUIRect MainView) { CUIRect Button; - int IsFavorite = ServerBrowser()->IsFavorite(CurrentServerInfo.m_NetAddr); + bool IsFavorite = ServerBrowser()->IsFavorite(CurrentServerInfo.m_NetAddr); ServerInfo.HSplitBottom(20.0f, &ServerInfo, &Button); static int s_AddFavButton = 0; if(DoButton_CheckBox(&s_AddFavButton, Localize("Favorite"), IsFavorite, &Button)) { if(IsFavorite) - ServerBrowser()->RemoveFavorite(CurrentServerInfo.m_NetAddr); + ServerBrowser()->RemoveFavorite(&CurrentServerInfo); else - ServerBrowser()->AddFavorite(CurrentServerInfo.m_NetAddr); + ServerBrowser()->AddFavorite(&CurrentServerInfo); } } diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 091673272..ce2b4fe9f 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -350,9 +350,6 @@ void CGameClient::OnConnected() m_All.m_paComponents[i]->OnReset(); } - CServerInfo CurrentServerInfo; - Client()->GetServerInfo(&CurrentServerInfo); - m_ServerMode = SERVERMODE_PURE; // send the inital info