diff --git a/build.gradle b/build.gradle index c161e88..28d5ffd 100644 --- a/build.gradle +++ b/build.gradle @@ -52,6 +52,7 @@ subprojects { name = 'CurseMaven' url "https://beta.cursemaven.com" } + mavenCentral() } dependencies { @@ -60,6 +61,7 @@ subprojects { it.mappings("net.fabricmc:yarn:$rootProject.yarn_mappings:v2") it.mappings("dev.architectury:yarn-mappings-patch-neoforge:$rootProject.yarn_mappings_patch_neoforge_version") } + include implementation("org.eclipse.jgit:org.eclipse.jgit:6.10.0.202406032230-r") } java { diff --git a/common/src/main/java/rearth/oracle/OracleClient.java b/common/src/main/java/rearth/oracle/OracleClient.java index 0ab6009..c643973 100644 --- a/common/src/main/java/rearth/oracle/OracleClient.java +++ b/common/src/main/java/rearth/oracle/OracleClient.java @@ -8,22 +8,30 @@ import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.option.KeyBinding; import net.minecraft.item.ItemStack; +import net.minecraft.resource.Resource; +import net.minecraft.resource.ResourceManager; import net.minecraft.util.Identifier; +import org.apache.commons.io.FileUtils; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.JGitInternalException; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; import rearth.oracle.ui.OracleScreen; import rearth.oracle.util.MarkdownParser; +import java.io.File; import java.io.IOException; +import java.io.PrintWriter; +import java.net.*; import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; +import java.util.*; public final class OracleClient { public static final KeyBinding ORACLE_WIKI = new KeyBinding("key.oracle_index.open", GLFW.GLFW_KEY_H, "key.categories.misc"); - + public static final Set LOADED_BOOKS = new HashSet<>(); public static final HashMap ITEM_LINKS = new HashMap<>(); @@ -73,39 +81,229 @@ public static void openScreen(@Nullable String bookId, @Nullable Identifier entr MinecraftClient.getInstance().setScreen(new OracleScreen(parent)); } - + + private static final HashMap loadedModIds_Urls = new HashMap<>(); + + private static String mainDownloadsFolder = ""; + + /**Called in the loader specific settings. + * These is a map of the laoded mods and their git repo link + */ + public static void setModIdAndUrls(HashMap ids_urls){ + loadedModIds_Urls.putAll(ids_urls); + } + + /**Sets where the repos will be downloaded*/ + public static void setMainDownloadsFolder(String folder){ + mainDownloadsFolder = folder; + } + + public static String getDownloadedWikisFolder(){ + return mainDownloadsFolder+"/"+Oracle.MOD_ID+"/downloaded_wikis/"; + } + + /**Downloads the repository from github, from the given url*/ + private static boolean pullFromWeb(String id, String url){ + if(url.equals("-")){ + return false; + } + try { + createDownloadedWikisResourcePack(); + } catch (IOException e) { + Oracle.LOGGER.error("Could not create the downloaded wikis' resourcepack folder!"); + throw new RuntimeException(e); + } + File dirPath = new File(getDownloadedWikisFolder()+id+"/"); + try { + //TODO find a way to download only somthing from the repo + //TODO add option to regenerate the repository/update it or something. + + //TODO migrate the dir path directly to resource folder? + Git git = Git.cloneRepository() + .setURI(url) + .setDirectory(dirPath) + .call(); + + sanitizeDirectory(dirPath); + + + //The copying over to the resource pack + try { + FileUtils.moveDirectory(new File(dirPath+"/docs/"+id+"/"), new File(getBooksFolder()+id+"/")); + FileUtils.deleteDirectory(new File(dirPath+"/docs/")); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return true; + } catch (GitAPIException e) { + Oracle.LOGGER.error("BIG ERRORR GIT HUB API THINGY"); + throw new RuntimeException(e); + } catch (JGitInternalException e){ + //means it already exists + //TODO maybe do this? Git.open(dirPath).fetch().call(); + Oracle.LOGGER.info("---------Already downloaded!!!!!!"); + return true; + } + } + + public static void createDownloadedWikisResourcePack() throws IOException { + File packmeta = new File(MinecraftClient.getInstance().getResourcePackDir().toString()+"/oracleDownloadedWikis/pack.mcmeta"); + + if(!packmeta.exists()){ + FileUtils.createParentDirectories(packmeta); + PrintWriter writer = new PrintWriter(packmeta.toString(), StandardCharsets.UTF_8); + + writer.println("{"); + writer.println(" \"pack\": {"); + writer.println(" \"pack_format\": 34,"); //34 is 1.21.1 + writer.println(" \"description\": \"OracleIndex downloaded wikis\""); + writer.println(" }"); + writer.println("}"); + writer.close(); + packmeta.createNewFile(); + } + } + + public static String getResourcePackFolder(){ + return MinecraftClient.getInstance().getResourcePackDir().toString()+"/oracleDownloadedWikis/"; + } + + public static String getBooksFolder(){ + return getResourcePackFolder()+"assets/"+Oracle.MOD_ID+"/books/"; + } + + /**Removes anything except the docs folder and the related files and the .git folder*/ + public static void sanitizeDirectory(@NotNull File dirPath){ + try { + for (File file : dirPath.listFiles()){ + if(file.isDirectory() && !(file.getName().equals("docs") || file.getName().equals(".git"))){ + FileUtils.cleanDirectory(file); + FileUtils.delete(file); + }else if(file.isFile()){ + FileUtils.delete(file); + }else if(file.isDirectory() && file.getName().equals("docs")){ + sanitizeDocsFolder(file); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /**Removes files that aren't supposed to be in the docs folder*/ + public static void sanitizeDocsFolder(File docsPath){ + File[] files = docsPath.listFiles(); + if(files == null){ + return; + } + for (File file : files){ + if(file.isDirectory()){ + sanitizeDocsFolder(file); + }else if(!checkValidExtension(file.getName())){ + try { + FileUtils.delete(file); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + + /**Checks if the files have a valid extension, which are .mdx .md .png .json + * + * Returns true if the file has one of the valid extensions*/ + public static boolean checkValidExtension(String fileName){ + return fileName.endsWith(".mdx") || fileName.endsWith(".md") || fileName.endsWith("png") || fileName.endsWith("json"); + } + private static void findAllResourceEntries() { - var resourceManager = MinecraftClient.getInstance().getResourceManager(); - var resources = resourceManager.findResources("books", path -> path.getPath().endsWith(".mdx")); - + ResourceManager resourceManager = MinecraftClient.getInstance().getResourceManager(); + Map resources = resourceManager.findResources("books", path -> path.getPath().endsWith(".mdx")); + LOADED_BOOKS.clear(); - - for (var resourceId : resources.keySet()) { - var purePath = resourceId.getPath().replaceFirst("books/", ""); - var segments = purePath.split("/"); - var modId = segments[0]; // e.g. "oritech" - var entryPath = purePath.replaceFirst(modId + "/", ""); // e.g. "tools/wrench.mdx" - var entryFileName = segments[segments.length - 1]; // e.g. "wrench.mdx" - var entryDirectory = entryPath.replace(entryFileName, ""); // e.g. "tools" or "processing/reactor" - - try { - var fileContent = new String(resources.get(resourceId).getInputStream().readAllBytes(), StandardCharsets.UTF_8); - var fileComponents = MarkdownParser.parseFrontmatter(fileContent); - if (fileComponents.containsKey("related_items")) { - var baseString = fileComponents.get("related_items").replace("[", "").replace("]", ""); - var itemStrings = baseString.split(", "); - for (var itemString : itemStrings) { - var itemId = Identifier.of(itemString); - var linkData = new BookItemLink(resourceId, fileComponents.getOrDefault("title", "missing"), modId); - ITEM_LINKS.put(itemId, linkData); + + for (Identifier resourceId : resources.keySet()) { + String purePath = resourceId.getPath().replaceFirst("books/", ""); + + @NotNull String[] segments = purePath.split("/"); + @NotNull String modId = segments[0]; // e.g. "oritech" + String entryPath = purePath.replaceFirst(modId + "/", ""); // e.g. "tools/wrench.mdx" + @NotNull String entryFileName = segments[segments.length - 1]; // e.g. "wrench.mdx" + String entryDirectory = entryPath.replace(entryFileName, ""); // e.g. "tools" or "processing/reactor" + + try { + String fileContent = new String(resources.get(resourceId).getInputStream().readAllBytes(), StandardCharsets.UTF_8); + readFiles(fileContent, resourceId, modId); + + } catch (IOException e) { + Oracle.LOGGER.error("Unable to load book with id: " + resourceId); + throw new RuntimeException(e); + } + + + LOADED_BOOKS.add(modId); + } + + boolean downloadedSomething = false; + + for(String id : loadedModIds_Urls.keySet()){ + + if(!LOADED_BOOKS.contains(id)){ + try { + if(queryWikiExists(id)){ + if(pullFromWeb(id, loadedModIds_Urls.get(id))){ + //TODO remove + downloadedSomething = true; + LOADED_BOOKS.add(id); + + }else{ + //TODO remove + Oracle.LOGGER.info("DEBUG: message error!"); + + } } + } catch (IOException | URISyntaxException e) { + throw new RuntimeException(e); } - } catch (IOException e) { - Oracle.LOGGER.error("Unable to load book with id: " + resourceId); - throw new RuntimeException(e); - } - - LOADED_BOOKS.add(modId); + } + } + + if(downloadedSomething){ + MinecraftClient.getInstance().getResourcePackManager().enable("file/oracleDownloadedWikis"); + MinecraftClient.getInstance().reloadResources(); + } + + } + + /**Sends an HTTP request to the wiki page of the mod. It checks the + * url of moddedwiki + the modid of the mod, so while setting up the wiki the + * slug and the modid must be the same. + * + * @return true if the http request is 200, aka it's ok, aka the page exists, False otherwise. */ + public static boolean queryWikiExists(String id) throws IOException, URISyntaxException { + //TODO add a check for having internet connection maybe? + URL url = new URI("https://moddedmc.wiki/en/project/"+id+"/docs").toURL(); + HttpURLConnection huc = (HttpURLConnection) url.openConnection(); + huc.setInstanceFollowRedirects(false); + huc.setRequestMethod("HEAD"); + + int responseCode = huc.getResponseCode(); + return responseCode == HttpURLConnection.HTTP_OK; + } + + /**Reads the file inputeed as an argument*/ + public static void readFiles(String fileContent, Identifier resourceId, String modId){ + Map fileComponents = MarkdownParser.parseFrontmatter(fileContent); + if (fileComponents.containsKey("related_items")) { + String baseString = fileComponents.get("related_items").replace("[", "").replace("]", ""); + @NotNull String[] itemStrings = baseString.split(", "); + for (String itemString : itemStrings) { + Identifier itemId = Identifier.of(itemString); + //TODO need to find a way to modify this thing here + BookItemLink linkData = new BookItemLink(resourceId, fileComponents.getOrDefault("title", "missing"), modId); + ITEM_LINKS.put(itemId, linkData); + } } } diff --git a/common/src/main/java/rearth/oracle/ui/OracleScreen.java b/common/src/main/java/rearth/oracle/ui/OracleScreen.java index d61da24..62c529d 100644 --- a/common/src/main/java/rearth/oracle/ui/OracleScreen.java +++ b/common/src/main/java/rearth/oracle/ui/OracleScreen.java @@ -32,40 +32,40 @@ import java.util.Objects; public class OracleScreen extends BaseOwoScreen { - + private FlowLayout navigationBar; private FlowLayout contentContainer; private FlowLayout rootComponent; private FlowLayout leftPanel; private ScrollContainer outerContentContainer; - + private final Screen parent; - + private boolean needsLayout = false; - + public static Identifier activeEntry; public static String activeBook; - + private static final int wideContentWidth = 50; // in % - + public OracleScreen() { this.parent = null; } - + public OracleScreen(Screen parent) { this.parent = parent; } - + @Override public void close() { Objects.requireNonNull(client).setScreen(parent); } - + @Override protected @NotNull OwoUIAdapter createAdapter() { return OwoUIAdapter.create(this, Containers::horizontalFlow); } - + @Override protected void build(FlowLayout rootComponent) { rootComponent.surface(Surface.blur(4f, 48f)); @@ -73,50 +73,50 @@ protected void build(FlowLayout rootComponent) { rootComponent.horizontalAlignment(HorizontalAlignment.LEFT); rootComponent.verticalAlignment(VerticalAlignment.CENTER); this.rootComponent = rootComponent; - + leftPanel = Containers.verticalFlow(Sizing.content(), Sizing.fill()); leftPanel.horizontalAlignment(HorizontalAlignment.CENTER); - + navigationBar = Containers.verticalFlow(Sizing.content(), Sizing.content(3)); navigationBar.surface(MarkdownParser.ORACLE_PANEL_DARK); navigationBar.padding(Insets.of(9, 5, 5, 5)); rootComponent.child(leftPanel); - + contentContainer = Containers.verticalFlow(Sizing.fill(), Sizing.content(3)); contentContainer.horizontalSizing(Sizing.fill()); contentContainer.horizontalAlignment(HorizontalAlignment.CENTER); contentContainer.margins(Insets.of(2, 2, 4, 4)); contentContainer.padding(Insets.of(20, 25, 0, 0)); contentContainer.allowOverflow(true); - + outerContentContainer = Containers.verticalScroll(Sizing.fill(wideContentWidth), Sizing.fill(), contentContainer); outerContentContainer.allowOverflow(true); rootComponent.child(outerContentContainer); - + buildModNavigation(leftPanel); - + var outerNavigationBarContainer = Containers.verticalScroll(Sizing.content(3), Sizing.fill(80), navigationBar); leftPanel.child(outerNavigationBarContainer); - + } - + @Override protected void init() { super.init(); - + updateLayout(); } - + private void updateLayout() { var leftOffset = Math.max(15, this.width / 20); var leftPanelSize = navigationBar.width(); var leftPanelEnd = navigationBar.x() + navigationBar.width(); var innerPanelWideLeft = this.width * 0.5f - this.width * wideContentWidth / 100f / 2f; - + var wideEnough = this.width >= 650; if (leftPanelEnd > innerPanelWideLeft + 30) wideEnough = false; - + // "responsive" layout if (wideEnough) { rootComponent.horizontalAlignment(HorizontalAlignment.CENTER); @@ -132,49 +132,49 @@ private void updateLayout() { outerContentContainer.horizontalSizing(Sizing.fixed(this.width - leftPanelSize - 20)); } } - + @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { super.render(context, mouseX, mouseY, delta); - + if (needsLayout) { needsLayout = false; this.updateLayout(); } } - + private void loadContentContainer(Identifier filePath, String bookId) throws IOException { - + contentContainer.clearChildren(); activeEntry = filePath; - + var resourceManager = MinecraftClient.getInstance().getResourceManager(); var resourceCandidate = resourceManager.getResource(filePath); - + if (resourceCandidate.isEmpty()) { System.out.println("No content file found for " + filePath); return; } - + var fileContent = new String(resourceCandidate.get().getInputStream().readAllBytes(), StandardCharsets.UTF_8); var parsedTexts = MarkdownParser.parseMarkdownToOwoComponents(fileContent, bookId, link -> { - + if (link.startsWith("http")) return false; - + var pathSegments = filePath.getPath().split("/"); var newPath = ""; - + // build path based on relative information var parentIteration = link.startsWith("../") ? 1 : 0; for (int i = 0; i < pathSegments.length - 1 - parentIteration; i++) { newPath += pathSegments[i] + "/"; } - + newPath = newPath.split("#")[0]; // anchors are not supported, so we just remove them newPath += link.replace("../", "") + ".mdx"; // add file ending - + var newId = Identifier.of(Oracle.MOD_ID, newPath); - + try { loadContentContainer(newId, bookId); } catch (IOException e) { @@ -182,9 +182,9 @@ private void loadContentContainer(Identifier filePath, String bookId) throws IOE } return true; }); - + for (var paragraph : parsedTexts) { - + if (paragraph instanceof LabelComponent) { paragraph.horizontalSizing(Sizing.fill()); } else if (paragraph instanceof TextureComponent textureComponent) { @@ -193,7 +193,7 @@ private void loadContentContainer(Identifier filePath, String bookId) throws IOE var maxWidth = this.width * 0.6f; var usedWidth = maxWidth * targetSize * 0.8f; var height = usedWidth / ratio; - + textureComponent.sizing(Sizing.fixed((int) usedWidth), Sizing.fixed((int) height)); } else if (paragraph instanceof ItemComponent itemComponent) { var ratio = 1f; @@ -201,29 +201,29 @@ private void loadContentContainer(Identifier filePath, String bookId) throws IOE var maxWidth = this.width * 0.6f; var usedWidth = maxWidth * targetSize * 0.8f; var height = usedWidth / ratio; - + itemComponent.sizing(Sizing.fixed((int) usedWidth), Sizing.fixed((int) height)); } - + if (paragraph.margins().get().equals(Insets.of(0))) paragraph.margins(Insets.of(4, 1, 0, 0)); contentContainer.child(paragraph); } } - + private void buildModNavigation(FlowLayout buttonContainer) { - + // collect all book ids var bookIds = OracleClient.LOADED_BOOKS.stream() - .sorted() - .toList(); - + .sorted() + .toList(); + var modSelectorDropdown = Components.dropdown(Sizing.content(3)); modSelectorDropdown.zIndex(5); - + if (activeBook == null) activeBook = bookIds.getFirst(); - + if (activeEntry != null) { try { loadContentContainer(activeEntry, activeBook); @@ -231,12 +231,12 @@ private void buildModNavigation(FlowLayout buttonContainer) { throw new RuntimeException(e); } } - + var topMargins = 40; if (this.height < 350) { topMargins = 5; } - + var bookTitleLabel = new ScalableLabelComponent(Text.translatable(Oracle.MOD_ID + ".title." + activeBook).formatted(Formatting.DARK_GRAY).append(" >").formatted(Formatting.DARK_GRAY), text -> false); bookTitleLabel.scale = 1.5f; var bookTitleWrapper = Containers.horizontalFlow(Sizing.content(), Sizing.content()); @@ -245,7 +245,7 @@ private void buildModNavigation(FlowLayout buttonContainer) { bookTitleWrapper.margins(Insets.of(topMargins, -7, 0, 0)); bookTitleWrapper.child(bookTitleLabel); buttonContainer.child(bookTitleWrapper.zIndex(5)); - + bookTitleWrapper.mouseEnter().subscribe(() -> { bookTitleWrapper.surface(MarkdownParser.ORACLE_PANEL_HOVER); }); @@ -260,7 +260,7 @@ private void buildModNavigation(FlowLayout buttonContainer) { rootComponent.child(modSelectorDropdown.positioning(Positioning.absolute(bookTitleWrapper.x() + bookTitleWrapper.width(), bookTitleWrapper.y()))); return true; }); - + for (var bookId : bookIds) { modSelectorDropdown.button(Text.translatable(Oracle.MOD_ID + ".title." + bookId), elem -> { activeEntry = null; @@ -270,31 +270,31 @@ private void buildModNavigation(FlowLayout buttonContainer) { activeBook = bookId; }); } - + buildModNavigationBar(activeBook); - + } - + private void buildModNavigationBar(String bookId) { navigationBar.clearChildren(); buildNavigationEntriesForModPath(bookId, "", navigationBar); } - + private void buildNavigationEntriesForModPath(String bookId, String path, FlowLayout container) { - + var resourceManager = MinecraftClient.getInstance().getResourceManager(); var metaPath = Identifier.of(Oracle.MOD_ID, "books/" + bookId + path + "/_meta.json"); var resourceCandidate = resourceManager.getResource(metaPath); - + if (resourceCandidate.isEmpty()) { System.out.println("No _meta.json found for " + bookId + " at " + metaPath); return; } - + try { var metaFile = new String(resourceCandidate.get().getInputStream().readAllBytes(), StandardCharsets.UTF_8); var entries = parseJson(metaFile); - + if (activeEntry == null) { var firstEntry = entries.stream().filter(elem -> !elem.directory).findFirst(); if (firstEntry.isPresent()) { @@ -303,19 +303,19 @@ private void buildNavigationEntriesForModPath(String bookId, String path, FlowLa activeEntry = firstEntryPath; } } - + var levelContainers = new ArrayList(); - + for (var entry : entries) { if (entry.directory) { var directoryContainer = new ColoredCollapsibleContainer( - Sizing.content(1), - Sizing.content(1), - Text.translatable(entry.name()).formatted(Formatting.WHITE), false); + Sizing.content(1), + Sizing.content(1), + Text.translatable(entry.name()).formatted(Formatting.WHITE), false); buildNavigationEntriesForModPath(bookId, path + "/" + entry.id(), directoryContainer); directoryContainer.margins(Insets.of(0, 0, 0, 0)); container.child(directoryContainer); - + // collapse all other containers directoryContainer.mouseDown().subscribe((a, b, c) -> { for (var elem : levelContainers) { @@ -327,21 +327,21 @@ private void buildNavigationEntriesForModPath(String bookId, String path, FlowLa this.needsLayout = true; return false; }); - + levelContainers.add(directoryContainer); - + } else { final var labelPath = Identifier.of(Oracle.MOD_ID, "books/" + bookId + path + "/" + entry.id()); final var labelText = Text.translatable(entry.name).formatted(Formatting.WHITE); final var label = Components.label(labelText.formatted(Formatting.UNDERLINE)); - + label.mouseEnter().subscribe(() -> { label.text(labelText.copy().formatted(Formatting.GRAY)); }); label.mouseLeave().subscribe(() -> { label.text(labelText.copy()); }); - + label.mouseDown().subscribe((a, b, c) -> { try { loadContentContainer(labelPath, bookId); @@ -351,7 +351,7 @@ private void buildNavigationEntriesForModPath(String bookId, String path, FlowLa return false; } }); - + label.margins(Insets.of(3, 2, 5, 2)); container.child(label); } @@ -360,20 +360,20 @@ private void buildNavigationEntriesForModPath(String bookId, String path, FlowLa throw new RuntimeException(e); } } - + private static List parseJson(String jsonString) { var gson = new Gson(); var jsonObject = gson.fromJson(jsonString, JsonObject.class); var entries = new ArrayList(); - + for (var entry : jsonObject.entrySet()) { var id = entry.getKey(); var value = entry.getValue(); String name; boolean directory; - + directory = !id.endsWith(".mdx"); - + if (value instanceof JsonPrimitive) { name = value.getAsString(); } else if (value instanceof JsonObject) { @@ -381,21 +381,21 @@ private static List parseJson(String jsonString) { } else { name = "Unknown Name"; // Fallback, should not happen } - + entries.add(new MetaJsonEntry(id, name, directory)); } return entries; - + } - + public record MetaJsonEntry(String id, String name, boolean directory) { @Override public String toString() { return "MetaJsonEntry{" + - "id='" + id + '\'' + - ", name='" + name + '\'' + - ", directory=" + directory + - '}'; + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", directory=" + directory + + '}'; } } } diff --git a/fabric/src/main/java/rearth/oracle/fabric/OracleFabricClient.java b/fabric/src/main/java/rearth/oracle/fabric/OracleFabricClient.java index 5d9c72e..b95fdd5 100644 --- a/fabric/src/main/java/rearth/oracle/fabric/OracleFabricClient.java +++ b/fabric/src/main/java/rearth/oracle/fabric/OracleFabricClient.java @@ -1,13 +1,36 @@ package rearth.oracle.fabric; import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.fabric.api.resource.ResourceManagerHelper; -import rearth.oracle.Oracle; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; import rearth.oracle.OracleClient; +import java.util.*; + + public final class OracleFabricClient implements ClientModInitializer { @Override public void onInitializeClient() { + OracleClient.init(); + OracleClient.setMainDownloadsFolder(FabricLoader.getInstance().getConfigDir().toString()); + + Collection mods = FabricLoader.getInstance().getAllMods(); + HashMap ids_urls = new HashMap<>(); + mods.forEach( mod -> { + if(mod.getMetadata().getId().startsWith("fabric")){ + return; + } + //TODO tell people to put their github + // url in the file + String url; + if(mod.getMetadata().getContact().get("sources").isPresent()){ + url = mod.getMetadata().getContact().get("sources").get(); + }else{ + url = "-"; + } + ids_urls.put(mod.getMetadata().getId(), url); + }); + OracleClient.setModIdAndUrls(ids_urls); } } diff --git a/gradle.properties b/gradle.properties index 5ecc5ec..a3b3551 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx6G org.gradle.parallel=true # Mod properties -mod_version = 0.2.0 +mod_version = 0.2.1-dev maven_group = rearth archives_name = oracle_index enabled_platforms = fabric,neoforge diff --git a/neoforge/src/main/java/rearth/oracle/neoforge/OracleNeoForgeClient.java b/neoforge/src/main/java/rearth/oracle/neoforge/OracleNeoForgeClient.java index a04b1f6..7a43d59 100644 --- a/neoforge/src/main/java/rearth/oracle/neoforge/OracleNeoForgeClient.java +++ b/neoforge/src/main/java/rearth/oracle/neoforge/OracleNeoForgeClient.java @@ -1,15 +1,31 @@ package rearth.oracle.neoforge; import net.neoforged.api.distmarker.Dist; +import net.neoforged.fml.ModList; import net.neoforged.fml.common.Mod; +import net.neoforged.fml.loading.FMLConfig; import rearth.oracle.Oracle; import rearth.oracle.OracleClient; +import java.util.HashMap; + @Mod(value = Oracle.MOD_ID, dist = Dist.CLIENT) public final class OracleNeoForgeClient { public OracleNeoForgeClient() { // Run our common setup. OracleClient.init(); + OracleClient.setMainDownloadsFolder(FMLConfig.defaultConfigPath()); + HashMap ids_urls = new HashMap<>(); + + ModList.get().getMods().forEach( mod -> { + String url = "-"; + if(mod.getModURL().isPresent()){ + url = mod.getModURL().get().toString(); + } + //TODO tell people to put their github link inside neoforge.mods.toml "modUrl" thingy + ids_urls.put(mod.getModId(), url); + }); + OracleClient.setModIdAndUrls(ids_urls); } }