forked from RepoMirrors/baritone
Created MemoryBehavior
Includes basic memory of inventories that have been interacted with.
This commit is contained in:
parent
6a13e2da64
commit
ebde6f26e9
|
@ -65,7 +65,7 @@ repositories {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
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
|
// Mixin includes a lot of dependencies that are too up-to-date
|
||||||
exclude module: 'launchwrapper'
|
exclude module: 'launchwrapper'
|
||||||
exclude module: 'guava'
|
exclude module: 'guava'
|
||||||
|
|
|
@ -19,6 +19,7 @@ package baritone.bot;
|
||||||
|
|
||||||
import baritone.bot.behavior.Behavior;
|
import baritone.bot.behavior.Behavior;
|
||||||
import baritone.bot.behavior.impl.LookBehavior;
|
import baritone.bot.behavior.impl.LookBehavior;
|
||||||
|
import baritone.bot.behavior.impl.MemoryBehavior;
|
||||||
import baritone.bot.behavior.impl.PathingBehavior;
|
import baritone.bot.behavior.impl.PathingBehavior;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -61,6 +62,7 @@ public enum Baritone {
|
||||||
this.behaviors = new ArrayList<>();
|
this.behaviors = new ArrayList<>();
|
||||||
behaviors.add(PathingBehavior.INSTANCE);
|
behaviors.add(PathingBehavior.INSTANCE);
|
||||||
behaviors.add(LookBehavior.INSTANCE);
|
behaviors.add(LookBehavior.INSTANCE);
|
||||||
|
behaviors.add(MemoryBehavior.INSTANCE);
|
||||||
|
|
||||||
this.active = true;
|
this.active = true;
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
|
|
|
@ -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;
|
package baritone.bot.event.events;
|
||||||
|
|
||||||
|
import baritone.bot.event.events.type.EventState;
|
||||||
import net.minecraft.network.Packet;
|
import net.minecraft.network.Packet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,13 +26,25 @@ import net.minecraft.network.Packet;
|
||||||
*/
|
*/
|
||||||
public final class PacketEvent {
|
public final class PacketEvent {
|
||||||
|
|
||||||
|
private final EventState state;
|
||||||
|
|
||||||
private final Packet<?> packet;
|
private final Packet<?> packet;
|
||||||
|
|
||||||
public PacketEvent(Packet<?> packet) {
|
public PacketEvent(EventState state, Packet<?> packet) {
|
||||||
|
this.state = state;
|
||||||
this.packet = packet;
|
this.packet = packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final EventState getState() {
|
||||||
|
return this.state;
|
||||||
|
}
|
||||||
|
|
||||||
public final Packet<?> getPacket() {
|
public final Packet<?> getPacket() {
|
||||||
return this.packet;
|
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.Baritone;
|
||||||
import baritone.bot.event.events.PacketEvent;
|
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.channel.ChannelHandlerContext;
|
||||||
import io.netty.util.concurrent.Future;
|
import io.netty.util.concurrent.Future;
|
||||||
import io.netty.util.concurrent.GenericFutureListener;
|
import io.netty.util.concurrent.GenericFutureListener;
|
||||||
import net.minecraft.network.NetworkManager;
|
import net.minecraft.network.NetworkManager;
|
||||||
import net.minecraft.network.Packet;
|
import net.minecraft.network.Packet;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
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.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
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
|
* @since 8/6/2018 9:30 PM
|
||||||
*/
|
*/
|
||||||
@Mixin(NetworkManager.class)
|
@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(
|
@Inject(
|
||||||
method = "dispatchPacket",
|
method = "dispatchPacket",
|
||||||
at = @At("HEAD")
|
at = @At("HEAD")
|
||||||
)
|
)
|
||||||
private void dispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void >>[] futureListeners, CallbackInfo ci) {
|
private void preDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void >>[] futureListeners, CallbackInfo ci) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onSendPacket(new PacketEvent(inPacket));
|
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(
|
@Inject(
|
||||||
|
@ -49,9 +64,20 @@ public class MixinNetworkManager {
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "net/minecraft/network/Packet.processPacket(Lnet/minecraft/network/INetHandler;)V"
|
target = "net/minecraft/network/Packet.processPacket(Lnet/minecraft/network/INetHandler;)V"
|
||||||
)
|
),
|
||||||
|
remap = false
|
||||||
)
|
)
|
||||||
private void preProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue