NullValkyrie

Minecraft 1.19 multipurpose plugin for spigot servers with a lot of features where most modern servers have.
git clone https://codeberg.org/night0721/NullValkyrie
Log | Files | Refs | README | LICENSE

NPCManager.java (6693B)


      1 package me.night.nullvalkyrie.entities.npcs;
      2 
      3 import com.mojang.authlib.GameProfile;
      4 import com.mojang.authlib.properties.Property;
      5 import com.mojang.datafixers.util.Pair;
      6 import me.night.nullvalkyrie.NullValkyrie;
      7 import me.night.nullvalkyrie.database.NPCDataManager;
      8 import me.night.nullvalkyrie.packets.protocol.PacketPlayOutEntityMetadata;
      9 import me.night.nullvalkyrie.util.*;
     10 import net.minecraft.network.protocol.game.*;
     11 import net.minecraft.network.syncher.*;
     12 import net.minecraft.server.MinecraftServer;
     13 import net.minecraft.server.level.ServerLevel;
     14 import net.minecraft.server.level.ServerPlayer;
     15 import net.minecraft.server.network.ServerGamePacketListenerImpl;
     16 import net.minecraft.world.entity.EquipmentSlot;
     17 import org.bukkit.Bukkit;
     18 import org.bukkit.Location;
     19 import org.bukkit.Material;
     20 import org.bukkit.craftbukkit.v1_19_R1.CraftServer;
     21 import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
     22 import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer;
     23 import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack;
     24 import org.bukkit.entity.Player;
     25 import org.bukkit.inventory.ItemStack;
     26 
     27 import java.util.ArrayList;
     28 import java.util.HashMap;
     29 import java.util.List;
     30 import java.util.UUID;
     31 
     32 public class NPCManager {
     33     private static final HashMap<Integer, ServerPlayer> NPCs = new HashMap<>();
     34 
     35     public static HashMap<Integer, ServerPlayer> getNPCs() {
     36         return NPCs;
     37     }
     38     @SuppressWarnings("ConstantConditions")
     39     public static void createNPC(Player player, String name) { // name must be less than 16 characters including color codes
     40         ServerPlayer sp = ((CraftPlayer) player).getHandle();
     41         MinecraftServer server = sp.server;
     42         ServerLevel level = ((CraftWorld) player.getLocation().getWorld()).getHandle();
     43         GameProfile gameProfile = new GameProfile(UUID.randomUUID(), Util.color(name));
     44         String[] skin = Skin.getSkin(player);
     45         gameProfile.getProperties().put("textures", new Property("textures", skin[0], skin[1]));
     46         ServerPlayer npc = new ServerPlayer(server, level, gameProfile, null);
     47         Location location = player.getLocation();
     48         npc.setPos(location.getX(), location.getY(), location.getZ());
     49         addNPCPacket(npc);
     50         NPCs.put(npc.getId(), npc);
     51         NPCDataManager.setNPC(name, player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), (int) player.getLocation().getPitch(), (int) player.getLocation().getYaw(), player.getLocation().getWorld().getName(), skin[0], skin[1]);
     52     }
     53 
     54     public static void addNPCPacket(ServerPlayer npc) {
     55         for (Player player : Bukkit.getOnlinePlayers()) {
     56             ServerGamePacketListenerImpl pc = ((CraftPlayer) player).getHandle().connection;
     57             pc.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, npc));
     58             pc.send(new ClientboundAddPlayerPacket(npc));
     59             pc.send(new ClientboundRotateHeadPacket(npc, (byte) (npc.getBukkitYaw() * 256 / 360)));
     60             SynchedEntityData watcher = npc.getEntityData();
     61             watcher.set(new EntityDataAccessor<>(17, EntityDataSerializers.BYTE), (byte) 127);
     62             new PacketPlayOutEntityMetadata(player, npc, watcher);
     63             Bukkit.getScheduler().runTaskLaterAsynchronously(NullValkyrie.getPlugin(NullValkyrie.class), () -> pc.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.REMOVE_PLAYER, npc)), 50);
     64             ItemStack netheriteAxe = new ItemStack(Material.NETHERITE_AXE);
     65             ItemStack anotherAxe = new ItemStack(Material.NETHERITE_INGOT);
     66             List<Pair<EquipmentSlot, net.minecraft.world.item.ItemStack>> itemList = new ArrayList<>();
     67             itemList.add(new Pair<>(EquipmentSlot.MAINHAND, CraftItemStack.asNMSCopy(netheriteAxe)));
     68             itemList.add(new Pair<>(EquipmentSlot.OFFHAND, CraftItemStack.asNMSCopy(anotherAxe)));
     69             pc.send(new ClientboundSetEquipmentPacket(npc.getBukkitEntity().getEntityId(), itemList));
     70         }
     71     }
     72 
     73     public static void addJoinPacket(Player player) {
     74         for (ServerPlayer npc : NPCs.values()) {
     75             ServerGamePacketListenerImpl pc = ((CraftPlayer) player).getHandle().connection;
     76             pc.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, npc));
     77             pc.send(new ClientboundAddPlayerPacket(npc));
     78             pc.send(new ClientboundRotateHeadPacket(npc, (byte) (npc.getBukkitYaw() * 256 / 360)));
     79             SynchedEntityData watcher = npc.getEntityData();
     80             watcher.set(new EntityDataAccessor<>(17, EntityDataSerializers.BYTE), (byte) 127);
     81             new PacketPlayOutEntityMetadata(player, npc, watcher);
     82             Bukkit.getScheduler().runTaskLaterAsynchronously(NullValkyrie.getPlugin(NullValkyrie.class), () -> pc.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.REMOVE_PLAYER, npc)), 50);
     83             ItemStack netheriteAxe = new ItemStack(Material.NETHERITE_AXE);
     84             ItemStack anotherAxe = new ItemStack(Material.NETHERITE_INGOT);
     85             List<Pair<EquipmentSlot, net.minecraft.world.item.ItemStack>> itemList = new ArrayList<>();
     86             itemList.add(new Pair<>(EquipmentSlot.MAINHAND, CraftItemStack.asNMSCopy(netheriteAxe)));
     87             itemList.add(new Pair<>(EquipmentSlot.OFFHAND, CraftItemStack.asNMSCopy(anotherAxe)));
     88             pc.send(new ClientboundSetEquipmentPacket(npc.getBukkitEntity().getEntityId(), itemList));
     89         }
     90     }
     91     @SuppressWarnings("ConstantConditions")
     92     public static void reloadNPC(List<HashMap<String, Object>> npcs) {
     93         for (HashMap<String, Object> npc : npcs) {
     94             Location location = new Location(Bukkit.getWorld((String) npc.get("world")), (double) npc.get("x"), (double) npc.get("y"), (double) npc.get("z"), (int) npc.get("yaw"), (int) npc.get("pitch"));
     95             GameProfile gameProfile = new GameProfile(UUID.randomUUID(), Util.color((String) npc.get("name")));
     96             gameProfile.getProperties().put("textures", new Property("textures", (String) npc.get("texture"), (String) npc.get("signature")));
     97             MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer();
     98             ServerLevel w = ((CraftWorld) location.getWorld()).getHandle();
     99             ServerPlayer ep = new ServerPlayer(server, w, gameProfile, null);
    100             ep.setPos(location.getX(), location.getY(), location.getZ()); // NMS: 1.19.2 https://nms.screamingsandals.org/1.19.2/net/minecraft/world/entity/Entity.html absMoveTo
    101             addNPCPacket(ep);
    102             NPCs.put(ep.getId(), ep);
    103         }
    104     }
    105     public static ServerPlayer getNPC(int id) {
    106         return NPCs.get(id);
    107     }
    108 }