package MoF;
import amidst.Util;
import amidst.logging.Log;
import amidst.map.MapObjectPlayer;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.swing.filechooser.FileFilter;
import org.jnbt.CompoundTag;
import org.jnbt.DoubleTag;
import org.jnbt.ListTag;
import org.jnbt.NBTInputStream;
import org.jnbt.NBTOutputStream;
import org.jnbt.Tag;
public class SaveLoader {
public static Type genType = Type.DEFAULT;
public enum Type {
DEFAULT("Default", "default"), FLAT("Flat", "flat"), LARGE_BIOMES("Large Biomes", "largeBiomes"), AMPLIFIED("Amplified", "amplified"), CUSTOMIZED("Customized", "customized");
private final String name;
private final String value;
Type(String name, String value) {
this.name = name;
this.value = value;
}
@Override
public String toString() {
return name;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
public static Type fromMixedCase(String name) {
name = name.toLowerCase();
for (Type t : values())
if (t.name.toLowerCase().equals(name) || t.value.toLowerCase().equals(name))
return t;
Log.crash("Unable to find World Type: " + name);
return null;
}
}
public static Type[] selectableTypes = new Type[] { Type.DEFAULT, Type.FLAT, Type.LARGE_BIOMES, Type.AMPLIFIED };
public static FileFilter getFilter() {
return (new FileFilter() {
public boolean accept(File f) {
if (f.isDirectory())
return true;
String[] st = f.getName().split("\\/");
return st[st.length - 1].equalsIgnoreCase("level.dat");
}
@Override
public String getDescription() {
return "Minecraft Data File (level.dat)";
}
});
}
private File file;
private List<MapObjectPlayer> players;
public long seed;
private boolean multi;
private List<String> back;
private String generatorOptions = "";
public List<MapObjectPlayer> getPlayers() {
return players;
}
public void movePlayer(String name, int x, int y) {
File out;
if (multi) {
String outPath = file.getParent() + "/players/" + name +".dat";
out = new File(outPath);
backupFile(out);
try {
NBTInputStream inStream = new NBTInputStream(new FileInputStream(out));
CompoundTag root = (CompoundTag)inStream.readTag();
inStream.close();
HashMap<String, Tag> rootMap = new HashMap<String, Tag>(root.getValue());
ArrayList<Tag> posTag = new ArrayList<Tag>(((ListTag)rootMap.get("Pos")).getValue());
posTag.set(0, new DoubleTag("x", x));
posTag.set(1, new DoubleTag("y", 120));
posTag.set(2, new DoubleTag("z", y));
rootMap.put("Pos", new ListTag("Pos", DoubleTag.class, posTag));
root = new CompoundTag("Data", rootMap);
NBTOutputStream outStream = new NBTOutputStream(new FileOutputStream(out));
outStream.writeTag(root);
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}
} else {
out = file;
backupFile(out);
try {
NBTInputStream inStream = new NBTInputStream(new FileInputStream(out));
CompoundTag root = (CompoundTag)(((CompoundTag)inStream.readTag()).getValue().get("Data"));
inStream.close();
HashMap<String, Tag> rootMap = new HashMap<String, Tag>(root.getValue());
HashMap<String, Tag> playerMap = new HashMap<String, Tag>(((CompoundTag)rootMap.get("Player")).getValue());
ArrayList<Tag> posTag = new ArrayList<Tag>(((ListTag)playerMap.get("Pos")).getValue());
posTag.set(0, new DoubleTag("x", x));
posTag.set(1, new DoubleTag("y", 120));
posTag.set(2, new DoubleTag("z", y));
rootMap.put("Player", new CompoundTag("Player", playerMap));
playerMap.put("Pos", new ListTag("Pos", DoubleTag.class, posTag));
root = new CompoundTag("Data", rootMap);
HashMap<String, Tag> base = new HashMap<String, Tag>();
base.put("Data", root);
root = new CompoundTag("Base", base);
NBTOutputStream outStream = new NBTOutputStream(new FileOutputStream(out));
outStream.writeTag(root);
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void backupFile(File inputFile) {
File backupFolder = new File(inputFile.getParentFile() + "/amidst_backup/");
if (!backupFolder.exists())
backupFolder.mkdir();
File outputFile = new File(backupFolder + "/" + inputFile.getName());
if (!back.contains(outputFile.toString())) {
try {
FileReader in = new FileReader(inputFile);
FileWriter out = new FileWriter(outputFile);
int c;
while ((c = in.read()) != -1)
out.write(c);
in.close();
out.close();
back.add(outputFile.toString());
} catch (Exception ignored) {}
}
}
public SaveLoader(File f) {
file = f;
players = new ArrayList<MapObjectPlayer>();
back = new ArrayList<String>();
try {
NBTInputStream inStream = new NBTInputStream(new FileInputStream(f));
CompoundTag root = (CompoundTag) ((CompoundTag)inStream.readTag()).getValue().get("Data");
inStream.close();
seed = (Long)(root.getValue().get("RandomSeed").getValue());
if (root.getValue().get("generatorName") != null) {
genType = Type.fromMixedCase((String)(root.getValue().get("generatorName").getValue()));
if (genType == Type.CUSTOMIZED)
generatorOptions = (String)root.getValue().get("generatorOptions").getValue();
}
CompoundTag playerTag = (CompoundTag)root.getValue().get("Player");
File playersFolder = new File(f.getParent(), "players");
boolean multi = (playersFolder.exists() && (playersFolder.listFiles().length > 0));
if (multi)
Log.i("Multiplayer map detected.");
else
Log.i("Singleplayer map detected.");
if (!multi) {
addPlayer("Player", playerTag);
} else {
File[] listing = playersFolder.listFiles();
for (int i = 0; i < (listing != null ? listing.length : 0); i++) {
if (listing[i].isFile()) {
NBTInputStream playerInputStream = new NBTInputStream(new FileInputStream(listing[i]));
addPlayer(listing[i].getName().split("\\.")[0], (CompoundTag) ((CompoundTag)playerInputStream.readTag()));
playerInputStream.close();
}
}
}
} catch (Exception e) {
Util.showError(e);
}
}
private void addPlayer(String name, CompoundTag ps) {
List<Tag> pos = ((ListTag)(ps.getValue().get("Pos"))).getValue();
double x = (Double)pos.get(0).getValue();
double z = (Double)pos.get(2).getValue();
players.add(new MapObjectPlayer(name, (int) x, (int) z));
}
public String getGeneratorOptions() {
return generatorOptions;
}
}