Added for preprocessing

This commit is contained in:
Francesco Macagno 2015-09-08 17:29:15 -07:00
parent 918cc1ddf3
commit 682bfccbed
3 changed files with 232 additions and 94 deletions

View file

@ -1,9 +1,12 @@
package cr0s.warpdrive.config; package cr0s.warpdrive.config;
import java.util.ArrayList;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.TreeMap; import java.util.TreeMap;
import org.w3c.dom.Attr;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
@ -12,7 +15,7 @@ import cr0s.warpdrive.WarpDrive;
public class XmlPreprocessor { public class XmlPreprocessor {
/** /**
* Will check the given element for a mod attribute and return a string of all the ones that are not loaded, separated by commas * Will check the given element for a mod attribute and return a string of all the ones that are not loaded, separated by commas
* *
@ -22,30 +25,30 @@ public class XmlPreprocessor {
* @throws InvalidXmlException * @throws InvalidXmlException
*/ */
public static ModCheckResults checkModRequirements(Element e) { public static ModCheckResults checkModRequirements(Element e) {
ModCheckResults modErrors = new ModCheckResults(); ModCheckResults modErrors = new ModCheckResults();
for (String mod : e.getAttribute("mods").split(",")) { for (String mod : e.getAttribute("mods").split(",")) {
//TODO: add version check //TODO: add version check
if (mod.isEmpty()) if (mod.isEmpty())
continue; continue;
if (mod.startsWith("!")) { if (mod.startsWith("!")) {
if (Loader.isModLoaded(mod.substring(1))) if (Loader.isModLoaded(mod.substring(1)))
modErrors.addMod(mod, "loaded"); modErrors.addMod(mod, "loaded");
} else if (!Loader.isModLoaded(mod)) } else if (!Loader.isModLoaded(mod))
modErrors.addMod(mod, "not loaded"); modErrors.addMod(mod, "not loaded");
} }
return modErrors; return modErrors;
} }
/** /**
* Goes through every child node of the given node, and if it is an element and fails checkModRequirements() it is removed * Goes through every child node of the given node, and if it is an element and fails checkModRequirements() it is removed
* *
@ -53,61 +56,194 @@ public class XmlPreprocessor {
* @throws InvalidXmlException * @throws InvalidXmlException
*/ */
public static void doModReqSanitation(Node base) { public static void doModReqSanitation(Node base) {
NodeList children = base.getChildNodes(); NodeList children = base.getChildNodes();
for (int i = 0; i < children.getLength(); i++) { for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i); Node child = children.item(i);
if (child instanceof Element) { if (child instanceof Element) {
ModCheckResults res = checkModRequirements((Element) child); ModCheckResults res = checkModRequirements((Element) child);
if (!res.isEmpty()) { if (!res.isEmpty()) {
base.removeChild(child); base.removeChild(child);
WarpDrive.logger.info("Removed child element " + child.getBaseURI() + " of element " + base.getBaseURI() + ", results: " + res); WarpDrive.logger.info("Removed child element " + child.getBaseURI() + " of element " + base.getBaseURI() + ", results: " + res);
} else { } else {
doModReqSanitation(child); doModReqSanitation(child);
}
}
}
}
public static void doLogicPreprocessing(Node root) throws InvalidXmlException {
NodeList children = root.getChildNodes();
for (int i = 0; i < children.getLength(); i++)
doLogicPreprocessing(children.item(i));
if (root.getNodeType() == Node.ELEMENT_NODE && ((Element) root).getTagName().equalsIgnoreCase("for")) {
Element forTag = (Element) root;
String varName = forTag.getAttribute("variable");
if(varName.isEmpty())
throw new InvalidXmlException("A for tag must include a variable attribute!");
//In supersedes from
if (forTag.hasAttribute("in")) {
String inOptions = forTag.getAttribute("in");
for(String input : inOptions.split(",")) {
NodeList allChildren = root.getChildNodes();
for(int chI = 0; chI < allChildren.getLength(); chI ++) {
Node copy = getCopyVarReplace(allChildren.item(chI), varName, input);
root.getParentNode().appendChild(copy);
}
}
} else {
String fromStr = forTag.getAttribute("from");
String toStr = forTag.getAttribute("to");
if (toStr.isEmpty() || fromStr.isEmpty())
throw new InvalidXmlException("If a for doesnt have an in attr, it must have a from and to!");
int from, to;
try {
from = Integer.parseInt(fromStr);
to = Integer.parseInt(toStr);
} catch (NumberFormatException e) {
throw new InvalidXmlException(e);
}
for (; from <= to; from++) {
NodeList allChildren = root.getChildNodes();
for (int chI = 0; chI < allChildren.getLength(); chI++) {
Node copy = getCopyVarReplace(allChildren.item(chI), varName, "" + from);
root.getParentNode().appendChild(copy);
}
}
}
//Remove the old node
root.getParentNode().removeChild(root);
}
}
private static Node getCopyVarReplace(Node toCopy, String varName, String value) {
Node copy = toCopy.cloneNode(true);
replaceVar(copy, varName, value);
return copy;
}
private static void replaceVar(Node root, String varName, String value) {
ArrayList<String> toRemove = new ArrayList<String>();
ArrayList<Attr> toAdd = new ArrayList<Attr>();
if (root.getNodeType() == Node.ELEMENT_NODE) {
//First replace attributes
NamedNodeMap attrs = root.getAttributes();
for (int i = 0; i < attrs.getLength(); i++) {
Attr attr = (Attr) attrs.item(i);
String name = attr.getName();
String newName = name.replace("%" + varName + "%", value);
if (name.equals(newName)) {
//Easy, just adjust value
attr.setValue(attr.getValue().replace("%" + varName + "%", value));
} else {
//The name changed
toRemove.add(name);
Attr newAttr = attr.getOwnerDocument().createAttribute(newName);
newAttr.setValue(attr.getValue().replace("%" + varName + "%", value));
toAdd.add(newAttr);
} }
} }
//Now do the adds and removals
for (String attr : toRemove)
attrs.removeNamedItem(attr);
for (Attr attr : toAdd)
attrs.setNamedItem(attr);
}
//Now that Attributes are done, go through all of the children
NodeList children = root.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
switch (child.getNodeType()) {
case Node.ELEMENT_NODE://Recurse on the element
replaceVar(child, varName, value);
break;
case Node.TEXT_NODE:
child.setTextContent(child.getTextContent().replace("%" + varName + "%", value));
break;
}
} }
} }
public static void doLogicPreprocessing(Element root) {
}
public static class ModCheckResults { public static class ModCheckResults {
private TreeMap<String, String> mods; private TreeMap<String, String> mods;
public ModCheckResults() { public ModCheckResults() {
mods = new TreeMap<String, String>(); mods = new TreeMap<String, String>();
} }
public void addMod(String name, String error) { public void addMod(String name, String error) {
mods.put(name, error); mods.put(name, error);
} }
public boolean isEmpty() { public boolean isEmpty() {
return mods.isEmpty(); return mods.isEmpty();
} }
@Override @Override
public String toString() { public String toString() {
String s = "{"; String s = "{";
for (Entry<String, String> e : mods.entrySet()) for (Entry<String, String> e : mods.entrySet())
s = s + e.getKey() + ": " + e.getValue() + ", "; s = s + e.getKey() + ": " + e.getValue() + ", ";
return s + "}"; return s + "}";
} }
} }
} }

