/* * Copyright (c) 2010 SimpleServer authors (see CONTRIBUTORS) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package simpleserver.nbt; import java.io.FileNotFoundException; import java.io.IOException; public class Main { public static void main(String[] args) { if (args.length == 0) { System.out.println("Usage: java -jar NBT.jar file [command] [arguments]"); System.out.println("\nCommands:"); System.out.println("\tread [key]"); System.out.println("\tset key value"); System.out.println("\tremove key"); System.out.println("\tadd key [name type] [value]"); return; } NBTFile file = null; try { try { file = new GZipNBTFile(args[0]); } catch (IOException g) { file = new NBTFile(args[0]); } } catch (FileNotFoundException e) { System.out.println("Error: No such file or dictionary"); } catch (Exception e) { System.out.println("Error: " + e + " (" + e.getMessage() + ")"); } if (file == null) { return; } if (args.length <= 1) { System.out.println(file); return; } String command = args[1].toLowerCase(); if (command.equals("read")) { read(args, file); } else if (command.equals("set")) { set(args, file); } else if (command.equals("remove")) { remove(args, file); } else if (command.equals("add")) { add(args, file); } } private static void read(String[] args, NBTFile file) { NBTag tag = file.root(); if (args.length >= 3) { tag = tryGetTag(args[2], tag); } if (tag != null) { System.out.println(tag); } } private static void set(String[] args, NBTFile file) { if (args.length >= 4) { NBTag tag = tryGetTag(args[2], file.root()); if (tag == null) { return; } String value = args[3]; try { tag.set(value); } catch (NumberFormatException e) { System.out.println("Error: Wrong format (" + e.getMessage() + ")"); return; } trySave(file, args[0]); } else { System.out.println("Error: Wrong number of arguments"); } } @SuppressWarnings("unchecked") private static void remove(String[] args, NBTFile file) { if (args.length >= 3) { String path = args[2]; int split = Math.max(path.lastIndexOf('.'), path.lastIndexOf('/')); NBTag tag = tryGetTag(path.substring(0, split), file.root()); if (tag == null) { return; } String name = path.substring(split + 1); switch (tag.type()) { case COMPOUND: if (((NBTCompound) tag).containsKey(name)) { ((NBTCompound) tag).remove(name); } else { System.out.println(new NoSuchKeyException(path)); } break; case LIST: int index; try { index = Integer.valueOf(name); } catch (NumberFormatException e) { System.out.println(new NoSuchKeyException(path)); return; } if (((NBTList<NBTag>) tag).size() > index) { ((NBTList<NBTag>) tag).remove(((NBTList<NBTag>) tag).get(index)); } else { System.out.println(new NoSuchKeyException(path)); } break; default: System.out.println(new NoContainerException(tag)); return; } trySave(file, args[0]); } else { System.out.println("Error: Wrong number of arguments"); } } @SuppressWarnings("unchecked") private static void add(String[] args, NBTFile file) { NBTag newTag = null; if (args.length >= 3) { NBTag tag = tryGetTag(args[2], file.root()); if (tag == null) { return; } int index = 3; if (tag.type() == NBT.COMPOUND) { if (args.length >= 5) { String typeString = args[4].toLowerCase(); if (typeString.equals("list")) { System.out.println("Error: Use list.<type> for list tags (e.g. list.string)"); return; } else if (typeString.startsWith("list.")) { NBT type = NBT.get(args[4].substring(5)); if (type == null || type == NBT.END || type == NBT.LIST) { System.out.println("Error: Unknown type"); return; } newTag = new NBTList<NBTag>(type); } else { NBT type = NBT.get(args[4]); if (type == null || type == NBT.END) { System.out.println("Error: Unknown type"); return; } try { newTag = type.getInstance(); } catch (Exception e) { System.out.println("Error: " + e.getClass().getSimpleName() + " (" + e.getMessage() + ")"); return; } } newTag.rename(args[3]); ((NBTCompound) tag).put(newTag); index = 5; } else { System.out.println("Error: Wrong number of arguments"); } } else if (tag.type() == NBT.LIST) { NBTList<NBTag> list = (NBTList<NBTag>) tag; try { newTag = list.listType().getInstance(); } catch (Exception e) { System.out.println("Error: " + e.getClass().getSimpleName() + " (" + e.getMessage() + ")"); return; } list.add(newTag); } else { System.out.println("Error: Can't add tags to " + tag.getClass().getSimpleName()); return; } if (args.length > index) { String value = args[index]; try { newTag.set(value); } catch (NumberFormatException e) { System.out.println("Error: Wrong format (" + e.getMessage() + ")"); return; } } trySave(file, args[0]); } else { System.out.println("Error: Wrong number of arguments"); } } private static void trySave(NBTFile file, String filename) { try { file.save(filename); } catch (IOException e) { System.out.println("Error: File couldn't be saved (" + e.getMessage() + ")"); } } private static NBTag tryGetTag(String path, NBTag root) { try { return getTag(path, root); } catch (NoSuchKeyException e) { System.out.println("Error: " + e.getMessage()); return null; } catch (NoContainerException e) { System.out.println("Error: " + e.getMessage()); return null; } } @SuppressWarnings("unchecked") public static NBTag getTag(String path, NBTag root) throws NoSuchKeyException, NoContainerException { String[] keys = path.split("/|\\."); NBTag current = root; for (String name : keys) { switch (current.type()) { case COMPOUND: NBTCompound comp = (NBTCompound) current; if (!comp.containsKey(name)) { throw new NoSuchKeyException(name); } current = comp.get(name); break; case LIST: NBTList<NBTag> list = (NBTList<NBTag>) current; int key = Integer.valueOf(name); if (key >= list.size()) { throw new NoSuchKeyException(Integer.toString(key)); } current = list.get(key); break; default: throw new NoContainerException(current); } } return current; } public static class NoSuchKeyException extends Exception { private static final long serialVersionUID = 1L; public String key; public NoSuchKeyException(String key) { super("No such key: \"" + key + "\""); this.key = key; } } public static class NoContainerException extends Exception { private static final long serialVersionUID = 1L; public NBTag tag; public NoContainerException(NBTag tag) { super("Tag \"" + tag.name + "\" is not a container (" + tag.getClass().getSimpleName() + ")"); this.tag = tag; } } }