From 0e06590ffda8e701c30b731f09466e55ab4ecad4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lars=20M=C3=BCller?=
 <34514239+appgurueu@users.noreply.github.com>
Date: Sun, 3 Nov 2024 15:09:47 +0100
Subject: [PATCH] Apply "and" to server list & content search terms (#15365)

---
 builtin/mainmenu/content/contentdb.lua | 32 ++++++++++++++------------
 builtin/mainmenu/tab_online.lua        | 32 +++++++++-----------------
 2 files changed, 28 insertions(+), 36 deletions(-)

diff --git a/builtin/mainmenu/content/contentdb.lua b/builtin/mainmenu/content/contentdb.lua
index 1c09ac9c4..c352a260b 100644
--- a/builtin/mainmenu/content/contentdb.lua
+++ b/builtin/mainmenu/content/contentdb.lua
@@ -563,30 +563,32 @@ function contentdb.filter_packages(query, by_type)
 	end
 
 	local keywords = {}
-	for word in query:lower():gmatch("%S+") do
-		table.insert(keywords, word)
+	for word in query:gmatch("%S+") do
+		table.insert(keywords, word:lower())
+	end
+
+	local function contains_all_keywords(str)
+		str = str:lower()
+		for _, keyword in ipairs(keywords) do
+			if not str:find(keyword, 1, true) then
+				return false
+			end
+		end
+		return true
 	end
 
 	local function matches_keywords(package)
-		for k = 1, #keywords do
-			local keyword = keywords[k]
-
-			if string.find(package.name:lower(), keyword, 1, true) or
-					string.find(package.title:lower(), keyword, 1, true) or
-					string.find(package.author:lower(), keyword, 1, true) or
-					string.find(package.short_description:lower(), keyword, 1, true) then
-				return true
-			end
-		end
-
-		return false
+		return contains_all_keywords(package.name) or
+				contains_all_keywords(package.title) or
+				contains_all_keywords(package.author) or
+				contains_all_keywords(package.short_description)
 	end
 
 	contentdb.packages = {}
 	for _, package in pairs(contentdb.packages_full) do
 		if (query == "" or matches_keywords(package)) and
 				(by_type == nil or package.type == by_type) then
-			contentdb.packages[#contentdb.packages + 1] = package
+			table.insert(contentdb.packages, package)
 		end
 	end
 end
diff --git a/builtin/mainmenu/tab_online.lua b/builtin/mainmenu/tab_online.lua
index 8674d908a..a73b863ce 100644
--- a/builtin/mainmenu/tab_online.lua
+++ b/builtin/mainmenu/tab_online.lua
@@ -195,8 +195,7 @@ local function search_server_list(input)
 	-- setup the keyword list
 	local keywords = {}
 	for word in input:gmatch("%S+") do
-		word = word:gsub("(%W)", "%%%1")
-		table.insert(keywords, word)
+		table.insert(keywords, word:lower())
 	end
 
 	if #keywords == 0 then
@@ -207,26 +206,17 @@ local function search_server_list(input)
 
 	-- Search the serverlist
 	local search_result = {}
-	for i = 1, #serverlistmgr.servers do
-		local server = serverlistmgr.servers[i]
-		local found = 0
-		for k = 1, #keywords do
-			local keyword = keywords[k]
-			if server.name then
-				local sername = server.name:lower()
-				local _, count = sername:gsub(keyword, keyword)
-				found = found + count * 4
-			end
-
-			if server.description then
-				local desc = server.description:lower()
-				local _, count = desc:gsub(keyword, keyword)
-				found = found + count * 2
-			end
+	for i, server in ipairs(serverlistmgr.servers) do
+		local name_matches, description_matches = true, true
+		for _, keyword in ipairs(keywords) do
+			name_matches = name_matches and not not
+					(server.name or ""):lower():find(keyword, 1, true)
+			description_matches = description_matches and not not
+					(server.description or ""):lower():find(keyword, 1, true)
 		end
-		if found > 0 then
-			local points = (#serverlistmgr.servers - i) / 5 + found
-			server.points = points
+		if name_matches or description_matches then
+			server.points = #serverlistmgr.servers - i
+					+ (name_matches and 50 or 0)
 			table.insert(search_result, server)
 		end
 	end