View file

@ -20,12 +20,12 @@ import cr0s.warpdrive.config.XmlPreprocessor;
import cr0s.warpdrive.config.XmlPreprocessor.ModCheckResults; import cr0s.warpdrive.config.XmlPreprocessor.ModCheckResults;
public class FillerManager { public class FillerManager {
private static TreeMap<String, FillerSet> fillerSets = new TreeMap<String, FillerSet>(); private static TreeMap<String, FillerSet> fillerSets = new TreeMap<String, FillerSet>();
// Stores extra dependency information // Stores extra dependency information
static TreeMap<FillerSet, ArrayList<String>> fillerSetsAdditions = new TreeMap<FillerSet, ArrayList<String>>(); static TreeMap<FillerSet, ArrayList<String>> fillerSetsAdditions = new TreeMap<FillerSet, ArrayList<String>>();
/* TODO dead code? /* TODO dead code?
// FillerSets that are guaranteed to exist // FillerSets that are guaranteed to exist
public static final String COMMON_ORES = "commonOres"; public static final String COMMON_ORES = "commonOres";
@ -35,25 +35,25 @@ public class FillerManager {
public static final String NETHER = "nether"; public static final String NETHER = "nether";
public static final String END = "end"; public static final String END = "end";
/**/ /**/
public static void loadOres(String oreConfDirectory) { public static void loadOres(String oreConfDirectory) {
loadOres(new File(oreConfDirectory)); loadOres(new File(oreConfDirectory));
} }
public static void loadOres(File dir) { public static void loadOres(File dir) {
// directory is created by caller, so it can copy default files if any // directory is created by caller, so it can copy default files if any
if (!dir.isDirectory()) { if (!dir.isDirectory()) {
throw new IllegalArgumentException("File path " + dir.getName() + " must be a directory!"); throw new IllegalArgumentException("File path " + dir.getName() + " must be a directory!");
} }
File[] files = dir.listFiles(new FilenameFilter() { File[] files = dir.listFiles(new FilenameFilter() {
@Override @Override
public boolean accept(File file_notUsed, String name) { public boolean accept(File file_notUsed, String name) {
return name.startsWith("filler") && name.endsWith(".xml"); return name.startsWith("filler") && name.endsWith(".xml");
} }
}); });
for(File file : files) { for(File file : files) {
try { try {
WarpDrive.logger.info("Loading filler data file " + file.getName() + "..."); WarpDrive.logger.info("Loading filler data file " + file.getName() + "...");
@ -65,38 +65,39 @@ public class FillerManager {
} }
} }
} }
private static void loadXmlFillerFile(File file) throws InvalidXmlException, SAXException, IOException { private static void loadXmlFillerFile(File file) throws InvalidXmlException, SAXException, IOException {
Document base = WarpDriveConfig.getXmlDocumentBuilder().parse(file); Document base = WarpDriveConfig.getXmlDocumentBuilder().parse(file);
ModCheckResults res = XmlPreprocessor.checkModRequirements(base.getDocumentElement()); ModCheckResults res = XmlPreprocessor.checkModRequirements(base.getDocumentElement());
if (!res.isEmpty()) { if (!res.isEmpty()) {
WarpDrive.logger.info("Skippping filler data file " + file.getName() + " because of: " + res); WarpDrive.logger.info("Skippping filler data file " + file.getName() + " because of: " + res);
return; return;
} }
// Remove elements based on mod reqs sanitation // Remove elements based on mod reqs sanitation
XmlPreprocessor.doModReqSanitation(base); XmlPreprocessor.doModReqSanitation(base);
XmlPreprocessor.doLogicPreprocessing(base);
// Initially add FillerSets // Initially add FillerSets
NodeList nodesFillerSet = base.getElementsByTagName("FillerSet"); NodeList nodesFillerSet = base.getElementsByTagName("FillerSet");
for (int i = 0; i < nodesFillerSet.getLength(); i++) { for (int i = 0; i < nodesFillerSet.getLength(); i++) {
Element elementFillerSet = (Element) nodesFillerSet.item(i); Element elementFillerSet = (Element) nodesFillerSet.item(i);
String group = elementFillerSet.getAttribute("group"); String group = elementFillerSet.getAttribute("group");
if (group.isEmpty()) { if (group.isEmpty()) {
throw new InvalidXmlException("FillerSet " + i + " is missing a group attribute!"); throw new InvalidXmlException("FillerSet " + i + " is missing a group attribute!");
} }
FillerSet fillerSet = fillerSets.get(group); FillerSet fillerSet = fillerSets.get(group);
if (fillerSet == null) { if (fillerSet == null) {
fillerSet = new FillerSet(group); fillerSet = new FillerSet(group);
fillerSets.put(group, fillerSet); fillerSets.put(group, fillerSet);
} }
if (elementFillerSet.hasAttribute("fillerSets")) { if (elementFillerSet.hasAttribute("fillerSets")) {
ArrayList<String> setUnresolvedDeps = fillerSetsAdditions.get(fillerSet); ArrayList<String> setUnresolvedDeps = fillerSetsAdditions.get(fillerSet);
if (setUnresolvedDeps == null) { if (setUnresolvedDeps == null) {
@ -105,56 +106,56 @@ public class FillerManager {
} }
setUnresolvedDeps.addAll(Arrays.asList(elementFillerSet.getAttribute("import").split(","))); setUnresolvedDeps.addAll(Arrays.asList(elementFillerSet.getAttribute("import").split(",")));
} }
fillerSet.loadFromXmlElement(elementFillerSet); fillerSet.loadFromXmlElement(elementFillerSet);
} }
} }
public static void finishLoading() { public static void finishLoading() {
while (!fillerSetsAdditions.isEmpty()) { while (!fillerSetsAdditions.isEmpty()) {
attemptDependencyFilling(fillerSetsAdditions); attemptDependencyFilling(fillerSetsAdditions);
} }
// When everything is done, finalize // When everything is done, finalize
for (FillerSet fillerSet : fillerSets.values()) { for (FillerSet fillerSet : fillerSets.values()) {
fillerSet.finishContruction(); fillerSet.finishContruction();
} }
} }
private static void attemptDependencyFilling(TreeMap<FillerSet, ArrayList<String>> fillerSetsDeps) { private static void attemptDependencyFilling(TreeMap<FillerSet, ArrayList<String>> fillerSetsDeps) {
ArrayList<FillerSet> toRemove = new ArrayList<FillerSet>(); ArrayList<FillerSet> toRemove = new ArrayList<FillerSet>();
for (Entry<FillerSet, ArrayList<String>> entry : fillerSetsDeps.entrySet()) { for (Entry<FillerSet, ArrayList<String>> entry : fillerSetsDeps.entrySet()) {
for (String dep : entry.getValue()) { for (String dep : entry.getValue()) {
if (!fillerSets.containsKey(dep)) { if (!fillerSets.containsKey(dep)) {
WarpDrive.logger.error("A fillerSet " + entry.getKey() + " has a dependency that doesnt exist!"); WarpDrive.logger.error("A fillerSet " + entry.getKey() + " has a dependency that doesnt exist!");
fillerSets.remove(entry.getKey().getName()); fillerSets.remove(entry.getKey().getName());
toRemove.add(entry.getKey()); toRemove.add(entry.getKey());
} else if (fillerSetsDeps.containsKey(fillerSets.get(dep))) { } else if (fillerSetsDeps.containsKey(fillerSets.get(dep))) {
//Skip until it is loaded //Skip until it is loaded
} else { } else {
entry.getKey().loadFrom(fillerSets.get(dep)); entry.getKey().loadFrom(fillerSets.get(dep));
toRemove.add(entry.getKey()); toRemove.add(entry.getKey());
} }
} }
} }
for (FillerSet set : toRemove) { for (FillerSet set : toRemove) {
fillerSetsDeps.remove(set); fillerSetsDeps.remove(set);
} }
} }
public static FillerSet getFillerSet(String name) { public static FillerSet getFillerSet(String name) {
return fillerSets.get(name); return fillerSets.get(name);
} }
/* TODO dead code? /* TODO dead code?
public static class BlockComparator implements Comparator<Block> { public static class BlockComparator implements Comparator<Block> {

View file

@ -19,74 +19,75 @@ import cr0s.warpdrive.config.XmlPreprocessor.ModCheckResults;
public class StructureManager { public class StructureManager {
private static ArrayList<Star> stars = new ArrayList<Star>(); private static ArrayList<Star> stars = new ArrayList<Star>();
private static ArrayList<Planetoid> moons = new ArrayList<Planetoid>(); private static ArrayList<Planetoid> moons = new ArrayList<Planetoid>();
private static ArrayList<Planetoid> gasClouds = new ArrayList<Planetoid>(); private static ArrayList<Planetoid> gasClouds = new ArrayList<Planetoid>();
private static ArrayList<Asteroid> asteroids = new ArrayList<Asteroid>(); private static ArrayList<Asteroid> asteroids = new ArrayList<Asteroid>();
public static void loadStructures(String structureConfDir) { public static void loadStructures(String structureConfDir) {
loadStructures(new File(structureConfDir)); loadStructures(new File(structureConfDir));
} }
public static void loadStructures(File dir) { public static void loadStructures(File dir) {
dir.mkdir(); dir.mkdir();
if (!dir.isDirectory()) { if (!dir.isDirectory()) {
throw new IllegalArgumentException("File path " + dir.getPath() + " must be a directory!"); throw new IllegalArgumentException("File path " + dir.getPath() + " must be a directory!");
} }
File[] files = dir.listFiles(new FilenameFilter() { File[] files = dir.listFiles(new FilenameFilter() {
@Override @Override
public boolean accept(File file_notUsed, String name) { public boolean accept(File file_notUsed, String name) {
return name.startsWith("structure") && name.endsWith(".xml"); return name.startsWith("structure") && name.endsWith(".xml");
} }
}); });
for (File file : files) { for (File file : files) {
try { try {
WarpDrive.logger.info("Loading structure data file " + file.getName()); WarpDrive.logger.info("Loading structure data file " + file.getName());
loadXmlStructureFile(file); loadXmlStructureFile(file);
WarpDrive.logger.info("Finished loading structure data file " + file.getName()); WarpDrive.logger.info("Finished loading structure data file " + file.getName());
} catch (Exception e) { } catch (Exception e) {
WarpDrive.logger.error("Error loading file " + file.getName() + ": " + e.getMessage()); WarpDrive.logger.error("Error loading file " + file.getName() + ": " + e.getMessage());
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
private static void loadXmlStructureFile(File f) throws SAXException, IOException, InvalidXmlException { private static void loadXmlStructureFile(File f) throws SAXException, IOException, InvalidXmlException {
Document base = WarpDriveConfig.getXmlDocumentBuilder().parse(f); Document base = WarpDriveConfig.getXmlDocumentBuilder().parse(f);
ModCheckResults res = XmlPreprocessor.checkModRequirements(base.getDocumentElement()); ModCheckResults res = XmlPreprocessor.checkModRequirements(base.getDocumentElement());
if (!res.isEmpty()) { if (!res.isEmpty()) {
WarpDrive.logger.info("Skippping structure data file " + f.getName() + " because of: " + res); WarpDrive.logger.info("Skippping structure data file " + f.getName() + " because of: " + res);
return; return;
} }
XmlPreprocessor.doModReqSanitation(base); XmlPreprocessor.doModReqSanitation(base);
XmlPreprocessor.doLogicPreprocessing(base);
NodeList structures = base.getElementsByTagName("structure"); NodeList structures = base.getElementsByTagName("structure");
for (int i = 0; i < structures.getLength(); i++) { for (int i = 0; i < structures.getLength(); i++) {
Element struct = (Element) structures.item(i); Element struct = (Element) structures.item(i);
String group = struct.getAttribute("group"); String group = struct.getAttribute("group");
String name = struct.getAttribute("name"); String name = struct.getAttribute("name");
WarpDrive.logger.info("Loading structure " + name); WarpDrive.logger.info("Loading structure " + name);
if (group.isEmpty()) if (group.isEmpty())
throw new InvalidXmlException("Structure must have a group!"); throw new InvalidXmlException("Structure must have a group!");
int radius = 0; int radius = 0;
if (group.equalsIgnoreCase("star")) { if (group.equalsIgnoreCase("star")) {
Star s = new Star(radius); Star s = new Star(radius);
s.loadFromXmlElement(struct); s.loadFromXmlElement(struct);
@ -102,7 +103,7 @@ public class StructureManager {
} }
} }
} }
public static DeployableStructure getStructure(Random random, final String name, final String type) { public static DeployableStructure getStructure(Random random, final String name, final String type) {
if (name == null || name.length() == 0) { if (name == null || name.length() == 0) {
if (type == null || type.length() == 0) { if (type == null || type.length() == 0) {
@ -120,23 +121,23 @@ public class StructureManager {
return star; return star;
} }
} }
// not found or nothing defined => return null // not found or nothing defined => return null
return null; return null;
} }
public static DeployableStructure getStar(Random random, final String name) { public static DeployableStructure getStar(Random random, final String name) {
return getStructure(random, name, "star"); return getStructure(random, name, "star");
} }
public static DeployableStructure getMoon(Random random, final String name) { public static DeployableStructure getMoon(Random random, final String name) {
return getStructure(random, name, "moon"); return getStructure(random, name, "moon");
} }
public static DeployableStructure getAsteroid(Random random, final String name) { public static DeployableStructure getAsteroid(Random random, final String name) {
return getStructure(random, name, "asteroid"); return getStructure(random, name, "asteroid");
} }
public static DeployableStructure getGasCloud(Random random, final String name) { public static DeployableStructure getGasCloud(Random random, final String name) {
return getStructure(random, name, "cloud"); return getStructure(random, name, "cloud");
} }