Chunk cache improvements (#2053)

- Check for minimum and maximum Y values to fix stack traces
- Don't run half of the villager sleeping code unless they're actually sleeping
This commit is contained in:
Camotoy 2021-03-21 11:31:09 -04:00 committed by GitHub
parent 10c77a3214
commit 86397ef483
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 56 deletions

View file

@ -96,27 +96,25 @@ public class FishingHookEntity extends ThrowableEntity {
boolean touchingWater = false; boolean touchingWater = false;
boolean collided = false; boolean collided = false;
for (Vector3i blockPos : collidableBlocks) { for (Vector3i blockPos : collidableBlocks) {
if (0 <= blockPos.getY() && blockPos.getY() <= 255) { int blockID = session.getConnector().getWorldManager().getBlockAt(session, blockPos);
int blockID = session.getConnector().getWorldManager().getBlockAt(session, blockPos); BlockCollision blockCollision = CollisionTranslator.getCollision(blockID, blockPos.getX(), blockPos.getY(), blockPos.getZ());
BlockCollision blockCollision = CollisionTranslator.getCollision(blockID, blockPos.getX(), blockPos.getY(), blockPos.getZ()); if (blockCollision != null && blockCollision.checkIntersection(boundingBox)) {
if (blockCollision != null && blockCollision.checkIntersection(boundingBox)) { // TODO Push bounding box out of collision to improve movement
// TODO Push bounding box out of collision to improve movement collided = true;
collided = true; }
}
int waterLevel = BlockStateValues.getWaterLevel(blockID); int waterLevel = BlockStateValues.getWaterLevel(blockID);
if (BlockTranslator.isWaterlogged(blockID)) { if (BlockTranslator.isWaterlogged(blockID)) {
waterLevel = 0; waterLevel = 0;
}
if (waterLevel >= 0) {
double waterMaxY = blockPos.getY() + 1 - (waterLevel + 1) / 9.0;
// Falling water is a full block
if (waterLevel >= 8) {
waterMaxY = blockPos.getY() + 1;
} }
if (waterLevel >= 0) { if (position.getY() <= waterMaxY) {
double waterMaxY = blockPos.getY() + 1 - (waterLevel + 1) / 9.0; touchingWater = true;
// Falling water is a full block
if (waterLevel >= 8) {
waterMaxY = blockPos.getY() + 1;
}
if (position.getY() <= waterMaxY) {
touchingWater = true;
}
} }
} }
} }
@ -177,10 +175,8 @@ public class FishingHookEntity extends ThrowableEntity {
*/ */
protected boolean isInAir(GeyserSession session) { protected boolean isInAir(GeyserSession session) {
if (session.getConnector().getConfig().isCacheChunks()) { if (session.getConnector().getConfig().isCacheChunks()) {
if (0 <= position.getFloorY() && position.getFloorY() <= 255) { int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt()); return block == BlockTranslator.JAVA_AIR_ID;
return block == BlockTranslator.JAVA_AIR_ID;
}
} }
return false; return false;
} }

View file

@ -26,7 +26,6 @@
package org.geysermc.connector.entity.living.merchant; package org.geysermc.connector.entity.living.merchant;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.VillagerData; import com.github.steveice10.mc.protocol.data.game.entity.metadata.VillagerData;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.math.vector.Vector3i; import com.nukkitx.math.vector.Vector3i;
@ -101,11 +100,17 @@ public class VillagerEntity extends AbstractMerchantEntity {
@Override @Override
public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) { public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) {
if (!metadata.getFlags().getFlag(EntityFlag.SLEEPING)) {
// No need to worry about extra processing to compensate for sleeping
super.moveRelative(session, relX, relY, relZ, rotation, isOnGround);
return;
}
int z = 0; int z = 0;
int bedId = 0; int bedId = 0;
float bedPositionSubtractorW = 0; float bedPositionSubtractorW = 0;
float bedPositionSubtractorN = 0; float bedPositionSubtractorN = 0;
Vector3i bedPosition = metadata.getPos(EntityData.BED_POSITION); Vector3i bedPosition = metadata.getPos(EntityData.BED_POSITION, null);
if (session.getConnector().getConfig().isCacheChunks() && bedPosition != null) { if (session.getConnector().getConfig().isCacheChunks() && bedPosition != null) {
bedId = session.getConnector().getWorldManager().getBlockAt(session, bedPosition); bedId = session.getConnector().getWorldManager().getBlockAt(session, bedPosition);
} }
@ -117,39 +122,33 @@ public class VillagerEntity extends AbstractMerchantEntity {
MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket(); MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket();
moveEntityPacket.setRuntimeEntityId(geyserId); moveEntityPacket.setRuntimeEntityId(geyserId);
//Sets Villager position and rotation when sleeping //Sets Villager position and rotation when sleeping
if (!metadata.getFlags().getFlag(EntityFlag.SLEEPING)) { Pattern r = Pattern.compile("facing=([a-z]+)");
moveEntityPacket.setPosition(position); Matcher m = r.matcher(bedRotationZ);
moveEntityPacket.setRotation(getBedrockRotation()); if (m.find()) {
} else { switch (m.group(0)) {
//String Setup case "facing=south":
Pattern r = Pattern.compile("facing=([a-z]+)"); //bed is facing south
Matcher m = r.matcher(bedRotationZ); z = 180;
if (m.find()) { bedPositionSubtractorW = -.5f;
switch (m.group(0)) { break;
case "facing=south": case "facing=east":
//bed is facing south //bed is facing east
z = 180; z = 90;
bedPositionSubtractorW = -.5f; bedPositionSubtractorW = -.5f;
break; break;
case "facing=east": case "facing=west":
//bed is facing east //bed is facing west
z = 90; z = 270;
bedPositionSubtractorW = -.5f; bedPositionSubtractorW = .5f;
break; break;
case "facing=west": case "facing=north":
//bed is facing west //rotation does not change because north is 0
z = 270; bedPositionSubtractorN = .5f;
bedPositionSubtractorW = .5f; break;
break;
case "facing=north":
//rotation does not change because north is 0
bedPositionSubtractorN = .5f;
break;
}
} }
moveEntityPacket.setRotation(Vector3f.from(0, 0, z));
moveEntityPacket.setPosition(Vector3f.from(position.getX() + bedPositionSubtractorW, position.getY(), position.getZ() + bedPositionSubtractorN));
} }
moveEntityPacket.setRotation(Vector3f.from(0, 0, z));
moveEntityPacket.setPosition(Vector3f.from(position.getX() + bedPositionSubtractorW, position.getY(), position.getZ() + bedPositionSubtractorN));
moveEntityPacket.setOnGround(isOnGround); moveEntityPacket.setOnGround(isOnGround);
moveEntityPacket.setTeleported(false); moveEntityPacket.setTeleported(false);
session.sendUpstreamPacket(moveEntityPacket); session.sendUpstreamPacket(moveEntityPacket);

View file

@ -34,6 +34,7 @@ import org.geysermc.connector.network.translators.world.block.BlockTranslator;
import org.geysermc.connector.utils.MathUtils; import org.geysermc.connector.utils.MathUtils;
public class ChunkCache { public class ChunkCache {
private static final int MINIMUM_WORLD_HEIGHT = 0;
private final boolean cache; private final boolean cache;
@ -86,6 +87,11 @@ public class ChunkCache {
return; return;
} }
if (y < MINIMUM_WORLD_HEIGHT || (y >> 4) > column.getChunks().length - 1) {
// Y likely goes above or below the height limit of this world
return;
}
Chunk chunk = column.getChunks()[y >> 4]; Chunk chunk = column.getChunks()[y >> 4];
if (chunk != null) { if (chunk != null) {
chunk.set(x & 0xF, y & 0xF, z & 0xF, block); chunk.set(x & 0xF, y & 0xF, z & 0xF, block);
@ -102,6 +108,11 @@ public class ChunkCache {
return BlockTranslator.JAVA_AIR_ID; return BlockTranslator.JAVA_AIR_ID;
} }
if (y < MINIMUM_WORLD_HEIGHT || (y >> 4) > column.getChunks().length - 1) {
// Y likely goes above or below the height limit of this world
return BlockTranslator.JAVA_AIR_ID;
}
Chunk chunk = column.getChunks()[y >> 4]; Chunk chunk = column.getChunks()[y >> 4];
if (chunk != null) { if (chunk != null) {
return chunk.get(x & 0xF, y & 0xF, z & 0xF); return chunk.get(x & 0xF, y & 0xF, z & 0xF);