Add KoG tab in server browser

- As requested by qshar and KoG players
- Similar to DDNet tab
- Info fetched from servers-kog entry from https://info.ddnet.tw/info
- Also supports countries and types
- Doesn't inform whether map has been finished
- Generalized the code a bit but it's still ugly
- Depends on #1533, also shows KoG servers as official/verified
This commit is contained in:
def 2019-03-24 23:15:38 +01:00
parent 958778b441
commit bf576723a3
10 changed files with 271 additions and 168 deletions

View file

@ -490,15 +490,18 @@ CServerBrowser::CServerEntry *CServerBrowser::Add(const NETADDR &Addr)
}
// check if it's an official server
for(int i = 0; i < m_NumDDNetCountries; i++)
for(int Network = 0; Network < NUM_NETWORKS; Network++)
{
CDDNetCountry *pCntr = &m_aDDNetCountries[i];
for(int j = 0; j < pCntr->m_NumServers; j++)
for(int i = 0; i < m_aNetworks[Network].m_NumCountries; i++)
{
if(net_addr_comp(&Addr, &pCntr->m_aServers[j]) == 0)
CNetworkCountry *pCntr = &m_aNetworks[Network].m_aCountries[i];
for(int j = 0; j < pCntr->m_NumServers; j++)
{
pEntry->m_Info.m_Official = true;
break;
if(net_addr_comp(&Addr, &pCntr->m_aServers[j]) == 0)
{
pEntry->m_Info.m_Official = true;
break;
}
}
}
}
@ -561,6 +564,17 @@ void CServerBrowser::Set(const NETADDR &Addr, int Type, int Token, const CServer
QueueRequest(pEntry);
}
}
else if(Type == IServerBrowser::SET_KOG_ADD)
{
if(m_ServerlistType != IServerBrowser::TYPE_KOG)
return;
if(!Find(Addr))
{
pEntry = Add(Addr);
QueueRequest(pEntry);
}
}
else if(Type == IServerBrowser::SET_TOKEN)
{
int BasicToken = Token;
@ -678,12 +692,12 @@ void CServerBrowser::Refresh(int Type)
else if(Type == IServerBrowser::TYPE_DDNET)
{
// remove unknown elements of exclude list
DDNetCountryFilterClean();
DDNetTypeFilterClean();
CountryFilterClean(NETWORK_DDNET);
TypeFilterClean(NETWORK_DDNET);
for(int i = 0; i < m_NumDDNetCountries; i++)
for(int i = 0; i < m_aNetworks[NETWORK_DDNET].m_NumCountries; i++)
{
CDDNetCountry *pCntr = &m_aDDNetCountries[i];
CNetworkCountry *pCntr = &m_aNetworks[NETWORK_DDNET].m_aCountries[i];
// check for filter
if(DDNetFiltered(g_Config.m_BrFilterExcludeCountries, pCntr->m_aName))
@ -696,6 +710,27 @@ void CServerBrowser::Refresh(int Type)
}
}
}
else if(Type == IServerBrowser::TYPE_KOG)
{
// remove unknown elements of exclude list
CountryFilterClean(NETWORK_KOG);
TypeFilterClean(NETWORK_KOG);
for(int i = 0; i < m_aNetworks[NETWORK_KOG].m_NumCountries; i++)
{
CNetworkCountry *pCntr = &m_aNetworks[NETWORK_KOG].m_aCountries[i];
// check for filter
if(DDNetFiltered(g_Config.m_BrFilterExcludeCountriesKoG, pCntr->m_aName))
continue;
for(int g = 0; g < pCntr->m_NumServers; g++)
{
if(!DDNetFiltered(g_Config.m_BrFilterExcludeTypesKoG, pCntr->m_aTypes[g]))
Set(pCntr->m_aServers[g], IServerBrowser::SET_KOG_ADD, -1, 0);
}
}
}
}
void CServerBrowser::RequestImpl(const NETADDR &Addr, CServerEntry *pEntry) const
@ -1009,96 +1044,104 @@ void CServerBrowser::LoadDDNetServers()
if (!m_pDDNetInfo)
return;
// parse JSON
const json_value *pServers = json_object_get(m_pDDNetInfo, "servers");
if (!pServers || pServers->type != json_array)
return;
// reset servers / countries
m_NumDDNetCountries = 0;
m_NumDDNetTypes = 0;
for (int i = 0; i < json_array_length(pServers) && m_NumDDNetCountries < MAX_DDNET_COUNTRIES; i++)
for (int Network = 0; Network < NUM_NETWORKS; Network++)
{
// pSrv - { name, flagId, servers }
const json_value *pSrv = json_array_get(pServers, i);
const json_value *pTypes = json_object_get(pSrv, "servers");
const json_value *pName = json_object_get(pSrv, "name");
const json_value *pFlagID = json_object_get(pSrv, "flagId");
CNetwork *pNet = &m_aNetworks[Network];
if (pSrv->type != json_object || pTypes->type != json_object || pName->type != json_string || pFlagID->type != json_integer)
// parse JSON
const json_value *pServers = json_object_get(m_pDDNetInfo, Network == NETWORK_DDNET ? "servers" : "servers-kog");
if (!pServers || pServers->type != json_array)
return;
pNet->m_NumCountries = 0;
pNet->m_NumTypes = 0;
for (int i = 0; i < json_array_length(pServers) && pNet->m_NumCountries < MAX_COUNTRIES; i++)
{
dbg_msg("client_srvbrowse", "invalid attributes");
continue;
}
// pSrv - { name, flagId, servers }
const json_value *pSrv = json_array_get(pServers, i);
const json_value *pTypes = json_object_get(pSrv, "servers");
const json_value *pName = json_object_get(pSrv, "name");
const json_value *pFlagID = json_object_get(pSrv, "flagId");
// build structure
CDDNetCountry *pCntr = &m_aDDNetCountries[m_NumDDNetCountries];
pCntr->Reset();
str_copy(pCntr->m_aName, json_string_get(pName), sizeof(pCntr->m_aName));
pCntr->m_FlagID = json_int_get(pFlagID);
// add country
for (unsigned int t = 0; t < pTypes->u.object.length; t++)
{
const char *pType = pTypes->u.object.values[t].name;
const json_value *pAddrs = pTypes->u.object.values[t].value;
if (pAddrs->type != json_array)
if (pSrv->type != json_object || pTypes->type != json_object || pName->type != json_string || pFlagID->type != json_integer)
{
dbg_msg("client_srvbrowse", "invalid attributes");
continue;
}
// add type
if(json_array_length(pAddrs) > 0 && m_NumDDNetTypes < MAX_DDNET_TYPES)
{
int Pos;
for(Pos = 0; Pos < m_NumDDNetTypes; Pos++)
{
if(!str_comp(m_aDDNetTypes[Pos], pType))
break;
}
if(Pos == m_NumDDNetTypes)
{
str_copy(m_aDDNetTypes[m_NumDDNetTypes], pType, sizeof(m_aDDNetTypes[m_NumDDNetTypes]));
m_NumDDNetTypes++;
}
}
// build structure
CNetworkCountry *pCntr = &pNet->m_aCountries[pNet->m_NumCountries];
// add addresses
for (int g = 0; g < json_array_length(pAddrs); g++, pCntr->m_NumServers++)
pCntr->Reset();
str_copy(pCntr->m_aName, json_string_get(pName), sizeof(pCntr->m_aName));
pCntr->m_FlagID = json_int_get(pFlagID);
// add country
for (unsigned int t = 0; t < pTypes->u.object.length; t++)
{
const json_value *pAddr = json_array_get(pAddrs, g);
if (pAddr->type != json_string)
const char *pType = pTypes->u.object.values[t].name;
const json_value *pAddrs = pTypes->u.object.values[t].value;
if (pAddrs->type != json_array)
{
dbg_msg("client_srvbrowse", "invalid attributes");
continue;
}
const char *pStr = json_string_get(pAddr);
net_addr_from_str(&pCntr->m_aServers[pCntr->m_NumServers], pStr);
str_copy(pCntr->m_aTypes[pCntr->m_NumServers], pType, sizeof(pCntr->m_aTypes[pCntr->m_NumServers]));
}
}
m_NumDDNetCountries++;
// add type
if(json_array_length(pAddrs) > 0 && pNet->m_NumTypes < MAX_TYPES)
{
int Pos;
for(Pos = 0; Pos < pNet->m_NumTypes; Pos++)
{
if(!str_comp(pNet->m_aTypes[Pos], pType))
break;
}
if(Pos == pNet->m_NumTypes)
{
str_copy(pNet->m_aTypes[pNet->m_NumTypes], pType, sizeof(pNet->m_aTypes[pNet->m_NumTypes]));
pNet->m_NumTypes++;
}
}
// add addresses
for (int g = 0; g < json_array_length(pAddrs); g++, pCntr->m_NumServers++)
{
const json_value *pAddr = json_array_get(pAddrs, g);
if (pAddr->type != json_string)
{
dbg_msg("client_srvbrowse", "invalid attributes");
continue;
}
const char *pStr = json_string_get(pAddr);
net_addr_from_str(&pCntr->m_aServers[pCntr->m_NumServers], pStr);
str_copy(pCntr->m_aTypes[pCntr->m_NumServers], pType, sizeof(pCntr->m_aTypes[pCntr->m_NumServers]));
}
}
pNet->m_NumCountries++;
}
}
}
void CServerBrowser::RecheckOfficial()
{
for(int i = 0; i < m_NumDDNetCountries; i++)
for(int Network = 0; Network < NUM_NETWORKS; Network++)
{
CDDNetCountry *pCntr = &m_aDDNetCountries[i];
for(int j = 0; j < pCntr->m_NumServers; j++)
for(int i = 0; i < m_aNetworks[Network].m_NumCountries; i++)
{
CServerEntry *pEntry = Find(pCntr->m_aServers[j]);
if(pEntry)
CNetworkCountry *pCntr = &m_aNetworks[Network].m_aCountries[i];
for(int j = 0; j < pCntr->m_NumServers; j++)
{
pEntry->m_Info.m_Official = true;
CServerEntry *pEntry = Find(pCntr->m_aServers[j]);
if(pEntry)
{
pEntry->m_Info.m_Official = true;
}
}
}
}
@ -1265,15 +1308,39 @@ bool CServerBrowser::DDNetFiltered(char *pFilter, const char *pName)
return str_in_list(pFilter, ",", pName); // country not excluded
}
void CServerBrowser::DDNetCountryFilterClean()
void CServerBrowser::CountryFilterClean(int Network)
{
char *pExcludeCountries = Network == NETWORK_KOG ? g_Config.m_BrFilterExcludeCountriesKoG : g_Config.m_BrFilterExcludeCountries;
char aNewList[128];
aNewList[0] = '\0';
for(int i = 0; i < m_NumDDNetCountries; i++)
for(int Network = 0; Network < NUM_NETWORKS; Network++)
{
const char *pName = m_aDDNetCountries[i].m_aName;
if(DDNetFiltered(g_Config.m_BrFilterExcludeCountries, pName))
for(int i = 0; i < m_aNetworks[Network].m_NumCountries; i++)
{
const char *pName = m_aNetworks[Network].m_aCountries[i].m_aName;
if(DDNetFiltered(pExcludeCountries, pName))
{
char aBuf[128];
str_format(aBuf, sizeof(aBuf), ",%s", pName);
str_append(aNewList, aBuf, sizeof(aNewList));
}
}
}
str_copy(pExcludeCountries, aNewList, sizeof(g_Config.m_BrFilterExcludeCountries));
}
void CServerBrowser::TypeFilterClean(int Network)
{
char *pExcludeTypes = Network == NETWORK_KOG ? g_Config.m_BrFilterExcludeTypesKoG : g_Config.m_BrFilterExcludeTypes;
char aNewList[128];
aNewList[0] = '\0';
for(int i = 0; i < m_aNetworks[Network].m_NumTypes; i++)
{
const char *pName = m_aNetworks[Network].m_aTypes[i];
if(DDNetFiltered(pExcludeTypes, pName))
{
char aBuf[128];
str_format(aBuf, sizeof(aBuf), ",%s", pName);
@ -1281,24 +1348,5 @@ void CServerBrowser::DDNetCountryFilterClean()
}
}
str_copy(g_Config.m_BrFilterExcludeCountries, aNewList, sizeof(g_Config.m_BrFilterExcludeCountries));
}
void CServerBrowser::DDNetTypeFilterClean()
{
char aNewList[128];
aNewList[0] = '\0';
for(int i = 0; i < m_NumDDNetTypes; i++)
{
const char *pName = m_aDDNetTypes[i];
if(DDNetFiltered(g_Config.m_BrFilterExcludeTypes, pName))
{
char aBuf[128];
str_format(aBuf, sizeof(aBuf), ",%s", pName);
str_append(aNewList, aBuf, sizeof(aNewList));
}
}
str_copy(g_Config.m_BrFilterExcludeTypes, aNewList, sizeof(g_Config.m_BrFilterExcludeTypes));
str_copy(pExcludeTypes, aNewList, sizeof(g_Config.m_BrFilterExcludeTypes));
}

