diff --git a/src/main/java/baritone/chunk/Waypoint.java b/src/main/java/baritone/chunk/Waypoint.java
new file mode 100644
index 00000000..495608ba
--- /dev/null
+++ b/src/main/java/baritone/chunk/Waypoint.java
@@ -0,0 +1,74 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.chunk;
+
+import net.minecraft.util.math.BlockPos;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A single waypoint
+ *
+ * @author leijurv
+ */
+public class Waypoint {
+ public final String name;
+ public final Tag tag;
+ public final long creationTimestamp;
+ public final BlockPos location;
+
+ public Waypoint(String name, Tag tag, BlockPos location) {
+ this(name, tag, location, System.currentTimeMillis());
+ }
+
+ Waypoint(String name, Tag tag, BlockPos location, long creationTimestamp) { // read from disk
+ this.name = name;
+ this.tag = tag;
+ this.location = location;
+ this.creationTimestamp = creationTimestamp;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null) {
+ return false;
+ }
+ if (!(o instanceof Waypoint)) {
+ return false;
+ }
+ Waypoint w = (Waypoint) o;
+ return name.equals(w.name) && tag == w.tag && creationTimestamp == w.creationTimestamp && location.equals(w.location);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode() + tag.hashCode() + (int) creationTimestamp + location.hashCode(); //lol
+ }
+
+ public enum Tag {
+ HOME, DEATH, USER;
+
+ {
+ map.put(name().toLowerCase(), this);
+ }
+
+ }
+
+ private static final Map map = new HashMap<>();
+}
diff --git a/src/main/java/baritone/chunk/Waypoints.java b/src/main/java/baritone/chunk/Waypoints.java
index 4617ad63..255ac03d 100644
--- a/src/main/java/baritone/chunk/Waypoints.java
+++ b/src/main/java/baritone/chunk/Waypoints.java
@@ -17,12 +17,21 @@
package baritone.chunk;
-import java.io.IOException;
+import net.minecraft.util.math.BlockPos;
+
+import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.*;
+/**
+ * Waypoints for a world
+ *
+ * @author leijurv
+ */
public class Waypoints {
private final Path directory;
+ private final Map> waypoints;
Waypoints(Path directory) {
this.directory = directory;
@@ -32,5 +41,76 @@ public class Waypoints {
} catch (IOException ignored) {}
}
System.out.println("Would save waypoints to " + directory);
+ this.waypoints = new HashMap<>();
+ load();
+ }
+
+ private void load() {
+ for (Waypoint.Tag tag : Waypoint.Tag.values()) {
+ load(tag);
+ }
+ }
+
+ private synchronized void load(Waypoint.Tag tag) {
+ waypoints.put(tag, new HashSet<>());
+
+ Path fileName = directory.resolve(tag.name().toLowerCase());
+ if (!Files.exists(fileName))
+ return;
+
+ try (
+ FileInputStream fileIn = new FileInputStream(fileName.toFile());
+ BufferedInputStream bufIn = new BufferedInputStream(fileIn);
+ DataInputStream in = new DataInputStream(bufIn);
+ ) {
+ while (true) {
+ String name = in.readUTF();
+ long creationTimestamp = in.readLong();
+ int x = in.readInt();
+ int y = in.readInt();
+ int z = in.readInt();
+ waypoints.get(tag).add(new Waypoint(name, tag, new BlockPos(x, y, z), creationTimestamp));
+ }
+ } catch (IOException ex) { }
+ }
+
+ private synchronized void save(Waypoint.Tag tag) {
+ Path fileName = directory.resolve(tag.name().toLowerCase());
+ try (
+ FileOutputStream fileOut = new FileOutputStream(fileName.toFile());
+ BufferedOutputStream bufOut = new BufferedOutputStream(fileOut);
+ DataOutputStream out = new DataOutputStream(bufOut);
+ ) {
+ for (Waypoint waypoint : waypoints.get(tag)) {
+ out.writeUTF(waypoint.name);
+ out.writeLong(waypoint.creationTimestamp);
+ out.writeInt(waypoint.location.getX());
+ out.writeInt(waypoint.location.getY());
+ out.writeInt(waypoint.location.getZ());
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ public Set getByTag(Waypoint.Tag tag) {
+ return Collections.unmodifiableSet(waypoints.get(tag));
+ }
+
+ public Waypoint getMostRecentByTag(Waypoint.Tag tag) {
+ Set pts = waypoints.get(tag);
+ Waypoint best = null;
+ for (Waypoint waypoint : pts) {
+ if (best == null || waypoint.creationTimestamp > best.creationTimestamp) {
+ best = waypoint;
+ }
+ }
+ return best;
+ }
+
+ public void addWaypoint(Waypoint waypoint) {
+ // no need to check for duplicate, because it's a Set not a List
+ waypoints.get(waypoint.tag).add(waypoint);
+ save(waypoint.tag);
}
}
diff --git a/src/main/java/baritone/chunk/WorldData.java b/src/main/java/baritone/chunk/WorldData.java
index 7145742e..3cd7b737 100644
--- a/src/main/java/baritone/chunk/WorldData.java
+++ b/src/main/java/baritone/chunk/WorldData.java
@@ -19,6 +19,11 @@ package baritone.chunk;
import java.nio.file.Path;
+/**
+ * Data about a world, from baritone's point of view. Includes cached chunks, waypoints, and map data.
+ *
+ * @author leijurv
+ */
public class WorldData {
public final CachedWorld cache;
public final Waypoints waypoints;