package net.sourceforge.pain.util.rom; import net.sourceforge.pain.util.*; import java.io.*; import java.util.*; public class Rom24AreaLoader { private static String defaultDamType = "beating"; private String fileName = null; private StringBuffer tmpBuffer = new StringBuffer(); public String areaName; public String areaAuthor; public String levelRange; public String vnumRange; public String resetMessage; public String flags; public HashMap rooms = new HashMap(); public HashMap mobiles = new HashMap(); public HashMap objects = new HashMap(); public Rom24AreaLoader(String fileName) { if (fileName == null) { throw new NullPointerException("area file name is null"); } this.fileName = fileName; } public void load() throws Exception { // long starttime = System.currentTimeMillis(); Log.info("opening file:" + fileName); BufferedReader reader = new BufferedReader(new FileReader(fileName), 50 * 1000); Log.info("opened"); try { do { String state = getState(reader); if (state == null) { break; } else if (state.equals("#AREA")) { loadAreaHeaders(reader); } else if (state.equals("#RESETMESSAGE")) { loadResetMessage(reader); } else if (state.equals("#FLAG")) { loadFlags(reader); } else if (state.equals("#MOBILES")) { loadMobiles(reader); } else if (state.equals("#OBJECTS")) { loadObjects(reader); } else if (state.equals("#ROOMS")) { loadRooms(reader); } else if (state.equals("#RESETS")) { loadResets(reader); } else if (state.equals("#SHOPS")) { loadShops(reader); } else if (state.equals("#SPECIALS")) { loadSpecials(reader); } else if (state.equals("#PRACTICERS")) { loadPracticers(reader); } else if (state.equals("#OMPROGS")) { loadMobProgs(reader); } else if (state.equals("#OLIMITS")) { loadLimits(reader); } else { Log.warn("unknown state:" + state + " - ignoring"); } } while (true); } finally { reader.close(); } // System.out.println("time:" + (System.currentTimeMillis() - starttime)); } private void loadAreaHeaders(BufferedReader reader) throws Exception { reader.readLine();// fileName String tmp = reader.readLine().trim(); areaName = tmp.substring(0, tmp.length() - 1); levelRange = reader.readLine(); vnumRange = reader.readLine(); } private void loadResetMessage(BufferedReader reader) throws Exception { resetMessage = reader.readLine().split("~")[0]; } private void loadFlags(BufferedReader reader) throws Exception { flags = reader.readLine(); } private void loadMobiles(BufferedReader reader) throws Exception { Log.info("loading mobiles..."); String line; while ((line = findLineStarted(reader, "#", false)) != null) { String id = line.substring(1).trim(); if (Integer.parseInt(id) == 0) { break; } // ok its room and we have id; Log.info("mobile found, id =" + id); ROMMobile mobile = new ROMMobile(id); readUntilToken(reader, "~", true); line = tmpBuffer.toString().trim(); mobile.nameList = line.split(" "); for (int i = 0; i < mobile.nameList.length; i++) { mobile.nameList[i] = mobile.nameList[i].toLowerCase(); } // Log.debug("namelist:" + mobile.nameList[0]); readUntilToken(reader, "~", true); line = tmpBuffer.toString().trim(); mobile.shortDesc = line; readUntilToken(reader, "~", true); line = tmpBuffer.toString().trim(); mobile.longDesc = line; readUntilToken(reader, "~", true); line = tmpBuffer.toString().trim(); mobile.lookDesc = line; readUntilToken(reader, "~", true); line = tmpBuffer.toString().trim(); mobile.race = line; reader.readLine(); // \n line = reader.readLine(); StringTokenizer st = new StringTokenizer(line, " \t"); if (st.countTokens() != 4) { throw new IllegalArgumentException("wrong: VII. Act, Affect, Alignment and group:" + line); } mobile.act = st.nextToken(); mobile.affect = st.nextToken(); mobile.alignment = st.nextToken(); mobile.group = st.nextToken(); line = reader.readLine(); st = new StringTokenizer(line, " \t"); if (st.countTokens() < 5) { throw new IllegalArgumentException("wrong: Level, hit bonus, hit dice, mana dice, damage, damtype: " + line); } mobile.level = Integer.parseInt(st.nextToken()); mobile.hitBonus = Integer.parseInt(st.nextToken()); mobile.hitDice = parseDice(st.nextToken()); mobile.manaDice = parseDice(st.nextToken()); mobile.damDice = parseDice(st.nextToken()); mobile.damType = (st.hasMoreTokens() ? st.nextToken() : defaultDamType); line = reader.readLine(); st = new StringTokenizer(line, " \t"); if (st.countTokens() < 4) { throw new IllegalArgumentException("wrong: armor:" + line); } mobile.armor = new int[4]; mobile.armor[0] = Integer.parseInt(st.nextToken()); mobile.armor[1] = Integer.parseInt(st.nextToken()); mobile.armor[2] = Integer.parseInt(st.nextToken()); mobile.armor[3] = Integer.parseInt(st.nextToken()); line = reader.readLine(); st = new StringTokenizer(line, " \t"); if (st.countTokens() != 4) { throw new IllegalArgumentException("wrong: offence, immune, resist, vuln:" + line); } mobile.offenses = st.nextToken(); mobile.immunities = st.nextToken(); mobile.resistances = st.nextToken(); mobile.vulnerabilities = st.nextToken(); // line = reader.readLine(); // st = new StringTokenizer(line, " \t"); // mobile.offenses = st.nextToken(); // mobile.immunities = st.nextToken(); // mobile.resistances = st.nextToken(); // mobile.vulnerabilities = st.nextToken(); line = reader.readLine(); if (line.length() == 0) { line = reader.readLine(); // cells.are contains empty line } st = new StringTokenizer(line, " \t"); mobile.position1 = st.nextToken(); mobile.position2 = st.nextToken(); mobile.gender = st.nextToken(); mobile.treasure = Integer.parseInt(st.nextToken()); // form, parst sizes - ignored; mobiles.put(mobile.vnum, mobile); } } private void loadObjects(BufferedReader reader) throws Exception { Log.info("loading objects..."); String line; while ((line = findLineStarted(reader, "#", false)) != null) { String id = line.substring(1).trim(); if (Integer.parseInt(id) == 0) { break; } // ok its room and we have id; Log.info("object found, id =" + id); ROMObject obj = new ROMObject(id); readUntilToken(reader, "~", true); line = tmpBuffer.toString().trim(); obj.nameList = line.split(" "); readUntilToken(reader, "~", true); line = tmpBuffer.toString().trim(); obj.shortDesc = line; readUntilToken(reader, "~", true); line = tmpBuffer.toString().trim(); obj.longDesc = line; readUntilToken(reader, "~", true); line = tmpBuffer.toString().trim(); obj.material = line; reader.readLine(); // \n line = reader.readLine(); StringTokenizer st = new StringTokenizer(line, " \t"); if (st.countTokens() != 3) { throw new IllegalArgumentException("wrong: Flags, Extras, Wear locations:" + line); } obj.typeFlags = st.nextToken(); obj.extraFlags = st.nextToken(); obj.wearFlags = st.nextToken(); line = reader.readLine(); String complexTokens[] = parseComplexTokens(line); if (complexTokens.length != 5) { throw new IllegalArgumentException("wrong: V0 through V4:" + line); } obj.value[0] = complexTokens[0]; obj.value[1] = complexTokens[1]; ; obj.value[2] = complexTokens[2]; ; obj.value[3] = complexTokens[3]; ; obj.value[4] = complexTokens[4]; ; line = reader.readLine(); st = new StringTokenizer(line, " \t"); if (st.countTokens() != 4) { throw new IllegalArgumentException("wrong: <level> <weight> <cost> <cond>:" + line); } obj.level = Integer.parseInt(st.nextToken()); obj.weight = Integer.parseInt(st.nextToken()); obj.cost = Integer.parseInt(st.nextToken()); obj.condition = st.nextToken(); // + applies // + extraDescs objects.put(obj.vnum, obj); } } private void loadResets(BufferedReader reader) throws Exception { if (rooms.size() == 0 /*|| (mobiles.size() == 0 && objects.size() == 0)*/) { // offcol.are: rooms and resets! if (reader.readLine().trim().equals("S")) { return; } throw new RuntimeException("cant load resets before rooms, objects and mobiles!"); } Log.info("loading resets..."); // only MOB and OBJ reset loading implemented do { String line = reader.readLine(); String comment = ""; int commentStart = line.indexOf('*'); if (commentStart > 0) { comment = line.substring(commentStart + 1); line = line.substring(0, commentStart - 1); } if (line.startsWith("O")) { Log.info("reading reset:" + line); StringTokenizer st = new StringTokenizer(line, " \t"); if (st.countTokens() < 5) { Log.warn("IGNORING: wrong reset:" + line); continue; } ROMObjectReset reset = new ROMObjectReset(); reset.comment = comment; st.nextToken(); st.nextToken(); reset.obj = (ROMObject) objects.get(st.nextToken()); if (reset.obj == null) { Log.warn("IGNORING: can't find object for reset:" + line); continue; } reset.count = Integer.parseInt(st.nextToken()); if (reset.count < 1 && reset.count != -1) { Log.warn("IGNORING: wrong reset count:" + line); continue; } // String tmp = st.nextToken(); ROMRoom room = (ROMRoom) rooms.get(st.nextToken()); if (room == null) { Log.warn("IGNORING: can't find room for reset:" + line); continue; } room.resets.add(reset); } else if (line.startsWith("M")) { Log.info("reading reset:" + line); StringTokenizer st = new StringTokenizer(line, " \t"); if (st.countTokens() < 6) { Log.warn("IGNORING: wrong reset:" + line); continue; } ROMMobileReset reset = new ROMMobileReset(); reset.comment = comment; st.nextToken(); st.nextToken(); reset.mob = (ROMMobile) mobiles.get(st.nextToken()); if (reset.mob == null) { Log.warn("IGNORING: can't find mobile for reset:" + line); continue; } int limit = Integer.parseInt(st.nextToken()); if (reset.mob.limit != 0 && reset.mob.limit != limit) { if (reset.mob.limit < limit) { Log.warn("Mobile limit changed from:" + reset.mob.limit + " to:" + limit); } else { Log.warn("Mobile already has higher limit:" + reset.mob.limit + ". Ignoring" + limit); } } reset.mob.limit = limit; ROMRoom room = (ROMRoom) rooms.get(st.nextToken()); if (room == null) { Log.warn("IGNORING: can't find room for reset:" + line); continue; } String countStr = st.nextToken(); int commentIndex = countStr.indexOf("*"); if (commentIndex > -1) { // there is values like '1*' / mount the doom countStr = countStr.substring(0, commentIndex); } reset.count = Integer.parseInt(countStr); if (reset.count < 1) { Log.warn("IGNORING: wrong reset count:" + line); continue; } room.resets.add(reset); } else if (line.startsWith("S")) { break; } else { Log.info("ignoring unsupported reset:" + line); continue; } } while (true); } private void loadShops(BufferedReader reader) { } private void loadSpecials(BufferedReader reader) { } private void loadPracticers(BufferedReader reader) { } private void loadMobProgs(BufferedReader reader) { } private void loadLimits(BufferedReader reader) { } private void loadRooms(BufferedReader reader) throws Exception { Log.info("loading rooms..."); String line; while ((line = findLineStarted(reader, "#", false)) != null) { String id = line.substring(1).trim(); if (Integer.parseInt(id) == 0) { break; } // ok its room and we have id; Log.info("room found, id =" + id); ROMRoom room = new ROMRoom(id); // reading name readUntilToken(reader, "~", true); line = tmpBuffer.toString().trim(); room.name = line; // reading name if (readUntilToken(reader, "~", false)) { room.desc = tmpBuffer.toString().trim(); } // Log.info("loading exits for room"); // ok now load exits // String[] roomExits = new String[6]; do { line = reader.readLine().trim().toUpperCase(); if (line.length() == 2 && line.charAt(0) == 'D') { // ok its exit int direction = line.charAt(1) - '0'; readUntilToken(reader, "~", true); String exitDescr = tmpBuffer.toString(); readUntilToken(reader, "~", true); reader.readLine(); // \r\n line = reader.readLine().trim(); line = line.substring(line.lastIndexOf(' ') + 1, line.length()); room.exits[direction] = line; room.exitsDescs[direction] = exitDescr; } } while (!line.equals("S")); rooms.put(room.vnum, room); // Log.info("------------------------"); // Log.info("room added: rom id=" + id); // Log.info(" name=" + room.desc); // Log.info(" desc=" + room.name); } Log.info("rooms loaded OK"); } private static String findLineStarted(BufferedReader reader, String token, boolean required) throws Exception { // int c1 = token.charAt(token.length() - 1); String line; do { line = reader.readLine(); if (line == null) { break; } if (line.startsWith(token)) { return line; } } while (true); if (required) { throw new Exception("required linestart not found:" + token); } return null; } private boolean readUntilToken(BufferedReader reader, String token, boolean required) throws Exception { if (tmpBuffer.length() > 0) { tmpBuffer = new StringBuffer(); } final int tokenLen = token.length(); final int c1 = token.charAt(tokenLen - 1); int bufLen; while (true) { int c2 = reader.read(); if (c2 == -1) { if (required) { Log.info("Buffer before error:" + tmpBuffer.toString()); throw new Exception("required token not found:" + token); } else { return false; } } tmpBuffer.append((char) c2); if (c2 == c1 && (bufLen = tmpBuffer.length()) >= tokenLen) { boolean match = true; for (int i = 2; i <= tokenLen; i++) { if (tmpBuffer.charAt(bufLen - i) != token.charAt(tokenLen - i)) { match = false; } } if (match) { tmpBuffer.setLength(bufLen - tokenLen); break; } } } return true; } private static String getState(BufferedReader reader) throws Exception { String state; do { state = reader.readLine(); if (state == null) { return null; } if (state.startsWith("#")) { state = state.trim().toUpperCase(); if (state.equals("#$")) { return null; } return state; } } while (true); } private static int[] parseDice(String dice) { dice = dice.toUpperCase(); int indexD = dice.indexOf("D"); if (indexD < 0) { throw new IllegalArgumentException("wrong dice:" + dice); } int indexA = dice.indexOf("+", indexD); if (indexA < 0) { throw new IllegalArgumentException("wrong dice:" + dice); } int dices[] = new int[3]; dices[0] = Integer.parseInt(dice.substring(0, indexD)); dices[1] = Integer.parseInt(dice.substring(indexD + 1, indexA)); dices[2] = Integer.parseInt(dice.substring(indexA + 1)); return dices; } private String[] parseComplexTokens(String line) { if (tmpBuffer.length() > 0) { tmpBuffer = new StringBuffer(); } ArrayList list = new ArrayList(); boolean outQuote = true; for (int i = 0; i < line.length(); i++) { char c = line.charAt(i); if ((c == ' ' || c == '\t') && outQuote) { if (tmpBuffer.length() > 0) { list.add(tmpBuffer.toString()); tmpBuffer = new StringBuffer(); } } else if (c == '\'') { if (tmpBuffer.length() > 0) { list.add(tmpBuffer.toString()); tmpBuffer = new StringBuffer(); } else { if (!outQuote) { // '' exp list.add(null); } } outQuote = !outQuote; } else { tmpBuffer.append(c); } } if (tmpBuffer.length() > 0) { list.add(tmpBuffer.toString()); tmpBuffer = new StringBuffer(); } String result[] = new String[list.size()]; for (int i = 0; i < list.size(); i++) { result[i] = (String) list.get(i); } return result; } }