View file

@ -25,9 +25,8 @@ public:
CServerEntry *m_pNextReq;
};
class CDDNetCountry
struct CNetworkCountry
{
public:
enum
{
MAX_SERVERS = 1024
@ -53,10 +52,20 @@ public:
enum
{
MAX_FAVORITES=2048,
MAX_DDNET_COUNTRIES=16,
MAX_DDNET_TYPES=32,
MAX_COUNTRIES=16,
MAX_TYPES=32,
};
struct CNetwork
{
CNetworkCountry m_aCountries[MAX_COUNTRIES];
int m_NumCountries;
char m_aTypes[MAX_TYPES][32];
int m_NumTypes;
};
CServerBrowser();
virtual ~CServerBrowser();
@ -91,18 +100,18 @@ public:
void LoadDDNetInfoJson();
const json_value *LoadDDNetInfo();
int HasRank(const char *pMap);
int NumDDNetCountries() { return m_NumDDNetCountries; };
int GetDDNetCountryFlag(int Index) { return m_aDDNetCountries[Index].m_FlagID; };
const char *GetDDNetCountryName(int Index) { return m_aDDNetCountries[Index].m_aName; };
int NumCountries(int Network) { return m_aNetworks[Network].m_NumCountries; };
int GetCountryFlag(int Network, int Index) { return m_aNetworks[Network].m_aCountries[Index].m_FlagID; };
const char *GetCountryName(int Network, int Index) { return m_aNetworks[Network].m_aCountries[Index].m_aName; };
int NumDDNetTypes() { return m_NumDDNetTypes; };
const char *GetDDNetType(int Index) { return m_aDDNetTypes[Index]; };
int NumTypes(int Network) { return m_aNetworks[Network].m_NumTypes; };
const char *GetType(int Network, int Index) { return m_aNetworks[Network].m_aTypes[Index]; };
void DDNetFilterAdd(char *pFilter, const char *pName);
void DDNetFilterRem(char *pFilter, const char *pName);
bool DDNetFiltered(char *pFilter, const char *pName);
void DDNetCountryFilterClean();
void DDNetTypeFilterClean();
void CountryFilterClean(int Network);
void TypeFilterClean(int Network);
//
void Update(bool ForceResort);
@ -130,11 +139,7 @@ private:
NETADDR m_aFavoriteServers[MAX_FAVORITES];
int m_NumFavoriteServers;
CDDNetCountry m_aDDNetCountries[MAX_DDNET_COUNTRIES];
int m_NumDDNetCountries;
char m_aDDNetTypes[MAX_DDNET_TYPES][32];
int m_NumDDNetTypes;
CNetwork m_aNetworks[NUM_NETWORKS];
json_value *m_pDDNetInfo;

View file

@ -103,11 +103,17 @@ public:
TYPE_LAN = 2,
TYPE_FAVORITES = 3,
TYPE_DDNET = 4,
TYPE_KOG = 5,
SET_MASTER_ADD=1,
SET_FAV_ADD,
SET_DDNET_ADD,
SET_TOKEN
SET_KOG_ADD,
SET_TOKEN,
NETWORK_DDNET=0,
NETWORK_KOG=1,
NUM_NETWORKS,
};
virtual void Refresh(int Type) = 0;
@ -127,18 +133,18 @@ public:
virtual void AddFavorite(const NETADDR &Addr) = 0;
virtual void RemoveFavorite(const NETADDR &Addr) = 0;
virtual int NumDDNetCountries() = 0;
virtual int GetDDNetCountryFlag(int Index) = 0;
virtual const char *GetDDNetCountryName(int Index) = 0;
virtual int NumCountries(int Network) = 0;
virtual int GetCountryFlag(int Network, int Index) = 0;
virtual const char *GetCountryName(int Network, int Index) = 0;
virtual int NumDDNetTypes() = 0;
virtual const char *GetDDNetType(int Index) = 0;
virtual int NumTypes(int Network) = 0;
virtual const char *GetType(int Network, int Index) = 0;
virtual void DDNetFilterAdd(char *pFilter, const char *pName) = 0;
virtual void DDNetFilterRem(char *pFilter, const char *pName) = 0;
virtual bool DDNetFiltered(char *pFilter, const char *pName) = 0;
virtual void DDNetCountryFilterClean() = 0;
virtual void DDNetTypeFilterClean() = 0;
virtual void CountryFilterClean(int Network) = 0;
virtual void TypeFilterClean(int Network) = 0;
virtual int GetCurrentType() = 0;
};

