filter explored chunks with json
This commit is contained in:
parent
4eaa6e20c3
commit
4bec49de5b
2
scripts/proguard.pro
vendored
2
scripts/proguard.pro
vendored
@ -21,6 +21,8 @@
|
|||||||
-keep class baritone.BaritoneProvider
|
-keep class baritone.BaritoneProvider
|
||||||
-keep class baritone.api.IBaritoneProvider
|
-keep class baritone.api.IBaritoneProvider
|
||||||
|
|
||||||
|
-keep class baritone.api.utils.MyChunkPos { *; } # even in standalone we need to keep this for gson reflect
|
||||||
|
|
||||||
# setting names are reflected from field names, so keep field names
|
# setting names are reflected from field names, so keep field names
|
||||||
-keepclassmembers class baritone.api.Settings {
|
-keepclassmembers class baritone.api.Settings {
|
||||||
public <fields>;
|
public <fields>;
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
|
|
||||||
package baritone.api.process;
|
package baritone.api.process;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
public interface IExploreProcess extends IBaritoneProcess {
|
public interface IExploreProcess extends IBaritoneProcess {
|
||||||
void explore(int centerX, int centerZ);
|
void explore(int centerX, int centerZ);
|
||||||
|
|
||||||
|
void applyJsonFilter(Path path, boolean invert) throws Exception;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ import net.minecraft.item.ItemStack;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class ExampleBaritoneControl implements Helper, AbstractGameEventListener {
|
public class ExampleBaritoneControl implements Helper, AbstractGameEventListener {
|
||||||
@ -429,6 +430,23 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
|||||||
logDirect("Following " + toFollow.get());
|
logDirect("Following " + toFollow.get());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (msg.startsWith("explorefilter")) {
|
||||||
|
// explorefilter blah.json
|
||||||
|
// means that entries in blah.json are already explored
|
||||||
|
// explorefilter blah.json invert
|
||||||
|
// means that entries in blah.json are NOT already explored
|
||||||
|
String path = msg.substring("explorefilter".length()).trim();
|
||||||
|
String[] parts = path.split(" ");
|
||||||
|
Path path1 = Minecraft.getMinecraft().gameDir.toPath().resolve(parts[0]);
|
||||||
|
try {
|
||||||
|
baritone.getExploreProcess().applyJsonFilter(path1, parts.length > 1);
|
||||||
|
logDirect("Loaded filter");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
logDirect("Unable to load " + path1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (msg.equals("reloadall")) {
|
if (msg.equals("reloadall")) {
|
||||||
baritone.getWorldProvider().getCurrentWorld().getCachedWorld().reloadAllFromDisk();
|
baritone.getWorldProvider().getCurrentWorld().getCachedWorld().reloadAllFromDisk();
|
||||||
logDirect("ok");
|
logDirect("ok");
|
||||||
|
31
src/api/java/baritone/api/utils/MyChunkPos.java
Normal file
31
src/api/java/baritone/api/utils/MyChunkPos.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Need a non obfed chunkpos that we can load using GSON
|
||||||
|
*/
|
||||||
|
public class MyChunkPos {
|
||||||
|
public int x;
|
||||||
|
public int z;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return x + ", " + z;
|
||||||
|
}
|
||||||
|
}
|
@ -123,7 +123,7 @@ public class BackfillProcess extends BaritoneProcessHelper {
|
|||||||
blocksToReplace.clear();
|
blocksToReplace.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String displayName0() {
|
public String displayName0() {
|
||||||
return "Backfill";
|
return "Backfill";
|
||||||
|
@ -25,10 +25,18 @@ import baritone.api.pathing.goals.GoalXZ;
|
|||||||
import baritone.api.process.IExploreProcess;
|
import baritone.api.process.IExploreProcess;
|
||||||
import baritone.api.process.PathingCommand;
|
import baritone.api.process.PathingCommand;
|
||||||
import baritone.api.process.PathingCommandType;
|
import baritone.api.process.PathingCommandType;
|
||||||
|
import baritone.api.utils.MyChunkPos;
|
||||||
import baritone.cache.CachedWorld;
|
import baritone.cache.CachedWorld;
|
||||||
import baritone.utils.BaritoneProcessHelper;
|
import baritone.utils.BaritoneProcessHelper;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.ChunkPos;
|
||||||
|
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -36,6 +44,8 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
|||||||
|
|
||||||
private BlockPos explorationOrigin;
|
private BlockPos explorationOrigin;
|
||||||
|
|
||||||
|
private IChunkFilter filter;
|
||||||
|
|
||||||
public ExploreProcess(Baritone baritone) {
|
public ExploreProcess(Baritone baritone) {
|
||||||
super(baritone);
|
super(baritone);
|
||||||
}
|
}
|
||||||
@ -50,6 +60,21 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
|||||||
explorationOrigin = new BlockPos(centerX, 0, centerZ);
|
explorationOrigin = new BlockPos(centerX, 0, centerZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyJsonFilter(Path path, boolean invert) throws Exception {
|
||||||
|
filter = new JsonChunkFilter(path, invert);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IChunkFilter calcFilter() {
|
||||||
|
IChunkFilter filter;
|
||||||
|
if (this.filter != null) {
|
||||||
|
filter = new EitherChunk(this.filter, new BaritoneChunkCache());
|
||||||
|
} else {
|
||||||
|
filter = new BaritoneChunkCache();
|
||||||
|
}
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||||
if (calcFailed) {
|
if (calcFailed) {
|
||||||
@ -57,7 +82,13 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
|||||||
onLostControl();
|
onLostControl();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Goal[] closestUncached = closestUncachedChunks(explorationOrigin);
|
IChunkFilter filter = calcFilter();
|
||||||
|
if (filter.finished()) {
|
||||||
|
logDirect("Explored all chunks");
|
||||||
|
onLostControl();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Goal[] closestUncached = closestUncachedChunks(explorationOrigin, filter);
|
||||||
if (closestUncached == null) {
|
if (closestUncached == null) {
|
||||||
logDebug("awaiting region load from disk");
|
logDebug("awaiting region load from disk");
|
||||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||||
@ -65,10 +96,9 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
|||||||
return new PathingCommand(new GoalComposite(closestUncached), PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
|
return new PathingCommand(new GoalComposite(closestUncached), PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Goal[] closestUncachedChunks(BlockPos center) {
|
private Goal[] closestUncachedChunks(BlockPos center, IChunkFilter filter) {
|
||||||
int chunkX = center.getX() >> 4;
|
int chunkX = center.getX() >> 4;
|
||||||
int chunkZ = center.getZ() >> 4;
|
int chunkZ = center.getZ() >> 4;
|
||||||
ICachedWorld cache = baritone.getWorldProvider().getCurrentWorld().getCachedWorld();
|
|
||||||
for (int dist = 0; ; dist++) {
|
for (int dist = 0; ; dist++) {
|
||||||
List<BlockPos> centers = new ArrayList<>();
|
List<BlockPos> centers = new ArrayList<>();
|
||||||
for (int dx = -dist; dx <= dist; dx++) {
|
for (int dx = -dist; dx <= dist; dx++) {
|
||||||
@ -77,32 +107,28 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
|||||||
if (trueDist != dist) {
|
if (trueDist != dist) {
|
||||||
continue; // not considering this one just yet in our expanding search
|
continue; // not considering this one just yet in our expanding search
|
||||||
}
|
}
|
||||||
|
switch (filter.isAlreadyExplored(chunkX + dx, chunkZ + dz)) {
|
||||||
|
case UNKNOWN:
|
||||||
|
return null; // awaiting load
|
||||||
|
case NOT_EXPLORED:
|
||||||
|
break; // note: this breaks the switch not the for
|
||||||
|
case EXPLORED:
|
||||||
|
continue; // note: this continues the for
|
||||||
|
}
|
||||||
int centerX = (chunkX + dx) * 16 + 8;
|
int centerX = (chunkX + dx) * 16 + 8;
|
||||||
int centerZ = (chunkZ + dz) * 18 + 8;
|
int centerZ = (chunkZ + dz) * 18 + 8;
|
||||||
|
|
||||||
if (cache.isCached(centerX, centerZ)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!((CachedWorld) cache).regionLoaded(centerX, centerZ)) {
|
|
||||||
Baritone.getExecutor().execute(() -> {
|
|
||||||
((CachedWorld) cache).tryLoadFromDisk(centerX >> 9, centerZ >> 9);
|
|
||||||
});
|
|
||||||
return null; // we still need to load regions from disk in order to decide properly
|
|
||||||
}
|
|
||||||
int offsetCenterX = centerX;
|
|
||||||
int offsetCenterZ = centerZ;
|
|
||||||
int offset = 16 * Baritone.settings().worldExploringChunkOffset.value;
|
int offset = 16 * Baritone.settings().worldExploringChunkOffset.value;
|
||||||
if (dx < 0) {
|
if (dx < 0) {
|
||||||
offsetCenterX -= offset;
|
centerX -= offset;
|
||||||
} else {
|
} else {
|
||||||
offsetCenterX += offset;
|
centerX += offset;
|
||||||
}
|
}
|
||||||
if (dz < 0) {
|
if (dz < 0) {
|
||||||
offsetCenterZ -= offset;
|
centerZ -= offset;
|
||||||
} else {
|
} else {
|
||||||
offsetCenterZ += offset;
|
centerZ += offset;
|
||||||
}
|
}
|
||||||
centers.add(new BlockPos(offsetCenterX, 0, offsetCenterZ));
|
centers.add(new BlockPos(centerX, 0, centerZ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (centers.size() > Baritone.settings().exploreChunkSetMinimumSize.value) {
|
if (centers.size() > Baritone.settings().exploreChunkSetMinimumSize.value) {
|
||||||
@ -111,6 +137,113 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum Status {
|
||||||
|
EXPLORED, NOT_EXPLORED, UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface IChunkFilter {
|
||||||
|
Status isAlreadyExplored(int chunkX, int chunkZ);
|
||||||
|
|
||||||
|
boolean finished();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BaritoneChunkCache implements IChunkFilter {
|
||||||
|
|
||||||
|
private final ICachedWorld cache = baritone.getWorldProvider().getCurrentWorld().getCachedWorld();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Status isAlreadyExplored(int chunkX, int chunkZ) {
|
||||||
|
int centerX = chunkX << 4;
|
||||||
|
int centerZ = chunkZ << 4;
|
||||||
|
if (cache.isCached(centerX, centerZ)) {
|
||||||
|
return Status.EXPLORED;
|
||||||
|
}
|
||||||
|
if (!((CachedWorld) cache).regionLoaded(centerX, centerZ)) {
|
||||||
|
Baritone.getExecutor().execute(() -> {
|
||||||
|
((CachedWorld) cache).tryLoadFromDisk(centerX >> 9, centerZ >> 9);
|
||||||
|
});
|
||||||
|
return Status.UNKNOWN; // we still need to load regions from disk in order to decide properly
|
||||||
|
}
|
||||||
|
return Status.NOT_EXPLORED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean finished() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class JsonChunkFilter implements IChunkFilter {
|
||||||
|
private final boolean invert; // if true, the list is interpreted as a list of chunks that are NOT explored, if false, the list is interpreted as a list of chunks that ARE explored
|
||||||
|
private final LongOpenHashSet inFilter;
|
||||||
|
private final MyChunkPos[] positions;
|
||||||
|
|
||||||
|
private JsonChunkFilter(Path path, boolean invert) throws Exception { // ioexception, json exception, etc
|
||||||
|
this.invert = invert;
|
||||||
|
Gson gson = new GsonBuilder().create();
|
||||||
|
positions = gson.fromJson(new InputStreamReader(Files.newInputStream(path)), MyChunkPos[].class);
|
||||||
|
logDirect("Loaded " + positions.length + " positions");
|
||||||
|
inFilter = new LongOpenHashSet();
|
||||||
|
for (MyChunkPos mcp : positions) {
|
||||||
|
inFilter.add(ChunkPos.asLong(mcp.x, mcp.z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Status isAlreadyExplored(int chunkX, int chunkZ) {
|
||||||
|
if (inFilter.contains(ChunkPos.asLong(chunkX, chunkZ)) ^ invert) {
|
||||||
|
// either it's on the list of explored chunks, or it's not on the list of unexplored chunks
|
||||||
|
// either way, we have it
|
||||||
|
return Status.EXPLORED;
|
||||||
|
} else {
|
||||||
|
// either it's not on the list of explored chunks, or it's on the list of unexplored chunks
|
||||||
|
// either way, it depends on if baritone has cached it so defer to that
|
||||||
|
return Status.UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean finished() {
|
||||||
|
if (!invert) {
|
||||||
|
// if invert is false, anything not on the list is uncached
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// but if invert is true, anything not on the list IS assumed cached
|
||||||
|
// so we are done if everything on our list is cached!
|
||||||
|
BaritoneChunkCache bcc = new BaritoneChunkCache();
|
||||||
|
for (MyChunkPos pos : positions) {
|
||||||
|
if (bcc.isAlreadyExplored(pos.x, pos.z) != Status.EXPLORED) {
|
||||||
|
// either waiting for it or dont have it at all
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true; // we have everything cached
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class EitherChunk implements IChunkFilter {
|
||||||
|
private final IChunkFilter a;
|
||||||
|
private final IChunkFilter b;
|
||||||
|
|
||||||
|
private EitherChunk(IChunkFilter a, IChunkFilter b) {
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Status isAlreadyExplored(int chunkX, int chunkZ) {
|
||||||
|
if (a.isAlreadyExplored(chunkX, chunkZ) == Status.EXPLORED) {
|
||||||
|
return Status.EXPLORED;
|
||||||
|
}
|
||||||
|
return b.isAlreadyExplored(chunkX, chunkZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean finished() {
|
||||||
|
return a.finished() || b.finished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLostControl() {
|
public void onLostControl() {
|
||||||
explorationOrigin = null;
|
explorationOrigin = null;
|
||||||
@ -118,6 +251,6 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String displayName0() {
|
public String displayName0() {
|
||||||
return "Exploring around " + explorationOrigin + ", currently going to " + new GoalComposite(closestUncachedChunks(explorationOrigin));
|
return "Exploring around " + explorationOrigin + ", currently going to " + new GoalComposite(closestUncachedChunks(explorationOrigin, calcFilter()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user