Remove most Reflection from REntity

This commit is contained in:
2026-05-16 21:34:18 +02:00
parent 6fb018b86b
commit ba4ee08489
13 changed files with 87 additions and 202 deletions
@@ -19,18 +19,12 @@
package de.steamwar.bausystem.utils;
import de.steamwar.Reflection;
import de.steamwar.core.BountifulWrapper;
import de.steamwar.entity.REntity;
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
import net.minecraft.server.level.ServerPlayer;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class PlayerMovementWrapper {
Class<?> teleportPacket = REntity.teleportPacket;
Reflection.Field<Integer> teleportEntity = REntity.teleportEntity;
BountifulWrapper.PositionSetter teleportPosition = REntity.teleportPosition;
public static final PlayerMovementWrapper impl = new PlayerMovementWrapper();
@@ -45,8 +39,4 @@ public class PlayerMovementWrapper {
serverPlayer.setYRot(packetPlayInFlying.yRot);
}
}
public Object convertToOut(Player player, Object object) {
return object;
}
}
@@ -252,7 +252,7 @@ public class TinyProtocol {
packetFilters.computeIfAbsent(packetType, c -> new CopyOnWriteArrayList<>()).add(filter);
}
public void removeFilter(Class<?> packetType, BiFunction<Player, Object, Object> filter) {
public void removeFilter(Class<?> packetType, BiFunction<Player, ?, Object> filter) {
packetFilters.getOrDefault(packetType, Collections.emptyList()).remove(filter);
}
@@ -90,24 +90,6 @@ public class BountifulWrapper {
}
}
public BountifulWrapper.PositionSetter getRelMoveSetter(Class<?> packetClass) {
Class<?> type = short.class;
Reflection.Field<?> moveX = Reflection.getField(packetClass, type, 0);
Reflection.Field<?> moveY = Reflection.getField(packetClass, type, 1);
Reflection.Field<?> moveZ = Reflection.getField(packetClass, type, 2);
Reflection.Field<Byte> moveYaw = Reflection.getField(packetClass, byte.class, 0);
Reflection.Field<Byte> movePitch = Reflection.getField(packetClass, byte.class, 1);
return (packet, x, y, z, pitch, yaw) -> {
moveX.set(packet, (short)(x*4096));
moveY.set(packet, (short)(y*4096));
moveZ.set(packet, (short)(z*4096));
moveYaw.set(packet, (byte)(yaw*256/360));
movePitch.set(packet, (byte)(pitch*256/360));
};
}
public BountifulWrapper.UUIDSetter getUUIDSetter(Class<?> packetClass) {
Reflection.Field<UUID> uuidField = Reflection.getField(packetClass, UUID.class, 0);
@@ -20,11 +20,9 @@
package de.steamwar.core;
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.util.Pair;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GameType;
@@ -37,19 +35,12 @@ public class ProtocolWrapper {
public static final Class<?> itemStack = ItemStack.class;
public static final Class<?> spawnPacket = ClientboundAddEntityPacket.class;
public static final Class<?> spawnLivingPacket = ProtocolWrapper.spawnPacket;
public static final Class<?> equipmentPacket = ClientboundSetEquipmentPacket.class;
// 0: hand, 1: offhand, 2: feet, 3: legs, 4: chest, 5: head
public static final EquipmentSlot[] itemSlots = EquipmentSlot.values();
public static final ProtocolWrapper impl = new ProtocolWrapper();
public void setEquipmentPacketStack(Object packet, Object slot, Object stack) {
ClientboundSetEquipmentPacket setEquipmentPacket = (ClientboundSetEquipmentPacket) packet;
setEquipmentPacket.getSlots().add(Pair.of((EquipmentSlot) slot, (ItemStack) stack));
}
public Object playerInfoPacketConstructor(PlayerInfoAction action, GameProfile profile, GameMode mode) {
if(action == PlayerInfoAction.REMOVE)
return new ClientboundPlayerInfoRemovePacket(Collections.singletonList(profile.getId()));
@@ -1,53 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.entity;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.PositionMoveRotation;
import net.minecraft.world.phys.Vec3;
import java.util.Collections;
public class PacketConstructor {
public static final PacketConstructor impl = new PacketConstructor();
public Object teleportPacket(int entityId, double x, double y, double z, float yaw, float pitch) {
PositionMoveRotation rot = new PositionMoveRotation(new Vec3(x, y, z), Vec3.ZERO, pitch, yaw);
return new ClientboundTeleportEntityPacket(entityId, rot, Collections.emptySet(), false);
}
public Object createRPlayerSpawn(RPlayer player) {
return new ClientboundAddEntityPacket(
player.entityId,
player.uuid,
player.x,
player.y,
player.z,
player.yaw,
player.pitch,
EntityType.PLAYER,
0,
Vec3.ZERO,
player.headYaw
);
}
}
@@ -19,8 +19,9 @@
package de.steamwar.entity;
import de.steamwar.core.BountifulWrapper;
import lombok.Getter;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
@@ -28,7 +29,7 @@ import java.util.function.Consumer;
public class RArmorStand extends REntity {
private static final Object sizeWatcher = BountifulWrapper.impl.getDataWatcherObject(15, Byte.class);
private static final EntityDataAccessor<Byte> sizeWatcher = new EntityDataAccessor<>(15, EntityDataSerializers.BYTE);
@Getter
private final Size size;
@@ -19,8 +19,9 @@
package de.steamwar.entity;
import de.steamwar.core.BountifulWrapper;
import lombok.Getter;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.world.level.block.state.BlockState;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -58,7 +59,7 @@ public class RBlockDisplay extends RDisplay {
sendPacket(updatePacketSink, this::getBlock);
}
private static final Object blockWatcher = BountifulWrapper.impl.getDataWatcherObject(23, BlockState.class);
private static final EntityDataAccessor<BlockState> blockWatcher = new EntityDataAccessor<>(23, EntityDataSerializers.BLOCK_STATE);
private void getBlock(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || !block.getAsString(true).equals(DEFAULT_BLOCK.getAsString(true))) {
packetSink.accept(blockWatcher, ((CraftBlockData) block).getState());
@@ -19,9 +19,10 @@
package de.steamwar.entity;
import de.steamwar.core.BountifulWrapper;
import lombok.Getter;
import lombok.NonNull;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.entity.Display;
@@ -35,9 +36,6 @@ import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
* !! This class cannot be used in Versions lower than or equal to 1.19.4 !!
*/
@Getter
public abstract class RDisplay extends REntity {
@@ -110,10 +108,10 @@ public abstract class RDisplay extends REntity {
sendPacket(updatePacketSink, this::getTransformData);
}
private static final Object translationWatcher = BountifulWrapper.impl.getDataWatcherObject(11, Vector3f.class);
private static final Object leftRotationWatcher = BountifulWrapper.impl.getDataWatcherObject(13, Quaternionf.class);
private static final Object scaleWatcher = BountifulWrapper.impl.getDataWatcherObject(12, Vector3f.class);
private static final Object rightRotationWatcher = BountifulWrapper.impl.getDataWatcherObject(14, Quaternionf.class);
private static final EntityDataAccessor<Vector3f> translationWatcher = new EntityDataAccessor<>(11, EntityDataSerializers.VECTOR3);
private static final EntityDataAccessor<Quaternionf> leftRotationWatcher = new EntityDataAccessor<>(13, EntityDataSerializers.QUATERNION);
private static final EntityDataAccessor<Vector3f> scaleWatcher = new EntityDataAccessor<>(12, EntityDataSerializers.VECTOR3);
private static final EntityDataAccessor<Quaternionf> rightRotationWatcher = new EntityDataAccessor<>(14, EntityDataSerializers.QUATERNION);
private void getTransformData(boolean ignoreDefault, BiConsumer<Object, Object> dataSink) {
if (ignoreDefault || !transform.equals(DEFAULT_TRANSFORM)) {
@@ -129,8 +127,8 @@ public abstract class RDisplay extends REntity {
sendPacket(updatePacketSink, this::getInterpolationDuration);
}
private static final Object transformationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(9, Integer.class);
private static final Object positionOrRotationInterpolationDurationWatcher = BountifulWrapper.impl.getDataWatcherObject(10, Integer.class);
private static final EntityDataAccessor<Integer> transformationInterpolationDurationWatcher = new EntityDataAccessor<>(9, EntityDataSerializers.INT);
private static final EntityDataAccessor<Integer> positionOrRotationInterpolationDurationWatcher = new EntityDataAccessor<>(10, EntityDataSerializers.INT);
private void getInterpolationDuration(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || interpolationDelay != 0) {
@@ -144,7 +142,7 @@ public abstract class RDisplay extends REntity {
sendPacket(updatePacketSink, this::getViewRange);
}
private static final Object viewRangeWatcher = BountifulWrapper.impl.getDataWatcherObject(17, Float.class);
private static final EntityDataAccessor<Float> viewRangeWatcher = new EntityDataAccessor<>(17, EntityDataSerializers.FLOAT);
private void getViewRange(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || viewRange != 1.0F) {
@@ -157,7 +155,7 @@ public abstract class RDisplay extends REntity {
sendPacket(updatePacketSink, this::getShadowRadius);
}
private static final Object shadowRadiusWatcher = BountifulWrapper.impl.getDataWatcherObject(18, Float.class);
private static final EntityDataAccessor<Float> shadowRadiusWatcher = new EntityDataAccessor<>(18, EntityDataSerializers.FLOAT);
private void getShadowRadius(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || shadowRadius != 0.0F) {
@@ -170,7 +168,7 @@ public abstract class RDisplay extends REntity {
sendPacket(updatePacketSink, this::getShadowStrength);
}
private static final Object shadowStrengthWatcher = BountifulWrapper.impl.getDataWatcherObject(19, Float.class);
private static final EntityDataAccessor<Float> shadowStrengthWatcher = new EntityDataAccessor<>(19, EntityDataSerializers.FLOAT);
private void getShadowStrength(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || shadowStrength != 1.0F) {
@@ -183,7 +181,7 @@ public abstract class RDisplay extends REntity {
sendPacket(updatePacketSink, this::getDisplayWidth);
}
private static final Object displayWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(20, Float.class);
private static final EntityDataAccessor<Float> displayWidthWatcher = new EntityDataAccessor<>(20, EntityDataSerializers.FLOAT);
private void getDisplayWidth(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || displayWidth != 0.0F) {
@@ -196,7 +194,7 @@ public abstract class RDisplay extends REntity {
sendPacket(updatePacketSink, this::getDisplayHeight);
}
private static final Object displayHeightWatcher = BountifulWrapper.impl.getDataWatcherObject(21, Float.class);
private static final EntityDataAccessor<Float> displayHeightWatcher = new EntityDataAccessor<>(21, EntityDataSerializers.FLOAT);
private void getDisplayHeight(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || displayHeight != 0.0F) {
@@ -209,7 +207,7 @@ public abstract class RDisplay extends REntity {
sendPacket(updatePacketSink, this::getInterpolationDelay);
}
private static final Object interpolationDelayWatcher = BountifulWrapper.impl.getDataWatcherObject(8, Integer.class);
private static final EntityDataAccessor<Integer> interpolationDelayWatcher = new EntityDataAccessor<>(8, EntityDataSerializers.INT);
private void getInterpolationDelay(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || interpolationDelay != 0) {
@@ -222,7 +220,7 @@ public abstract class RDisplay extends REntity {
sendPacket(updatePacketSink, this::getBillboard);
}
private static final Object billboardWatcher = BountifulWrapper.impl.getDataWatcherObject(15, Byte.class);
private static final EntityDataAccessor<Byte> billboardWatcher = new EntityDataAccessor<>(15, EntityDataSerializers.BYTE);
private void getBillboard(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || billboard != Display.Billboard.FIXED) {
@@ -235,7 +233,7 @@ public abstract class RDisplay extends REntity {
sendPacket(updatePacketSink, this::getGlowColorOverride);
}
private static final Object glowColorOverrideWatcher = BountifulWrapper.impl.getDataWatcherObject(22, Integer.class);
private static final EntityDataAccessor<Integer> glowColorOverrideWatcher = new EntityDataAccessor<>(22, EntityDataSerializers.INT);
private void getGlowColorOverride(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || glowColorOverride != null) {
@@ -248,7 +246,7 @@ public abstract class RDisplay extends REntity {
sendPacket(updatePacketSink, this::getBrightness);
}
private static final Object brightnessWatcher = BountifulWrapper.impl.getDataWatcherObject(16, Integer.class);
private static final EntityDataAccessor<Integer> brightnessWatcher = new EntityDataAccessor<>(16, EntityDataSerializers.INT);
private void getBrightness(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || brightness != null) {
@@ -19,15 +19,22 @@
package de.steamwar.entity;
import com.mojang.datafixers.util.Pair;
import de.steamwar.Reflection;
import de.steamwar.core.BountifulWrapper;
import de.steamwar.core.ChatWrapper;
import de.steamwar.core.FlatteningWrapper;
import de.steamwar.core.ProtocolWrapper;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import lombok.Getter;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.*;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.PositionMoveRotation;
import net.minecraft.world.phys.Vec3;
import org.bukkit.Location;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.entity.EntityType;
@@ -39,13 +46,11 @@ import java.util.function.Function;
public class REntity {
private static final Object entityStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(0, Byte.class);
private static final Object sneakingDataWatcher = BountifulWrapper.impl.getDataWatcherObject(6, FlatteningWrapper.impl.getPose(FlatteningWrapper.EntityPose.NORMAL).getClass());
private static final Object bowDrawnWatcher = BountifulWrapper.impl.getDataWatcherObject(6, FlatteningWrapper.impl.getPose(FlatteningWrapper.EntityPose.NORMAL).getClass());
private static final Object nameWatcher = BountifulWrapper.impl.getDataWatcherObject(2, Optional.class); // Optional<IChatBaseComponent>
private static final Object nameVisibleWatcher = BountifulWrapper.impl.getDataWatcherObject(3, Boolean.class);
private static final Object noGravityDataWatcher = BountifulWrapper.impl.getDataWatcherObject(5,Boolean.class);
private static final EntityDataAccessor<Byte> entityStatusWatcher = new EntityDataAccessor<>(0, EntityDataSerializers.BYTE);
private static final EntityDataAccessor<Pose> poseDataWatcher = new EntityDataAccessor<>(6, EntityDataSerializers.POSE);
private static final EntityDataAccessor<Optional<Component>> nameWatcher = new EntityDataAccessor<>(2, EntityDataSerializers.OPTIONAL_COMPONENT);
private static final EntityDataAccessor<Boolean> nameVisibleWatcher = new EntityDataAccessor<>(3, EntityDataSerializers.BOOLEAN);
private static final EntityDataAccessor<Boolean> noGravityDataWatcher = new EntityDataAccessor<>(5, EntityDataSerializers.BOOLEAN);
private static int entityIdCounter = -1;
private static final Random random = new Random();
@@ -175,18 +180,8 @@ public class REntity {
server.updateEntity(this, packet);
}
private static final Class<?> velocityPacket = ClientboundSetEntityMotionPacket.class;
private static final Reflection.Field<Integer> velocityEntity = Reflection.getField(velocityPacket, int.class, 0);
private static final Reflection.Field<Integer> velocityX = Reflection.getField(velocityPacket, int.class, 1);
private static final Reflection.Field<Integer> velocityY = Reflection.getField(velocityPacket, int.class, 2);
private static final Reflection.Field<Integer> velocityZ = Reflection.getField(velocityPacket, int.class, 3);
public void setVelocity(double dX, double dY, double dZ) {
Object packet = Reflection.newInstance(velocityPacket);
velocityEntity.set(packet, entityId);
velocityX.set(packet, calcVelocity(dX));
velocityY.set(packet, calcVelocity(dY));
velocityZ.set(packet, calcVelocity(dZ));
server.updateEntity(this, packet);
server.updateEntity(this, new ClientboundSetEntityMotionPacket(entityId, new Vec3(calcVelocity(dX), calcVelocity(dY), calcVelocity(dZ))));
}
private static final Class<?> statusPacket = ClientboundEntityEventPacket.class;
@@ -201,7 +196,7 @@ public class REntity {
public void setPose(FlatteningWrapper.EntityPose pose) {
this.pose = pose;
server.updateEntity(this, getDataWatcherPacket(sneakingDataWatcher, FlatteningWrapper.impl.getPose(pose)));
server.updateEntity(this, getDataWatcherPacket(poseDataWatcher, FlatteningWrapper.impl.getPose(pose)));
}
public void setOnFire(boolean perma) {
@@ -220,7 +215,7 @@ public class REntity {
public void setBowDrawn(boolean drawn, boolean offHand) {
bowDrawn = drawn;
server.updateEntity(this, getDataWatcherPacket(bowDrawnWatcher, FlatteningWrapper.impl.getPose(FlatteningWrapper.EntityPose.SHOOTING)));
server.updateEntity(this, getDataWatcherPacket(poseDataWatcher, Pose.SHOOTING));
}
public void setDisplayName(String displayName) {
@@ -285,7 +280,7 @@ public class REntity {
}
if(pose != FlatteningWrapper.EntityPose.NORMAL) {
packetSink.accept(getDataWatcherPacket(sneakingDataWatcher, FlatteningWrapper.impl.getPose(pose)));
packetSink.accept(getDataWatcherPacket(poseDataWatcher, FlatteningWrapper.impl.getPose(pose)));
}
byte status = getEntityStatus();
@@ -311,12 +306,8 @@ public class REntity {
}
}
private static final Class<?> destroyPacket = ClientboundRemoveEntitiesPacket.class;
private static final Reflection.Field<?> destroyEntities = Reflection.getField(destroyPacket, IntList.class, 0);
void despawn(Consumer<Object> packetSink){
Object packet = Reflection.newInstance(destroyPacket);
destroyEntities.set(packet, new IntArrayList(new int[]{entityId}));
packetSink.accept(packet);
packetSink.accept(new ClientboundRemoveEntitiesPacket(new IntArrayList(new int[]{entityId})));
}
void delist(Consumer<Object> packetSink) {
@@ -350,36 +341,26 @@ public class REntity {
return ChatWrapper.impl.getDataWatcherPacket(entityId, dataWatcherKeyValues);
}
public static final Class<?> teleportPacket = ClientboundTeleportEntityPacket.class;
public static final Reflection.Field<Integer> teleportEntity = Reflection.getField(teleportPacket, int.class, 0);
public static final BountifulWrapper.PositionSetter teleportPosition = BountifulWrapper.impl.getPositionSetter(teleportPacket, 0);
private Object getTeleportPacket(){
return PacketConstructor.impl.teleportPacket(entityId, x, y, z, pitch, yaw);
PositionMoveRotation rot = new PositionMoveRotation(new Vec3(x, y, z), Vec3.ZERO, pitch, yaw);
return new ClientboundTeleportEntityPacket(entityId, rot, Collections.emptySet(), false);
}
private static final Class<?> entityPacket = ClientboundMoveEntityPacket.class;
private static final Reflection.Field<Integer> moveEntityId = Reflection.getField(entityPacket, int.class, 0);
private static final BountifulWrapper.PositionSetter movePosition = BountifulWrapper.impl.getRelMoveSetter(entityPacket);
private static final Class<?> lookPacket = ClientboundMoveEntityPacket.Rot.class;
private static final Class<?> movePacket = ClientboundMoveEntityPacket.Pos.class;
private static final Class<?> moveLookPacket = ClientboundMoveEntityPacket.PosRot.class;
private Object getMoveLookPacket(double diffX, double diffY, double diffZ, boolean rotEq) {
Class<?> clazz;
short x = (short)(this.x*4096);
short y = (short)(this.y*4096);
short z = (short)(this.z*4096);
byte yaw = (byte)(this.yaw*256/360);
byte pitch = (byte)(this.pitch*256/360);
if(diffX == 0 && diffY == 0 && diffZ == 0) {
if(rotEq)
return null;
clazz = lookPacket;
if(rotEq) return null;
return new ClientboundMoveEntityPacket.Rot(entityId, pitch, yaw, false);
} else if (rotEq) {
clazz = movePacket;
return new ClientboundMoveEntityPacket.Pos(entityId, x, y, z, false);
} else {
clazz = moveLookPacket;
return new ClientboundMoveEntityPacket.PosRot(entityId, x, y, z, pitch, yaw, false);
}
Object packet = Reflection.newInstance(clazz);
moveEntityId.set(packet, entityId);
movePosition.set(packet, diffX, diffY, diffZ, pitch, yaw);
return packet;
}
private static final Class<?> headRotationPacket = ClientboundRotateHeadPacket.class;
@@ -392,15 +373,8 @@ public class REntity {
return packet;
}
private static final Reflection.Field<Integer> equipmentEntity = Reflection.getField(ProtocolWrapper.equipmentPacket, int.class, 0);
private static final Reflection.Field<List> equipmentSlots = Reflection.getField(ProtocolWrapper.equipmentPacket, List.class, 0);
protected Object getEquipmentPacket(Object slot, ItemStack stack){
Object packet = Reflection.newInstance(ProtocolWrapper.equipmentPacket);
equipmentEntity.set(packet, entityId);
equipmentSlots.set(packet, new ArrayList<>());
ProtocolWrapper.impl.setEquipmentPacketStack(packet, slot, CraftItemStack.asNMSCopy(stack));
return packet;
protected Object getEquipmentPacket(Object slot, ItemStack stack) {
return new ClientboundSetEquipmentPacket(entityId, Collections.singletonList(Pair.of((EquipmentSlot) slot, CraftItemStack.asNMSCopy(stack))));
}
private static Function<REntity, Object> entitySpawnPacketGenerator(Class<?> spawnPacket, int posOffset) {
@@ -20,7 +20,6 @@
package de.steamwar.entity;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.Reflection;
import de.steamwar.core.Core;
import de.steamwar.core.FlatteningWrapper;
import net.minecraft.network.protocol.game.ServerboundInteractPacket;
@@ -39,7 +38,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -48,17 +46,6 @@ public class REntityServer implements Listener {
private static final HashSet<REntity> emptyEntities = new HashSet<>(0);
private static final HashSet<Player> emptyPlayers = new HashSet<>(0);
private static final Class<?> useEntity = ServerboundInteractPacket.class;
private static final Reflection.Field<Integer> useEntityTarget = Reflection.getField(useEntity, int.class, 0);
private static final Class<?> useEntityEnumAction = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundInteractPacket$Action");
private static final Reflection.Field<?> useEntityAction = Reflection.getField(useEntity, useEntityEnumAction, 0);
private static final Function<Object, Integer> getEntityAction;
static {
Class<?> useEntityEnumActionType = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundInteractPacket$ActionType");
Reflection.Method useEntityGetAction = Reflection.getTypedMethod(useEntityEnumAction, null, useEntityEnumActionType);
getEntityAction = value -> ((Enum<?>) useEntityGetAction.invoke(value)).ordinal();
}
private final ConcurrentHashMap<Integer, REntity> entityMap = new ConcurrentHashMap<>();
private final HashMap<Long, HashSet<REntity>> entities = new HashMap<>();
private final HashMap<Long, Set<Player>> players = new HashMap<>();
@@ -68,8 +55,8 @@ public class REntityServer implements Listener {
private EntityActionListener callback = null;
private final Set<Player> playersThatClicked = Collections.synchronizedSet(new HashSet<>());
private final BiFunction<Player, Object, Object> filter = (player, packet) -> {
REntity entity = entityMap.get(useEntityTarget.get(packet));
private final BiFunction<Player, ServerboundInteractPacket, Object> filter = (player, packet) -> {
REntity entity = entityMap.get(packet.getEntityId());
if (entity == null)
return packet;
@@ -77,7 +64,7 @@ public class REntityServer implements Listener {
return null;
playersThatClicked.add(player);
EntityAction action = getEntityAction.apply(useEntityAction.get(packet)) == 1 ? EntityAction.ATTACK : EntityAction.INTERACT;
EntityAction action = packet.isAttack() ? EntityAction.ATTACK : EntityAction.INTERACT;
Bukkit.getScheduler().runTask(Core.getInstance(), () -> {
playersThatClicked.remove(player);
callback.onAction(player, entity, action);
@@ -94,7 +81,7 @@ public class REntityServer implements Listener {
this.callback = callback;
if(uninitialized)
TinyProtocol.instance.addFilter(useEntity, filter);
TinyProtocol.instance.addTypedFilter(ServerboundInteractPacket.class, filter);
}
public void addPlayer(Player player) {
@@ -117,7 +104,7 @@ public class REntityServer implements Listener {
}
public void close() {
TinyProtocol.instance.removeFilter(useEntity, filter);
TinyProtocol.instance.removeFilter(ServerboundInteractPacket.class, filter);
for(Player player : lastLocation.keySet().toArray(new Player[0])) {
removePlayer(player);
}
@@ -19,9 +19,9 @@
package de.steamwar.entity;
import de.steamwar.core.BountifulWrapper;
import de.steamwar.core.ProtocolWrapper;
import lombok.Getter;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
@@ -61,14 +61,14 @@ public class RItemDisplay extends RDisplay {
sendPacket(updatePacketSink, this::getItemStack);
}
private static final Object itemStackWatcher = BountifulWrapper.impl.getDataWatcherObject(23, ProtocolWrapper.itemStack);
private static final EntityDataAccessor<net.minecraft.world.item.ItemStack> itemStackWatcher = new EntityDataAccessor<>(23, EntityDataSerializers.ITEM_STACK);
private void getItemStack(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || !itemStack.equals(DEFAULT_ITEM_STACK)) {
packetSink.accept(itemStackWatcher, CraftItemStack.asNMSCopy(itemStack));
}
}
private static final Object itemDisplayTransformWatcher = BountifulWrapper.impl.getDataWatcherObject(24, Byte.class);
private static final EntityDataAccessor<Byte> itemDisplayTransformWatcher = new EntityDataAccessor<>(24, EntityDataSerializers.BYTE);
public void setItemDisplayTransform(ItemDisplay.ItemDisplayTransform itemDisplayTransform) {
this.itemDisplayTransform = itemDisplayTransform;
sendPacket(updatePacketSink, this::getItemDisplayTransform);
@@ -28,6 +28,8 @@ import de.steamwar.network.CoreNetworkHandler;
import de.steamwar.network.NetworkSender;
import de.steamwar.network.packets.common.PlayerSkinRequestPacket;
import lombok.Getter;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.world.phys.Vec3;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
@@ -95,6 +97,18 @@ public class RPlayer extends REntity {
}
private Object getNamedSpawnPacket() {
return PacketConstructor.impl.createRPlayerSpawn(this);
return new ClientboundAddEntityPacket(
entityId,
uuid,
x,
y,
z,
yaw,
pitch,
net.minecraft.world.entity.EntityType.PLAYER,
0,
Vec3.ZERO,
headYaw
);
}
}
@@ -19,10 +19,11 @@
package de.steamwar.entity;
import de.steamwar.core.BountifulWrapper;
import de.steamwar.core.ChatWrapper;
import lombok.Getter;
import net.minecraft.network.chat.Component;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.TextDisplay;
@@ -73,8 +74,7 @@ public class RTextDisplay extends RDisplay {
sendPacket(updatePacketSink, this::getText);
}
private static final Class<?> iChatBaseComponent = Component.class;
private static final Object textWatcher = BountifulWrapper.impl.getDataWatcherObject(23, iChatBaseComponent);
private static final EntityDataAccessor<Component> textWatcher = new EntityDataAccessor<>(23, EntityDataSerializers.COMPONENT);
private void getText(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || !text.isEmpty()) {
packetSink.accept(textWatcher, ChatWrapper.impl.stringToChatComponent(text));
@@ -86,7 +86,7 @@ public class RTextDisplay extends RDisplay {
sendPacket(updatePacketSink, this::getLineWidth);
}
private static final Object lineWidthWatcher = BountifulWrapper.impl.getDataWatcherObject(24, Integer.class);
private static final EntityDataAccessor<Integer> lineWidthWatcher = new EntityDataAccessor<>(24, EntityDataSerializers.INT);
private void getLineWidth(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || lineWidth != 200) {
packetSink.accept(lineWidthWatcher, lineWidth);
@@ -98,7 +98,7 @@ public class RTextDisplay extends RDisplay {
sendPacket(updatePacketSink, this::getTextOpacity);
}
private static final Object textOpacityWatcher = BountifulWrapper.impl.getDataWatcherObject(26, Byte.class);
private static final EntityDataAccessor<Byte> textOpacityWatcher = new EntityDataAccessor<>(26, EntityDataSerializers.BYTE);
private void getTextOpacity(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || textOpacity != (byte) -1) {
packetSink.accept(textOpacityWatcher, textOpacity);
@@ -120,7 +120,7 @@ public class RTextDisplay extends RDisplay {
sendPacket(updatePacketSink, this::getTextStatus, this::getBackgroundColor);
}
private static final Object backgroundColorWatcher = BountifulWrapper.impl.getDataWatcherObject(25, Integer.class);
private static final EntityDataAccessor<Integer> backgroundColorWatcher = new EntityDataAccessor<>(25, EntityDataSerializers.INT);
private void getBackgroundColor(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
if (ignoreDefault || backgroundColor != null) {
packetSink.accept(backgroundColorWatcher, backgroundColor);
@@ -139,7 +139,7 @@ public class RTextDisplay extends RDisplay {
sendPacket(updatePacketSink, this::getTextStatus);
}
private static final Object textStatusWatcher = BountifulWrapper.impl.getDataWatcherObject(27, Byte.class);
private static final EntityDataAccessor<Byte> textStatusWatcher = new EntityDataAccessor<>(27, EntityDataSerializers.BYTE);
private void getTextStatus(boolean ignoreDefault, BiConsumer<Object, Object> packetSink) {
byte status = 0;