View file

@ -53,9 +53,12 @@ MACRO_CONFIG_INT(BrFilterPureMap, br_filter_pure_map, 0, 0, 1, CFGFLAG_SAVE|CFGF
MACRO_CONFIG_INT(BrFilterCompatversion, br_filter_compatversion, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out non-compatible servers in browser")
MACRO_CONFIG_INT(BrFilterUnfinishedMap, br_filter_unfinished_map, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Show only servers with unfinished maps")
MACRO_CONFIG_STR(BrFilterExcludeCountries, br_filter_exclude_countries, 128, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out ddnet servers by country")
MACRO_CONFIG_STR(BrFilterExcludeTypes, br_filter_exclude_types, 128, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out ddnet servers by type (mod)")
MACRO_CONFIG_INT(BrIndicateFinished, br_indicate_finished, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Show whether you have finished a DDNet map (transmits your player name to info.ddnet.tw)")
MACRO_CONFIG_STR(BrFilterExcludeCountries, br_filter_exclude_countries, 128, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out DDNet servers by country")
MACRO_CONFIG_STR(BrFilterExcludeTypes, br_filter_exclude_types, 128, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out DDNet servers by type (mod)")
MACRO_CONFIG_INT(BrIndicateFinished, br_indicate_finished, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Show whether you have finished a DDNet map (transmits your player name to info.ddnet.tw/info)")
MACRO_CONFIG_STR(BrFilterExcludeCountriesKoG, br_filter_exclude_countries_kog, 128, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out kog servers by country")
MACRO_CONFIG_STR(BrFilterExcludeTypesKoG, br_filter_exclude_types_kog, 128, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out kog servers by type (mod)")
MACRO_CONFIG_INT(BrSort, br_sort, 4, 0, 256, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Sorting column in server browser")
MACRO_CONFIG_INT(BrSortOrder, br_sort_order, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Sorting order in server browser")

View file

@ -735,9 +735,9 @@ int CMenus::RenderMenubar(CUIRect r)
m_DoubleClickIndex = -1;
}
Box.VSplitLeft(100.0f, &Button, &Box);
Box.VSplitLeft(80.0f, &Button, &Box);
static int s_DDNetButton=0;
if(DoButton_MenuTab(&s_DDNetButton, Localize("DDNet"), m_ActivePage==PAGE_DDNET, &Button, CUI::CORNER_TR))
if(DoButton_MenuTab(&s_DDNetButton, "DDNet", m_ActivePage==PAGE_DDNET, &Button, 0))
{
if(ServerBrowser()->GetCurrentType() != IServerBrowser::TYPE_DDNET)
{
@ -748,6 +748,19 @@ int CMenus::RenderMenubar(CUIRect r)
m_DoubleClickIndex = -1;
}
Box.VSplitLeft(60.0f, &Button, &Box);
static int s_KoGButton=0;
if(DoButton_MenuTab(&s_KoGButton, "KoG", m_ActivePage==PAGE_KOG, &Button, CUI::CORNER_TR))
{
if(ServerBrowser()->GetCurrentType() != IServerBrowser::TYPE_KOG)
{
Client()->RequestDDNetInfo();
ServerBrowser()->Refresh(IServerBrowser::TYPE_KOG);
}
NewPage = PAGE_KOG;
m_DoubleClickIndex = -1;
}
Box.VSplitLeft(10.0f, 0, &Box);
Box.VSplitLeft(100.0f, &Button, &Box);
static int s_DemosButton=0;
@ -894,7 +907,7 @@ void CMenus::RenderLoading()
void CMenus::RenderNews(CUIRect MainView)
{
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f);
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B, 10.0f);
MainView.HSplitTop(15.0f, 0, &MainView);
MainView.VSplitLeft(15.0f, 0, &MainView);
@ -973,6 +986,8 @@ int CMenus::Render()
ServerBrowser()->Refresh(IServerBrowser::TYPE_FAVORITES);
else if(g_Config.m_UiPage == PAGE_DDNET)
ServerBrowser()->Refresh(IServerBrowser::TYPE_DDNET);
else if(g_Config.m_UiPage == PAGE_KOG)
ServerBrowser()->Refresh(IServerBrowser::TYPE_KOG);
}
if(Client()->State() == IClient::STATE_ONLINE)
@ -1049,11 +1064,12 @@ int CMenus::Render()
RenderServerbrowser(MainView);
else if(g_Config.m_UiPage == PAGE_DDNET)
RenderServerbrowser(MainView);
else if(g_Config.m_UiPage == PAGE_KOG)
RenderServerbrowser(MainView);
else if(g_Config.m_UiPage == PAGE_SETTINGS)
RenderSettings(MainView);
// do tab bar
TabBar.VMargin(20.0f, &TabBar);
RenderMenubar(TabBar);
}
else

View file

@ -337,6 +337,7 @@ public:
PAGE_LAN,
PAGE_FAVORITES,
PAGE_DDNET,
PAGE_KOG,
PAGE_DEMOS,
PAGE_SETTINGS,
PAGE_SYSTEM,

View file

@ -675,7 +675,11 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
{
g_Config.m_BrFilterUnfinishedMap = 0;
}
}
if(g_Config.m_UiPage == PAGE_DDNET || g_Config.m_UiPage == PAGE_KOG)
{
int Network = g_Config.m_UiPage == PAGE_DDNET ? IServerBrowser::NETWORK_DDNET : IServerBrowser::NETWORK_KOG;
// add more space
ServerFilter.HSplitTop(10.0f, 0, &ServerFilter);
ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter);
@ -701,8 +705,9 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
if(s_ActivePage == 1)
{
int MaxTypes = ServerBrowser()->NumDDNetTypes();
int NumTypes = ServerBrowser()->NumDDNetTypes();
char *pFilterExcludeTypes = Network == IServerBrowser::NETWORK_DDNET ? g_Config.m_BrFilterExcludeTypes : g_Config.m_BrFilterExcludeTypesKoG;
int MaxTypes = ServerBrowser()->NumTypes(Network);
int NumTypes = ServerBrowser()->NumTypes(Network);
int PerLine = 3;
ServerFilter.HSplitTop(4.0f, 0, &ServerFilter);
@ -723,8 +728,8 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
for(int i = 0; i < PerLine && NumTypes > 0; i++, NumTypes--)
{
int TypeIndex = MaxTypes - NumTypes;
const char *pName = ServerBrowser()->GetDDNetType(TypeIndex);
bool Active = !ServerBrowser()->DDNetFiltered(g_Config.m_BrFilterExcludeTypes, pName);
const char *pName = ServerBrowser()->GetType(Network, TypeIndex);
bool Active = !ServerBrowser()->DDNetFiltered(pFilterExcludeTypes, pName);
vec2 Pos = vec2(TypesRect.x+TypesRect.w*((i+0.5f)/(float)PerLine), TypesRect.y);
@ -744,28 +749,28 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
{
// left click to toggle flag filter
if(Active)
ServerBrowser()->DDNetFilterAdd(g_Config.m_BrFilterExcludeTypes, pName);
ServerBrowser()->DDNetFilterAdd(pFilterExcludeTypes, pName);
else
ServerBrowser()->DDNetFilterRem(g_Config.m_BrFilterExcludeTypes, pName);
ServerBrowser()->DDNetFilterRem(pFilterExcludeTypes, pName);
ServerBrowser()->Refresh(IServerBrowser::TYPE_DDNET);
ServerBrowser()->Refresh(ServerBrowser()->GetCurrentType());
}
else if(Button == 2)
{
// right click to exclusively activate one
g_Config.m_BrFilterExcludeTypes[0] = '\0';
pFilterExcludeTypes[0] = '\0';
for(int j = 0; j < MaxTypes; ++j)
{
if(j != TypeIndex)
ServerBrowser()->DDNetFilterAdd(g_Config.m_BrFilterExcludeTypes, ServerBrowser()->GetDDNetType(j));
ServerBrowser()->DDNetFilterAdd(pFilterExcludeTypes, ServerBrowser()->GetType(Network, j));
}
ServerBrowser()->Refresh(IServerBrowser::TYPE_DDNET);
ServerBrowser()->Refresh(ServerBrowser()->GetCurrentType());
}
else if(Button == 3)
{
// middle click to reset (re-enable all)
g_Config.m_BrFilterExcludeTypes[0] = '\0';
ServerBrowser()->Refresh(IServerBrowser::TYPE_DDNET);
pFilterExcludeTypes[0] = '\0';
ServerBrowser()->Refresh(ServerBrowser()->GetCurrentType());
}
vec4 Color(1.0f, 1.0f, 1.0f, 1.0f);
@ -780,6 +785,7 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
}
else
{
char *pFilterExcludeCountries = Network == IServerBrowser::NETWORK_DDNET ? g_Config.m_BrFilterExcludeCountries : g_Config.m_BrFilterExcludeCountriesKoG;
ServerFilter.HSplitTop(17.0f, &ServerFilter, &ServerFilter);
vec4 Color(1.0f, 1.0f, 1.0f, 1.0f);
@ -787,8 +793,8 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
const float FlagWidth = 40.0f;
const float FlagHeight = 20.0f;
int MaxFlags = ServerBrowser()->NumDDNetCountries();
int NumFlags = ServerBrowser()->NumDDNetCountries();
int MaxFlags = ServerBrowser()->NumCountries(Network);
int NumFlags = ServerBrowser()->NumCountries(Network);
int PerLine = MaxFlags > 9 ? 4 : 3;
CUIRect FlagsRect;
@ -802,9 +808,9 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
for(int i = 0; i < PerLine && NumFlags > 0; i++, NumFlags--)
{
int CountryIndex = MaxFlags - NumFlags;
const char *pName = ServerBrowser()->GetDDNetCountryName(CountryIndex);
bool Active = !ServerBrowser()->DDNetFiltered(g_Config.m_BrFilterExcludeCountries, pName);
int FlagID = ServerBrowser()->GetDDNetCountryFlag(CountryIndex);
const char *pName = ServerBrowser()->GetCountryName(Network, CountryIndex);
bool Active = !ServerBrowser()->DDNetFiltered(pFilterExcludeCountries, pName);
int FlagID = ServerBrowser()->GetCountryFlag(Network, CountryIndex);
vec2 Pos = vec2(FlagsRect.x+FlagsRect.w*((i+0.5f)/(float)PerLine), FlagsRect.y);
@ -825,28 +831,28 @@ void CMenus::RenderServerbrowserFilters(CUIRect View)
{
// left click to toggle flag filter
if(Active)
ServerBrowser()->DDNetFilterAdd(g_Config.m_BrFilterExcludeCountries, pName);
ServerBrowser()->DDNetFilterAdd(pFilterExcludeCountries, pName);
else
ServerBrowser()->DDNetFilterRem(g_Config.m_BrFilterExcludeCountries, pName);
ServerBrowser()->DDNetFilterRem(pFilterExcludeCountries, pName);
ServerBrowser()->Refresh(IServerBrowser::TYPE_DDNET);
ServerBrowser()->Refresh(ServerBrowser()->GetCurrentType());
}
else if(Button == 2)
{
// right click to exclusively activate one
g_Config.m_BrFilterExcludeCountries[0] = '\0';
pFilterExcludeCountries[0] = '\0';
for(int j = 0; j < MaxFlags; ++j)
{
if(j != CountryIndex)
ServerBrowser()->DDNetFilterAdd(g_Config.m_BrFilterExcludeCountries, ServerBrowser()->GetDDNetCountryName(j));
ServerBrowser()->DDNetFilterAdd(pFilterExcludeCountries, ServerBrowser()->GetCountryName(Network, j));
}
ServerBrowser()->Refresh(IServerBrowser::TYPE_DDNET);
ServerBrowser()->Refresh(ServerBrowser()->GetCurrentType());
}
else if(Button == 3)
{
// middle click to reset (re-enable all)
g_Config.m_BrFilterExcludeCountries[0] = '\0';
ServerBrowser()->Refresh(IServerBrowser::TYPE_DDNET);
pFilterExcludeCountries[0] = '\0';
ServerBrowser()->Refresh(ServerBrowser()->GetCurrentType());
}
vec4 Color(1.0f, 1.0f, 1.0f, 1.0f);
@ -1240,7 +1246,7 @@ void CMenus::RenderServerbrowser(CUIRect MainView)
CUIRect ServerList, ToolBox, StatusBox, TabBar;
// background
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f);
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B, 10.0f);
MainView.Margin(10.0f, &MainView);
// create server list, status box, tab bar and tool box area
@ -1414,6 +1420,12 @@ void CMenus::RenderServerbrowser(CUIRect MainView)
Client()->RequestDDNetInfo();
ServerBrowser()->Refresh(IServerBrowser::TYPE_DDNET);
}
else if(g_Config.m_UiPage == PAGE_KOG)
{
// start a new serverlist request
Client()->RequestDDNetInfo();
ServerBrowser()->Refresh(IServerBrowser::TYPE_KOG);
}
m_DoubleClickIndex = -1;
}

View file

@ -793,7 +793,7 @@ void CMenus::RenderDemoList(CUIRect MainView)
}
// render background
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f);
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B, 10.0f);
MainView.Margin(10.0f, &MainView);
CUIRect ButtonBar, RefreshRect, FetchRect, PlayRect, DeleteRect, RenameRect, LabelRect, ListBox;

View file

@ -39,7 +39,7 @@ void CMenus::RenderGame(CUIRect MainView)
#else
MainView.HSplitTop(45.0f, &ButtonBar, &MainView);
#endif
RenderTools()->DrawUIRect(&ButtonBar, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f);
RenderTools()->DrawUIRect(&ButtonBar, ms_ColorTabbarActive, CUI::CORNER_B, 10.0f);
// button bar
ButtonBar.HSplitTop(10.0f, 0, &ButtonBar);
@ -157,7 +157,7 @@ void CMenus::RenderGame(CUIRect MainView)
void CMenus::RenderPlayers(CUIRect MainView)
{
CUIRect Button, Button2, ButtonBar, Options, Player;
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f);
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B, 10.0f);
// player options
MainView.Margin(10.0f, &Options);
@ -351,7 +351,7 @@ void CMenus::RenderServerInfo(CUIRect MainView)
Client()->GetServerInfo(&CurrentServerInfo);
// render background
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f);
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B, 10.0f);
CUIRect View, ServerInfo, GameInfo, Motd;
@ -564,7 +564,7 @@ void CMenus::RenderServerControl(CUIRect MainView)
#else
MainView.HSplitTop(20.0f, &Bottom, &MainView);
#endif
RenderTools()->DrawUIRect(&Bottom, ms_ColorTabbarActive, CUI::CORNER_T, 10.0f);
RenderTools()->DrawUIRect(&Bottom, ms_ColorTabbarActive, 0, 10.0f);
#if defined(__ANDROID__)
MainView.HSplitTop(50.0f, &TabBar, &MainView);
#else
@ -768,7 +768,7 @@ void CMenus::RenderInGameNetwork(CUIRect MainView)
int Page = g_Config.m_UiPage;
int NewPage = -1;
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f);
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B, 10.0f);
Box.HSplitTop(5.0f, &MainView, &MainView);
Box.HSplitTop(24.0f, &Box, &MainView);
@ -798,19 +798,31 @@ void CMenus::RenderInGameNetwork(CUIRect MainView)
{
if(Page != PAGE_FAVORITES)
ServerBrowser()->Refresh(IServerBrowser::TYPE_FAVORITES);
NewPage = PAGE_FAVORITES;
NewPage = PAGE_FAVORITES;
}
Box.VSplitLeft(110.0f, &Button, &Box);
static int s_DDNetButton=0;
if(DoButton_MenuTab(&s_DDNetButton, Localize("DDNet"), Page==PAGE_DDNET, &Button, CUI::CORNER_BR) || Page < PAGE_INTERNET || Page > PAGE_DDNET)
if(DoButton_MenuTab(&s_DDNetButton, "DDNet", Page==PAGE_DDNET, &Button, 0) || Page < PAGE_INTERNET || Page > PAGE_KOG)
{
if(Page != PAGE_DDNET)
{
Client()->RequestDDNetInfo();
ServerBrowser()->Refresh(IServerBrowser::TYPE_DDNET);
}
NewPage = PAGE_DDNET;
NewPage = PAGE_DDNET;
}
Box.VSplitLeft(110.0f, &Button, &Box);
static int s_KoGButton=0;
if(DoButton_MenuTab(&s_KoGButton, "KoG", Page==PAGE_KOG, &Button, CUI::CORNER_BR))
{
if(Page != PAGE_KOG)
{
Client()->RequestDDNetInfo();
ServerBrowser()->Refresh(IServerBrowser::TYPE_KOG);
}
NewPage = PAGE_KOG;
}
if(NewPage != -1)
@ -903,7 +915,7 @@ void CMenus::DeleteGhostItem(int Index)
void CMenus::RenderGhost(CUIRect MainView)
{
// render background
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B|CUI::CORNER_TL, 10.0f);
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B, 10.0f);
MainView.HSplitTop(10.0f, 0, &MainView);
MainView.HSplitBottom(5.0f, &MainView, 0);

View file

@ -1374,11 +1374,11 @@ void CMenus::RenderSettings(CUIRect MainView)
// render background
CUIRect Temp, TabBar, RestartWarning;
MainView.VSplitRight(120.0f, &MainView, &TabBar);
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B|CUI::CORNER_TL, 10.0f);
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B, 10.0f);
MainView.Margin(10.0f, &MainView);
MainView.HSplitBottom(15.0f, &MainView, &RestartWarning);
TabBar.HSplitTop(50.0f, &Temp, &TabBar);
RenderTools()->DrawUIRect(&Temp, ms_ColorTabbarActive, CUI::CORNER_R, 10.0f);
RenderTools()->DrawUIRect(&Temp, ms_ColorTabbarActive, CUI::CORNER_BR, 10.0f);
MainView.HSplitTop(10.0f, 0, &MainView);