Commit ad82d280 authored by Ashijin's avatar Ashijin
Browse files

1.19.3 support, cleaned up dependencies

parent ea5c8224
package io.lumine.cosmetics.nms.v1_19_R2.cosmetic;
import io.lumine.cosmetics.MCCosmeticsPlugin;
import io.lumine.cosmetics.managers.sprays.Spray;
import io.lumine.cosmetics.nms.VolatileCodeEnabled_v1_19_R2;
import io.lumine.cosmetics.nms.cosmetic.VolatileSprayHelper;
import lombok.Getter;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.game.ClientboundMapItemDataPacket;
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
import net.minecraft.world.entity.decoration.ItemFrame;
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta;
public class VolatileSprayImpl implements VolatileSprayHelper {
@Getter private final MCCosmeticsPlugin plugin;
private final VolatileCodeEnabled_v1_19_R2 nmsHandler;
public VolatileSprayImpl(MCCosmeticsPlugin plugin, VolatileCodeEnabled_v1_19_R2 nmsHandler) {
this.plugin = plugin;
this.nmsHandler = nmsHandler;
}
private static final ItemStack map = new ItemStack(Material.FILLED_MAP);
private static final MapMeta mapMeta = (MapMeta) map.getItemMeta();
@Override
public int drawSpray(Spray spray, Location location, BlockFace face, int rotation) {
var world = ((CraftWorld) location.getWorld()).getHandle();
var pos = new BlockPos(location.getX(), location.getY(), location.getZ());
var image = spray.getImage();
mapMeta.setMapId(image.getMapNumber());
map.setItemMeta(mapMeta);
var nmsMap = CraftItemStack.asNMSCopy(map);
final int dir = switch(face) {
case DOWN -> 0;
case UP -> 1;
case NORTH -> 2;
case SOUTH -> 3;
case WEST -> 4;
case EAST -> 5;
default -> 1;
};
var frame = new ItemFrame(world, pos, Direction.UP);
frame.setItem(nmsMap);
frame.setInvisible(true);
frame.setRotation(rotation);
var packetAdd = new ClientboundAddEntityPacket(frame, dir);
var packetData = new ClientboundSetEntityDataPacket(frame.getId(), frame.getEntityData().getNonDefaultValues());
var packetMap = constructMapPacket(image.getMapNumber(), image.getPixels());
nmsHandler.broadcast(packetAdd, packetData, packetMap);
return frame.getId();
}
private static final int startX = 0;
private static final int startY = 0;
private static final int mapWidth = 128;
private static final int mapHeight = 128;
private static final byte mapScale = 1;
private static final boolean mapLocked = true;
private ClientboundMapItemDataPacket constructMapPacket(int id, byte[] pixels) {
var mapData = constructMapData(startX, startY, mapWidth, mapHeight, pixels);
var packet = new ClientboundMapItemDataPacket(id, mapScale, mapLocked, null, mapData);
return packet;
}
private MapItemSavedData.MapPatch constructMapData(int startX, int startY, int width, int height, byte[] pixels) {
return new MapItemSavedData.MapPatch(startX, startY, width, height, pixels);
}
}
package io.lumine.cosmetics.nms.v1_19_R2.network;
import io.lumine.cosmetics.nms.VolatileCodeEnabled_v1_19_R2;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import lombok.Getter;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class VolatileChannelHandler extends ChannelDuplexHandler {
private final VolatileCodeEnabled_v1_19_R2 nmsHandler;
@Getter private final Player player;
public VolatileChannelHandler(Player player, VolatileCodeEnabled_v1_19_R2 nmsHandler) {
this.player = player;
this.nmsHandler = nmsHandler;
}
@Override
public void write(ChannelHandlerContext ctx, Object obj, ChannelPromise promise) {
try {
List<Object> packets = new ArrayList<>();
for(final var helper : nmsHandler.getCosmeticHelpers()) {
final var writes = helper.write(player, obj);
if(writes != null)
packets.addAll(writes);
}
if(!packets.contains(obj))
super.write(ctx, obj, promise);
packets.remove(obj);
for (var p : packets) {
super.write(ctx, p, promise.channel().newPromise());
}
}catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object obj) throws Exception {
boolean isCanceled = false;
for(final var helper : nmsHandler.getCosmeticHelpers()) {
isCanceled |= !helper.read(player, obj, isCanceled);
}
if(!isCanceled)
super.channelRead(ctx, obj);
}
}
package io.lumine.cosmetics.nms.v1_19_R2.wardrobe;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.util.Pair;
import io.lumine.cosmetics.api.cosmetics.Cosmetic;
import io.lumine.cosmetics.api.players.wardrobe.Mannequin;
import io.lumine.cosmetics.api.players.wardrobe.WardrobeTracker;
import io.lumine.cosmetics.nms.VolatileCodeEnabled_v1_19_R2;
import io.netty.buffer.Unpooled;
import lombok.Getter;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.protocol.game.ClientboundAddPlayerPacket;
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket;
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.EquipmentSlot;
public class MannequinEntity implements Mannequin {
private final VolatileCodeEnabled_v1_19_R2 handler;
@Getter private final WardrobeTracker tracker;
@Getter private final UUID uniqueId;
@Getter private final Player player;
@Getter private final Location location;
@Getter private float rotation;
@Getter private ServerPlayer fakePlayer;
private Map<Class<? extends Cosmetic>,Integer> extraEntities = Maps.newConcurrentMap();
public MannequinEntity(WardrobeTracker tracker, VolatileCodeEnabled_v1_19_R2 handler, Player player, Location location) {
this.tracker = tracker;
this.handler = handler;
this.player = player;
this.location = location;
this.uniqueId = UUID.randomUUID();
var serverPlayer = ((CraftPlayer) player).getHandle();
var level = ((CraftWorld) location.getWorld()).getHandle();
this.rotation = serverPlayer.getYRot() + 180;
if(rotation > 180) {
rotation = rotation - 360;
}
var gameProfile = serverPlayer.getGameProfile();
gameProfile = new GameProfile(uniqueId, "Wardrobe");
gameProfile.getProperties().putAll(serverPlayer.getGameProfile().getProperties());
this.fakePlayer = new ServerPlayer(level.getServer(), level, gameProfile);
var spawn = new FriendlyByteBuf(Unpooled.buffer());
spawn.writeVarInt(fakePlayer.getId());
spawn.writeUUID(fakePlayer.getUUID());
spawn.writeDouble(location.getX());
spawn.writeDouble(location.getY());
spawn.writeDouble(location.getZ());
spawn.writeByte((byte)(int)(serverPlayer.getYRot() * 256.0F / 360.0F));
spawn.writeByte((byte)(int)(serverPlayer.getXRot() * 256.0F / 360.0F));
var packetPlayerInfo = new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, fakePlayer);
var packetAddPlayer = new ClientboundAddPlayerPacket(spawn);
var equipmentPacket = new ClientboundSetEquipmentPacket(fakePlayer.getId(),
List.of(Pair.of(EquipmentSlot.HEAD, serverPlayer.getItemBySlot(EquipmentSlot.HEAD)),
Pair.of(EquipmentSlot.CHEST, serverPlayer.getItemBySlot(EquipmentSlot.CHEST)),
Pair.of(EquipmentSlot.LEGS, serverPlayer.getItemBySlot(EquipmentSlot.LEGS)),
Pair.of(EquipmentSlot.FEET, serverPlayer.getItemBySlot(EquipmentSlot.FEET)),
Pair.of(EquipmentSlot.MAINHAND, serverPlayer.getItemBySlot(EquipmentSlot.MAINHAND)),
Pair.of(EquipmentSlot.OFFHAND, serverPlayer.getItemBySlot(EquipmentSlot.OFFHAND))));
var head = (byte)(int)(rotation * 256.0F / 360.0F);
var rotatePacket = new ClientboundRotateHeadPacket(fakePlayer, head);
var swingPacket = new ClientboundAnimatePacket(fakePlayer, 0);
handler.broadcast(player, packetPlayerInfo, packetAddPlayer, equipmentPacket, rotatePacket, swingPacket);
for(var eq : handler.getPlugin().getProfiles().getProfile(player).getEquipped().values()) {
eq.getCosmetic().getManager().equipMannequin(this, eq);
}
}
public void despawn() {
var packetPlayerInfo = new ClientboundPlayerInfoRemovePacket(Lists.newArrayList(fakePlayer.getUUID()));
var packetRemovePlayer = new ClientboundRemoveEntitiesPacket(fakePlayer.getId());
handler.broadcast(player, packetPlayerInfo, packetRemovePlayer);
for(var i : extraEntities.values()) {
var removePacket = new ClientboundRemoveEntitiesPacket(i);
handler.broadcast(player, removePacket);
}
}
public void addExtraEntity(Class<? extends Cosmetic> type, int id) {
extraEntities.put(type, id);
}
public void removeExtraEntity(Class<? extends Cosmetic> type) {
var id = extraEntities.remove(type);
if(id != null) {
var removePacket = new ClientboundRemoveEntitiesPacket(id);
handler.broadcast(player, removePacket);
}
}
public int getEntityId() {
return fakePlayer.getId();
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment