From 202d5d8866984ba41ec44c29843e604b3d51c440 Mon Sep 17 00:00:00 2001 From: east Date: Fri, 19 Sep 2014 23:52:09 +0200 Subject: [PATCH] Filter flag grid added --- src/engine/client/serverbrowser.cpp | 108 +++++++++++++++++-- src/engine/client/serverbrowser.h | 13 ++- src/engine/serverbrowser.h | 7 ++ src/engine/shared/config_variables.h | 2 + src/game/client/components/menus_browser.cpp | 71 +++++++++++- 5 files changed, 190 insertions(+), 11 deletions(-) diff --git a/src/engine/client/serverbrowser.cpp b/src/engine/client/serverbrowser.cpp index e6aa6f1cf..65647a4d6 100644 --- a/src/engine/client/serverbrowser.cpp +++ b/src/engine/client/serverbrowser.cpp @@ -539,8 +539,21 @@ void CServerBrowser::Refresh(int Type) else if(Type == IServerBrowser::TYPE_DDNET) { LoadDDNet(); - /*for(int i = 0; i < m_NumDDNetServers; i++) - Set(m_aDDNetServers[i], IServerBrowser::SET_DDNET_ADD, -1, 0);*/ + + // remove unknown elements of exclude list + DDNetCountryFilterClean(); + + for(int i = 0; i < m_NumDDNetCountries; i++) + { + CDDNetCountry *pCntr = &m_aDDNetCountries[i]; + + // check for filter + if (DDNetCountryFiltered(pCntr->m_aName)) + continue; + + for(int g = 0; g < pCntr->m_NumServers; g++) + Set(pCntr->m_aServers[g], IServerBrowser::SET_DDNET_ADD, -1, 0); + } } } @@ -877,19 +890,25 @@ void CServerBrowser::LoadDDNet() const json_value *pAddrs = json_object_get(pSrv, "servers"); const json_value *pName = json_object_get(pSrv, "name"); const json_value *pFlagID = json_object_get(pSrv, "flagId"); - + + if (pSrv->type != json_object || pAddrs->type != json_array || pName->type != json_string || pFlagID->type != json_integer) + continue; // invalid attributes + // 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); + pCntr->m_FlagID = json_int_get(pFlagID); // add addresses - for (int srv = 0; srv < json_array_length(pAddrs); srv++) + for (int g = 0; g < json_array_length(pAddrs); g++) { - const json_value *pAddr = json_array_get(pAddrs, srv); + const json_value *pAddr = json_array_get(pAddrs, g); const char *pStr = json_string_get(pAddr); - res = net_addr_from_str(&pCntr->m_aServers[i], pStr); + net_addr_from_str(&pCntr->m_aServers[g], pStr); pCntr->m_NumServers++; } @@ -934,3 +953,78 @@ void CServerBrowser::ConfigSaveCallback(IConfig *pConfig, void *pUserData) pConfig->WriteLine(aBuffer); } } + +void CServerBrowser::DDNetCountryFilterAdd(const char *pName) +{ + if (DDNetCountryFiltered(pName)) + return; + + char aBuf[256]; + str_format(aBuf, sizeof(aBuf), ",%s", pName); + str_append(g_Config.m_BrFilterExcludeCountries, aBuf, sizeof(g_Config.m_BrFilterExcludeCountries)); +} + +void CServerBrowser::DDNetCountryFilterRem(const char *pName) +{ + if (!DDNetCountryFiltered(pName)) + return; + + // rewrite exclude/filter list + char aBuf[256]; + char *p; + + str_copy(aBuf, g_Config.m_BrFilterExcludeCountries, sizeof(aBuf)); + g_Config.m_BrFilterExcludeCountries[0] = '\0'; + + p = strtok(aBuf, ","); + + while(p) + { + if(str_comp_nocase(pName, p) != 0) + { + char aBuf2[256]; + str_format(aBuf2, sizeof(aBuf2), ",%s", p); + str_append(g_Config.m_BrFilterExcludeCountries, aBuf2, sizeof(g_Config.m_BrFilterExcludeCountries)); + } + + p = strtok(NULL, ","); + } +} + +bool CServerBrowser::DDNetCountryFiltered(const char *pName) +{ + char aBuf[256]; + char *p; + + str_copy(aBuf, g_Config.m_BrFilterExcludeCountries, sizeof(aBuf)); + + p = strtok(aBuf, ","); + + while(p) + { + if(str_comp_nocase(pName, p) == 0) + return true; // country excluded + + p = strtok(NULL, ","); + } + + return false; // contry not excluded +} + +void CServerBrowser::DDNetCountryFilterClean() +{ + char aNewList[256]; + + for(int i = 0; i < m_NumDDNetCountries; i++) + { + const char *pName = m_aDDNetCountries[i].m_aName; + if(DDNetCountryFiltered(pName)) + { + char aBuf[256]; + str_format(aBuf, sizeof(aBuf), ",%s", pName); + str_append(aNewList, aBuf, sizeof(aNewList)); + } + } + + str_copy(g_Config.m_BrFilterExcludeCountries, aNewList, sizeof(g_Config.m_BrFilterExcludeCountries)); +} diff --git a/src/engine/client/serverbrowser.h b/src/engine/client/serverbrowser.h index 881693f23..fdcf9ce15 100644 --- a/src/engine/client/serverbrowser.h +++ b/src/engine/client/serverbrowser.h @@ -32,11 +32,11 @@ public: }; char m_aName[256]; - int m_FlagId; + int m_FlagID; NETADDR m_aServers[MAX_SERVERS]; int m_NumServers; - void Reset() { m_NumServers = 0; }; + void Reset() { m_NumServers = 0; m_FlagID = -1; m_aName[0] = '\0'; }; void Add(NETADDR Addr) { if (m_NumServers < MAX_SERVERS) m_aServers[m_NumServers++] = Addr; }; }; @@ -64,7 +64,14 @@ public: void RemoveFavorite(const NETADDR &Addr); void LoadDDNet(); - + 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; }; + void DDNetCountryFilterAdd(const char *pName); + void DDNetCountryFilterRem(const char *pName); + bool DDNetCountryFiltered(const char *pName); + void DDNetCountryFilterClean(); + // void Update(bool ForceResort); void Set(const NETADDR &Addr, int Type, int Token, const CServerInfo *pInfo); diff --git a/src/engine/serverbrowser.h b/src/engine/serverbrowser.h index 960864a64..192e0f220 100644 --- a/src/engine/serverbrowser.h +++ b/src/engine/serverbrowser.h @@ -98,6 +98,13 @@ public: virtual bool IsFavorite(const NETADDR &Addr) const = 0; 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 void DDNetCountryFilterAdd(const char *pName) = 0; + virtual void DDNetCountryFilterRem(const char *pName) = 0; + virtual bool DDNetCountryFiltered(const char *pName) = 0; }; #endif diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index 25bfecce9..5f3d50e57 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -50,6 +50,8 @@ MACRO_CONFIG_INT(BrFilterPure, br_filter_pure, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLI MACRO_CONFIG_INT(BrFilterPureMap, br_filter_pure_map, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out non-standard maps in browser") MACRO_CONFIG_INT(BrFilterCompatversion, br_filter_compatversion, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out non-compatible servers in browser") +MACRO_CONFIG_STR(BrFilterExcludeCountries, br_filter_exclude_countries, 128, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Filter out ddnet servers by country") + // DDNet filters MACRO_CONFIG_INT(BrFilterGer, br_filter_ger, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "") MACRO_CONFIG_INT(BrFilterFra, br_filter_fra, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "") diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index 7eca988ec..d641190d3 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -571,7 +571,7 @@ void CMenus::RenderServerbrowserFilters(CUIRect View) { CUIRect ServerFilter = View, FilterHeader; const float FontSize = 12.0f; - ServerFilter.HSplitBottom(42.5f, &ServerFilter, 0); + ServerFilter.HSplitBottom(/*42.5f*/ 0.0f, &ServerFilter, 0); // server filter ServerFilter.HSplitTop(ms_ListheaderHeight, &FilterHeader, &ServerFilter); @@ -680,6 +680,75 @@ void CMenus::RenderServerbrowserFilters(CUIRect View) ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter); if (DoButton_CheckBox((char *)&g_Config.m_UiColorizePing, Localize("Colorize ping"), g_Config.m_UiColorizePing, &Button)) g_Config.m_UiColorizePing ^= 1; + + // ddnet country filters + if(g_Config.m_UiPage == PAGE_DDNET) + { + // add more space + ServerFilter.HSplitTop(10.0f, &Button, &ServerFilter); + + ServerFilter.HSplitTop(40.0f, &Button, &ServerFilter); + UI()->DoLabelScaled(&Button, Localize("DDNet Countries:"), FontSize, -1); + + vec4 Color(1.0f, 1.0f, 1.0f, 1.0f); + + const float FlagWidth = 40.0f; + const float FlagHeight = 20.0f; + + int MaxFlags = ServerBrowser()->NumDDNetCountries(); + int NumFlags = ServerBrowser()->NumDDNetCountries(); + + CUIRect FlagsRect; + + static int s_aFlagButtons[64]; + + while(NumFlags > 0) + { + ServerFilter.HSplitTop(30.0f, &FlagsRect, &ServerFilter); + + for(int i = 0; i < 3 && NumFlags > 0; i++) + { + int CountryIndex = MaxFlags - NumFlags; + const char *pName = ServerBrowser()->GetDDNetCountryName(CountryIndex); + bool Active = !ServerBrowser()->DDNetCountryFiltered(pName); + int FlagID = ServerBrowser()->GetDDNetCountryFlag(CountryIndex); + + vec2 Pos = vec2(FlagsRect.x+FlagsRect.w*((i+0.5f)/3.0f), FlagsRect.y); + + // correct pos + Pos.x -= FlagWidth / 2.0f; + Pos.y -= FlagHeight / 2.0f; + + // create button logic + CUIRect Rect; + + Rect.x = Pos.x; + Rect.y = Pos.y; + Rect.w = FlagWidth; + Rect.h = FlagHeight; + + if (UI()->DoButtonLogic(&s_aFlagButtons[CountryIndex], "", 0, &Rect)) + { + // toggle flag filter + if (Active) + ServerBrowser()->DDNetCountryFilterAdd(pName); + else + ServerBrowser()->DDNetCountryFilterRem(pName); + + ServerBrowser()->Refresh(IServerBrowser::TYPE_DDNET); + } + + vec4 Color(1.0f, 1.0f, 1.0f, 1.0f); + + if (!Active) + Color.a = 0.2f; + + m_pClient->m_pCountryFlags->Render(FlagID, &Color, Pos.x, Pos.y, FlagWidth, FlagHeight); + + NumFlags--; + } + } + } ServerFilter.HSplitBottom(5.0f, &ServerFilter, 0); ServerFilter.HSplitBottom(ms_ButtonHeight-2.0f, &ServerFilter, &Button);