package com.thebrokenrail.scriptcraft.quickjs; import com.thebrokenrail.scriptcraft.ScriptCraft; import com.thebrokenrail.scriptcraft.util.OSUtil; import com.thebrokenrail.scriptcraft.util.ScriptCraftEntrypoint; import net.fabricmc.loader.api.FabricLoader; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.List; @SuppressWarnings("unused") public class QuickJS { public QuickJS() throws JSException { init(); } private long ctx; private long rt; public native void init() throws JSException; public native void free(); public native Object bridge(String method, Object... args) throws JSException; public native void run(String data); static { try { File file = File.createTempFile("lib" + ScriptCraft.NAMESPACE, OSUtil.getLibExtension()); file.deleteOnExit(); System.out.println("Extracting ScriptCraft Native To: " + file.getAbsoluteFile().toPath()); InputStream so = (QuickJS.class.getResourceAsStream(File.separator + "natives" + File.separator + OSUtil.getOS() + File.separator + "lib" + ScriptCraft.NAMESPACE + OSUtil.getLibExtension())); if (so == null) { throw new RuntimeException("ScriptCraft does not support your OS: " + OSUtil.getOS()); } else { Files.copy(so, file.getAbsoluteFile().toPath(), StandardCopyOption.REPLACE_EXISTING); System.load(file.getAbsolutePath()); } } catch (IOException e) { throw new RuntimeException(e); } } public static String loadModule(String name) { String[] arr = name.split(File.separator, 2); if (ScriptCraft.MOD_ID_PATTERN.matcher(arr[0]).matches()) { List mods = FabricLoader.getInstance().getEntrypoints(ScriptCraft.NAMESPACE, ScriptCraftEntrypoint.class); if (arr.length == 1) { return null; } else { for (ScriptCraftEntrypoint mod : mods) { if (mod.getModID().equals(arr[0])) { //noinspection CatchMayIgnoreException try { InputStream stream = mod.getClass().getResourceAsStream(File.separator + ScriptCraft.NAMESPACE + File.separator + arr[0] + File.separator + arr[1]); if (stream != null) { StringBuilder textBuilder = new StringBuilder(); try (Reader reader = new BufferedReader(new InputStreamReader(stream))) { int c; while ((c = reader.read()) != -1) { textBuilder.append((char) c); } } stream.close(); return textBuilder.toString(); } } catch (IOException e) { } } } } } return null; } private static final String[] SUPPORTED_EXTENSION = new String[]{"", ".js", ".json", ".mjs"}; public static String normalizeModule(String baseName, String name) { String normalizedPath; if (name.startsWith(".")) { Path parentPath = Paths.get(baseName.replaceAll("/", File.separator)).getParent(); if (parentPath == null) { parentPath = Paths.get(File.separator); } normalizedPath = Paths.get(parentPath.toString(), name.replaceAll("/", File.separator)).normalize().toString(); if (normalizedPath.charAt(0) == File.separatorChar) { normalizedPath = normalizedPath.substring(1); } } else { normalizedPath = name; } String result = null; boolean success = false; String[] arr = normalizedPath.split(File.separator, 2); if (ScriptCraft.MOD_ID_PATTERN.matcher(arr[0]).matches()) { List mods = FabricLoader.getInstance().getEntrypoints(ScriptCraft.NAMESPACE, ScriptCraftEntrypoint.class); if (arr.length == 1) { for (ScriptCraftEntrypoint mod : mods) { if (mod.getModID().equals(arr[0])) { result = arr[0] + File.separator + mod.getModIndex(); success = true; break; } } } else { result = arr[0] + File.separator + arr[1]; success = true; } } if (success) { for (String extension : SUPPORTED_EXTENSION) { if (loadModule(result + extension) != null) { return result + extension; } } } return null; } public static void print(String data, boolean err) { String[] lines = data.split("\n"); for (String line : lines) { if (err) { System.err.println(line); } else { System.out.println(line); } } } }