mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 14:38:18 +00:00
Merge #5879
5879: Support multiple values to search/exclude (fixes #4119) r=Robyt3 a=def- ![screenshot-20220925@143701](https://user-images.githubusercontent.com/2335377/192143966-bd91670c-bcdd-45ea-90aa-189a9fce0975.png) ## Checklist - [x] Tested the change ingame - [x] Provided screenshots if it is a visual change - [ ] Tested in combination with possibly related configuration options - [ ] Written a unit test (especially base/) or added coverage to integration test - [ ] Considered possible null pointers and out of bounds array indexing - [ ] Changed no physics that affect existing maps - [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional) Co-authored-by: def <dennis@felsin9.de>
This commit is contained in:
commit
c5401b8607
|
@ -300,14 +300,23 @@ void CServerBrowser::Filter()
|
|||
}
|
||||
}
|
||||
|
||||
if(!Filtered && g_Config.m_BrFilterString[0] != 0)
|
||||
if(!Filtered && g_Config.m_BrFilterString[0] != '\0')
|
||||
{
|
||||
int MatchFound = 0;
|
||||
|
||||
m_ppServerlist[i]->m_Info.m_QuickSearchHit = 0;
|
||||
|
||||
const char *pStr = g_Config.m_BrFilterString;
|
||||
char aFilterStr[sizeof(g_Config.m_BrFilterString)];
|
||||
while((pStr = str_next_token(pStr, IServerBrowser::SEARCH_EXCLUDE_TOKEN, aFilterStr, sizeof(aFilterStr))))
|
||||
{
|
||||
if(aFilterStr[0] == '\0')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// match against server name
|
||||
if(str_utf8_find_nocase(m_ppServerlist[i]->m_Info.m_aName, g_Config.m_BrFilterString))
|
||||
if(str_utf8_find_nocase(m_ppServerlist[i]->m_Info.m_aName, aFilterStr))
|
||||
{
|
||||
MatchFound = 1;
|
||||
m_ppServerlist[i]->m_Info.m_QuickSearchHit |= IServerBrowser::QUICK_SERVERNAME;
|
||||
|
@ -316,8 +325,8 @@ void CServerBrowser::Filter()
|
|||
// match against players
|
||||
for(p = 0; p < minimum(m_ppServerlist[i]->m_Info.m_NumClients, (int)MAX_CLIENTS); p++)
|
||||
{
|
||||
if(str_utf8_find_nocase(m_ppServerlist[i]->m_Info.m_aClients[p].m_aName, g_Config.m_BrFilterString) ||
|
||||
str_utf8_find_nocase(m_ppServerlist[i]->m_Info.m_aClients[p].m_aClan, g_Config.m_BrFilterString))
|
||||
if(str_utf8_find_nocase(m_ppServerlist[i]->m_Info.m_aClients[p].m_aName, aFilterStr) ||
|
||||
str_utf8_find_nocase(m_ppServerlist[i]->m_Info.m_aClients[p].m_aClan, aFilterStr))
|
||||
{
|
||||
MatchFound = 1;
|
||||
m_ppServerlist[i]->m_Info.m_QuickSearchHit |= IServerBrowser::QUICK_PLAYER;
|
||||
|
@ -326,40 +335,49 @@ void CServerBrowser::Filter()
|
|||
}
|
||||
|
||||
// match against map
|
||||
if(str_utf8_find_nocase(m_ppServerlist[i]->m_Info.m_aMap, g_Config.m_BrFilterString))
|
||||
if(str_utf8_find_nocase(m_ppServerlist[i]->m_Info.m_aMap, aFilterStr))
|
||||
{
|
||||
MatchFound = 1;
|
||||
m_ppServerlist[i]->m_Info.m_QuickSearchHit |= IServerBrowser::QUICK_MAPNAME;
|
||||
}
|
||||
}
|
||||
|
||||
if(!MatchFound)
|
||||
Filtered = 1;
|
||||
}
|
||||
|
||||
if(!Filtered && g_Config.m_BrExcludeString[0] != 0)
|
||||
if(!Filtered && g_Config.m_BrExcludeString[0] != '\0')
|
||||
{
|
||||
int MatchFound = 0;
|
||||
const char *pStr = g_Config.m_BrExcludeString;
|
||||
char aExcludeStr[sizeof(g_Config.m_BrExcludeString)];
|
||||
while((pStr = str_next_token(pStr, IServerBrowser::SEARCH_EXCLUDE_TOKEN, aExcludeStr, sizeof(aExcludeStr))))
|
||||
{
|
||||
if(aExcludeStr[0] == '\0')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// match against server name
|
||||
if(str_utf8_find_nocase(m_ppServerlist[i]->m_Info.m_aName, g_Config.m_BrExcludeString))
|
||||
if(str_utf8_find_nocase(m_ppServerlist[i]->m_Info.m_aName, aExcludeStr))
|
||||
{
|
||||
MatchFound = 1;
|
||||
Filtered = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// match against map
|
||||
if(str_utf8_find_nocase(m_ppServerlist[i]->m_Info.m_aMap, g_Config.m_BrExcludeString))
|
||||
if(str_utf8_find_nocase(m_ppServerlist[i]->m_Info.m_aMap, aExcludeStr))
|
||||
{
|
||||
MatchFound = 1;
|
||||
Filtered = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// match against gametype
|
||||
if(str_utf8_find_nocase(m_ppServerlist[i]->m_Info.m_aGameType, g_Config.m_BrExcludeString))
|
||||
if(str_utf8_find_nocase(m_ppServerlist[i]->m_Info.m_aGameType, aExcludeStr))
|
||||
{
|
||||
MatchFound = 1;
|
||||
}
|
||||
|
||||
if(MatchFound)
|
||||
Filtered = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -141,6 +141,8 @@ public:
|
|||
NUM_NETWORKS,
|
||||
};
|
||||
|
||||
static constexpr const char *SEARCH_EXCLUDE_TOKEN = ";";
|
||||
|
||||
virtual void Refresh(int Type) = 0;
|
||||
virtual bool IsGettingServerlist() const = 0;
|
||||
virtual bool IsRefreshing() const = 0;
|
||||
|
|
|
@ -44,8 +44,8 @@ MACRO_CONFIG_STR(ClAssetParticles, cl_asset_particles, 50, "default", CFGFLAG_SA
|
|||
MACRO_CONFIG_STR(ClAssetHud, cl_asset_hud, 50, "default", CFGFLAG_SAVE | CFGFLAG_CLIENT, "The asset for HUD")
|
||||
MACRO_CONFIG_STR(ClAssetExtras, cl_asset_extras, 50, "default", CFGFLAG_SAVE | CFGFLAG_CLIENT, "The asset for the game graphics that do not come from Teeworlds")
|
||||
|
||||
MACRO_CONFIG_STR(BrFilterString, br_filter_string, 25, "Novice", CFGFLAG_SAVE | CFGFLAG_CLIENT, "Server browser filtering string")
|
||||
MACRO_CONFIG_STR(BrExcludeString, br_exclude_string, 25, "", CFGFLAG_SAVE | CFGFLAG_CLIENT, "Server browser exclusion string")
|
||||
MACRO_CONFIG_STR(BrFilterString, br_filter_string, 128, "Novice", CFGFLAG_SAVE | CFGFLAG_CLIENT, "Server browser filtering string")
|
||||
MACRO_CONFIG_STR(BrExcludeString, br_exclude_string, 128, "", CFGFLAG_SAVE | CFGFLAG_CLIENT, "Server browser exclusion string")
|
||||
MACRO_CONFIG_INT(BrFilterFull, br_filter_full, 0, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Filter out full server in browser")
|
||||
MACRO_CONFIG_INT(BrFilterEmpty, br_filter_empty, 0, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Filter out empty server in browser")
|
||||
MACRO_CONFIG_INT(BrFilterSpectators, br_filter_spectators, 0, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Filter out spectators from player numbers")
|
||||
|
|
|
@ -347,23 +347,34 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
else if(ID == COL_NAME)
|
||||
{
|
||||
float FontSize = 12.0f;
|
||||
bool Printed = false;
|
||||
|
||||
if(g_Config.m_BrFilterString[0] && (pItem->m_QuickSearchHit & IServerBrowser::QUICK_SERVERNAME))
|
||||
{
|
||||
const char *pStrToken = g_Config.m_BrFilterString;
|
||||
char aFilterStr[sizeof(g_Config.m_BrFilterString)];
|
||||
while((pStrToken = str_next_token(pStrToken, IServerBrowser::SEARCH_EXCLUDE_TOKEN, aFilterStr, sizeof(aFilterStr))))
|
||||
{
|
||||
if(aFilterStr[0] == '\0')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// highlight the parts that matches
|
||||
const char *pStr = str_utf8_find_nocase(pItem->m_aName, g_Config.m_BrFilterString);
|
||||
const char *pStr = str_utf8_find_nocase(pItem->m_aName, aFilterStr);
|
||||
if(pStr)
|
||||
{
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName + 0), &Button, pItem->m_aName, FontSize, TEXTALIGN_LEFT, Button.w, 1, true, (int)(pStr - pItem->m_aName));
|
||||
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName + 1), &Button, pStr, FontSize, TEXTALIGN_LEFT, Button.w, 1, true, (int)str_length(g_Config.m_BrFilterString), &pItem->m_pUIElement->Rect(gs_OffsetColName + 0)->m_Cursor);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName + 1), &Button, pStr, FontSize, TEXTALIGN_LEFT, Button.w, 1, true, (int)str_length(aFilterStr), &pItem->m_pUIElement->Rect(gs_OffsetColName + 0)->m_Cursor);
|
||||
TextRender()->TextColor(1, 1, 1, 1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName + 2), &Button, pStr + str_length(g_Config.m_BrFilterString), FontSize, TEXTALIGN_LEFT, Button.w, 1, true, -1, &pItem->m_pUIElement->Rect(gs_OffsetColName + 1)->m_Cursor);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName + 2), &Button, pStr + str_length(aFilterStr), FontSize, TEXTALIGN_LEFT, Button.w, 1, true, -1, &pItem->m_pUIElement->Rect(gs_OffsetColName + 1)->m_Cursor);
|
||||
Printed = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName), &Button, pItem->m_aName, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
||||
}
|
||||
else
|
||||
}
|
||||
if(!Printed)
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName), &Button, pItem->m_aName, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
||||
}
|
||||
else if(ID == COL_MAP)
|
||||
|
@ -382,23 +393,29 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
}
|
||||
|
||||
float FontSize = 12.0f;
|
||||
bool Printed = false;
|
||||
|
||||
if(g_Config.m_BrFilterString[0] && (pItem->m_QuickSearchHit & IServerBrowser::QUICK_MAPNAME))
|
||||
{
|
||||
const char *pStrToken = g_Config.m_BrFilterString;
|
||||
char aFilterStr[sizeof(g_Config.m_BrFilterString)];
|
||||
while((pStrToken = str_next_token(pStrToken, IServerBrowser::SEARCH_EXCLUDE_TOKEN, aFilterStr, sizeof(aFilterStr))))
|
||||
{
|
||||
// highlight the parts that matches
|
||||
const char *pStr = str_utf8_find_nocase(pItem->m_aMap, g_Config.m_BrFilterString);
|
||||
const char *pStr = str_utf8_find_nocase(pItem->m_aMap, aFilterStr);
|
||||
if(pStr)
|
||||
{
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap + 0), &Button, pItem->m_aMap, FontSize, TEXTALIGN_LEFT, Button.w, 1, true, (int)(pStr - pItem->m_aMap));
|
||||
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap + 1), &Button, pStr, FontSize, TEXTALIGN_LEFT, Button.w, 1, true, (int)str_length(g_Config.m_BrFilterString), &pItem->m_pUIElement->Rect(gs_OffsetColMap + 0)->m_Cursor);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap + 1), &Button, pStr, FontSize, TEXTALIGN_LEFT, Button.w, 1, true, (int)str_length(aFilterStr), &pItem->m_pUIElement->Rect(gs_OffsetColMap + 0)->m_Cursor);
|
||||
TextRender()->TextColor(1, 1, 1, 1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap + 2), &Button, pStr + str_length(g_Config.m_BrFilterString), FontSize, TEXTALIGN_LEFT, Button.w, 1, true, -1, &pItem->m_pUIElement->Rect(gs_OffsetColMap + 1)->m_Cursor);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap + 2), &Button, pStr + str_length(aFilterStr), FontSize, TEXTALIGN_LEFT, Button.w, 1, true, -1, &pItem->m_pUIElement->Rect(gs_OffsetColMap + 1)->m_Cursor);
|
||||
Printed = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap), &Button, pItem->m_aMap, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
||||
}
|
||||
else
|
||||
}
|
||||
if(!Printed)
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap), &Button, pItem->m_aMap, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
||||
}
|
||||
else if(ID == COL_PLAYERS)
|
||||
|
@ -1172,44 +1189,56 @@ void CMenus::RenderServerbrowserServerDetail(CUIRect View)
|
|||
TextRender()->SetCursor(&Cursor, Name.x, Name.y + (Name.h - (FontSize - 2)) / 2.f, FontSize - 2, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END);
|
||||
Cursor.m_LineWidth = Name.w;
|
||||
const char *pName = pSelectedServer->m_aClients[i].m_aName;
|
||||
bool Printed = false;
|
||||
if(g_Config.m_BrFilterString[0])
|
||||
{
|
||||
const char *pStr = g_Config.m_BrFilterString;
|
||||
char aFilterStr[sizeof(g_Config.m_BrFilterString)];
|
||||
while((pStr = str_next_token(pStr, IServerBrowser::SEARCH_EXCLUDE_TOKEN, aFilterStr, sizeof(aFilterStr))))
|
||||
{
|
||||
// highlight the parts that matches
|
||||
const char *pFilteredStr = str_utf8_find_nocase(pName, g_Config.m_BrFilterString);
|
||||
const char *pFilteredStr = str_utf8_find_nocase(pName, aFilterStr);
|
||||
if(pFilteredStr)
|
||||
{
|
||||
TextRender()->TextEx(&Cursor, pName, (int)(pFilteredStr - pName));
|
||||
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1.0f);
|
||||
TextRender()->TextEx(&Cursor, pFilteredStr, str_length(g_Config.m_BrFilterString));
|
||||
TextRender()->TextEx(&Cursor, pFilteredStr, str_length(aFilterStr));
|
||||
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
TextRender()->TextEx(&Cursor, pFilteredStr + str_length(g_Config.m_BrFilterString), -1);
|
||||
TextRender()->TextEx(&Cursor, pFilteredStr + str_length(aFilterStr), -1);
|
||||
Printed = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
TextRender()->TextEx(&Cursor, pName, -1);
|
||||
}
|
||||
else
|
||||
}
|
||||
if(!Printed)
|
||||
TextRender()->TextEx(&Cursor, pName, -1);
|
||||
|
||||
// clan
|
||||
TextRender()->SetCursor(&Cursor, Clan.x, Clan.y + (Clan.h - (FontSize - 2)) / 2.f, FontSize - 2, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END);
|
||||
Cursor.m_LineWidth = Clan.w;
|
||||
const char *pClan = pSelectedServer->m_aClients[i].m_aClan;
|
||||
Printed = false;
|
||||
if(g_Config.m_BrFilterString[0])
|
||||
{
|
||||
const char *pStr = g_Config.m_BrFilterString;
|
||||
char aFilterStr[sizeof(g_Config.m_BrFilterString)];
|
||||
while((pStr = str_next_token(pStr, IServerBrowser::SEARCH_EXCLUDE_TOKEN, aFilterStr, sizeof(aFilterStr))))
|
||||
{
|
||||
// highlight the parts that matches
|
||||
const char *pFilteredString = str_utf8_find_nocase(pClan, g_Config.m_BrFilterString);
|
||||
const char *pFilteredString = str_utf8_find_nocase(pClan, aFilterStr);
|
||||
if(pFilteredString)
|
||||
{
|
||||
TextRender()->TextEx(&Cursor, pClan, (int)(pFilteredString - pClan));
|
||||
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1.0f);
|
||||
TextRender()->TextEx(&Cursor, pFilteredString, str_length(g_Config.m_BrFilterString));
|
||||
TextRender()->TextEx(&Cursor, pFilteredString, str_length(aFilterStr));
|
||||
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
TextRender()->TextEx(&Cursor, pFilteredString + str_length(g_Config.m_BrFilterString), -1);
|
||||
TextRender()->TextEx(&Cursor, pFilteredString + str_length(aFilterStr), -1);
|
||||
Printed = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
TextRender()->TextEx(&Cursor, pClan, -1);
|
||||
}
|
||||
else
|
||||
}
|
||||
if(!Printed)
|
||||
TextRender()->TextEx(&Cursor, pClan, -1);
|
||||
|
||||
// flag
|
||||
|
|
Loading…
Reference in a new issue