Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/main/java/cn/nukkit/AdventureSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ void update(boolean reset) {
layer.getAbilityValues().add(PlayerAbility.OPERATOR_COMMANDS);
}

layer.setWalkSpeed(Player.DEFAULT_SPEED);
layer.setFlySpeed(Player.DEFAULT_FLY_SPEED);
layer.setVerticalFlySpeed(1.0f);
layer.setWalkSpeed(player.getWalkSpeed());
layer.setFlySpeed(player.getFlySpeed());
layer.setVerticalFlySpeed(player.getVerticalFlySpeed());
packet.getAbilityLayers().add(layer);

if (player.isSpectator()) {
Expand Down
60 changes: 39 additions & 21 deletions src/main/java/cn/nukkit/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,15 @@
import com.google.common.base.Strings;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Sets;
import io.netty.util.internal.PlatformDependent;
import it.unimi.dsi.fastutil.bytes.ByteOpenHashSet;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.longs.*;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongIterator;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import lombok.Getter;
import lombok.Setter;
Expand All @@ -90,10 +93,10 @@
import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.nio.ByteOrder;
import java.util.List;
import java.util.*;
import java.util.Queue;
import java.util.List;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
Expand Down Expand Up @@ -125,6 +128,7 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
public static final float DEFAULT_SPEED = 0.1f;
public static final float MAXIMUM_SPEED = 6f; // TODO: Decrease when block collisions are fixed
public static final float DEFAULT_FLY_SPEED = 0.05f;
public static final float DEFAULT_VERTICAL_FLY_SPEED = 1f;

public static final int PERMISSION_CUSTOM = 3;
public static final int PERMISSION_OPERATOR = 2;
Expand Down Expand Up @@ -178,7 +182,7 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
protected Vector3 teleportPosition;
protected Vector3 newPosition;
protected Vector3 sleeping;
private Vector3 lastRightClickPos;
private BlockVector3 lastRightClickPos;
private final Queue<Vector3> clientMovements = PlatformDependent.newMpscQueue(4);

protected boolean connected = true;
Expand Down Expand Up @@ -215,6 +219,24 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
@Getter
@Setter
private boolean canTickShield = true;
/**
* Player's client-side walk speed. Remember to call getAdventureSettings().update() if changed.
*/
@Getter
@Setter
private float walkSpeed = DEFAULT_SPEED;
/**
* Player's client-side fly speed. Remember to call getAdventureSettings().update() if changed.
*/
@Getter
@Setter
private float flySpeed = DEFAULT_FLY_SPEED;
/**
* Player's client-side vertical fly speed. Remember to call getAdventureSettings().update() if changed.
*/
@Getter
@Setter
private float verticalFlySpeed = DEFAULT_VERTICAL_FLY_SPEED;

private int exp;
private int expLevel;
Expand Down Expand Up @@ -296,7 +318,7 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
/**
* Packets that can be received before the player has logged in
*/
private static final Set<Byte> PRE_LOGIN_PACKETS = Sets.newHashSet(ProtocolInfo.BATCH_PACKET, ProtocolInfo.LOGIN_PACKET, ProtocolInfo.REQUEST_NETWORK_SETTINGS_PACKET, ProtocolInfo.REQUEST_CHUNK_RADIUS_PACKET, ProtocolInfo.SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET, ProtocolInfo.RESOURCE_PACK_CHUNK_REQUEST_PACKET, ProtocolInfo.RESOURCE_PACK_CLIENT_RESPONSE_PACKET, ProtocolInfo.CLIENT_CACHE_STATUS_PACKET, ProtocolInfo.PACKET_VIOLATION_WARNING_PACKET, ProtocolInfo.CLIENT_TO_SERVER_HANDSHAKE_PACKET);
private static final ByteOpenHashSet PRE_LOGIN_PACKETS = new ByteOpenHashSet(new byte[]{ProtocolInfo.BATCH_PACKET, ProtocolInfo.LOGIN_PACKET, ProtocolInfo.REQUEST_NETWORK_SETTINGS_PACKET, ProtocolInfo.REQUEST_CHUNK_RADIUS_PACKET, ProtocolInfo.SET_LOCAL_PLAYER_AS_INITIALIZED_PACKET, ProtocolInfo.RESOURCE_PACK_CHUNK_REQUEST_PACKET, ProtocolInfo.RESOURCE_PACK_CLIENT_RESPONSE_PACKET, ProtocolInfo.CLIENT_CACHE_STATUS_PACKET, ProtocolInfo.PACKET_VIOLATION_WARNING_PACKET, ProtocolInfo.CLIENT_TO_SERVER_HANDSHAKE_PACKET});
/**
* Default kick message for flying
*/
Expand Down Expand Up @@ -4197,7 +4219,6 @@ public void onCompletion(Server server) {
UseItemData useItemData = (UseItemData) transactionPacket.transactionData;
BlockVector3 blockVector = useItemData.blockPos;
BlockFace face = useItemData.face;
int type = useItemData.actionType;

this.setShieldBlockingDelay(5);

Expand All @@ -4209,14 +4230,14 @@ public void onCompletion(Server server) {
itemSent = true; // Assume that the item is still correct even if the selected slot is not
}

switch (type) {
switch (useItemData.actionType) {
case InventoryTransactionPacket.USE_ITEM_ACTION_CLICK_BLOCK:
// Hack: Fix client spamming right clicks
if ((lastRightClickPos != null && this.getInventory().getItemInHandFast().getBlockId() == BlockID.AIR && System.currentTimeMillis() - lastRightClickTime < 200.0 && blockVector.distanceSquared(lastRightClickPos) < 0.00001)) {
return;
}

lastRightClickPos = blockVector.asVector3();
lastRightClickPos = blockVector;
lastRightClickTime = System.currentTimeMillis();

this.breakingBlock = null;
Expand Down Expand Up @@ -4366,17 +4387,15 @@ public void onCompletion(Server server) {
return;
}

type = useItemOnEntityData.actionType;

if (inventory.getHeldItemIndex() != useItemOnEntityData.hotbarSlot) {
inventory.equipItem(useItemOnEntityData.hotbarSlot);
}

item = this.inventory.getItemInHand();

switch (type) {
switch (useItemOnEntityData.actionType) {
case InventoryTransactionPacket.USE_ITEM_ON_ENTITY_ACTION_INTERACT:
if (this.distanceSquared(target) > 1000) {
if (this.distanceSquared(target) > 256) { // TODO: Note entity scale
this.getServer().getLogger().debug(username + ": target entity is too far away");
return;
}
Expand Down Expand Up @@ -4513,8 +4532,7 @@ public void onCompletion(Server server) {
ReleaseItemData releaseItemData = (ReleaseItemData) transactionPacket.transactionData;

try {
type = releaseItemData.actionType;
switch (type) {
switch (releaseItemData.actionType) {
case InventoryTransactionPacket.RELEASE_ITEM_ACTION_RELEASE:
if (this.isUsingItem()) {
int ticksUsed = this.server.getTick() - this.startAction;
Expand All @@ -4529,7 +4547,7 @@ public void onCompletion(Server server) {
case InventoryTransactionPacket.RELEASE_ITEM_ACTION_CONSUME:
return;
default:
this.getServer().getLogger().debug(username + ": unknown release item action type: " + type);
this.getServer().getLogger().debug(username + ": unknown release item action type: " + releaseItemData.actionType);
}
} finally {
this.setUsingItem(false);
Expand Down Expand Up @@ -4687,12 +4705,11 @@ public void onCompletion(Server server) {
}

LecternUpdatePacket lecternUpdatePacket = (LecternUpdatePacket) packet;
Vector3 lecternPos = lecternUpdatePacket.blockPosition.asVector3();
if (lecternPos.distanceSquared(this) > 4096) {
if (lecternUpdatePacket.blockPosition.distanceSquared(this) > 4096) {
return;
}
if (!lecternUpdatePacket.dropBook) {
BlockEntity blockEntityLectern = this.level.getBlockEntityIfLoaded(this.chunk, lecternPos);
BlockEntity blockEntityLectern = this.level.getBlockEntityIfLoaded(this.chunk, lecternUpdatePacket.blockPosition.asVector3());
if (blockEntityLectern instanceof BlockEntityLectern) {
BlockEntityLectern lectern = (BlockEntityLectern) blockEntityLectern;
if (lectern.getRawPage() != lecternUpdatePacket.page) {
Expand Down Expand Up @@ -4917,8 +4934,9 @@ private void onBlockBreakComplete(BlockVector3 blockPos, BlockFace face) { // Fr
}
this.needSendHeldItem = true;
if (blockPos.distanceSquared(this) < 10000) {
this.level.sendBlocks(this, new Block[]{this.level.getBlock(blockPos.asVector3(), false)}, UpdateBlockPacket.FLAG_ALL_PRIORITY);
BlockEntity blockEntity = this.level.getBlockEntityIfLoaded(this.chunk, blockPos.asVector3());
Vector3 pos = blockPos.asVector3();
this.level.sendBlocks(this, new Block[]{this.level.getBlock(pos, false)}, UpdateBlockPacket.FLAG_ALL_PRIORITY);
BlockEntity blockEntity = this.level.getBlockEntityIfLoaded(this.chunk, pos);
if (blockEntity instanceof BlockEntitySpawnable) {
((BlockEntitySpawnable) blockEntity).spawnTo(this);
}
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/cn/nukkit/block/Block.java
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@ public Block getSide(BlockLayer layer, BlockFace face, int step) {
if (this.isValid()) {
return this.getLevel().getBlock(super.getSide(face, step), layer, true);
}
return Block.get(AIR, 0, Position.fromObject(new Vector3(this.x, this.y, this.z).getSide(face, step)), layer);
return Block.get(AIR, 0, Position.fromObject(this.getSideVec(face, step)), layer);
}

protected Block getSideIfLoaded(BlockFace face) {
Expand All @@ -649,7 +649,7 @@ protected Block getSideIfLoaded(BlockFace face) {
(int) this.x + face.getXOffset(), (int) this.y + face.getYOffset(), (int) this.z + face.getZOffset(),
BlockLayer.NORMAL, false);
}
return Block.get(AIR, 0, Position.fromObject(new Vector3(this.x, this.y, this.z).getSide(face, 1)), BlockLayer.NORMAL);
return Block.get(AIR, 0, Position.fromObject(this.getSideVec(face, 1)), BlockLayer.NORMAL);
}

protected Block getSideIfLoadedOrNull(BlockFace face) {
Expand All @@ -667,7 +667,7 @@ protected Block getSideIfLoadedOrNull(BlockFace face) {
BlockLayer.NORMAL, false);
}

return Block.get(AIR, 0, Position.fromObject(new Vector3(this.x, this.y, this.z).getSide(face, 1)), BlockLayer.NORMAL);
return Block.get(AIR, 0, Position.fromObject(this.getSideVec(face, 1)), BlockLayer.NORMAL);
}

public Block up() {
Expand Down
13 changes: 8 additions & 5 deletions src/main/java/cn/nukkit/block/BlockCactus.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.math.AxisAlignedBB;
import cn.nukkit.math.BlockFace;
import cn.nukkit.math.SimpleAxisAlignedBB;
import cn.nukkit.utils.BlockColor;

/**
Expand Down Expand Up @@ -45,7 +47,7 @@ public boolean hasEntityCollision() {
return true;
}

/*@Override
@Override
public double getMinX() {
return this.x + 0.0625;
}
Expand All @@ -63,11 +65,12 @@ public double getMaxX() {
@Override
public double getMaxZ() {
return this.z + 0.9375;
}*/
}

// Hack: Fix entity collisions
// No need for separate collision box
// Y-collisions need another fix anyway
@Override
protected AxisAlignedBB recalculateCollisionBoundingBox() {
return new SimpleAxisAlignedBB(x, y, z, x + 1, y + 1, z + 1);
}

@Override
public double getMaxY() {
Expand Down
5 changes: 0 additions & 5 deletions src/main/java/cn/nukkit/block/BlockCampfire.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,6 @@ public int getToolType() {
return ItemTool.TYPE_AXE;
}

@Override
public boolean canHarvestWithHand() {
return false;
}

@Override
public Item[] getDrops(Item item) {
return new Item[] {Item.get(ItemID.COAL, 0, 1 + ThreadLocalRandom.current().nextInt(1))};
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/cn/nukkit/block/BlockChorusFlower.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
import cn.nukkit.Player;
import cn.nukkit.Server;
import cn.nukkit.entity.Entity;
import cn.nukkit.entity.item.EntityFirework;
import cn.nukkit.entity.projectile.EntityArrow;
import cn.nukkit.entity.projectile.EntityEgg;
import cn.nukkit.entity.projectile.EntitySnowball;
import cn.nukkit.entity.projectile.EntityThrownTrident;
import cn.nukkit.event.block.BlockGrowEvent;
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemBlock;
Expand Down Expand Up @@ -194,9 +197,15 @@ public Item toItem() {
return new ItemBlock(Block.get(this.getId(), 0), 0);
}

@Override
public boolean hasEntityCollision() {
return true;
}

@Override
public void onEntityCollide(Entity entity) {
if (entity instanceof EntityArrow || entity instanceof EntitySnowball) {
int e = entity.getNetworkId();
if (e == EntityArrow.NETWORK_ID || e == EntityThrownTrident.NETWORK_ID || e == EntityFirework.NETWORK_ID || e == EntitySnowball.NETWORK_ID || e == EntityEgg.NETWORK_ID || e == 85 || e == 94 || e == 79 || e == 89) {
entity.close();
this.getLevel().useBreakOn(this);
}
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/cn/nukkit/block/BlockJukebox.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,15 @@ public BlockColor getColor() {
public boolean canBePushed() {
return false;
}

@Override
public boolean hasComparatorInputOverride() {
return true;
}

@Override
public int getComparatorInputOverride() {
BlockEntity blockEntity = this.getLevel().getBlockEntityIfLoaded(this);
return blockEntity instanceof BlockEntityJukebox ? ((BlockEntityJukebox) blockEntity).getComparatorSignal() : 0;
}
}
4 changes: 4 additions & 0 deletions src/main/java/cn/nukkit/block/BlockLeaves.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ public Item[] getDrops(Item item) {
@Override
public int onUpdate(int type) {
if (type == Level.BLOCK_UPDATE_NORMAL && !isPersistent() && !isCheckDecay()) {
if (this.level.getBlockIdAt((int) this.x, (int) this.y, (int) this.z) != this.getId()) {
return 0;
}

setCheckDecay(true);
getLevel().setBlock((int) this.x, (int) this.y, (int) this.z, BlockLayer.NORMAL, this, false, false, false); // No need to send this to client

Expand Down
54 changes: 39 additions & 15 deletions src/main/java/cn/nukkit/block/BlockLectern.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import cn.nukkit.item.Item;
import cn.nukkit.item.ItemID;
import cn.nukkit.item.ItemTool;
import cn.nukkit.level.Level;
import cn.nukkit.math.BlockFace;
import cn.nukkit.math.NukkitMath;
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.network.protocol.ContainerOpenPacket;
import cn.nukkit.network.protocol.LevelSoundEventPacket;
Expand Down Expand Up @@ -80,21 +82,6 @@ public BlockFace getBlockFace() {
return BlockFace.fromHorizontalIndex(getDamage() & 0b11);
}

public boolean dropBook() {
BlockEntity blockEntity = this.getLevel().getBlockEntity(this);
if (blockEntity instanceof BlockEntityLectern) {
BlockEntityLectern lectern = (BlockEntityLectern) blockEntity;
Item book = lectern.getBook();
if (book.getId() != BlockID.AIR) {
lectern.setBook(Item.get(BlockID.AIR));
lectern.spawnToAll();
this.level.dropItem(lectern.add(0.5f, 1, 0.5f), book);
return true;
}
}
return false;
}

@Override
public boolean isPowerSource() {
return true;
Expand Down Expand Up @@ -167,4 +154,41 @@ public boolean onActivate(Item item, Player player) {
public boolean canBePushed() {
return false; // prevent item loss issue with pistons until a working implementation
}

@Override
public boolean hasComparatorInputOverride() {
return true;
}

@Override
public int getComparatorInputOverride() {
int power = 0;
BlockEntity lectern = level.getBlockEntityIfLoaded(this);
if (lectern instanceof BlockEntityLectern && ((BlockEntityLectern) lectern).hasBook()) {
int currentPage = ((BlockEntityLectern) lectern).getLeftPage();
int totalPages = ((BlockEntityLectern) lectern).getTotalPages();
power = NukkitMath.floorDouble(1 + ((double) (currentPage - 1) / (totalPages - 1)) * 14);
}
return power;
}

public void onPageChange(boolean active) {
if (isActivated() != active) {
setActivated(active);
level.setBlock((int) this.x, (int) this.y, (int) this.z, BlockLayer.NORMAL, this, false, false, false); // No need to send this to client
level.updateAroundRedstone(this, null);
if (active) {
level.scheduleUpdate(this, 1);
}
}
}

@Override
public int onUpdate(int type) {
if (type == Level.BLOCK_UPDATE_SCHEDULED || type == Level.BLOCK_UPDATE_NORMAL) {
onPageChange(false);
}

return 0;
}
}
Loading
Loading