package org.dynmap.utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class ForgeConfigFile {
private File cfg;
private HashMap<String, String> settings = new HashMap<String, String>();
public static final String ALLOWED_CHARS = "._-:";
public ForgeConfigFile(File cfgfile) {
cfg = cfgfile;
}
public boolean load() {
settings.clear();
FileInputStream fis = null;
BufferedReader rdr = null;
boolean rslt = true;
try {
fis = new FileInputStream(cfg);
rdr = new BufferedReader(new InputStreamReader(fis, "UTF-8"));
String line;
ArrayList<String> section = new ArrayList<String>();
String tok = "";
while((line = rdr.readLine()) != null) {
boolean skip = false;
boolean instr = false;
boolean intok = false;
tok = "";
char last_c = ' ';
int off = line.indexOf(": "); // If "tok: value style (Minegicka), fix to look normal
if (off > 0) {
line = line.substring(0, off).replace(' ', '_') + "=" + line.substring(off+1);
}
for (int i = 0; i < line.length() && !skip; ++i) {
char c = line.charAt(i);
if(instr) {
if(c != '"') {
tok += c;
}
else if (last_c == '"') {
// Ignore double double-quotes
}
else {
instr = false;
intok = false;
}
}
else if(c == '"') {
if (last_c != '"') {
intok = instr = true;
}
}
else if(Character.isLetterOrDigit(c) || ALLOWED_CHARS.indexOf(c) != -1) {
if(intok) {
tok += c;
}
else {
tok = "" + c;
intok = true;
}
}
else if (Character.isWhitespace(c)) {
if((!instr) && intok) {
intok = false;
}
}
else {
switch (line.charAt(i)) {
case '#':
skip = true;
instr = intok = false;
break;
case '{':
if(tok.equals("") == false) {
section.add(tok);
tok = "";
instr = intok = false;
}
break;
case '}':
if(section.size() > 0) {
section.remove(section.size()-1);
}
break;
case '=':
intok = instr = false;
String propertyName = tok;
tok = "";
off = propertyName.indexOf(':');
if(off >= 0) { /* Trim off the Forge 6.4.1+ type prefix */
propertyName = propertyName.substring(off+1);
}
for(int j = section.size()-1; j >= 0; j--) {
propertyName = section.get(j) + "/" + propertyName;
}
propertyName = propertyName.replace(' ', '_');
settings.put(propertyName, line.substring(i + 1).trim());
skip = true;
break;
}
}
last_c = c;
}
}
} catch (IOException iox) {
rslt = false;
} finally {
if(fis != null) {
try { fis.close(); } catch (IOException iox) {}
fis = null;
}
}
return rslt;
}
public int getBlockID(String id) {
int idval = -1;
String val = settings.get(id);
if (val == null)
val = settings.get("block/" + id); /* Check for "block/" */
if (val != null) {
val = val.trim();
if ((val.length() > 0) && Character.isDigit(val.charAt(0))) {
try {
idval = (int) Double.parseDouble(val); // Handle floats - used by weird mods like Minegicka for some reason
} catch (NumberFormatException nfx) {
}
}
}
return idval;
}
public void addBlockIDs(Map<String,Integer> map) {
for(String k : settings.keySet()) {
if(k.startsWith("block/")) {
map.put(k.substring("block/".length()), getBlockID(k));
}
else if(k.startsWith("blocks/")) { /* RP2 */
map.put(k.substring("blocks/".length()), getBlockID(k));
}
else if(k.startsWith("item/")) { /* Item codes? */
map.put("item_" + k.substring("item/".length()), getBlockID(k));
}
else if(k.startsWith("walls/")) { /* Walls (Fancy Walls) codes? */
map.put(k, getBlockID(k));
}
else if(k.startsWith("world/blocks/")) { /* XyCraft world/blocks */
map.put(k.substring("world/".length()), getBlockID(k));
}
else {
map.put(k, getBlockID(k));
}
}
}
}