Remove container memory
Signed-off-by: scorbett123 <50634068+scorbett123@users.noreply.github.com>
This commit is contained in:
parent
0ca84a790b
commit
90fcffdf2a
@ -555,13 +555,6 @@ public final class Settings {
|
|||||||
*/
|
*/
|
||||||
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(true);
|
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
|
||||||
* Remember the contents of containers (chests, echests, furnaces)
|
|
||||||
* <p>
|
|
||||||
* Really buggy since the packet stuff is multithreaded badly thanks to brady
|
|
||||||
*/
|
|
||||||
public final Setting<Boolean> containerMemory = new Setting<>(false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill in blocks behind you
|
* Fill in blocks behind you
|
||||||
*/
|
*/
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.cache;
|
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Brady
|
|
||||||
* @since 9/23/2018
|
|
||||||
*/
|
|
||||||
public interface IContainerMemory {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a remembered inventory by its block position.
|
|
||||||
*
|
|
||||||
* @param pos The position of the container block
|
|
||||||
* @return The remembered inventory
|
|
||||||
*/
|
|
||||||
IRememberedInventory getInventoryByPos(BlockPos pos);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the map of all block positions to their remembered inventories.
|
|
||||||
*
|
|
||||||
* @return Map of block positions to their respective remembered inventories
|
|
||||||
*/
|
|
||||||
Map<BlockPos, IRememberedInventory> getRememberedInventories();
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.cache;
|
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Brady
|
|
||||||
* @since 9/23/2018
|
|
||||||
*/
|
|
||||||
public interface IRememberedInventory {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The contents of this inventory
|
|
||||||
*/
|
|
||||||
List<ItemStack> getContents();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The number of slots in this inventory
|
|
||||||
*/
|
|
||||||
int getSize();
|
|
||||||
}
|
|
@ -37,9 +37,4 @@ public interface IWorldData {
|
|||||||
*/
|
*/
|
||||||
IWaypointCollection getWaypoints();
|
IWaypointCollection getWaypoints();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The {@link IContainerMemory} instance
|
|
||||||
* @see IContainerMemory
|
|
||||||
*/
|
|
||||||
IContainerMemory getContainerMemory();
|
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,6 @@ public class Baritone implements IBaritone {
|
|||||||
|
|
||||||
private PathingBehavior pathingBehavior;
|
private PathingBehavior pathingBehavior;
|
||||||
private LookBehavior lookBehavior;
|
private LookBehavior lookBehavior;
|
||||||
private MemoryBehavior memoryBehavior;
|
|
||||||
private InventoryBehavior inventoryBehavior;
|
private InventoryBehavior inventoryBehavior;
|
||||||
private InputOverrideHandler inputOverrideHandler;
|
private InputOverrideHandler inputOverrideHandler;
|
||||||
|
|
||||||
@ -100,7 +99,6 @@ public class Baritone implements IBaritone {
|
|||||||
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
|
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
|
||||||
pathingBehavior = new PathingBehavior(this);
|
pathingBehavior = new PathingBehavior(this);
|
||||||
lookBehavior = new LookBehavior(this);
|
lookBehavior = new LookBehavior(this);
|
||||||
memoryBehavior = new MemoryBehavior(this);
|
|
||||||
inventoryBehavior = new InventoryBehavior(this);
|
inventoryBehavior = new InventoryBehavior(this);
|
||||||
inputOverrideHandler = new InputOverrideHandler(this);
|
inputOverrideHandler = new InputOverrideHandler(this);
|
||||||
}
|
}
|
||||||
@ -151,10 +149,6 @@ public class Baritone implements IBaritone {
|
|||||||
return this.playerContext;
|
return this.playerContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemoryBehavior getMemoryBehavior() {
|
|
||||||
return this.memoryBehavior;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FollowProcess getFollowProcess() {
|
public FollowProcess getFollowProcess() {
|
||||||
return this.followProcess;
|
return this.followProcess;
|
||||||
|
@ -1,332 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.behavior;
|
|
||||||
|
|
||||||
import baritone.Baritone;
|
|
||||||
import baritone.api.cache.IWaypoint;
|
|
||||||
import baritone.api.cache.Waypoint;
|
|
||||||
import baritone.api.event.events.BlockInteractEvent;
|
|
||||||
import baritone.api.event.events.PacketEvent;
|
|
||||||
import baritone.api.event.events.PlayerUpdateEvent;
|
|
||||||
import baritone.api.event.events.TickEvent;
|
|
||||||
import baritone.api.event.events.type.EventState;
|
|
||||||
import baritone.api.utils.BetterBlockPos;
|
|
||||||
import baritone.api.utils.Helper;
|
|
||||||
import baritone.cache.ContainerMemory;
|
|
||||||
import baritone.utils.BlockStateInterface;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockBed;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
|
||||||
import net.minecraft.init.Blocks;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.network.Packet;
|
|
||||||
import net.minecraft.network.play.client.CPacketCloseWindow;
|
|
||||||
import net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock;
|
|
||||||
import net.minecraft.network.play.server.SPacketCloseWindow;
|
|
||||||
import net.minecraft.network.play.server.SPacketOpenWindow;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
|
||||||
import net.minecraft.tileentity.TileEntityLockable;
|
|
||||||
import net.minecraft.util.EnumFacing;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.text.ITextComponent;
|
|
||||||
import net.minecraft.util.text.TextComponentString;
|
|
||||||
import net.minecraft.util.text.TextComponentTranslation;
|
|
||||||
import net.minecraft.util.text.TextFormatting;
|
|
||||||
import net.minecraft.util.text.event.ClickEvent;
|
|
||||||
import net.minecraft.util.text.event.HoverEvent;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* doesn't work for horse inventories :^)
|
|
||||||
*
|
|
||||||
* @author Brady
|
|
||||||
* @since 8/6/2018
|
|
||||||
*/
|
|
||||||
public final class MemoryBehavior extends Behavior {
|
|
||||||
|
|
||||||
private final List<FutureInventory> futureInventories = new ArrayList<>(); // this is per-bot
|
|
||||||
|
|
||||||
private Integer enderChestWindowId; // nae nae
|
|
||||||
|
|
||||||
public MemoryBehavior(Baritone baritone) {
|
|
||||||
super(baritone);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void onTick(TickEvent event) {
|
|
||||||
if (!Baritone.settings().containerMemory.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getType() == TickEvent.Type.OUT) {
|
|
||||||
enderChestWindowId = null;
|
|
||||||
futureInventories.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void onPlayerUpdate(PlayerUpdateEvent event) {
|
|
||||||
if (event.getState() == EventState.PRE) {
|
|
||||||
updateInventory();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void onSendPacket(PacketEvent event) {
|
|
||||||
if (!Baritone.settings().containerMemory.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Packet p = event.getPacket();
|
|
||||||
|
|
||||||
if (event.getState() == EventState.PRE) {
|
|
||||||
if (p instanceof CPacketPlayerTryUseItemOnBlock) {
|
|
||||||
CPacketPlayerTryUseItemOnBlock packet = event.cast();
|
|
||||||
|
|
||||||
TileEntity tileEntity = ctx.world().getTileEntity(packet.getPos());
|
|
||||||
// if tileEntity is an ender chest, we don't need to do anything. ender chests are treated the same regardless of what coordinate right clicked
|
|
||||||
|
|
||||||
// Ensure the TileEntity is a container of some sort
|
|
||||||
if (tileEntity instanceof TileEntityLockable) {
|
|
||||||
|
|
||||||
TileEntityLockable lockable = (TileEntityLockable) tileEntity;
|
|
||||||
int size = lockable.getSizeInventory();
|
|
||||||
BetterBlockPos position = BetterBlockPos.from(tileEntity.getPos());
|
|
||||||
BetterBlockPos adj = BetterBlockPos.from(neighboringConnectedBlock(position));
|
|
||||||
System.out.println(position + " " + adj);
|
|
||||||
if (adj != null) {
|
|
||||||
size *= 2; // double chest or double trapped chest
|
|
||||||
if (adj.getX() < position.getX() || adj.getZ() < position.getZ()) {
|
|
||||||
position = adj; // standardize on the lower coordinate, regardless of which side of the large chest we right clicked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.futureInventories.add(new FutureInventory(System.nanoTime() / 1000000L, size, lockable.getGuiID(), position));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p instanceof CPacketCloseWindow) {
|
|
||||||
getCurrent().save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void onReceivePacket(PacketEvent event) {
|
|
||||||
if (!Baritone.settings().containerMemory.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Packet p = event.getPacket();
|
|
||||||
|
|
||||||
if (event.getState() == EventState.PRE) {
|
|
||||||
if (p instanceof SPacketOpenWindow) {
|
|
||||||
SPacketOpenWindow packet = event.cast();
|
|
||||||
// Remove any entries that were created over a second ago, this should make up for INSANE latency
|
|
||||||
futureInventories.removeIf(i -> System.nanoTime() / 1000000L - i.time > 1000);
|
|
||||||
|
|
||||||
System.out.println("Received packet " + packet.getGuiId() + " " + packet.getEntityId() + " " + packet.getSlotCount() + " " + packet.getWindowId());
|
|
||||||
System.out.println(packet.getWindowTitle());
|
|
||||||
if (packet.getWindowTitle() instanceof TextComponentTranslation && ((TextComponentTranslation) packet.getWindowTitle()).getKey().equals("container.enderchest")) {
|
|
||||||
// title is not customized (i.e. this isn't just a renamed shulker)
|
|
||||||
enderChestWindowId = packet.getWindowId();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
futureInventories.stream()
|
|
||||||
.filter(i -> i.type.equals(packet.getGuiId()) && i.slots == packet.getSlotCount())
|
|
||||||
.findFirst().ifPresent(matched -> {
|
|
||||||
// Remove the future inventory
|
|
||||||
futureInventories.remove(matched);
|
|
||||||
|
|
||||||
// Setup the remembered inventory
|
|
||||||
getCurrentContainer().setup(matched.pos, packet.getWindowId(), packet.getSlotCount());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p instanceof SPacketCloseWindow) {
|
|
||||||
getCurrent().save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBlockInteract(BlockInteractEvent event) {
|
|
||||||
if (event.getType() == BlockInteractEvent.Type.USE) {
|
|
||||||
BetterBlockPos pos = BetterBlockPos.from(event.getPos());
|
|
||||||
IBlockState state = BlockStateInterface.get(ctx, pos);
|
|
||||||
if (state.getBlock() instanceof BlockBed) {
|
|
||||||
if (state.getValue(BlockBed.PART) == BlockBed.EnumPartType.FOOT) {
|
|
||||||
pos = pos.offset(state.getValue(BlockBed.FACING));
|
|
||||||
}
|
|
||||||
Set<IWaypoint> waypoints = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getByTag(IWaypoint.Tag.BED);
|
|
||||||
boolean exists = waypoints.stream().map(IWaypoint::getLocation).filter(pos::equals).findFirst().isPresent();
|
|
||||||
if (!exists) {
|
|
||||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, pos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPlayerDeath() {
|
|
||||||
Waypoint deathWaypoint = new Waypoint("death", Waypoint.Tag.DEATH, ctx.playerFeet());
|
|
||||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(deathWaypoint);
|
|
||||||
ITextComponent component = new TextComponentString("Death position saved.");
|
|
||||||
component.getStyle()
|
|
||||||
.setColor(TextFormatting.WHITE)
|
|
||||||
.setHoverEvent(new HoverEvent(
|
|
||||||
HoverEvent.Action.SHOW_TEXT,
|
|
||||||
new TextComponentString("Click to goto death")
|
|
||||||
))
|
|
||||||
.setClickEvent(new ClickEvent(
|
|
||||||
ClickEvent.Action.RUN_COMMAND,
|
|
||||||
String.format(
|
|
||||||
"%s%s goto %s @ %d",
|
|
||||||
FORCE_COMMAND_PREFIX,
|
|
||||||
"wp",
|
|
||||||
deathWaypoint.getTag().getName(),
|
|
||||||
deathWaypoint.getCreationTimestamp()
|
|
||||||
)
|
|
||||||
));
|
|
||||||
Helper.HELPER.logDirect(component);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void updateInventory() {
|
|
||||||
if (!Baritone.settings().containerMemory.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int windowId = ctx.player().openContainer.windowId;
|
|
||||||
if (enderChestWindowId != null) {
|
|
||||||
if (windowId == enderChestWindowId) {
|
|
||||||
getCurrent().contents = ctx.player().openContainer.getInventory().subList(0, 27);
|
|
||||||
} else {
|
|
||||||
getCurrent().save();
|
|
||||||
enderChestWindowId = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (getCurrentContainer() != null) {
|
|
||||||
getCurrentContainer().getInventoryFromWindow(windowId).ifPresent(inventory -> inventory.updateFromOpenWindow(ctx));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ContainerMemory getCurrentContainer() {
|
|
||||||
if (baritone.getWorldProvider().getCurrentWorld() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return (ContainerMemory) baritone.getWorldProvider().getCurrentWorld().getContainerMemory();
|
|
||||||
}
|
|
||||||
|
|
||||||
private BlockPos neighboringConnectedBlock(BlockPos in) {
|
|
||||||
BlockStateInterface bsi = baritone.bsi;
|
|
||||||
Block block = bsi.get0(in).getBlock();
|
|
||||||
if (block != Blocks.TRAPPED_CHEST && block != Blocks.CHEST) {
|
|
||||||
return null; // other things that have contents, but can be placed adjacent without combining
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
BlockPos adj = in.offset(EnumFacing.byHorizontalIndex(i));
|
|
||||||
if (bsi.get0(adj).getBlock() == block) {
|
|
||||||
return adj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An inventory that we are not yet fully aware of, but are expecting to exist at some point in the future.
|
|
||||||
*/
|
|
||||||
private static final class FutureInventory {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The time that we initially expected the inventory to be provided, in milliseconds
|
|
||||||
*/
|
|
||||||
private final long time;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The amount of slots in the inventory
|
|
||||||
*/
|
|
||||||
private final int slots;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of inventory
|
|
||||||
*/
|
|
||||||
private final String type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The position of the inventory container
|
|
||||||
*/
|
|
||||||
private final BlockPos pos;
|
|
||||||
|
|
||||||
private FutureInventory(long time, int slots, String type, BlockPos pos) {
|
|
||||||
this.time = time;
|
|
||||||
this.slots = slots;
|
|
||||||
this.type = type;
|
|
||||||
this.pos = pos;
|
|
||||||
// betterblockpos has censoring
|
|
||||||
System.out.println("Future inventory created " + time + " " + slots + " " + type + " " + BetterBlockPos.from(pos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<List<ItemStack>> echest() {
|
|
||||||
return Optional.ofNullable(getCurrent().contents).map(Collections::unmodifiableList);
|
|
||||||
}
|
|
||||||
|
|
||||||
public EnderChestMemory getCurrent() {
|
|
||||||
Path path = baritone.getWorldProvider().getCurrentWorld().directory;
|
|
||||||
return EnderChestMemory.getByServerAndPlayer(path.getParent(), ctx.player().getUniqueID());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class EnderChestMemory {
|
|
||||||
|
|
||||||
private static final Map<Path, EnderChestMemory> memory = new HashMap<>();
|
|
||||||
private final Path enderChest;
|
|
||||||
private List<ItemStack> contents;
|
|
||||||
|
|
||||||
private EnderChestMemory(Path enderChest) {
|
|
||||||
this.enderChest = enderChest;
|
|
||||||
System.out.println("Echest storing in " + enderChest);
|
|
||||||
try {
|
|
||||||
this.contents = ContainerMemory.readItemStacks(Files.readAllBytes(enderChest));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
System.out.println("CANNOT read echest =( =(");
|
|
||||||
this.contents = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void save() {
|
|
||||||
System.out.println("Saving");
|
|
||||||
if (contents != null) {
|
|
||||||
try {
|
|
||||||
enderChest.getParent().toFile().mkdir();
|
|
||||||
Files.write(enderChest, ContainerMemory.writeItemStacks(contents));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
System.out.println("CANNOT save echest =( =(");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static synchronized EnderChestMemory getByServerAndPlayer(Path serverStorage, UUID player) {
|
|
||||||
return memory.computeIfAbsent(serverStorage.resolve("echests").resolve(player.toString()), EnderChestMemory::new);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
183
src/main/java/baritone/cache/ContainerMemory.java
vendored
183
src/main/java/baritone/cache/ContainerMemory.java
vendored
@ -1,183 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.cache;
|
|
||||||
|
|
||||||
import baritone.Baritone;
|
|
||||||
import baritone.api.cache.IContainerMemory;
|
|
||||||
import baritone.api.cache.IRememberedInventory;
|
|
||||||
import baritone.api.utils.IPlayerContext;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.network.PacketBuffer;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.NoSuchFileException;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class ContainerMemory implements IContainerMemory {
|
|
||||||
|
|
||||||
private final Path saveTo;
|
|
||||||
/**
|
|
||||||
* The current remembered inventories
|
|
||||||
*/
|
|
||||||
private final Map<BlockPos, RememberedInventory> inventories = new HashMap<>();
|
|
||||||
|
|
||||||
|
|
||||||
public ContainerMemory(Path saveTo) {
|
|
||||||
this.saveTo = saveTo;
|
|
||||||
try {
|
|
||||||
read(Files.readAllBytes(saveTo));
|
|
||||||
} catch (NoSuchFileException ignored) {
|
|
||||||
inventories.clear();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
inventories.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void read(byte[] bytes) throws IOException {
|
|
||||||
PacketBuffer in = new PacketBuffer(Unpooled.wrappedBuffer(bytes));
|
|
||||||
int chests = in.readInt();
|
|
||||||
for (int i = 0; i < chests; i++) {
|
|
||||||
int x = in.readInt();
|
|
||||||
int y = in.readInt();
|
|
||||||
int z = in.readInt();
|
|
||||||
RememberedInventory rem = new RememberedInventory();
|
|
||||||
rem.items.addAll(readItemStacks(in));
|
|
||||||
rem.size = rem.items.size();
|
|
||||||
rem.windowId = -1;
|
|
||||||
if (rem.items.isEmpty()) {
|
|
||||||
continue; // this only happens if the list has no elements, not if the list has elements that are all empty item stacks
|
|
||||||
}
|
|
||||||
inventories.put(new BlockPos(x, y, z), rem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void save() throws IOException {
|
|
||||||
if (!Baritone.settings().containerMemory.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ByteBuf buf = Unpooled.buffer(0, Integer.MAX_VALUE);
|
|
||||||
PacketBuffer out = new PacketBuffer(buf);
|
|
||||||
out.writeInt(inventories.size());
|
|
||||||
for (Map.Entry<BlockPos, RememberedInventory> entry : inventories.entrySet()) {
|
|
||||||
out = new PacketBuffer(out.writeInt(entry.getKey().getX()));
|
|
||||||
out = new PacketBuffer(out.writeInt(entry.getKey().getY()));
|
|
||||||
out = new PacketBuffer(out.writeInt(entry.getKey().getZ()));
|
|
||||||
out = writeItemStacks(entry.getValue().getContents(), out);
|
|
||||||
}
|
|
||||||
Files.write(saveTo, out.array());
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void setup(BlockPos pos, int windowId, int slotCount) {
|
|
||||||
RememberedInventory inventory = inventories.computeIfAbsent(pos, x -> new RememberedInventory());
|
|
||||||
inventory.windowId = windowId;
|
|
||||||
inventory.size = slotCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized Optional<RememberedInventory> getInventoryFromWindow(int windowId) {
|
|
||||||
return inventories.values().stream().filter(i -> i.windowId == windowId).findFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final synchronized RememberedInventory getInventoryByPos(BlockPos pos) {
|
|
||||||
return inventories.get(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final synchronized Map<BlockPos, IRememberedInventory> getRememberedInventories() {
|
|
||||||
// make a copy since this map is modified from the packet thread
|
|
||||||
return new HashMap<>(inventories);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<ItemStack> readItemStacks(byte[] bytes) throws IOException {
|
|
||||||
PacketBuffer in = new PacketBuffer(Unpooled.wrappedBuffer(bytes));
|
|
||||||
return readItemStacks(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<ItemStack> readItemStacks(PacketBuffer in) throws IOException {
|
|
||||||
int count = in.readInt();
|
|
||||||
List<ItemStack> result = new ArrayList<>();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
result.add(in.readItemStack());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] writeItemStacks(List<ItemStack> write) {
|
|
||||||
ByteBuf buf = Unpooled.buffer(0, Integer.MAX_VALUE);
|
|
||||||
PacketBuffer out = new PacketBuffer(buf);
|
|
||||||
out = writeItemStacks(write, out);
|
|
||||||
return out.array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PacketBuffer writeItemStacks(List<ItemStack> write, PacketBuffer out2) {
|
|
||||||
PacketBuffer out = out2; // avoid reassigning an argument LOL
|
|
||||||
out = new PacketBuffer(out.writeInt(write.size()));
|
|
||||||
for (ItemStack stack : write) {
|
|
||||||
out = out.writeItemStack(stack);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An inventory that we are aware of.
|
|
||||||
* <p>
|
|
||||||
* Associated with a {@link BlockPos} in {@link ContainerMemory#inventories}.
|
|
||||||
*/
|
|
||||||
public static class RememberedInventory implements IRememberedInventory {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The list of items in the inventory
|
|
||||||
*/
|
|
||||||
private final List<ItemStack> items;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The last known window ID of the inventory
|
|
||||||
*/
|
|
||||||
private int windowId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The size of the inventory
|
|
||||||
*/
|
|
||||||
private int size;
|
|
||||||
|
|
||||||
private RememberedInventory() {
|
|
||||||
this.items = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final List<ItemStack> getContents() {
|
|
||||||
return Collections.unmodifiableList(this.items);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final int getSize() {
|
|
||||||
return this.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateFromOpenWindow(IPlayerContext ctx) {
|
|
||||||
items.clear();
|
|
||||||
items.addAll(ctx.player().openContainer.getInventory().subList(0, size));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
17
src/main/java/baritone/cache/WorldData.java
vendored
17
src/main/java/baritone/cache/WorldData.java
vendored
@ -19,7 +19,6 @@ package baritone.cache;
|
|||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.cache.ICachedWorld;
|
import baritone.api.cache.ICachedWorld;
|
||||||
import baritone.api.cache.IContainerMemory;
|
|
||||||
import baritone.api.cache.IWaypointCollection;
|
import baritone.api.cache.IWaypointCollection;
|
||||||
import baritone.api.cache.IWorldData;
|
import baritone.api.cache.IWorldData;
|
||||||
|
|
||||||
@ -35,7 +34,6 @@ public class WorldData implements IWorldData {
|
|||||||
|
|
||||||
public final CachedWorld cache;
|
public final CachedWorld cache;
|
||||||
private final WaypointCollection waypoints;
|
private final WaypointCollection waypoints;
|
||||||
private final ContainerMemory containerMemory;
|
|
||||||
//public final MapData map;
|
//public final MapData map;
|
||||||
public final Path directory;
|
public final Path directory;
|
||||||
public final int dimension;
|
public final int dimension;
|
||||||
@ -44,7 +42,6 @@ public class WorldData implements IWorldData {
|
|||||||
this.directory = directory;
|
this.directory = directory;
|
||||||
this.cache = new CachedWorld(directory.resolve("cache"), dimension);
|
this.cache = new CachedWorld(directory.resolve("cache"), dimension);
|
||||||
this.waypoints = new WaypointCollection(directory.resolve("waypoints"));
|
this.waypoints = new WaypointCollection(directory.resolve("waypoints"));
|
||||||
this.containerMemory = new ContainerMemory(directory.resolve("containers"));
|
|
||||||
this.dimension = dimension;
|
this.dimension = dimension;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,15 +50,6 @@ public class WorldData implements IWorldData {
|
|||||||
System.out.println("Started saving the world in a new thread");
|
System.out.println("Started saving the world in a new thread");
|
||||||
cache.save();
|
cache.save();
|
||||||
});
|
});
|
||||||
Baritone.getExecutor().execute(() -> {
|
|
||||||
System.out.println("Started saving saved containers in a new thread");
|
|
||||||
try {
|
|
||||||
containerMemory.save();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
System.out.println("Failed to save saved containers");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -73,9 +61,4 @@ public class WorldData implements IWorldData {
|
|||||||
public IWaypointCollection getWaypoints() {
|
public IWaypointCollection getWaypoints() {
|
||||||
return this.waypoints;
|
return this.waypoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IContainerMemory getContainerMemory() {
|
|
||||||
return this.containerMemory;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.command.defaults;
|
|
||||||
|
|
||||||
import baritone.api.IBaritone;
|
|
||||||
import baritone.api.cache.IRememberedInventory;
|
|
||||||
import baritone.api.command.Command;
|
|
||||||
import baritone.api.command.argument.IArgConsumer;
|
|
||||||
import baritone.api.command.exception.CommandException;
|
|
||||||
import baritone.api.command.exception.CommandInvalidStateException;
|
|
||||||
import baritone.api.utils.BetterBlockPos;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.text.ITextComponent;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class ChestsCommand extends Command {
|
|
||||||
|
|
||||||
public ChestsCommand(IBaritone baritone) {
|
|
||||||
super(baritone, "chests");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(String label, IArgConsumer args) throws CommandException {
|
|
||||||
args.requireMax(0);
|
|
||||||
Set<Map.Entry<BlockPos, IRememberedInventory>> entries =
|
|
||||||
ctx.worldData().getContainerMemory().getRememberedInventories().entrySet();
|
|
||||||
if (entries.isEmpty()) {
|
|
||||||
throw new CommandInvalidStateException("No remembered inventories");
|
|
||||||
}
|
|
||||||
for (Map.Entry<BlockPos, IRememberedInventory> entry : entries) {
|
|
||||||
// betterblockpos has censoring
|
|
||||||
BetterBlockPos pos = new BetterBlockPos(entry.getKey());
|
|
||||||
IRememberedInventory inv = entry.getValue();
|
|
||||||
logDirect(pos.toString());
|
|
||||||
for (ItemStack item : inv.getContents()) {
|
|
||||||
ITextComponent component = item.getTextComponent();
|
|
||||||
component.appendText(String.format(" x %d", item.getCount()));
|
|
||||||
logDirect(component);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<String> tabComplete(String label, IArgConsumer args) {
|
|
||||||
return Stream.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getShortDesc() {
|
|
||||||
return "Display remembered inventories";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getLongDesc() {
|
|
||||||
return Arrays.asList(
|
|
||||||
"The chests command lists remembered inventories, I guess?",
|
|
||||||
"",
|
|
||||||
"Usage:",
|
|
||||||
"> chests"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -51,7 +51,6 @@ public final class DefaultCommands {
|
|||||||
new TunnelCommand(baritone),
|
new TunnelCommand(baritone),
|
||||||
new RenderCommand(baritone),
|
new RenderCommand(baritone),
|
||||||
new FarmCommand(baritone),
|
new FarmCommand(baritone),
|
||||||
new ChestsCommand(baritone),
|
|
||||||
new FollowCommand(baritone),
|
new FollowCommand(baritone),
|
||||||
new ExploreFilterCommand(baritone),
|
new ExploreFilterCommand(baritone),
|
||||||
new ReloadAllCommand(baritone),
|
new ReloadAllCommand(baritone),
|
||||||
|
Loading…
Reference in New Issue
Block a user