package me.exz.omniocular.handler; import cpw.mods.fml.common.Loader; import me.exz.omniocular.OmniOcular; import me.exz.omniocular.reference.Reference; import me.exz.omniocular.util.LogHelper; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.net.URISyntaxException; import java.net.URLDecoder; import java.nio.charset.Charset; import java.nio.file.Files; import java.util.*; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.regex.Matcher; import java.util.regex.Pattern; @SuppressWarnings("CanBeFinal") public class ConfigHandler { public static File minecraftConfigDirectory; public static String mergedConfig = ""; static Map<Pattern, Node> entityPattern = new HashMap<>(); static Map<Pattern, Node> tileEntityPattern = new HashMap<>(); static Map<Pattern, Node> tooltipPattern = new HashMap<>(); static Map<String, String> settingList = new HashMap<>(); private static File configDir; public static void initConfigFiles() { configDir = new File(minecraftConfigDirectory, Reference.MOD_ID); if (!configDir.exists()) { if (!configDir.mkdir()) { LogHelper.fatal("Can't create config folder"); } else { LogHelper.info("Config folder created"); } } } public static void releasePreConfigFiles() throws IOException, URISyntaxException { final String assetConfigPath = "assets/omniocular/config/"; final String xmlExt = ".xml"; Set<String> configList = new HashSet<>(); Pattern p = Pattern.compile("[\\\\/:*?\"<>|]"); String classPath = OmniOcular.class.getProtectionDomain().getCodeSource().getLocation().getFile(); String classFileName = "!/" + OmniOcular.class.getName().replace(".", "/") + ".class"; String jarPath = StringUtils.removeStart(StringUtils.removeEnd(classPath, classFileName), "file:/"); if (jarPath.endsWith(".class")) { File xmlDirectory = new File(OmniOcular.class.getResource("/" + assetConfigPath).toURI()); for (String xmlFilename : xmlDirectory.list()) { configList.add(StringUtils.removeEnd(xmlFilename, xmlExt)); } } else { if (!(System.getProperty("os.name").startsWith("Windows"))) jarPath = "/" + jarPath; File jar = new File(URLDecoder.decode(jarPath, "utf8")); JarFile jarFile = new JarFile(jar); final Enumeration<JarEntry> entries = jarFile.entries(); //gives ALL entries in jar while (entries.hasMoreElements()) { final String name = entries.nextElement().getName(); if (name.startsWith(assetConfigPath) && name.endsWith(xmlExt)) { //filter according to the path configList.add(StringUtils.removeStart(StringUtils.removeEnd(name, xmlExt), assetConfigPath)); } } } Set<String> modList = Loader.instance().getIndexedModList().keySet(); for (String configName : configList) { for (String modID : modList) { Matcher m = p.matcher(modID); if (configName.equals(m.replaceAll("")) || configName.equals("minecraft")) { File targetFile = new File(configDir, configName + xmlExt); if (!targetFile.exists()) { InputStream resource = OmniOcular.class.getClassLoader().getResourceAsStream(assetConfigPath + configName + xmlExt); FileUtils.copyInputStreamToFile(resource, targetFile); LogHelper.info("Release pre-config file : " + configName); } } } } } public static void mergeConfig() { mergedConfig = ""; File configDir = new File(minecraftConfigDirectory, Reference.MOD_ID); File[] configFiles = configDir.listFiles(); if (configFiles != null) { for (File configFile : configFiles) { if (configFile.isFile()) { try { List<String> lines = Files.readAllLines(configFile.toPath(), Charset.forName("UTF-8")); for (String line : lines) { mergedConfig += line; } } catch (Exception e) { e.printStackTrace(); } } } } mergedConfig = "<root>" + mergedConfig + "</root>"; final String[][] quoteChars = { {"&", "&"}, {"<", "<"}, {">", ">"}, // {"\"", """}, // {"'", "'"} }; StringBuffer quotedBuffer = new StringBuffer(); Pattern tagSelectorRegex = Pattern.compile("(?<=<(init|line)[^>]*>).*?(?=</\\1>)"); Matcher tagSelectorMatcher = tagSelectorRegex.matcher(mergedConfig); while (tagSelectorMatcher.find()) { String quotedString = tagSelectorMatcher.group(); for (String[] quoteCharPair : quoteChars) { quotedString = quotedString.replace(quoteCharPair[0], quoteCharPair[1]); } tagSelectorMatcher.appendReplacement(quotedBuffer, quotedString); } tagSelectorMatcher.appendTail(quotedBuffer); mergedConfig = quotedBuffer.toString(); } public static void parseConfigFiles() { // System.out.println(mergedConfig); try { JSHandler.initEngine(); entityPattern.clear(); tileEntityPattern.clear(); tooltipPattern.clear(); settingList.clear(); JSHandler.scriptSet.clear(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new InputSource(new StringReader(mergedConfig))); doc.getDocumentElement().normalize(); Element root = doc.getDocumentElement(); NodeList ooList = root.getElementsByTagName("oo"); for (int i = 0; i < ooList.getLength(); i++) { NodeList entityList = ((Element) ooList.item(i)).getElementsByTagName("entity"); for (int j = 0; j < entityList.getLength(); j++) { Node node = entityList.item(j); entityPattern.put(Pattern.compile(node.getAttributes().getNamedItem("id").getTextContent()), node); } NodeList tileEntityList = ((Element) ooList.item(i)).getElementsByTagName("tileentity"); for (int j = 0; j < tileEntityList.getLength(); j++) { Node node = tileEntityList.item(j); tileEntityPattern.put(Pattern.compile(node.getAttributes().getNamedItem("id").getTextContent()), node); } NodeList tooltipList = ((Element) ooList.item(i)).getElementsByTagName("tooltip"); for (int j = 0; j < tooltipList.getLength(); j++) { Node node = tooltipList.item(j); tooltipPattern.put(Pattern.compile(node.getAttributes().getNamedItem("id").getTextContent()), node); } NodeList initList = ((Element) ooList.item(i)).getElementsByTagName("init"); for (int j = 0; j < initList.getLength(); j++) { Node node = initList.item(j); JSHandler.engine.eval(node.getTextContent()); } NodeList configList = ((Element) ooList.item(i)).getElementsByTagName("setting"); for (int j = 0; j < configList.getLength(); j++) { Node node = configList.item(j); String settingText = node.getTextContent(); try { String settingResult = JSHandler.engine.eval(settingText.trim()).toString(); settingList.put(node.getAttributes().getNamedItem("id").getTextContent(), settingResult); } catch (Exception e) { e.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } } }