diff --git a/CommonCore b/CommonCore index 8b8e6a9..5cde375 160000 --- a/CommonCore +++ b/CommonCore @@ -1 +1 @@ -Subproject commit 8b8e6a9e574040eea1bdea955f69263e63eb8078 +Subproject commit 5cde375310a42eec781ef240284d533f87b49842 diff --git a/SpigotCore_Main/src/de/steamwar/entity/RArmorStand.java b/SpigotCore_Main/src/de/steamwar/entity/RArmorStand.java index 7e0e7a7..5513d2b 100644 --- a/SpigotCore_Main/src/de/steamwar/entity/RArmorStand.java +++ b/SpigotCore_Main/src/de/steamwar/entity/RArmorStand.java @@ -59,7 +59,9 @@ public class RArmorStand extends REntity { @Override void spawn(Consumer packetSink) { super.spawn(packetSink); - packetSink.accept(getDataWatcherPacket(sizeWatcher, size.value)); + + if(size != null && size != Size.NORMAL) + packetSink.accept(getDataWatcherPacket(sizeWatcher, size.value)); } public enum Size { diff --git a/SpigotCore_Main/src/de/steamwar/entity/REntity.java b/SpigotCore_Main/src/de/steamwar/entity/REntity.java index 6c5bf80..d6ace1a 100644 --- a/SpigotCore_Main/src/de/steamwar/entity/REntity.java +++ b/SpigotCore_Main/src/de/steamwar/entity/REntity.java @@ -23,6 +23,7 @@ import com.comphenix.tinyprotocol.Reflection; import de.steamwar.core.*; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; +import lombok.Getter; import org.bukkit.Location; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; @@ -39,12 +40,16 @@ public class REntity { private static final Object nameWatcher = BountifulWrapper.impl.getDataWatcherObject(2, Core.getVersion() > 12 ? Optional.class : String.class); // Optional private static final Object nameVisibleWatcher = BountifulWrapper.impl.getDataWatcherObject(3, Boolean.class); + private static final Object noGravityDataWatcher = BountifulWrapper.impl.getDataWatcherObject(5,Boolean.class); + private static int entityIdCounter = -1; private static final Random random = new Random(); private final REntityServer server; private final EntityType entityType; + @Getter protected final int entityId; + @Getter protected final UUID uuid; protected double x; @@ -57,15 +62,24 @@ public class REntity { private boolean invisible; private FlatteningWrapper.EntityPose pose = FlatteningWrapper.EntityPose.NORMAL; private boolean bowDrawn; + private boolean noGravity; + private boolean isGlowing; private int fireTick; + + private final int objectData; + @Getter private String displayName; protected final Map itemSlots; public REntity(REntityServer server, EntityType entityType, Location location) { - this(server, entityType, new UUID(random.nextLong() & -61441L | 16384L, random.nextLong() & 4611686018427387903L | -9223372036854775808L), location); + this(server,entityType,location,0); } - protected REntity(REntityServer server, EntityType entityType, UUID uuid, Location location) { + protected REntity(REntityServer server, EntityType entityType, Location location,int objectData) { + this(server, entityType, new UUID(random.nextLong() & -61441L | 16384L, random.nextLong() & 4611686018427387903L | -9223372036854775808L), location,objectData); + } + + protected REntity(REntityServer server, EntityType entityType, UUID uuid, Location location,int objectData) { this.server = server; this.entityType = entityType; this.entityId = entityIdCounter--; @@ -79,9 +93,18 @@ public class REntity { this.itemSlots = entityType == EntityType.PLAYER ? new HashMap<>() : null; + this.noGravity = false; + this.isGlowing = false; + + this.objectData = objectData; + server.addEntity(this); } + public void move(Location location) { + move(location.getX(), location.getY(), location.getZ(), location.getPitch(), location.getYaw(), rotToByte(location.getYaw())); + } + public void move(double locX, double locY, double locZ, float pitch, float yaw, byte headYaw) { server.preEntityMove(this, locX, locZ); double fromX = this.x; @@ -178,6 +201,19 @@ public class REntity { server.removeEntity(this); } + public void setNoGravity(boolean noGravity) { + this.noGravity = noGravity; + if(Core.getVersion() > 8) + server.updateEntity(this,getDataWatcherPacket(noGravityDataWatcher,noGravity)); + } + + public void setGlowing(boolean glowing) { + this.isGlowing = glowing; + if(Core.getVersion() > 8) { + server.updateEntity(this,getDataWatcherPacket(entityStatusWatcher,getEntityStatus())); + } + } + private static int spawnPacketOffset() { switch (Core.getVersion()) { case 8: @@ -195,12 +231,35 @@ public class REntity { } } private static final Function spawnPacketGenerator = entitySpawnPacketGenerator(ProtocolWrapper.spawnPacket, spawnPacketOffset()); - private static final Function livingSpawnPacketGenerator = Core.getVersion() >= 19 ? spawnPacketGenerator : entitySpawnPacketGenerator(ProtocolWrapper.spawnLivingPacket, Core.getVersion() == 8 ? 2 : 0); + private static int objectDataOffset() { + switch (Core.getVersion()) { + case 8: + return 9; + case 9: + case 14: + case 12: + case 10: + case 15: + case 18: + return 6; + case 19: + default: + return 4; + } + } + private static final Reflection.FieldAccessor additionalData = Reflection.getField(ProtocolWrapper.spawnPacket, int.class, objectDataOffset()); + private Object spawnPacketGenerator() { + Object packet = spawnPacketGenerator.apply(this); + additionalData.set(packet, objectData); + return packet; + } + + private static final Function livingSpawnPacketGenerator = Core.getVersion() >= 19 ? REntity::spawnPacketGenerator : entitySpawnPacketGenerator(ProtocolWrapper.spawnLivingPacket, Core.getVersion() == 8 ? 2 : 0); void spawn(Consumer packetSink) { if(entityType.isAlive()) { packetSink.accept(livingSpawnPacketGenerator.apply(this)); } else { - packetSink.accept(spawnPacketGenerator.apply(this)); + packetSink.accept(spawnPacketGenerator()); } postSpawn(packetSink); @@ -223,6 +282,9 @@ public class REntity { if(displayName != null) { packetSink.accept(getDataWatcherPacket(nameWatcher, FlatteningWrapper.impl.formatDisplayName(displayName), nameVisibleWatcher, true)); } + + if(Core.getVersion() > 8 && noGravity) + packetSink.accept(getDataWatcherPacket(noGravityDataWatcher, true)); } void tick() { @@ -267,6 +329,8 @@ public class REntity { status |= 0x10; if(invisible) status |= 0x20; + if(Core.getVersion() > 8 && isGlowing) + status |= 0x40; return status; } diff --git a/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java b/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java index 97ecc3a..70a5fee 100644 --- a/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java +++ b/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java @@ -30,7 +30,6 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Set; @@ -46,6 +45,7 @@ public class REntityServer implements Listener { private final HashMap> entities = new HashMap<>(); private final HashMap> players = new HashMap<>(); private final HashMap lastLocation = new HashMap<>(); + private final HashMap viewDistance = new HashMap<>(); public REntityServer() { Core.getInstance().getServer().getPluginManager().registerEvents(this, Core.getInstance()); @@ -54,12 +54,13 @@ public class REntityServer implements Listener { public void addPlayer(Player player) { Location location = player.getLocation(); lastLocation.put(player, location); + viewDistance.put(player, viewRadius(player)); forChunkInView(player, location, (x, z) -> addPlayerToChunk(player, x, z)); } public void removePlayer(Player player) { - Location location = lastLocation.remove(player); - forChunkInView(player, location, (x, z) -> removePlayerFromChunk(player, x, z)); + forChunkInView(player, lastLocation.remove(player), (x, z) -> removePlayerFromChunk(player, x, z)); + viewDistance.remove(player); } public void close() { @@ -117,8 +118,6 @@ public class REntityServer implements Listener { entities.remove(id); } - //TODO on settings, on respawn? on boatmove? - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) public void onMove(PlayerMoveEvent e) { Player player = e.getPlayer(); @@ -134,14 +133,18 @@ public class REntityServer implements Listener { if(fromX == toX && fromZ == toZ) return; - int viewDistance = viewRadius(player); + lastLocation.put(player, to); + + int toViewDistance = viewRadius(player); forChunkInView(player, from, (x, z) -> { - if(Math.abs(x - toX) > viewDistance || Math.abs(z - toX) > viewDistance) { + if(Math.abs(x - toX) > toViewDistance || Math.abs(z - toZ) > toViewDistance) { removePlayerFromChunk(player, x, z); } }); + + int fromViewDistance = this.viewDistance.put(player, toViewDistance); forChunkInView(player, to, (x, z) -> { - if(Math.abs(x - fromX) > viewDistance || Math.abs(z - fromZ) > viewDistance) { + if(Math.abs(x - fromX) > fromViewDistance || Math.abs(z - fromZ) > fromViewDistance) { addPlayerToChunk(player, x, z); } }); @@ -171,7 +174,7 @@ public class REntityServer implements Listener { private void forChunkInView(Player player, Location location, BiConsumer func) { int chunkX = posToChunk(location.getX()); int chunkZ = posToChunk(location.getZ()); - int viewDistance = viewRadius(player); + int viewDistance = this.viewDistance.get(player); for(int x = chunkX - viewDistance; x <= chunkX + viewDistance; x++) { for(int z = chunkZ - viewDistance; z <= chunkZ + viewDistance; z++) { @@ -190,7 +193,7 @@ public class REntityServer implements Listener { private void removePlayerFromChunk(Player player, int x, int z) { long id = chunkToId(x, z); - players.getOrDefault(id, Collections.emptySet()).remove(player); + players.get(id).remove(player); for(REntity entity : entities.getOrDefault(id, emptyEntities)) { entity.despawn(packet -> TinyProtocol.instance.sendPacket(player, packet)); } @@ -221,7 +224,6 @@ public class REntityServer implements Listener { } private long chunkToId(int x, int z) { - //TODO negative coord clash? - return (long) x << 32 + z; + return ((long) x << 32) + z; } } diff --git a/SpigotCore_Main/src/de/steamwar/entity/RFallingBlockEntity.java b/SpigotCore_Main/src/de/steamwar/entity/RFallingBlockEntity.java new file mode 100644 index 0000000..b436997 --- /dev/null +++ b/SpigotCore_Main/src/de/steamwar/entity/RFallingBlockEntity.java @@ -0,0 +1,33 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.entity; + +import de.steamwar.core.Core; +import de.steamwar.techhider.BlockIds; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; + +public class RFallingBlockEntity extends REntity{ + + public RFallingBlockEntity(REntityServer server, Location location, Material material) { + super(server, EntityType.FALLING_BLOCK, location, BlockIds.impl.materialToId(material) >> (Core.getVersion() <= 12 ? 4 : 0)); + } +} diff --git a/SpigotCore_Main/src/de/steamwar/entity/RPlayer.java b/SpigotCore_Main/src/de/steamwar/entity/RPlayer.java index c5a080b..fa6d513 100644 --- a/SpigotCore_Main/src/de/steamwar/entity/RPlayer.java +++ b/SpigotCore_Main/src/de/steamwar/entity/RPlayer.java @@ -76,7 +76,7 @@ public class RPlayer extends REntity { private final String name; public RPlayer(REntityServer server, UUID uuid, String name, Location location) { - super(server, EntityType.PLAYER, uuid, location); + super(server, EntityType.PLAYER, uuid, location,0); this.name = name; //team.addEntry(name); }