Clean ups

This commit is contained in:
Brady 2019-12-19 11:40:38 -06:00
parent ea8d7fb3b9
commit aa3bd80ab2
No known key found for this signature in database
GPG Key ID: 73A788379A197567
3 changed files with 120 additions and 35 deletions

View File

@ -65,7 +65,7 @@ public class MapArtSchematic extends AbstractSchematic {
@Override
public boolean inSchematic(int x, int y, int z, IBlockState currentState) {
// in map art, we only care about coordinates in or above the art
return super.inSchematic(x, y, z, currentState) && y >= heightMap[x][z];
return this.child.inSchematic(x, y, z, currentState) && y >= heightMap[x][z];
}
@Override

View File

@ -19,16 +19,14 @@ package baritone.utils.schematic.parse;
import baritone.api.schematic.AbstractSchematic;
import baritone.api.schematic.ISchematic;
import baritone.api.utils.BlockOptionalMeta;
import baritone.utils.schematic.format.SchematicFormat;
import io.netty.buffer.Unpooled;
import baritone.utils.type.VarInt;
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import net.minecraft.block.Block;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.ResourceLocation;
import java.io.IOException;
@ -97,17 +95,18 @@ public enum SpongeParser implements ISchematicParser {
palette.put(index, state);
}
// BlockData is stored as an NBT byte[], however, the actual data that is represented is a varint[].
// This is kind of a hacky approach but it works /shrug
// BlockData is stored as an NBT byte[], however, the actual data that is represented is a varint[]
byte[] rawBlockData = nbt.getByteArray("BlockData");
int[] blockData = new int[this.x * this.y * this.z];
PacketBuffer buffer = new PacketBuffer(Unpooled.wrappedBuffer(rawBlockData));
int offset = 0;
for (int i = 0; i < blockData.length; i++) {
if (buffer.readableBytes() > 0) {
blockData[i] = buffer.readVarInt();
} else {
throw new IllegalArgumentException("Buffer has no remaining bytes");
if (offset >= blockData.length) {
throw new IllegalArgumentException("No remaining bytes in BlockData for complete schematic");
}
VarInt varInt = VarInt.read(rawBlockData, offset);
blockData[i] = varInt.getValue();
offset += varInt.getSize();
}
for (int y = 0; y < this.y; y++) {
@ -144,35 +143,18 @@ public enum SpongeParser implements ISchematicParser {
this.properties = properties;
}
ResourceLocation getResourceLocation() {
return this.resourceLocation;
}
Map<String, String> getProperties() {
return this.properties;
}
IBlockState deserialize() {
if (this.blockState == null) {
// Get the base state for the block specified
this.blockState = Block.REGISTRY.getObject(this.resourceLocation).getDefaultState();
Block block = Block.REGISTRY.getObject(this.resourceLocation);
this.blockState = block.getDefaultState();
// AFAIK it is best to order the property keys so that Minecraft caches the Block States ideally
this.properties.keySet().stream().sorted(String::compareTo).forEachOrdered(key -> {
// getProperty(String) when lol
IProperty<?> property = this.blockState.getPropertyKeys().stream()
.filter(p -> p.getName().equals(key))
.findFirst().orElseThrow(IllegalArgumentException::new);
Optional<?> value = property.parseValue(this.properties.get(key)).toJavaUtil();
if (value.isPresent()) {
this.blockState = this.blockState.withProperty(
BlockOptionalMeta.castToIProperty(property),
BlockOptionalMeta.castToIPropertyValue(property, value)
);
} else {
throw new IllegalArgumentException();
IProperty<?> property = block.getBlockState().getProperty(key);
if (property == null) {
throw new IllegalArgumentException("Invalid property");
}
this.blockState = setPropertyValue(this.blockState, property, this.properties.get(key));
});
}
return this.blockState;
@ -203,5 +185,14 @@ public enum SpongeParser implements ISchematicParser {
return null;
}
}
private static <T extends Comparable<T>> IBlockState setPropertyValue(IBlockState state, IProperty<T> property, String value) {
Optional<T> parsed = property.parseValue(value).toJavaUtil();
if (parsed.isPresent()) {
return state.withProperty(property, parsed.get());
} else {
throw new IllegalArgumentException("Invalid value for property " + property);
}
}
}
}

View File

@ -0,0 +1,94 @@
/*
* 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.utils.type;
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
import it.unimi.dsi.fastutil.bytes.ByteList;
/**
* @author Brady
* @since 12/19/2019
*/
public final class VarInt {
private final int value;
private final byte[] serialized;
private final int size;
public VarInt(int value) {
this.value = value;
this.serialized = serialize0(this.value);
this.size = this.serialized.length;
}
/**
* @return The integer value that is represented by this {@link VarInt}.
*/
public final int getValue() {
return this.value;
}
/**
* @return The size of this {@link VarInt}, in bytes, once serialized.
*/
public final int getSize() {
return this.size;
}
public final byte[] serialize() {
return this.serialized;
}
private static byte[] serialize0(int value) {
ByteList bytes = new ByteArrayList();
while ((value & 0xFF) != 0) {
bytes.add((byte) (value & 0x7F | 0x80));
value >>>= 7;
}
bytes.add((byte) (value & 0xFF));
return bytes.toByteArray();
}
public static VarInt read(byte[] bytes) {
return read(bytes, 0);
}
public static VarInt read(byte[] bytes, int start) {
int value = 0;
int size = 0;
int index = start;
while (true) {
byte b = bytes[index++];
value |= (b & 0x7F) << size++ * 7;
if (size > 5) {
throw new IllegalArgumentException("VarInt size cannot exceed 5 bytes");
}
// Most significant bit denotes another byte is to be read.
if ((b & 0x80) != 0x80) {
break;
}
}
return new VarInt(value);
}
}