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;