Created MemoryBehavior
Includes basic memory of inventories that have been interacted with.
This commit is contained in:
		@@ -65,7 +65,7 @@ repositories {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation ('org.spongepowered:mixin:0.7.10-SNAPSHOT') {
 | 
			
		||||
    implementation ('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
 | 
			
		||||
        // Mixin includes a lot of dependencies that are too up-to-date
 | 
			
		||||
        exclude module: 'launchwrapper'
 | 
			
		||||
        exclude module: 'guava'
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ package baritone.bot;
 | 
			
		||||
 | 
			
		||||
import baritone.bot.behavior.Behavior;
 | 
			
		||||
import baritone.bot.behavior.impl.LookBehavior;
 | 
			
		||||
import baritone.bot.behavior.impl.MemoryBehavior;
 | 
			
		||||
import baritone.bot.behavior.impl.PathingBehavior;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
@@ -61,6 +62,7 @@ public enum Baritone {
 | 
			
		||||
        this.behaviors = new ArrayList<>();
 | 
			
		||||
        behaviors.add(PathingBehavior.INSTANCE);
 | 
			
		||||
        behaviors.add(LookBehavior.INSTANCE);
 | 
			
		||||
        behaviors.add(MemoryBehavior.INSTANCE);
 | 
			
		||||
 | 
			
		||||
        this.active = true;
 | 
			
		||||
        this.initialized = true;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										185
									
								
								src/main/java/baritone/bot/behavior/impl/MemoryBehavior.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								src/main/java/baritone/bot/behavior/impl/MemoryBehavior.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,185 @@
 | 
			
		||||
package baritone.bot.behavior.impl;
 | 
			
		||||
 | 
			
		||||
import baritone.bot.behavior.Behavior;
 | 
			
		||||
import baritone.bot.event.events.PacketEvent;
 | 
			
		||||
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.math.BlockPos;
 | 
			
		||||
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Brady
 | 
			
		||||
 * @since 8/6/2018 9:47 PM
 | 
			
		||||
 */
 | 
			
		||||
public class MemoryBehavior extends Behavior {
 | 
			
		||||
 | 
			
		||||
    public static MemoryBehavior INSTANCE = new MemoryBehavior();
 | 
			
		||||
 | 
			
		||||
    private MemoryBehavior() {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Possible future inventories that we will be able to remember
 | 
			
		||||
     */
 | 
			
		||||
    private final List<FutureInventory> futureInventories = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The current remembered inventories
 | 
			
		||||
     */
 | 
			
		||||
    private final Map<BlockPos, RememberedInventory> rememberedInventories = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onPlayerUpdate() {
 | 
			
		||||
        updateInventory();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onSendPacket(PacketEvent event) {
 | 
			
		||||
        Packet p = event.getPacket();
 | 
			
		||||
 | 
			
		||||
        switch (event.getState()) {
 | 
			
		||||
            case PRE: {
 | 
			
		||||
                if (p instanceof CPacketPlayerTryUseItemOnBlock) {
 | 
			
		||||
                    CPacketPlayerTryUseItemOnBlock packet = event.cast();
 | 
			
		||||
 | 
			
		||||
                    TileEntity tileEntity = world().getTileEntity(packet.getPos());
 | 
			
		||||
 | 
			
		||||
                    // Ensure the TileEntity is a container of some sort
 | 
			
		||||
                    if (tileEntity instanceof TileEntityLockable) {
 | 
			
		||||
 | 
			
		||||
                        TileEntityLockable lockable = (TileEntityLockable) tileEntity;
 | 
			
		||||
                        int size = lockable.getSizeInventory();
 | 
			
		||||
 | 
			
		||||
                        this.futureInventories.add(new FutureInventory(System.currentTimeMillis(), size, lockable.getGuiID(), tileEntity.getPos()));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (p instanceof CPacketCloseWindow) {
 | 
			
		||||
                    updateInventory();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onReceivePacket(PacketEvent event) {
 | 
			
		||||
        Packet p = event.getPacket();
 | 
			
		||||
 | 
			
		||||
        switch (event.getState()) {
 | 
			
		||||
            case 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
 | 
			
		||||
                    this.futureInventories.removeIf(i -> System.currentTimeMillis() - i.time > 1000);
 | 
			
		||||
 | 
			
		||||
                    this.futureInventories.stream()
 | 
			
		||||
                            .filter(i -> i.type.equals(packet.getGuiId()) && i.slots == packet.getSlotCount())
 | 
			
		||||
                            .findFirst().ifPresent(matched -> {
 | 
			
		||||
                                // Remove the future inventory
 | 
			
		||||
                                this.futureInventories.remove(matched);
 | 
			
		||||
 | 
			
		||||
                                // Setup the remembered inventory
 | 
			
		||||
                                RememberedInventory inventory = this.rememberedInventories.computeIfAbsent(matched.pos, pos -> new RememberedInventory());
 | 
			
		||||
                                inventory.windowId = packet.getWindowId();
 | 
			
		||||
                                inventory.size = packet.getSlotCount();
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (p instanceof SPacketCloseWindow) {
 | 
			
		||||
                    updateInventory();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Optional<RememberedInventory> getInventoryFromWindow(int windowId) {
 | 
			
		||||
        return this.rememberedInventories.values().stream().filter(i -> i.windowId == windowId).findFirst();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void updateInventory() {
 | 
			
		||||
        getInventoryFromWindow(player().openContainer.windowId).ifPresent(inventory -> {
 | 
			
		||||
            inventory.items.clear();
 | 
			
		||||
            inventory.items.addAll(player().openContainer.getInventory().subList(0, inventory.size));
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public final RememberedInventory getInventoryByPos(BlockPos pos) {
 | 
			
		||||
        return this.rememberedInventories.get(pos);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * An inventory that we are aware of.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * Associated with a {@link BlockPos} in {@link MemoryBehavior#rememberedInventories}.
 | 
			
		||||
     */
 | 
			
		||||
    public static class RememberedInventory {
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 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<>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * @return The list of items in the inventory
 | 
			
		||||
         */
 | 
			
		||||
        public final List<ItemStack> getItems() {
 | 
			
		||||
            return this.items;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -17,6 +17,7 @@
 | 
			
		||||
 | 
			
		||||
package baritone.bot.event.events;
 | 
			
		||||
 | 
			
		||||
import baritone.bot.event.events.type.EventState;
 | 
			
		||||
import net.minecraft.network.Packet;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -25,13 +26,25 @@ import net.minecraft.network.Packet;
 | 
			
		||||
 */
 | 
			
		||||
public final class PacketEvent {
 | 
			
		||||
 | 
			
		||||
    private final EventState state;
 | 
			
		||||
 | 
			
		||||
    private final Packet<?> packet;
 | 
			
		||||
 | 
			
		||||
    public PacketEvent(Packet<?> packet) {
 | 
			
		||||
    public PacketEvent(EventState state, Packet<?> packet) {
 | 
			
		||||
        this.state = state;
 | 
			
		||||
        this.packet = packet;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public final EventState getState() {
 | 
			
		||||
        return this.state;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public final Packet<?> getPacket() {
 | 
			
		||||
        return this.packet;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings("unchecked")
 | 
			
		||||
    public final <T extends Packet<?>> T cast() {
 | 
			
		||||
        return (T) this.packet;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,12 +19,15 @@ package baritone.launch.mixins;
 | 
			
		||||
 | 
			
		||||
import baritone.bot.Baritone;
 | 
			
		||||
import baritone.bot.event.events.PacketEvent;
 | 
			
		||||
import baritone.bot.event.events.type.EventState;
 | 
			
		||||
import io.netty.channel.Channel;
 | 
			
		||||
import io.netty.channel.ChannelHandlerContext;
 | 
			
		||||
import io.netty.util.concurrent.Future;
 | 
			
		||||
import io.netty.util.concurrent.GenericFutureListener;
 | 
			
		||||
import net.minecraft.network.NetworkManager;
 | 
			
		||||
import net.minecraft.network.Packet;
 | 
			
		||||
import org.spongepowered.asm.mixin.Mixin;
 | 
			
		||||
import org.spongepowered.asm.mixin.Shadow;
 | 
			
		||||
import org.spongepowered.asm.mixin.injection.At;
 | 
			
		||||
import org.spongepowered.asm.mixin.injection.Inject;
 | 
			
		||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
 | 
			
		||||
@@ -34,14 +37,26 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
 | 
			
		||||
 * @since 8/6/2018 9:30 PM
 | 
			
		||||
 */
 | 
			
		||||
@Mixin(NetworkManager.class)
 | 
			
		||||
public class MixinNetworkManager {
 | 
			
		||||
public abstract class MixinNetworkManager {
 | 
			
		||||
 | 
			
		||||
    @Shadow private Channel channel;
 | 
			
		||||
 | 
			
		||||
    @Shadow protected abstract void channelRead0(ChannelHandlerContext p_channelRead0_1_, Packet<?> p_channelRead0_2_) throws Exception;
 | 
			
		||||
 | 
			
		||||
    @Inject(
 | 
			
		||||
            method = "dispatchPacket",
 | 
			
		||||
            at = @At("HEAD")
 | 
			
		||||
    )
 | 
			
		||||
    private void dispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void >>[] futureListeners, CallbackInfo ci) {
 | 
			
		||||
        Baritone.INSTANCE.getGameEventHandler().onSendPacket(new PacketEvent(inPacket));
 | 
			
		||||
    private void preDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void >>[] futureListeners, CallbackInfo ci) {
 | 
			
		||||
        Baritone.INSTANCE.getGameEventHandler().onSendPacket(new PacketEvent(EventState.PRE, inPacket));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Inject(
 | 
			
		||||
            method = "dispatchPacket",
 | 
			
		||||
            at = @At("RETURN")
 | 
			
		||||
    )
 | 
			
		||||
    private void postDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void >>[] futureListeners, CallbackInfo ci) {
 | 
			
		||||
        Baritone.INSTANCE.getGameEventHandler().onSendPacket(new PacketEvent(EventState.POST, inPacket));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Inject(
 | 
			
		||||
@@ -49,9 +64,20 @@ public class MixinNetworkManager {
 | 
			
		||||
            at = @At(
 | 
			
		||||
                    value = "INVOKE",
 | 
			
		||||
                    target = "net/minecraft/network/Packet.processPacket(Lnet/minecraft/network/INetHandler;)V"
 | 
			
		||||
            )
 | 
			
		||||
            ),
 | 
			
		||||
            remap = false
 | 
			
		||||
    )
 | 
			
		||||
    private void preProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
 | 
			
		||||
        Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent(packet));
 | 
			
		||||
        Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent(EventState.PRE, packet));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Inject(
 | 
			
		||||
            method = "channelRead0",
 | 
			
		||||
            at = @At("RETURN"),
 | 
			
		||||
            remap = false
 | 
			
		||||
    )
 | 
			
		||||
    private void postProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
 | 
			
		||||
        if (this.channel.isOpen())
 | 
			
		||||
            Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent(EventState.POST, packet));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user