feat: FINALLY chunk parsing with actual working core complete check
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package me.chayapak1.chomens_bot.chunk;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import me.chayapak1.chomens_bot.data.chunk.ChunkPos;
|
||||
import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.ChunkSection;
|
||||
|
||||
// Author: hhhzzzsss
|
||||
public class ChunkColumn {
|
||||
public final ChunkPos pos;
|
||||
public final ChunkSection[] chunks;
|
||||
|
||||
private final int minY;
|
||||
|
||||
public ChunkColumn (ChunkPos chunkPos, byte[] data, int worldHeight, int minY) {
|
||||
this.pos = chunkPos;
|
||||
this.minY = minY;
|
||||
|
||||
final ByteBuf in = Unpooled.wrappedBuffer(data);
|
||||
final int numSections = -Math.floorDiv(-worldHeight, 16);
|
||||
|
||||
chunks = new ChunkSection[numSections];
|
||||
|
||||
for (int i = 0; i < numSections; i++) {
|
||||
chunks[i] = MinecraftTypes.readChunkSection(in);
|
||||
}
|
||||
}
|
||||
|
||||
public int getBlock (int x, int y, int z) {
|
||||
int yIndex = (y - minY) >> 4;
|
||||
|
||||
if (chunks[yIndex] == null) return 0;
|
||||
|
||||
return chunks[yIndex].getBlock(x, y & 15, z);
|
||||
}
|
||||
|
||||
public void setBlock (int x, int y, int z, int id) {
|
||||
int yIndex = (y - minY) >> 4;
|
||||
|
||||
if (chunks[yIndex] == null) {
|
||||
chunks[yIndex] = new ChunkSection();
|
||||
chunks[yIndex].setBlock(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
chunks[yIndex].setBlock(x, y & 15, z, id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package me.chayapak1.chomens_bot.data.chunk;
|
||||
|
||||
public record ChunkPos (int x, int z) {
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.mcprotocollib.network.Session;
|
||||
import org.geysermc.mcprotocollib.network.event.session.DisconnectedEvent;
|
||||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction;
|
||||
@@ -20,11 +19,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponen
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockChangeEntry;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.CommandBlockMode;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundBlockUpdatePacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundLevelChunkWithLightPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundSectionBlocksUpdatePacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetCommandBlockPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundSetCreativeModeSlotPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket;
|
||||
@@ -87,6 +82,8 @@ public class CorePlugin extends PositionPlugin.Listener {
|
||||
}
|
||||
|
||||
bot.executor.scheduleAtFixedRate(() -> {
|
||||
checkCoreTick();
|
||||
|
||||
if (!shouldRefill) return;
|
||||
|
||||
refill();
|
||||
@@ -102,13 +99,6 @@ public class CorePlugin extends PositionPlugin.Listener {
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void packetReceived(Session session, Packet packet) {
|
||||
if (packet instanceof ClientboundBlockUpdatePacket) CorePlugin.this.packetReceived((ClientboundBlockUpdatePacket) packet);
|
||||
else if (packet instanceof ClientboundSectionBlocksUpdatePacket) CorePlugin.this.packetReceived((ClientboundSectionBlocksUpdatePacket) packet);
|
||||
else if (packet instanceof ClientboundLevelChunkWithLightPacket) CorePlugin.this.packetReceived((ClientboundLevelChunkWithLightPacket) packet);
|
||||
}
|
||||
});
|
||||
|
||||
bot.tick.addListener(new TickPlugin.Listener() {
|
||||
@@ -217,7 +207,7 @@ public class CorePlugin extends PositionPlugin.Listener {
|
||||
final CompletableFuture<String> future = bot.query.block(coreBlock, "LastOutput");
|
||||
|
||||
future.thenApplyAsync(output -> {
|
||||
if (output == null) return output;
|
||||
if (output == null) return null;
|
||||
|
||||
trackedFuture.complete(
|
||||
Component.join(
|
||||
@@ -284,29 +274,24 @@ public class CorePlugin extends PositionPlugin.Listener {
|
||||
session.send(new ServerboundUseItemOnPacket(temporaryBlockPosition, Direction.UP, Hand.MAIN_HAND, 0.5f, 0.5f, 0.5f, false, false, 1));
|
||||
}
|
||||
|
||||
public void packetReceived (ClientboundBlockUpdatePacket packet) {
|
||||
final BlockChangeEntry entry = packet.getEntry();
|
||||
public boolean isCoreComplete () {
|
||||
if (!ready) return false;
|
||||
|
||||
final Vector3i position = entry.getPosition();
|
||||
for (int x = from.getX(); x <= to.getX(); x++) {
|
||||
for (int y = from.getY(); y <= to.getY(); y++) {
|
||||
for (int z = from.getZ(); z <= to.getZ(); z++) {
|
||||
final int block = bot.world.getBlock(x, y, z);
|
||||
|
||||
if (isCore(position) && !isCommandBlockState(entry.getBlock())) shouldRefill = true;
|
||||
}
|
||||
|
||||
public void packetReceived (ClientboundSectionBlocksUpdatePacket packet) {
|
||||
final BlockChangeEntry[] entries = packet.getEntries();
|
||||
|
||||
for (BlockChangeEntry entry : entries) {
|
||||
final Vector3i position = entry.getPosition();
|
||||
|
||||
if (isCore(position) && !isCommandBlockState(entry.getBlock())) {
|
||||
shouldRefill = true;
|
||||
break;
|
||||
if (!isCommandBlockState(block)) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void packetReceived (ClientboundLevelChunkWithLightPacket packet) {
|
||||
shouldRefill = true; // worst fix
|
||||
private void checkCoreTick () {
|
||||
if (!isCoreComplete()) shouldRefill = true;
|
||||
}
|
||||
|
||||
private boolean isCommandBlockState (int blockState) {
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
package me.chayapak1.chomens_bot.plugins;
|
||||
|
||||
import me.chayapak1.chomens_bot.Bot;
|
||||
import me.chayapak1.chomens_bot.chunk.ChunkColumn;
|
||||
import me.chayapak1.chomens_bot.data.chunk.ChunkPos;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.geysermc.mcprotocollib.network.Session;
|
||||
import org.geysermc.mcprotocollib.network.event.session.DisconnectedEvent;
|
||||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockChangeEntry;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundLoginPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundRespawnPacket;
|
||||
import me.chayapak1.chomens_bot.Bot;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.ClientboundSetSimulationDistancePacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.level.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class WorldPlugin extends Bot.Listener {
|
||||
public int minY = 0;
|
||||
@@ -19,6 +23,8 @@ public class WorldPlugin extends Bot.Listener {
|
||||
|
||||
public int simulationDistance = 8;
|
||||
|
||||
private final Map<ChunkPos, ChunkColumn> chunks = new HashMap<>();
|
||||
|
||||
public List<RegistryEntry> registry = null;
|
||||
|
||||
private final List<Listener> listeners = new ArrayList<>();
|
||||
@@ -33,6 +39,15 @@ public class WorldPlugin extends Bot.Listener {
|
||||
else if (packet instanceof ClientboundRespawnPacket t_packet) packetReceived(t_packet);
|
||||
else if (packet instanceof ClientboundRegistryDataPacket t_packet) packetReceived(t_packet);
|
||||
else if (packet instanceof ClientboundSetSimulationDistancePacket t_packet) packetReceived(t_packet);
|
||||
else if (packet instanceof ClientboundLevelChunkWithLightPacket t_packet) packetReceived(t_packet);
|
||||
else if (packet instanceof ClientboundForgetLevelChunkPacket t_packet) packetReceived(t_packet);
|
||||
else if (packet instanceof ClientboundBlockUpdatePacket t_packet) packetReceived(t_packet);
|
||||
else if (packet instanceof ClientboundSectionBlocksUpdatePacket t_packet) packetReceived(t_packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected (DisconnectedEvent event) {
|
||||
chunks.clear();
|
||||
}
|
||||
|
||||
private void worldChanged (String dimension) {
|
||||
@@ -53,26 +68,69 @@ public class WorldPlugin extends Bot.Listener {
|
||||
for (Listener listener : listeners) listener.worldChanged(dimension);
|
||||
}
|
||||
|
||||
public void packetReceived (ClientboundRegistryDataPacket packet) {
|
||||
private void packetReceived (ClientboundRegistryDataPacket packet) {
|
||||
if (!packet.getRegistry().value().equals("dimension_type")) return;
|
||||
|
||||
registry = packet.getEntries();
|
||||
}
|
||||
|
||||
public void packetReceived (ClientboundLoginPacket packet) {
|
||||
private void packetReceived (ClientboundLoginPacket packet) {
|
||||
simulationDistance = packet.getSimulationDistance();
|
||||
|
||||
worldChanged(packet.getCommonPlayerSpawnInfo().getWorldName().asString());
|
||||
}
|
||||
|
||||
public void packetReceived (ClientboundRespawnPacket packet) {
|
||||
private void packetReceived (ClientboundRespawnPacket packet) {
|
||||
worldChanged(packet.getCommonPlayerSpawnInfo().getWorldName().asString());
|
||||
}
|
||||
|
||||
public void packetReceived (ClientboundSetSimulationDistancePacket packet) {
|
||||
private void packetReceived (ClientboundSetSimulationDistancePacket packet) {
|
||||
simulationDistance = packet.getSimulationDistance();
|
||||
}
|
||||
|
||||
private void packetReceived (ClientboundLevelChunkWithLightPacket packet) {
|
||||
final ChunkPos pos = new ChunkPos(packet.getX(), packet.getZ());
|
||||
final ChunkColumn column = new ChunkColumn(pos, packet.getChunkData(), maxY, minY);
|
||||
chunks.put(pos, column);
|
||||
}
|
||||
|
||||
private void packetReceived (ClientboundForgetLevelChunkPacket packet) {
|
||||
chunks.remove(new ChunkPos(packet.getX(), packet.getZ()));
|
||||
}
|
||||
|
||||
private void packetReceived (ClientboundBlockUpdatePacket packet) {
|
||||
final Vector3i position = packet.getEntry().getPosition();
|
||||
final int id = packet.getEntry().getBlock();
|
||||
|
||||
setBlock(position.getX(), position.getY(), position.getZ(), id);
|
||||
}
|
||||
|
||||
private void packetReceived (ClientboundSectionBlocksUpdatePacket packet) {
|
||||
for (BlockChangeEntry entry : packet.getEntries()) {
|
||||
final Vector3i position = entry.getPosition();
|
||||
final int id = entry.getBlock();
|
||||
|
||||
setBlock(position.getX(), position.getY(), position.getZ(), id);
|
||||
}
|
||||
}
|
||||
|
||||
public ChunkColumn getChunk (int x, int z) { return chunks.get(new ChunkPos(x, z)); }
|
||||
public ChunkColumn getChunk (ChunkPos pos) { return chunks.get(pos); }
|
||||
public Collection<ChunkColumn> getChunks () { return chunks.values(); }
|
||||
|
||||
public int getBlock (int x, int y, int z) {
|
||||
final ChunkPos chunkPos = new ChunkPos(Math.floorDiv(x, 16), Math.floorDiv(z, 16));
|
||||
final ChunkColumn chunk = chunks.get(chunkPos);
|
||||
return chunk == null ? 0 : chunks.get(chunkPos).getBlock(x & 15, y, z & 15);
|
||||
}
|
||||
|
||||
// should this be public?
|
||||
public void setBlock (int x, int y, int z, int id) {
|
||||
final ChunkPos chunkPos = new ChunkPos(Math.floorDiv(x, 16), Math.floorDiv(z, 16));
|
||||
if (!chunks.containsKey(chunkPos)) return;
|
||||
chunks.get(chunkPos).setBlock(x & 15, y, z & 15, id);
|
||||
}
|
||||
|
||||
public static class Listener {
|
||||
public void worldChanged (String dimension) {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user