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
20 changes: 20 additions & 0 deletions NMS/V1_21_5/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
plugins {
id("io.papermc.paperweight.userdev")
}

group "NMS:V1_21_5"

dependencies {
compileOnly(project(":API"))
paperweight.paperDevBundle("1.21.5-R0.1-SNAPSHOT")
}

paperweight.reobfArtifactConfiguration = io.papermc.paperweight.userdev.ReobfArtifactConfiguration.REOBF_PRODUCTION

java {
toolchain.languageVersion = JavaLanguageVersion.of(21)
}

tasks.assemble {
dependsOn(tasks.reobfJar)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package fr.maxlego08.essentials.nms.v1_21_5;

import com.mojang.math.Transformation;
import fr.maxlego08.essentials.api.EssentialsPlugin;
import fr.maxlego08.essentials.api.hologram.Hologram;
import fr.maxlego08.essentials.api.hologram.HologramType;
import fr.maxlego08.essentials.api.hologram.configuration.BlockHologramConfiguration;
import fr.maxlego08.essentials.api.hologram.configuration.HologramConfiguration;
import fr.maxlego08.essentials.api.hologram.configuration.ItemHologramConfiguration;
import fr.maxlego08.essentials.api.hologram.configuration.TextHologramConfiguration;
import fr.maxlego08.essentials.api.utils.ReflectionUtils;
import fr.maxlego08.essentials.api.utils.SafeLocation;
import io.papermc.paper.adventure.PaperAdventure;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket;
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerEntity;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Brightness;
import net.minecraft.world.entity.Display;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.PositionMoveRotation;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.joml.Quaternionf;

import java.util.ArrayList;
import java.util.Set;

public class CraftHologram extends Hologram {

private Display display = null;

public CraftHologram(EssentialsPlugin plugin, HologramType hologramType, HologramConfiguration configuration, String fileName, String name, SafeLocation location) {
super(plugin, hologramType, name, fileName, location, configuration);
}

@Override
public void create(Player player) {
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
ServerEntity serverEntity = new ServerEntity(serverPlayer.level(), display, 0, false, packet -> {
}, (a, b) -> {
}, Set.of());
send(player, new ClientboundAddEntityPacket(display, serverEntity));

this.update(player);
}

@Override
public void delete(Player player) {
this.send(player, new ClientboundRemoveEntitiesPacket(display.getId()));
}

@Override
public void update(Player player) {

send(player, new ClientboundTeleportEntityPacket(display.getId(), PositionMoveRotation.of(display), Set.of(), display.onGround));

if (display instanceof Display.TextDisplay textDisplay) {
textDisplay.setText(PaperAdventure.asVanilla(getComponentText(player)));
}

final var values = new ArrayList<SynchedEntityData.DataValue<?>>();
for (final var item : ((SynchedEntityData.DataItem<?>[]) ReflectionUtils.getValue(display.getEntityData(), "itemsById"))) {
values.add(item.value());
}
send(player, new ClientboundSetEntityDataPacket(display.getId(), values));
}

@Override
public void create() {
ServerLevel serverLevel = ((CraftWorld) location.getLocation().getWorld()).getHandle();
switch (hologramType) {
case BLOCK -> this.display = new Display.BlockDisplay(EntityType.BLOCK_DISPLAY, serverLevel);
case ITEM -> this.display = new Display.ItemDisplay(EntityType.ITEM_DISPLAY, serverLevel);
case TEXT -> this.display = new Display.TextDisplay(EntityType.TEXT_DISPLAY, serverLevel);
}

display.getEntityData().set((EntityDataAccessor<Integer>) ReflectionUtils.getStaticValue(Display.class, "DATA_TRANSFORMATION_INTERPOLATION_DURATION_ID"), 1); // Transformation duration
display.getEntityData().set((EntityDataAccessor<Integer>) ReflectionUtils.getStaticValue(Display.class, "DATA_TRANSFORMATION_INTERPOLATION_START_DELTA_TICKS_ID"), 0); // Interpolation start

this.updateLocation();
this.update();
}

@Override
public void updateLocation() {
display.setPosRaw(location.getX(), location.getY(), location.getZ());
display.setYRot(location.getYaw());
display.setXRot(location.getPitch());
}

@Override
public void update() {

display.setBillboardConstraints(switch (this.configuration.getBillboard()) {
case FIXED -> Display.BillboardConstraints.FIXED;
case VERTICAL -> Display.BillboardConstraints.VERTICAL;
case HORIZONTAL -> Display.BillboardConstraints.HORIZONTAL;
case CENTER -> Display.BillboardConstraints.CENTER;
});

if (display instanceof Display.TextDisplay textDisplay && configuration instanceof TextHologramConfiguration textHologramConfiguration) {

display.getEntityData().set((EntityDataAccessor<Integer>) ReflectionUtils.getStaticValue(Display.TextDisplay.class, "DATA_LINE_WIDTH_ID"), Hologram.LINE_WIDTH);

var backgroundColor = (EntityDataAccessor<Integer>) ReflectionUtils.getStaticValue(Display.TextDisplay.class, "DATA_BACKGROUND_COLOR_ID");
var background = textHologramConfiguration.getBackground();
int backgroundValue = (background == null) ? Display.TextDisplay.INITIAL_BACKGROUND : (background == Hologram.TRANSPARENT) ? 0 : background.value() | 0xC8000000;
display.getEntityData().set(backgroundColor, backgroundValue);

byte flags = textDisplay.getFlags();
flags = (byte) (textHologramConfiguration.isTextShadow() ? (flags | Display.TextDisplay.FLAG_SHADOW) : (flags & ~Display.TextDisplay.FLAG_SHADOW));
flags = (byte) (textHologramConfiguration.getTextAlignment() == org.bukkit.entity.TextDisplay.TextAlignment.LEFT ? (flags | Display.TextDisplay.FLAG_ALIGN_LEFT) : (flags & ~Display.TextDisplay.FLAG_ALIGN_LEFT));
flags = (byte) (textHologramConfiguration.isSeeThrough() ? (flags | Display.TextDisplay.FLAG_SEE_THROUGH) : (flags & ~Display.TextDisplay.FLAG_SEE_THROUGH));
flags = (byte) (textHologramConfiguration.getTextAlignment() == org.bukkit.entity.TextDisplay.TextAlignment.RIGHT ? (flags | Display.TextDisplay.FLAG_ALIGN_RIGHT) : (flags & ~Display.TextDisplay.FLAG_ALIGN_RIGHT));
textDisplay.setFlags(flags);
} else if (display instanceof Display.ItemDisplay itemDisplay && configuration instanceof ItemHologramConfiguration itemHologramConfiguration) {

var context = switch (itemHologramConfiguration.getItemDisplayTransform()) {
case THIRDPERSON_LEFTHAND -> ItemDisplayContext.THIRD_PERSON_LEFT_HAND;
case THIRDPERSON_RIGHTHAND -> ItemDisplayContext.THIRD_PERSON_RIGHT_HAND;
case FIRSTPERSON_LEFTHAND -> ItemDisplayContext.FIRST_PERSON_LEFT_HAND;
case FIRSTPERSON_RIGHTHAND -> ItemDisplayContext.FIRST_PERSON_RIGHT_HAND;
default -> ItemDisplayContext.valueOf(itemHologramConfiguration.getItemDisplayTransform().name());
};
itemDisplay.setItemTransform(context);
itemDisplay.setItemStack(ItemStack.fromBukkitCopy(itemHologramConfiguration.getItemStack()));
} else if (display instanceof Display.BlockDisplay blockDisplay && configuration instanceof BlockHologramConfiguration blockData) {

var optional = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(blockData.getMaterial().name().toLowerCase()));
if (optional.isPresent()) {
Block block = optional.get().value();
blockDisplay.setBlockState(block.defaultBlockState());
}
}

if (this.configuration.getBrightness() != null) {
display.setBrightnessOverride(new Brightness(this.configuration.getBrightness().getBlockLight(), this.configuration.getBrightness().getSkyLight()));
}

display.setTransformation(new Transformation(this.configuration.getTranslation(), new Quaternionf(), this.configuration.getScale(), new Quaternionf()));

display.setShadowRadius(this.configuration.getShadowRadius());
display.setShadowStrength(this.configuration.getShadowStrength());
}

private void send(Player player, Packet<?> packet) {
((CraftPlayer) player).getHandle().connection.send(packet);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package fr.maxlego08.essentials.nms.v1_21_5;

import fr.maxlego08.essentials.api.EssentialsPlugin;
import fr.maxlego08.essentials.api.nms.PlayerUtil;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;

public class PlayerUtils implements PlayerUtil {

private final EssentialsPlugin plugin;

public PlayerUtils(EssentialsPlugin plugin) {
this.plugin = plugin;
}

@Override
public boolean openEnderChest(Player player, OfflinePlayer offlinePlayer) {

/*CraftPlayerManager craftPlayerManager = new CraftPlayerManager(plugin.getLogger());
var loadPlayer = craftPlayerManager.loadPlayer(offlinePlayer);

if (loadPlayer != null) {
EnderChestHolder enderChestHolder = new EnderChestHolder(loadPlayer);
player.openInventory(enderChestHolder.getInventory());
return true;
}*/
return false;
}

@Override
public boolean openPlayerInventory(Player player, OfflinePlayer offlinePlayer) {
/*CraftPlayerManager craftPlayerManager = new CraftPlayerManager(plugin.getLogger());
var loadPlayer = craftPlayerManager.loadPlayer(offlinePlayer);

if (loadPlayer != null) {
PlayerInventoryHolder enderChestHolder = new PlayerInventoryHolder(loadPlayer);
player.openInventory(enderChestHolder.getInventory());
return true;
}*/
return false;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package fr.maxlego08.essentials.nms.v1_21_5;

import fr.maxlego08.essentials.api.waypoint.WayPointHelper;
import fr.maxlego08.essentials.api.waypoint.WayPointIcon;
import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundTrackedWaypointPacket;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.waypoints.Waypoint;
import net.minecraft.world.waypoints.WaypointStyleAssets;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Player;

import java.util.Optional;
import java.util.UUID;

public class WayPointPacket implements WayPointHelper {

@Override
public void addWayPoint(Player player, UUID uniqueId, Location location, WayPointIcon wayPointIcon) {

var icon = toIcon(wayPointIcon);
var blockPos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
var packet = ClientboundTrackedWaypointPacket.addWaypointPosition(uniqueId, icon, blockPos);

sendPacket(player, packet);
}

@Override
public void updateWayPointPosition(Player player, UUID uniqueId, Location location, WayPointIcon wayPointIcon) {

var icon = toIcon(wayPointIcon);
var blockPos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
var packet = ClientboundTrackedWaypointPacket.updateWaypointPosition(uniqueId, icon, blockPos);

sendPacket(player, packet);
}

@Override
public void addWayPoint(Player player, UUID uniqueId, Chunk chunk, WayPointIcon wayPointIcon) {

var icon = toIcon(wayPointIcon);
var chunkPos = new ChunkPos(chunk.getX(), chunk.getZ());
var packet = ClientboundTrackedWaypointPacket.addWaypointChunk(uniqueId, icon, chunkPos);

sendPacket(player, packet);
}

@Override
public void updateWayPointPosition(Player player, UUID uniqueId, Chunk chunk, WayPointIcon wayPointIcon) {

var icon = toIcon(wayPointIcon);
var chunkPos = new ChunkPos(chunk.getX(), chunk.getZ());
var packet = ClientboundTrackedWaypointPacket.updateWaypointChunk(uniqueId, icon, chunkPos);

sendPacket(player, packet);
}

@Override
public void removeWayPoint(Player player, UUID uniqueId) {

var packet = ClientboundTrackedWaypointPacket.removeWaypoint(uniqueId);
sendPacket(player, packet);
}

private void sendPacket(Player player, Packet<?> packet) {
((CraftPlayer) player).getHandle().connection.send(packet);
}

/**
* Converts a {@link WayPointIcon} to a {@link Waypoint.Icon}.
* <p>
* If the given {@link WayPointIcon} has a texture, then the style of the resulting icon will be set to the
* death waypoint style. Otherwise, the style will be left unchanged.
* <p>
* The color of the resulting icon will be set to the color of the given {@link WayPointIcon}.
*
* @param wayPointIcon the icon to convert
* @return the converted icon
*/
private Waypoint.Icon toIcon(WayPointIcon wayPointIcon) {
var icon = new Waypoint.Icon();
if (wayPointIcon.texture() != null) {
icon.style = WaypointStyleAssets.createId(wayPointIcon.texture());
}
icon.color = Optional.of(wayPointIcon.color().getRGB() & 0xFFFFFF);
return icon;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package fr.maxlego08.essentials.nms.v1_21_5.enderchest;

import org.apache.commons.lang3.NotImplementedException;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* Based on: <a href="https://github.com/Jikoo/OpenInv/tree/master">OpenInv</a>
*/
public class CraftPlayerManager implements fr.maxlego08.essentials.api.nms.PlayerManager {


@Override
public @Nullable Player loadPlayer(@NotNull OfflinePlayer offline) {
throw new NotImplementedException();
}

@Override
public @NotNull Player inject(@NotNull Player player) {
throw new NotImplementedException();
}
}
20 changes: 20 additions & 0 deletions NMS/V1_21_6/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
plugins {
id("io.papermc.paperweight.userdev")
}

group "NMS:V1_21_6"

dependencies {
compileOnly(project(":API"))
paperweight.paperDevBundle("1.21.6-R0.1-SNAPSHOT")
}

paperweight.reobfArtifactConfiguration = io.papermc.paperweight.userdev.ReobfArtifactConfiguration.REOBF_PRODUCTION

java {
toolchain.languageVersion = JavaLanguageVersion.of(21)
}

tasks.assemble {
dependsOn(tasks.reobfJar)
}
Loading
Loading