diff --git a/build.gradle.kts b/build.gradle.kts index 5d5fd49e..8b2e2bbd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -74,6 +74,7 @@ allprojects { dependencies { implementation(project(path = ":common")) + implementation(project(path = ":v1_18_R2", configuration = "reobf")) implementation(project(path = ":v1_19_R1", configuration = "reobf")) implementation(project(path = ":v1_19_R2", configuration = "reobf")) @@ -108,6 +109,7 @@ tasks { } shadowJar { + dependsOn(":v1_18_R2:reobfJar") dependsOn(":v1_19_R1:reobfJar") dependsOn(":v1_19_R2:reobfJar") mergeServiceFiles() @@ -144,7 +146,7 @@ tasks { bukkit { load = BukkitPluginDescription.PluginLoadOrder.POSTWORLD main = "com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin" - apiVersion = "1.19" + apiVersion = "1.16" authors = listOf("LoJoSho") depend = listOf("ProtocolLib", "PlaceholderAPI") softDepend = listOf("ModelEngine", "Oraxen", "ItemsAdder", "HMCColor", "WorldGuard", "MythicMobs") diff --git a/common/src/main/java/com/hibiscusmc/hmccosmetics/nms/NMSHandlers.java b/common/src/main/java/com/hibiscusmc/hmccosmetics/nms/NMSHandlers.java index cad71d8f..4bdb9874 100644 --- a/common/src/main/java/com/hibiscusmc/hmccosmetics/nms/NMSHandlers.java +++ b/common/src/main/java/com/hibiscusmc/hmccosmetics/nms/NMSHandlers.java @@ -8,7 +8,7 @@ import java.util.logging.Level; public class NMSHandlers { - private static final String[] SUPPORTED_VERSION = new String[]{"v1_19_R1", "v1_19_R2"}; + private static final String[] SUPPORTED_VERSION = new String[]{"v1_18_R2", "v1_19_R1", "v1_19_R2"}; private static NMSHandler handler; private static String version; diff --git a/settings.gradle.kts b/settings.gradle.kts index 62692f60..c466ff59 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,6 +7,7 @@ pluginManagement { rootProject.name = "HMCCosmetics" include( "common", + "v1_18_R2", "v1_19_R1", "v1_19_R2" ) diff --git a/v1_18_R2/build.gradle.kts b/v1_18_R2/build.gradle.kts new file mode 100644 index 00000000..90085440 --- /dev/null +++ b/v1_18_R2/build.gradle.kts @@ -0,0 +1,27 @@ +plugins { + id("java") + id("io.papermc.paperweight.userdev") version "1.3.8" +} + +dependencies { + paperDevBundle("1.18.2-R0.1-SNAPSHOT") + implementation(project(":common")) +} + +tasks { + + build { + dependsOn(reobfJar) + } + + compileJava { + options.encoding = Charsets.UTF_8.name() + options.release.set(17) + } + javadoc { + options.encoding = Charsets.UTF_8.name() + } + processResources { + filteringCharset = Charsets.UTF_8.name() + } +} \ No newline at end of file diff --git a/v1_18_R2/src/main/java/com/hibiscusmc/hmccosmetics/nms/v1_18_R2/InvisibleArmorstand.java b/v1_18_R2/src/main/java/com/hibiscusmc/hmccosmetics/nms/v1_18_R2/InvisibleArmorstand.java new file mode 100644 index 00000000..e7146b87 --- /dev/null +++ b/v1_18_R2/src/main/java/com/hibiscusmc/hmccosmetics/nms/v1_18_R2/InvisibleArmorstand.java @@ -0,0 +1,24 @@ +package com.hibiscusmc.hmccosmetics.nms.v1_18_R2; + +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.level.Level; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; + +public class InvisibleArmorstand extends ArmorStand { + + public InvisibleArmorstand(Level world, double x, double y, double z) { + super(world, x, y, z); + } + + public InvisibleArmorstand(Location loc) { + super(((CraftWorld) loc.getWorld()).getHandle(), loc.getX(), loc.getY(), loc.getZ()); + this.setPos(loc.getX(), loc.getY(), loc.getZ()); + setInvisible(true); + setInvulnerable(true); + setMarker(true); + setSilent(true); + getBukkitLivingEntity().setCollidable(false); + persist = false; + } +} diff --git a/v1_18_R2/src/main/java/com/hibiscusmc/hmccosmetics/nms/v1_18_R2/MEGEntity.java b/v1_18_R2/src/main/java/com/hibiscusmc/hmccosmetics/nms/v1_18_R2/MEGEntity.java new file mode 100644 index 00000000..9a3a2b85 --- /dev/null +++ b/v1_18_R2/src/main/java/com/hibiscusmc/hmccosmetics/nms/v1_18_R2/MEGEntity.java @@ -0,0 +1,31 @@ +package com.hibiscusmc.hmccosmetics.nms.v1_18_R2; + +import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; +import com.hibiscusmc.hmccosmetics.util.MessagesUtil; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.decoration.ArmorStand; +import org.bukkit.Location; +import org.bukkit.NamespacedKey; +import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; +import org.bukkit.persistence.PersistentDataType; + +public class MEGEntity extends ArmorStand { + + public MEGEntity(Location loc) { + super(EntityType.ARMOR_STAND, ((CraftWorld) loc.getWorld()).getHandle()); + this.setPos(loc.getX(), loc.getY(), loc.getZ()); + + MessagesUtil.sendDebugMessages("Spawned MEGEntity at " + loc); + setInvisible(true); + setNoGravity(true); + setSilent(true); + setInvulnerable(true); + setSmall(true); + setMarker(true); + + persist = false; + getBukkitEntity().getPersistentDataContainer().set(new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmeticMob"), PersistentDataType.SHORT, Short.valueOf("1")); + + ((CraftWorld) loc.getWorld()).getHandle().addFreshEntity(this); + } +} diff --git a/v1_18_R2/src/main/java/com/hibiscusmc/hmccosmetics/nms/v1_18_R2/NMSHandler.java b/v1_18_R2/src/main/java/com/hibiscusmc/hmccosmetics/nms/v1_18_R2/NMSHandler.java new file mode 100644 index 00000000..d9d1fa4b --- /dev/null +++ b/v1_18_R2/src/main/java/com/hibiscusmc/hmccosmetics/nms/v1_18_R2/NMSHandler.java @@ -0,0 +1,244 @@ +package com.hibiscusmc.hmccosmetics.nms.v1_18_R2; + +import com.hibiscusmc.hmccosmetics.config.Settings; +import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; +import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType; +import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType; +import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType; +import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticMainhandType; +import com.hibiscusmc.hmccosmetics.entities.BalloonEntity; +import com.hibiscusmc.hmccosmetics.user.CosmeticUser; +import com.hibiscusmc.hmccosmetics.util.InventoryUtils; +import com.hibiscusmc.hmccosmetics.util.MessagesUtil; +import com.hibiscusmc.hmccosmetics.util.PlayerUtils; +import com.hibiscusmc.hmccosmetics.util.packets.PacketManager; +import com.mojang.datafixers.util.Pair; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; +import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; +import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerPlayerConnection; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.scores.PlayerTeam; +import net.minecraft.world.scores.Team; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_18_R2.CraftEquipmentSlot; +import org.bukkit.craftbukkit.v1_18_R2.CraftServer; +import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_18_R2.scoreboard.CraftScoreboard; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class NMSHandler implements com.hibiscusmc.hmccosmetics.nms.NMSHandler { + @Override + public int getNextEntityId() { + return Entity.nextEntityId(); + } + + @Override + public org.bukkit.entity.Entity getEntity(int entityId) { + net.minecraft.world.entity.Entity entity = getNMSEntity(entityId); + if (entity == null) return null; + return entity.getBukkitEntity(); + } + + private net.minecraft.world.entity.Entity getNMSEntity(int entityId) { + for (ServerLevel world : ((CraftServer) Bukkit.getServer()).getHandle().getServer().getAllLevels()) { + net.minecraft.world.entity.Entity entity = world.getEntity(entityId); + if (entity == null) return null; + return entity; + } + return null; + } + + @Override + public org.bukkit.entity.Entity getInvisibleArmorstand(Location loc) { + InvisibleArmorstand invisibleArmorstand = new InvisibleArmorstand(loc); + return invisibleArmorstand.getBukkitEntity(); + } + + @Override + public ArmorStand getMEGEntity(Location loc) { + return (ArmorStand) new MEGEntity(loc).getBukkitEntity(); + } + + @Override + public org.bukkit.entity.Entity spawnBackpack(CosmeticUser user, CosmeticBackpackType cosmeticBackpackType) { + InvisibleArmorstand invisibleArmorstand = new InvisibleArmorstand(user.getPlayer().getLocation()); + + ItemStack item = user.getUserCosmeticItem(cosmeticBackpackType); + + invisibleArmorstand.setItemSlot(EquipmentSlot.HEAD, CraftItemStack.asNMSCopy(item)); + ((CraftWorld) user.getPlayer().getWorld()).getHandle().addFreshEntity(invisibleArmorstand, CreatureSpawnEvent.SpawnReason.CUSTOM); + + MessagesUtil.sendDebugMessages("spawnBackpack NMS"); + + return invisibleArmorstand.getBukkitLivingEntity(); + //PacketManager.armorStandMetaPacket(invisibleArmorstand.getBukkitEntity(), sentTo); + //PacketManager.ridingMountPacket(player.getEntityId(), invisibleArmorstand.getId(), sentTo); + + } + + + + @Override + public BalloonEntity spawnBalloon(CosmeticUser user, CosmeticBalloonType cosmeticBalloonType) { + Player player = user.getPlayer(); + Location newLoc = player.getLocation().clone().add(Settings.getBalloonOffset()); + + BalloonEntity balloonEntity1 = new BalloonEntity(user.getPlayer().getLocation()); + List sentTo = PlayerUtils.getNearbyPlayers(player.getLocation()); + balloonEntity1.getModelEntity().teleport(user.getPlayer().getLocation().add(Settings.getBalloonOffset())); + + balloonEntity1.spawnModel(cosmeticBalloonType, user.getCosmeticColor(cosmeticBalloonType.getSlot())); + balloonEntity1.addPlayerToModel(player, cosmeticBalloonType, user.getCosmeticColor(cosmeticBalloonType.getSlot())); + + PacketManager.sendEntitySpawnPacket(newLoc, balloonEntity1.getPufferfishBalloonId(), EntityType.PUFFERFISH, balloonEntity1.getPufferfishBalloonUniqueId(), sentTo); + PacketManager.sendInvisibilityPacket(balloonEntity1.getPufferfishBalloonId(), sentTo); + PacketManager.sendLeashPacket(balloonEntity1.getPufferfishBalloonId(), player.getEntityId(), sentTo); + + return balloonEntity1; + } + + @Override + public void equipmentSlotUpdate( + int entityId, + CosmeticUser user, + CosmeticSlot cosmeticSlot, + List sendTo + ) { + + EquipmentSlot nmsSlot = null; + net.minecraft.world.item.ItemStack nmsItem = null; + + if (!(user.getCosmetic(cosmeticSlot) instanceof CosmeticArmorType)) { + + if (user.getCosmetic(cosmeticSlot) instanceof CosmeticMainhandType) { + CosmeticMainhandType cosmeticMainhandType = (CosmeticMainhandType) user.getCosmetic(CosmeticSlot.MAINHAND); + nmsItem = CraftItemStack.asNMSCopy(user.getUserCosmeticItem(cosmeticMainhandType)); + } else { + nmsItem = CraftItemStack.asNMSCopy(user.getPlayer().getInventory().getItem(InventoryUtils.getEquipmentSlot(cosmeticSlot))); + } + + nmsSlot = CraftEquipmentSlot.getNMS(InventoryUtils.getEquipmentSlot(cosmeticSlot)); + + if (nmsSlot == null) return; + + Pair pair = new Pair<>(nmsSlot, nmsItem); + + List> pairs = Collections.singletonList(pair); + + ClientboundSetEquipmentPacket packet = new ClientboundSetEquipmentPacket(entityId, pairs); + for (Player p : sendTo) sendPacket(p, packet); + return; + } + CosmeticArmorType cosmeticArmor = (CosmeticArmorType) user.getCosmetic(cosmeticSlot); + + // Converting EquipmentSlot and ItemStack to NMS ones. + nmsSlot = CraftEquipmentSlot.getNMS(cosmeticArmor.getEquipSlot()); + nmsItem = CraftItemStack.asNMSCopy(user.getUserCosmeticItem(cosmeticArmor)); + + if (nmsSlot == null) return; + + Pair pair = new Pair<>(nmsSlot, nmsItem); + + List> pairs = Collections.singletonList(pair); + + ClientboundSetEquipmentPacket packet = new ClientboundSetEquipmentPacket(entityId, pairs); + for (Player p : sendTo) sendPacket(p, packet); + } + + + @Override + public void equipmentSlotUpdate( + int entityId, + org.bukkit.inventory.EquipmentSlot slot, + ItemStack item, + List sendTo + ) { + + EquipmentSlot nmsSlot = null; + net.minecraft.world.item.ItemStack nmsItem = null; + + // Converting EquipmentSlot and ItemStack to NMS ones. + nmsSlot = CraftEquipmentSlot.getNMS(slot); + nmsItem = CraftItemStack.asNMSCopy(item); + + if (nmsSlot == null) return; + + Pair pair = new Pair<>(nmsSlot, nmsItem); + + List> pairs = Collections.singletonList(pair); + + ClientboundSetEquipmentPacket packet = new ClientboundSetEquipmentPacket(entityId, pairs); + for (Player p : sendTo) sendPacket(p, packet); + } + + + @Override + public void slotUpdate( + Player player, + int slot + ) { + int index = 0; + + ServerPlayer player1 = ((CraftPlayer) player).getHandle(); + + if (index < Inventory.getSelectionSize()) { + index += 36; + } else if (index > 39) { + index += 5; // Off hand + } else if (index > 35) { + index = 8 - (index - 36); + } + ItemStack item = player.getInventory().getItem(slot); + + Packet packet = new ClientboundContainerSetSlotPacket(player1.inventoryMenu.containerId, player1.inventoryMenu.incrementStateId(), index, CraftItemStack.asNMSCopy(item)); + sendPacket(player, packet); + } + + public void hideNPCName(Player player, String NPCName) { + //Creating the team + PlayerTeam team = new PlayerTeam(((CraftScoreboard) Bukkit.getScoreboardManager().getMainScoreboard()).getHandle(), NPCName); + + //Setting name visibility + team.setNameTagVisibility(Team.Visibility.NEVER); + + //Remove the Team (i assume so if it exists) + ClientboundSetPlayerTeamPacket removeTeamPacket = ClientboundSetPlayerTeamPacket.createRemovePacket(team); + sendPacket(player, removeTeamPacket); + //Creating the Team + ClientboundSetPlayerTeamPacket createTeamPacket = ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, true); + sendPacket(player, createTeamPacket); + //Adding players to the team (You have to use the NPC's name, and add it to a list) + ClientboundSetPlayerTeamPacket createPlayerTeamPacket = ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, new ArrayList() {{ + add(NPCName); + }}, ClientboundSetPlayerTeamPacket.Action.ADD); + sendPacket(player, createPlayerTeamPacket); + } + + public void sendPacket(Player player, Packet packet) { + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + ServerPlayerConnection connection = serverPlayer.connection; + connection.send(packet); + } + + @Override + public boolean getSupported() { + return true; + } +}