Merge branch 'master' into command-suggestion

This commit is contained in:
themode 2021-03-09 22:51:29 +01:00
commit 94526b218f
12 changed files with 131 additions and 78 deletions

View File

@ -13,9 +13,19 @@ public class Attribute {
private static final Map<String, Attribute> ATTRIBUTES = new HashMap<>();
static {
Attributes.init();
}
public static final Attribute MAX_HEALTH = (new Attribute("generic.max_health", true, 20, 1024)).register();
public static final Attribute FOLLOW_RANGE = (new Attribute("generic.follow_range", true, 32, 2048)).register();
public static final Attribute KNOCKBACK_RESISTANCE = (new Attribute("generic.knockback_resistance", true, 0, 1)).register();
public static final Attribute MOVEMENT_SPEED = (new Attribute("generic.movement_speed", true, 0.25f, 1024)).register();
public static final Attribute ATTACK_DAMAGE = (new Attribute("generic.attack_damage", true, 2, 2048)).register();
public static final Attribute ATTACK_SPEED = (new Attribute("generic.attack_speed", true, 4, 1024)).register();
public static final Attribute FLYING_SPEED = (new Attribute("generic.flying_speed", true, 0.4f, 1024)).register();
public static final Attribute ARMOR = (new Attribute("generic.armor", true, 0, 30)).register();
public static final Attribute ARMOR_TOUGHNESS = (new Attribute("generic.armor_toughness", true, 0, 20)).register();
public static final Attribute ATTACK_KNOCKBACK = (new Attribute("generic.attack_knockback", true, 0, 5)).register();
public static final Attribute LUCK = (new Attribute("generic.luck", true, 0, 1024)).register();
public static final Attribute HORSE_JUMP_STRENGTH = (new Attribute("horse.jump_strength", true, 0.7f, 2)).register();
public static final Attribute ZOMBIE_SPAWN_REINFORCEMENTS = (new Attribute("zombie.spawn_reinforcements", true, 0, 1)).register();
private final String key;
private final float defaultValue;

View File

@ -2,22 +2,25 @@ package net.minestom.server.attribute;
/**
* The Minecraft, vanilla, standards attributes.
*
* @deprecated use the constants in {@link Attribute}
*/
@Deprecated
public final class Attributes {
public static final Attribute MAX_HEALTH = (new Attribute("generic.max_health", true, 20, 1024)).register();
public static final Attribute FOLLOW_RANGE = (new Attribute("generic.follow_range", true, 32, 2048)).register();
public static final Attribute KNOCKBACK_RESISTANCE = (new Attribute("generic.knockback_resistance", true, 0, 1)).register();
public static final Attribute MOVEMENT_SPEED = (new Attribute("generic.movement_speed", true, 0.25f, 1024)).register();
public static final Attribute ATTACK_DAMAGE = (new Attribute("generic.attack_damage", true, 2, 2048)).register();
public static final Attribute ATTACK_SPEED = (new Attribute("generic.attack_speed", true, 4, 1024)).register();
public static final Attribute FLYING_SPEED = (new Attribute("generic.flying_speed", true, 0.4f, 1024)).register();
public static final Attribute ARMOR = (new Attribute("generic.armor", true, 0, 30)).register();
public static final Attribute ARMOR_TOUGHNESS = (new Attribute("generic.armor_toughness", true, 0, 20)).register();
public static final Attribute ATTACK_KNOCKBACK = (new Attribute("generic.attack_knockback", true, 0, 5)).register();
public static final Attribute LUCK = (new Attribute("generic.luck", true, 0, 1024)).register();
public static final Attribute HORSE_JUMP_STRENGTH = (new Attribute("horse.jump_strength", true, 0.7f, 2)).register();
public static final Attribute ZOMBIE_SPAWN_REINFORCEMENTS = (new Attribute("zombie.spawn_reinforcements", true, 0, 1)).register();
public static final Attribute MAX_HEALTH = Attribute.MAX_HEALTH;
public static final Attribute FOLLOW_RANGE = Attribute.FOLLOW_RANGE;
public static final Attribute KNOCKBACK_RESISTANCE = Attribute.KNOCKBACK_RESISTANCE;
public static final Attribute MOVEMENT_SPEED = Attribute.MOVEMENT_SPEED;
public static final Attribute ATTACK_DAMAGE = Attribute.ATTACK_DAMAGE;
public static final Attribute ATTACK_SPEED = Attribute.ATTACK_SPEED;
public static final Attribute FLYING_SPEED = Attribute.FLYING_SPEED;
public static final Attribute ARMOR = Attribute.ARMOR;
public static final Attribute ARMOR_TOUGHNESS = Attribute.ARMOR_TOUGHNESS;
public static final Attribute ATTACK_KNOCKBACK = Attribute.ATTACK_KNOCKBACK;
public static final Attribute LUCK = Attribute.LUCK;
public static final Attribute HORSE_JUMP_STRENGTH = Attribute.HORSE_JUMP_STRENGTH;
public static final Attribute ZOMBIE_SPAWN_REINFORCEMENTS = Attribute.ZOMBIE_SPAWN_REINFORCEMENTS;
private Attributes() throws IllegalAccessException {
throw new IllegalAccessException("Cannot instantiate a static class");

View File

@ -1,11 +1,9 @@
package net.minestom.server.entity;
import com.extollit.gaming.ai.path.HydrazinePathFinder;
import net.minestom.server.attribute.Attributes;
import net.minestom.server.attribute.Attribute;
import net.minestom.server.entity.ai.EntityAI;
import net.minestom.server.entity.ai.EntityAIGroup;
import net.minestom.server.entity.ai.GoalSelector;
import net.minestom.server.entity.ai.TargetSelector;
import net.minestom.server.entity.pathfinding.NavigableEntity;
import net.minestom.server.entity.pathfinding.Navigator;
import net.minestom.server.event.entity.EntityAttackEvent;
@ -15,7 +13,10 @@ import net.minestom.server.utils.time.TimeUnit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
public class EntityCreature extends LivingEntity implements NavigableEntity, EntityAI {
@ -59,7 +60,7 @@ public class EntityCreature extends LivingEntity implements NavigableEntity, Ent
aiTick(time);
// Path finding
this.navigator.tick(getAttributeValue(Attributes.MOVEMENT_SPEED));
this.navigator.tick(getAttributeValue(Attribute.MOVEMENT_SPEED));
// Fire, item pickup, ...
super.update(time);

View File

@ -457,7 +457,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
* @return the entity max health
*/
public float getMaxHealth() {
return getAttributeValue(Attributes.MAX_HEALTH);
return getAttributeValue(Attribute.MAX_HEALTH);
}
/**
@ -466,7 +466,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
* Retrieved from {@link #getAttributeValue(Attribute)} with the attribute {@link Attributes#MAX_HEALTH}.
*/
public void heal() {
setHealth(getAttributeValue(Attributes.MAX_HEALTH));
setHealth(getAttributeValue(Attribute.MAX_HEALTH));
}
/**

View File

@ -3,8 +3,8 @@ package net.minestom.server.entity;
import com.google.common.collect.Queues;
import net.minestom.server.MinecraftServer;
import net.minestom.server.advancements.AdvancementTab;
import net.minestom.server.attribute.Attribute;
import net.minestom.server.attribute.AttributeInstance;
import net.minestom.server.attribute.Attributes;
import net.minestom.server.bossbar.BossBar;
import net.minestom.server.chat.ChatParser;
import net.minestom.server.chat.ColoredText;
@ -179,7 +179,7 @@ public class Player extends LivingEntity implements CommandSender {
this.gameMode = GameMode.SURVIVAL;
this.dimensionType = DimensionType.OVERWORLD; // Default dimension
this.levelFlat = true;
getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.1f);
getAttribute(Attribute.MOVEMENT_SPEED).setBaseValue(0.1f);
// FakePlayer init its connection there
playerConnectionInit();
@ -709,10 +709,7 @@ public class Player extends LivingEntity implements CommandSender {
teleport(spawnPosition);
} else if (updateChunks) {
// Send newly visible chunks to player once spawned in the instance
final Chunk chunk = getChunk();
if (chunk != null) {
refreshVisibleChunks(chunk);
}
refreshVisibleChunks();
}
if (dimensionChange || firstSpawn) {
@ -1549,6 +1546,13 @@ public class Player extends LivingEntity implements CommandSender {
}
}
public void refreshVisibleChunks() {
final Chunk chunk = getChunk();
if (chunk != null) {
refreshVisibleChunks(chunk);
}
}
/**
* Refreshes the list of entities that the player should be able to see based on {@link MinecraftServer#getEntityViewDistance()}
* and {@link Entity#isAutoViewable()}.
@ -2322,11 +2326,15 @@ public class Player extends LivingEntity implements CommandSender {
* based on which one is the lowest
*/
public int getChunkRange() {
final int serverRange = MinecraftServer.getChunkViewDistance();
final int playerRange = getSettings().viewDistance;
if (playerRange == 0) {
return serverRange; // Didn't receive settings packet yet (is the case on login)
if (playerRange < 1) {
// Didn't receive settings packet yet (is the case on login)
// In this case we send the smallest amount of chunks possible
// Will be updated in PlayerSettings#refresh.
// Non-compliant clients might also be stuck with this view
return 1;
} else {
final int serverRange = MinecraftServer.getChunkViewDistance();
return Math.min(playerRange, serverRange);
}
}
@ -2585,7 +2593,7 @@ public class Player extends LivingEntity implements CommandSender {
public void refresh(String locale, byte viewDistance, ChatMode chatMode, boolean chatColors,
byte displayedSkinParts, MainHand mainHand) {
final boolean viewDistanceChanged = !firstRefresh && this.viewDistance != viewDistance;
final boolean viewDistanceChanged = this.viewDistance != viewDistance;
this.locale = locale;
this.viewDistance = viewDistance;
@ -2600,10 +2608,7 @@ public class Player extends LivingEntity implements CommandSender {
// Client changed his view distance in the settings
if (viewDistanceChanged) {
final Chunk playerChunk = getChunk();
if (playerChunk != null) {
refreshVisibleChunks(playerChunk);
}
refreshVisibleChunks();
}
}

View File

@ -2,7 +2,7 @@ package net.minestom.server.entity.fakeplayer;
import com.extollit.gaming.ai.path.HydrazinePathFinder;
import net.minestom.server.MinecraftServer;
import net.minestom.server.attribute.Attributes;
import net.minestom.server.attribute.Attribute;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.pathfinding.NavigableEntity;
import net.minestom.server.entity.pathfinding.Navigator;
@ -114,7 +114,7 @@ public class FakePlayer extends Player implements NavigableEntity {
super.update(time);
// Path finding
this.navigator.tick(getAttributeValue(Attributes.MOVEMENT_SPEED));
this.navigator.tick(getAttributeValue(Attribute.MOVEMENT_SPEED));
}
@Override

View File

@ -5,7 +5,6 @@ import com.extollit.gaming.ai.path.model.IPathingEntity;
import com.extollit.gaming.ai.path.model.Passibility;
import com.extollit.linalg.immutable.Vec3d;
import net.minestom.server.attribute.Attribute;
import net.minestom.server.attribute.Attributes;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.LivingEntity;
import net.minestom.server.utils.Position;
@ -34,7 +33,7 @@ public class PFPathingEntity implements IPathingEntity {
this.navigator = navigator;
this.entity = navigator.getEntity();
this.searchRange = getAttributeValue(Attributes.FOLLOW_RANGE);
this.searchRange = getAttributeValue(Attribute.FOLLOW_RANGE);
}
public Position getTargetPosition() {
@ -137,7 +136,7 @@ public class PFPathingEntity implements IPathingEntity {
return new Capabilities() {
@Override
public float speed() {
return getAttributeValue(Attributes.MOVEMENT_SPEED);
return getAttributeValue(Attribute.MOVEMENT_SPEED);
}
@Override

View File

@ -60,7 +60,7 @@ public class PlayerDiggingListener {
if (instantBreak) {
// No need to check custom block
breakBlock(instance, player, blockPosition, blockStateId);
breakBlock(instance, player, blockPosition, blockStateId, status);
} else {
final CustomBlock customBlock = instance.getCustomBlock(blockPosition);
final int customBlockId = customBlock == null ? 0 : customBlock.getCustomBlockId();
@ -105,7 +105,7 @@ public class PlayerDiggingListener {
ClientPlayerDiggingPacket.Status.FINISHED_DIGGING, false);
} else {
// Vanilla block
breakBlock(instance, player, blockPosition, blockStateId);
breakBlock(instance, player, blockPosition, blockStateId, status);
}
} else if (status == ClientPlayerDiggingPacket.Status.DROP_ITEM_STACK) {
@ -163,7 +163,10 @@ public class PlayerDiggingListener {
}
}
private static void breakBlock(Instance instance, Player player, BlockPosition blockPosition, int blockStateId) {
private static void breakBlock(Instance instance,
Player player,
BlockPosition blockPosition, int blockStateId,
ClientPlayerDiggingPacket.Status status) {
// Finished digging, remove effect if any
player.resetTargetBlock();
@ -174,7 +177,7 @@ public class PlayerDiggingListener {
// Send acknowledge packet to allow or cancel the digging process
sendAcknowledgePacket(player, blockPosition, updatedBlockId,
ClientPlayerDiggingPacket.Status.FINISHED_DIGGING, result);
status, result);
if (!result) {
final boolean solid = Block.fromStateId((short) blockStateId).isSolid();

View File

@ -65,8 +65,6 @@ public final class NettyServer {
private final PacketProcessor packetProcessor;
private final GlobalChannelTrafficShapingHandler globalTrafficHandler;
private boolean tcpNoDelay = false;
private EventLoopGroup boss, worker;
private ServerBootstrap bootstrap;
@ -163,7 +161,7 @@ public final class NettyServer {
bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(@NotNull SocketChannel ch) {
ChannelConfig config = ch.config();
config.setOption(ChannelOption.TCP_NODELAY, tcpNoDelay);
config.setOption(ChannelOption.TCP_NODELAY, true);
config.setOption(ChannelOption.SO_SNDBUF, 262_144);
config.setAllocator(ByteBufAllocator.DEFAULT);
@ -259,14 +257,6 @@ public final class NettyServer {
return globalTrafficHandler;
}
public boolean isTcpNoDelay() {
return tcpNoDelay;
}
public void setTcpNoDelay(boolean tcpNoDelay) {
this.tcpNoDelay = tcpNoDelay;
}
/**
* Stops the server and the various services.
*/

View File

@ -8,6 +8,7 @@ import net.minestom.server.entity.Player;
import net.minestom.server.network.ConnectionManager;
import net.minestom.server.network.PacketProcessor;
import net.minestom.server.network.netty.packet.InboundPacket;
import net.minestom.server.network.player.NettyPlayerConnection;
import net.minestom.server.network.player.PlayerConnection;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
@ -67,6 +68,11 @@ public class ClientChannel extends SimpleChannelInboundHandler<InboundPacket> {
CONNECTION_MANAGER.removePlayer(playerConnection);
}
packetProcessor.removePlayerConnection(ctx);
// Release tick buffer
if (playerConnection instanceof NettyPlayerConnection) {
((NettyPlayerConnection) playerConnection).getTickBuffer().release();
}
}
}

View File

@ -1,6 +1,7 @@
package net.minestom.server.network.player;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.socket.SocketChannel;
@ -59,6 +60,8 @@ public class NettyPlayerConnection extends PlayerConnection {
private UUID bungeeUuid;
private PlayerSkin bungeeSkin;
private final ByteBuf tickBuffer = Unpooled.directBuffer();
public NettyPlayerConnection(@NotNull SocketChannel channel) {
super();
this.channel = channel;
@ -69,6 +72,7 @@ public class NettyPlayerConnection extends PlayerConnection {
public void update() {
// Flush
if (channel.isActive()) {
writeWaitingPackets();
this.channel.flush();
}
// Network stats
@ -141,10 +145,9 @@ public class NettyPlayerConnection extends PlayerConnection {
if (shouldUpdate) {
final ByteBuf buffer = PacketUtils.createFramedPacket(serverPacket, false);
timedBuffer = new TimedBuffer(buffer, timestamp);
temporaryCache.cache(identifier, timedBuffer);
}
temporaryCache.cache(identifier, timedBuffer);
write(new FramedPacket(timedBuffer.getBuffer()));
}
@ -155,33 +158,61 @@ public class NettyPlayerConnection extends PlayerConnection {
}
}
@NotNull
public ChannelFuture write(@NotNull Object message) {
ChannelFuture channelFuture = channel.write(message);
if (MinecraftServer.shouldProcessNettyErrors()) {
return channelFuture.addListener(future -> {
if (!future.isSuccess() && channel.isActive()) {
MinecraftServer.getExceptionManager().handleException(future.cause());
public void write(@NotNull Object message) {
if (message instanceof FramedPacket) {
final FramedPacket framedPacket = (FramedPacket) message;
synchronized (tickBuffer) {
final ByteBuf body = framedPacket.getBody();
tickBuffer.writeBytes(body, body.readerIndex(), body.readableBytes());
}
});
} else {
return channelFuture;
return;
} else if (message instanceof ServerPacket) {
final ServerPacket serverPacket = (ServerPacket) message;
final ByteBuf buffer = PacketUtils.createFramedPacket(serverPacket, true);
synchronized (tickBuffer) {
tickBuffer.writeBytes(buffer);
}
buffer.release();
return;
} else if (message instanceof ByteBuf) {
synchronized (tickBuffer) {
tickBuffer.writeBytes((ByteBuf) message);
}
return;
}
throw new UnsupportedOperationException("type " + message.getClass() + " is not supported");
}
@NotNull
public ChannelFuture writeAndFlush(@NotNull Object message) {
public void writeAndFlush(@NotNull Object message) {
writeWaitingPackets();
ChannelFuture channelFuture = channel.writeAndFlush(message);
if (MinecraftServer.shouldProcessNettyErrors()) {
return channelFuture.addListener(future -> {
channelFuture.addListener(future -> {
if (!future.isSuccess() && channel.isActive()) {
MinecraftServer.getExceptionManager().handleException(future.cause());
}
});
} else {
return channelFuture;
}
}
private void writeWaitingPackets() {
synchronized (tickBuffer) {
final ByteBuf copy = tickBuffer.copy();
ChannelFuture channelFuture = channel.write(new FramedPacket(copy));
channelFuture.addListener(future -> copy.release());
// Netty debug
if (MinecraftServer.shouldProcessNettyErrors()) {
channelFuture.addListener(future -> {
if (!future.isSuccess() && channel.isActive()) {
MinecraftServer.getExceptionManager().handleException(future.cause());
}
});
}
tickBuffer.clear();
}
}
@ -324,6 +355,11 @@ public class NettyPlayerConnection extends PlayerConnection {
this.serverPort = serverPort;
}
@NotNull
public ByteBuf getTickBuffer() {
return tickBuffer;
}
public byte[] getNonce() {
return nonce;
}

View File

@ -1,7 +1,7 @@
package demo.entity;
import com.google.common.collect.ImmutableList;
import net.minestom.server.attribute.Attributes;
import net.minestom.server.attribute.Attribute;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.LivingEntity;
@ -38,7 +38,7 @@ public class ChickenCreature extends EntityCreature {
// .build()
// );
getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.1f);
getAttribute(Attribute.MOVEMENT_SPEED).setBaseValue(0.1f);
addEventCallback(EntityAttackEvent.class, event -> {
//System.out.println("CALL ATTACK");