From 32c9083fad267ce8700a979a364ed8e6fcae214e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 9 Feb 2026 13:32:44 +0100 Subject: [PATCH 1/6] Add opening looked up article's URL --- .../clientcommands/command/WikiCommand.java | 25 +++++++++++++++++++ .../features/WikiRetriever.java | 2 +- .../assets/clientcommands/lang/en_us.json | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/command/WikiCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/WikiCommand.java index 5d6df37e9..c8e360c1a 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/WikiCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/WikiCommand.java @@ -5,14 +5,24 @@ import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import net.earthcomputer.clientcommands.features.WikiRetriever; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; +import java.net.URI; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + import static com.mojang.brigadier.arguments.StringArgumentType.*; import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.*; public class WikiCommand { private static final SimpleCommandExceptionType FAILED_EXCEPTION = new SimpleCommandExceptionType(Component.translatable("commands.cwiki.failed")); + private static final String WIKI_HOST = "https://minecraft.wiki/"; + private static final String WIKI_ARTICLE = WIKI_HOST + "w/%s"; + + public static void register(CommandDispatcher dispatcher) { dispatcher.register(literal("cwiki") .then(argument("page", greedyString()) @@ -21,15 +31,30 @@ public static void register(CommandDispatcher dispatc private static int displayWikiPage(FabricClientCommandSource source, String page) throws CommandSyntaxException { String content = WikiRetriever.getWikiSummary(page); + String pageName = URLEncoder.encode(page, StandardCharsets.UTF_8).replace('+', '_'); + String url = String.format(WIKI_ARTICLE, pageName); if (content == null) { throw FAILED_EXCEPTION.create(); } + URI uri = URI.create(url); + + ClickEvent clickEvent = new ClickEvent.OpenUrl(uri); + + Component link = Component.translatable("commands.cwiki.openArticle") + .withStyle(style -> style + .withClickEvent(clickEvent) + .withColor(ChatFormatting.GREEN) + .withUnderlined(true) + ); + + content = content.trim(); for (String line : content.split("\n")) { source.sendFeedback(Component.literal(line)); } + source.sendFeedback(link); return content.length(); } diff --git a/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java b/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java index 64a11f2b7..1160e7f0c 100644 --- a/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java +++ b/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java @@ -182,7 +182,7 @@ public static String decode(String html) { return rawStr; } - + @Nullable public static String getWikiSummary(String pageName) { URL url; diff --git a/src/main/resources/assets/clientcommands/lang/en_us.json b/src/main/resources/assets/clientcommands/lang/en_us.json index 943ba578d..54f0f69be 100644 --- a/src/main/resources/assets/clientcommands/lang/en_us.json +++ b/src/main/resources/assets/clientcommands/lang/en_us.json @@ -317,6 +317,7 @@ "commands.cwiki.failed": "Could not retrieve wiki content", "commands.cwiki.noContent": "There is no introductory paragraph in that article", + "commands.cwiki.openArticle": "[Open article]", "connectFourGame.draw": "Draw!", "connectFourGame.lost": "Lost!", From da89fbec1331fa6dfa60739476da66a868d02506 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 9 Feb 2026 15:10:52 +0100 Subject: [PATCH 2/6] Add searching article names --- .../features/WikiRetriever.java | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java b/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java index 1160e7f0c..78d877ec3 100644 --- a/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java +++ b/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java @@ -13,6 +13,7 @@ import java.net.URL; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.regex.Matcher; @@ -21,6 +22,7 @@ public class WikiRetriever { private static final String WIKI_HOST = "https://minecraft.wiki/"; + private static final String SEARCH_QUERY = WIKI_HOST + "api.php?action=query&list=search&srlimit=1&srprop=snippet&format=json&srsearch=intitle:%s"; private static final String PAGE_SUMMARY_QUERY = WIKI_HOST + "api.php?action=query&prop=extracts&exintro=true&format=json&titles=%s"; private static final Pattern HTML_TAG_PATTERN = Pattern.compile("<\\s*(/)?\\s*(\\w+).*?>||\n", Pattern.DOTALL); private static final ChatFormatting CODE_COLOR = ChatFormatting.DARK_GREEN; @@ -182,12 +184,42 @@ public static String decode(String html) { return rawStr; } - + + @Nullable + public static String getArticleName(String pageInput){ + URL url; + try { + String encodedPage = URLEncoder.encode(pageInput, StandardCharsets.UTF_8); + url = URI.create(String.format(SEARCH_QUERY, encodedPage)).toURL(); + } catch (MalformedURLException e) { + return null; + } + + QueryResult result; + try (InputStream in = url.openConnection().getInputStream()) { + result = GSON.fromJson(new InputStreamReader(in), QueryResult.class); + } catch (IOException e) { + return null; + } + + if (result.query == null || result.query.search == null || result.query.search.isEmpty()) { + return null; + } + + return result.query.search.getFirst().title; + } + + @Nullable public static String getWikiSummary(String pageName) { + String title = getArticleName(pageName); + if (title == null) { + return null; + } + URL url; try { - String encodedPage = URLEncoder.encode(pageName, StandardCharsets.UTF_8); + String encodedPage = URLEncoder.encode(title, StandardCharsets.UTF_8); url = URI.create(String.format(PAGE_SUMMARY_QUERY, encodedPage)).toURL(); } catch (MalformedURLException e) { return null; @@ -222,7 +254,7 @@ private static class Query { @Nullable private Map pages; private static class Page { - public int pageid; + public int pageId; @Nullable public String title; @Nullable @@ -230,6 +262,12 @@ private static class Page { @Nullable public String missing; } + @Nullable + private List search; + private static class Search { + @Nullable + public String title; + } } } From 702570e24f9dc33c48cdd94fffc4d4e1daf123c0 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 9 Feb 2026 22:15:27 +0100 Subject: [PATCH 3/6] Modularize the WikiRetriever code and fix minor bugs --- .../clientcommands/command/WikiCommand.java | 29 +++++++--- .../features/WikiRetriever.java | 57 ++++++++++++------- 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/command/WikiCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/WikiCommand.java index c8e360c1a..cce335e74 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/WikiCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/WikiCommand.java @@ -8,6 +8,7 @@ import net.minecraft.ChatFormatting; import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; +import org.jspecify.annotations.Nullable; import java.net.URI; import java.net.URLEncoder; @@ -29,31 +30,43 @@ public static void register(CommandDispatcher dispatc .executes(ctx -> displayWikiPage(ctx.getSource(), getString(ctx, "page"))))); } - private static int displayWikiPage(FabricClientCommandSource source, String page) throws CommandSyntaxException { - String content = WikiRetriever.getWikiSummary(page); - String pageName = URLEncoder.encode(page, StandardCharsets.UTF_8).replace('+', '_'); - String url = String.format(WIKI_ARTICLE, pageName); - - if (content == null) { - throw FAILED_EXCEPTION.create(); + @Nullable + private static Component getLinkComponent(String page) { + String title = WikiRetriever.searchArticleName(page); + if (title == null) { + return null; } + String pageName = URLEncoder.encode(title, StandardCharsets.UTF_8).replace('+', '_'); + String url = String.format(WIKI_ARTICLE, pageName); URI uri = URI.create(url); ClickEvent clickEvent = new ClickEvent.OpenUrl(uri); - Component link = Component.translatable("commands.cwiki.openArticle") + return Component.translatable("commands.cwiki.openArticle") .withStyle(style -> style .withClickEvent(clickEvent) .withColor(ChatFormatting.GREEN) .withUnderlined(true) ); + } + private static int displayWikiPage(FabricClientCommandSource source, String page) throws CommandSyntaxException { + String content = WikiRetriever.getWikiSummary(page); + if (content == null) { + throw FAILED_EXCEPTION.create(); + } content = content.trim(); for (String line : content.split("\n")) { source.sendFeedback(Component.literal(line)); } + + Component link = getLinkComponent(page); + if (link == null) { + throw FAILED_EXCEPTION.create(); + } + source.sendFeedback(link); return content.length(); diff --git a/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java b/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java index 78d877ec3..e72e06042 100644 --- a/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java +++ b/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java @@ -22,7 +22,7 @@ public class WikiRetriever { private static final String WIKI_HOST = "https://minecraft.wiki/"; - private static final String SEARCH_QUERY = WIKI_HOST + "api.php?action=query&list=search&srlimit=1&srprop=snippet&format=json&srsearch=intitle:%s"; + private static final String SEARCH_QUERY = WIKI_HOST + "api.php?action=query&list=search&srlimit=1&srprop=snippet&format=json&srsearch=%s"; private static final String PAGE_SUMMARY_QUERY = WIKI_HOST + "api.php?action=query&prop=extracts&exintro=true&format=json&titles=%s"; private static final Pattern HTML_TAG_PATTERN = Pattern.compile("<\\s*(/)?\\s*(\\w+).*?>||\n", Pattern.DOTALL); private static final ChatFormatting CODE_COLOR = ChatFormatting.DARK_GREEN; @@ -186,19 +186,37 @@ public static String decode(String html) { } @Nullable - public static String getArticleName(String pageInput){ + public static QueryResult getResult(URL url) { + QueryResult result; + try (InputStream in = url.openConnection().getInputStream()) { + result = GSON.fromJson(new InputStreamReader(in), QueryResult.class); + } catch (IOException e) { + return null; + } + return result; + } + + @Nullable + public static URL buildURL(String page, String query) { URL url; try { - String encodedPage = URLEncoder.encode(pageInput, StandardCharsets.UTF_8); - url = URI.create(String.format(SEARCH_QUERY, encodedPage)).toURL(); + String encodedPage = URLEncoder.encode(page, StandardCharsets.UTF_8); + url = URI.create(String.format(query, encodedPage)).toURL(); } catch (MalformedURLException e) { return null; } + return url; + } - QueryResult result; - try (InputStream in = url.openConnection().getInputStream()) { - result = GSON.fromJson(new InputStreamReader(in), QueryResult.class); - } catch (IOException e) { + @Nullable + public static String searchArticleName(String pageInput){ + URL url = buildURL(pageInput, SEARCH_QUERY); + if (url == null) { + return null; + } + + QueryResult result = getResult(url); + if (result == null) { return null; } @@ -209,26 +227,20 @@ public static String getArticleName(String pageInput){ return result.query.search.getFirst().title; } - @Nullable public static String getWikiSummary(String pageName) { - String title = getArticleName(pageName); + String title = searchArticleName(pageName); if (title == null) { return null; } - URL url; - try { - String encodedPage = URLEncoder.encode(title, StandardCharsets.UTF_8); - url = URI.create(String.format(PAGE_SUMMARY_QUERY, encodedPage)).toURL(); - } catch (MalformedURLException e) { + URL url = buildURL(title, PAGE_SUMMARY_QUERY); + if (url == null) { return null; } - QueryResult result; - try (InputStream in = url.openConnection().getInputStream()) { - result = GSON.fromJson(new InputStreamReader(in), QueryResult.class); - } catch (IOException e) { + QueryResult result = getResult(url); + if (result == null) { return null; } @@ -244,17 +256,17 @@ public static String getWikiSummary(String pageName) { } @SuppressWarnings("unused") - private static class QueryResult { + public static class QueryResult { @Nullable public String batchcomplete; @Nullable public Query query; - private static class Query { + public static class Query { @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") @Nullable private Map pages; private static class Page { - public int pageId; + public int pageid; @Nullable public String title; @Nullable @@ -262,6 +274,7 @@ private static class Page { @Nullable public String missing; } + @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") @Nullable private List search; private static class Search { From caa7504bad3379a6470cc1762d40c922cfb066ea Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Feb 2026 00:06:36 +0100 Subject: [PATCH 4/6] Improve searching and fix minor bugs --- .../features/WikiRetriever.java | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java b/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java index e72e06042..a69d5f860 100644 --- a/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java +++ b/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java @@ -13,11 +13,13 @@ import java.net.URL; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; public class WikiRetriever { @@ -198,9 +200,13 @@ public static QueryResult getResult(URL url) { @Nullable public static URL buildURL(String page, String query) { + String result = Arrays.stream(page.split("\\s+")) + .map(w -> Character.toUpperCase(w.charAt(0)) + w.substring(1)) + .collect(Collectors.joining(" ")); + URL url; try { - String encodedPage = URLEncoder.encode(page, StandardCharsets.UTF_8); + String encodedPage = URLEncoder.encode(result, StandardCharsets.UTF_8); url = URI.create(String.format(query, encodedPage)).toURL(); } catch (MalformedURLException e) { return null; @@ -210,7 +216,7 @@ public static URL buildURL(String page, String query) { @Nullable public static String searchArticleName(String pageInput){ - URL url = buildURL(pageInput, SEARCH_QUERY); + URL url = buildURL(pageInput.trim(), SEARCH_QUERY); if (url == null) { return null; } @@ -220,11 +226,22 @@ public static String searchArticleName(String pageInput){ return null; } - if (result.query == null || result.query.search == null || result.query.search.isEmpty()) { + var query = result.query; + if (query == null) { return null; } - return result.query.search.getFirst().title; + var search = query.search; + var searchinfo = query.searchinfo; + if (search == null || search.isEmpty() || searchinfo == null || searchinfo.totalhits == 0) { + return null; + } + + if (searchinfo.suggestion != null) { + return searchinfo.suggestion; + } + + return query.search.getFirst().title; } @Nullable @@ -281,6 +298,14 @@ private static class Search { @Nullable public String title; } + @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") + @Nullable + private SearchInfo searchinfo; + private static class SearchInfo { + public int totalhits; + @Nullable + public String suggestion; + } } } From 98d58afbc9ad7506800279c0e0a62d1c0e209761 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Feb 2026 00:21:16 +0100 Subject: [PATCH 5/6] Small fix for tolerating more inputs --- .../earthcomputer/clientcommands/features/WikiRetriever.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java b/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java index a69d5f860..d54b2f306 100644 --- a/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java +++ b/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java @@ -201,9 +201,11 @@ public static QueryResult getResult(URL url) { @Nullable public static URL buildURL(String page, String query) { String result = Arrays.stream(page.split("\\s+")) - .map(w -> Character.toUpperCase(w.charAt(0)) + w.substring(1)) + .map(w -> w.substring(0, 1).toUpperCase() + + w.substring(1).toLowerCase()) .collect(Collectors.joining(" ")); + URL url; try { String encodedPage = URLEncoder.encode(result, StandardCharsets.UTF_8); From f673a32f2bc13268e2f448f36dada4893b717f56 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Feb 2026 01:13:11 +0100 Subject: [PATCH 6/6] Set Locale to ROOT --- .../earthcomputer/clientcommands/features/WikiRetriever.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java b/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java index d54b2f306..ec13f25ec 100644 --- a/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java +++ b/src/main/java/net/earthcomputer/clientcommands/features/WikiRetriever.java @@ -201,8 +201,8 @@ public static QueryResult getResult(URL url) { @Nullable public static URL buildURL(String page, String query) { String result = Arrays.stream(page.split("\\s+")) - .map(w -> w.substring(0, 1).toUpperCase() - + w.substring(1).toLowerCase()) + .map(w -> w.substring(0, 1).toUpperCase(Locale.ROOT) + + w.substring(1).toLowerCase(Locale.ROOT)) .collect(Collectors.joining(" "));