diff --git a/CombatTagPlus/pom.xml b/CombatTagPlus/pom.xml index 3ad8e6e..f3ebf9b 100644 --- a/CombatTagPlus/pom.xml +++ b/CombatTagPlus/pom.xml @@ -5,15 +5,15 @@ CombatTagPlusParent net.minelink - 1.3.3-SNAPSHOT + 1.4.0-SNAPSHOT 4.0.0 CombatTagPlus - 1.8 - 1.8 + 16 + 16 @@ -28,7 +28,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.1 + 3.3.0-SNAPSHOT false @@ -53,7 +53,7 @@ byteflux-repo - http://repo.byteflux.net/repository/maven-public/ + https://repo.byteflux.net/repository/maven-public/ spigot-repo @@ -63,51 +63,51 @@ - org.spigotmc - spigot - 1.16.1-R0.1-SNAPSHOT + io.papermc.paper + paper + 1.17.1-R0.1-SNAPSHOT provided net.minelink CombatTagPlusCompat-API - 1.3.3-SNAPSHOT + 1.4.0-SNAPSHOT compile + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + net.minelink - CombatTagPlusCompat-v1_12_R1 - 1.3.3-SNAPSHOT - compile - - - net.minelink - CombatTagPlusCompat-v1_13_R2 - 1.3.3-SNAPSHOT - compile - - - net.minelink - CombatTagPlusCompat-v1_14_R1 - 1.3.3-SNAPSHOT - compile - - - net.minelink - CombatTagPlusCompat-v1_15_R1 - 1.3.3-SNAPSHOT - compile - - - net.minelink - CombatTagPlusCompat-v1_16_R1 - 1.3.3-SNAPSHOT - compile - - - net.minelink - CombatTagPlusCompat-v1_16_R3 - 1.3.3-SNAPSHOT + CombatTagPlusCompat-v1_17_R1 + 1.4.0-SNAPSHOT compile @@ -116,12 +116,12 @@ 1.3.3-SNAPSHOT compile - - net.minelink - CombatTagPlusFactions-v2_7 - 1.3.3-SNAPSHOT - compile - + + + + + + net.minelink CombatTagPlusWG-v7 diff --git a/CombatTagPlus/src/main/resources/plugin.yml b/CombatTagPlus/src/main/resources/plugin.yml index 289f555..e1d7ccf 100644 --- a/CombatTagPlus/src/main/resources/plugin.yml +++ b/CombatTagPlus/src/main/resources/plugin.yml @@ -4,7 +4,7 @@ version: ${version} authors: [Byteflux, Sudzzy] main: net.minelink.ctplus.CombatTagPlus softdepend: [BarAPI, PlayerHeads, WorldGuard, Factions, Towny, BossBarAPI, ActionBarAPI, mcMMO] -api-version: 1.14 +api-version: 1.17 commands: combattagplus: aliases: [ctplus, ct, combattag] diff --git a/CombatTagPlusCompat-API/pom.xml b/CombatTagPlusCompat-API/pom.xml index 07d66fa..b9e02fb 100644 --- a/CombatTagPlusCompat-API/pom.xml +++ b/CombatTagPlusCompat-API/pom.xml @@ -5,7 +5,7 @@ CombatTagPlusParent net.minelink - 1.3.3-SNAPSHOT + 1.4.0-SNAPSHOT 4.0.0 diff --git a/CombatTagPlusCompat-v1_16_R3/pom.xml b/CombatTagPlusCompat-v1_16_R3/pom.xml old mode 100644 new mode 100755 index 413fdc9..0332b31 --- a/CombatTagPlusCompat-v1_16_R3/pom.xml +++ b/CombatTagPlusCompat-v1_16_R3/pom.xml @@ -15,7 +15,7 @@ com.destroystokyo.paper paper - 1.16.4-R0.1-SNAPSHOT + 1.16.5-R0.1-SNAPSHOT provided diff --git a/CombatTagPlusCompat-v1_17_R1/pom.xml b/CombatTagPlusCompat-v1_17_R1/pom.xml new file mode 100644 index 0000000..cab1c37 --- /dev/null +++ b/CombatTagPlusCompat-v1_17_R1/pom.xml @@ -0,0 +1,28 @@ + + + + CombatTagPlusParent + net.minelink + 1.4.0-SNAPSHOT + + 4.0.0 + + CombatTagPlusCompat-v1_17_R1 + + + + io.papermc.paper + paper + 1.17.1-R0.1-SNAPSHOT + provided + + + net.minelink + CombatTagPlusCompat-API + 1.4.0-SNAPSHOT + provided + + + diff --git a/CombatTagPlusCompat-v1_17_R1/src/main/java/net/minelink/ctplus/compat/v1_17_R1/NpcNetworkManager.java b/CombatTagPlusCompat-v1_17_R1/src/main/java/net/minelink/ctplus/compat/v1_17_R1/NpcNetworkManager.java new file mode 100644 index 0000000..0e33f17 --- /dev/null +++ b/CombatTagPlusCompat-v1_17_R1/src/main/java/net/minelink/ctplus/compat/v1_17_R1/NpcNetworkManager.java @@ -0,0 +1,83 @@ +package net.minelink.ctplus.compat.v1_17_R1; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.util.concurrent.GenericFutureListener; +import java.net.SocketAddress; +import net.minecraft.network.EnumProtocol; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.PacketListener; +import net.minecraft.network.protocol.EnumProtocolDirection; +import net.minecraft.network.protocol.Packet; + +public final class NpcNetworkManager extends NetworkManager { + + public NpcNetworkManager() { + super(EnumProtocolDirection.a); + } + + @Override + public void channelActive(ChannelHandlerContext channelhandlercontext) throws Exception { + + } + + @Override + public void setProtocol(EnumProtocol enumprotocol) { + + } + + @Override + public void channelInactive(ChannelHandlerContext channelhandlercontext) { + + } + + @Override + public void exceptionCaught(ChannelHandlerContext channelhandlercontext, Throwable throwable) { + + } + + @Override + protected void channelRead0(ChannelHandlerContext channelhandlercontext, Packet packet) { + + } + + @Override + public void setPacketListener(PacketListener packetlistener) { + + } + + @Override + public void sendPacket(Packet packet) { + + } + + @Override + public void sendPacket(Packet packet, GenericFutureListener genericfuturelistener) { + + } + + @Override + public SocketAddress getSocketAddress() { + return new SocketAddress() {}; + } + + @Override + public boolean isLocal() { + return false; + } + + @Override + public boolean isConnected() { + return true; + } + + @Override + public void stopReading() { + + } + + @Override + public void handleDisconnection() { + + } + +} diff --git a/CombatTagPlusCompat-v1_17_R1/src/main/java/net/minelink/ctplus/compat/v1_17_R1/NpcPlayer.java b/CombatTagPlusCompat-v1_17_R1/src/main/java/net/minelink/ctplus/compat/v1_17_R1/NpcPlayer.java new file mode 100644 index 0000000..b4f40af --- /dev/null +++ b/CombatTagPlusCompat-v1_17_R1/src/main/java/net/minelink/ctplus/compat/v1_17_R1/NpcPlayer.java @@ -0,0 +1,45 @@ +package net.minelink.ctplus.compat.v1_17_R1; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import java.util.Map; +import java.util.UUID; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.EntityPlayer; +import net.minecraft.server.level.WorldServer; +import net.minelink.ctplus.compat.api.NpcIdentity; +import net.minelink.ctplus.compat.api.NpcNameGeneratorFactory; +import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; + +public final class NpcPlayer extends EntityPlayer { + + private NpcIdentity identity; + + private NpcPlayer(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile) { + super(minecraftserver, worldserver, gameprofile); + } + + public NpcIdentity getNpcIdentity() { + return identity; + } + + public static NpcPlayer valueOf(Player player) { + MinecraftServer minecraftServer = MinecraftServer.getServer(); + WorldServer worldServer = ((CraftWorld) player.getWorld()).getHandle(); + GameProfile gameProfile = new GameProfile(UUID.randomUUID(), NpcNameGeneratorFactory.getNameGenerator().generate(player)); + + for (Map.Entry entry: ((CraftPlayer) player).getProfile().getProperties().entries()) { + gameProfile.getProperties().put(entry.getKey(), entry.getValue()); + } + + NpcPlayer npcPlayer = new NpcPlayer(minecraftServer, worldServer, gameProfile); + npcPlayer.identity = new NpcIdentity(player); + + new NpcPlayerConnection(npcPlayer); + + return npcPlayer; + } + +} diff --git a/CombatTagPlusCompat-v1_17_R1/src/main/java/net/minelink/ctplus/compat/v1_17_R1/NpcPlayerConnection.java b/CombatTagPlusCompat-v1_17_R1/src/main/java/net/minelink/ctplus/compat/v1_17_R1/NpcPlayerConnection.java new file mode 100644 index 0000000..f5db7f0 --- /dev/null +++ b/CombatTagPlusCompat-v1_17_R1/src/main/java/net/minelink/ctplus/compat/v1_17_R1/NpcPlayerConnection.java @@ -0,0 +1,168 @@ +package net.minelink.ctplus.compat.v1_17_R1; + + +import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.PacketPlayInAbilities; +import net.minecraft.network.protocol.game.PacketPlayInArmAnimation; +import net.minecraft.network.protocol.game.PacketPlayInBlockDig; +import net.minecraft.network.protocol.game.PacketPlayInBlockPlace; +import net.minecraft.network.protocol.game.PacketPlayInChat; +import net.minecraft.network.protocol.game.PacketPlayInClientCommand; +import net.minecraft.network.protocol.game.PacketPlayInCloseWindow; +import net.minecraft.network.protocol.game.PacketPlayInCustomPayload; +import net.minecraft.network.protocol.game.PacketPlayInEnchantItem; +import net.minecraft.network.protocol.game.PacketPlayInEntityAction; +import net.minecraft.network.protocol.game.PacketPlayInFlying; +import net.minecraft.network.protocol.game.PacketPlayInHeldItemSlot; +import net.minecraft.network.protocol.game.PacketPlayInKeepAlive; +import net.minecraft.network.protocol.game.PacketPlayInResourcePackStatus; +import net.minecraft.network.protocol.game.PacketPlayInSetCreativeSlot; +import net.minecraft.network.protocol.game.PacketPlayInSettings; +import net.minecraft.network.protocol.game.PacketPlayInSpectate; +import net.minecraft.network.protocol.game.PacketPlayInSteerVehicle; +import net.minecraft.network.protocol.game.PacketPlayInTabComplete; +import net.minecraft.network.protocol.game.PacketPlayInUpdateSign; +import net.minecraft.network.protocol.game.PacketPlayInUseEntity; +import net.minecraft.network.protocol.game.PacketPlayInWindowClick; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.EntityPlayer; +import net.minecraft.server.network.PlayerConnection; + +public final class NpcPlayerConnection extends PlayerConnection { + + public NpcPlayerConnection(EntityPlayer entityplayer) { + super(MinecraftServer.getServer(), new NpcNetworkManager(), entityplayer); + } + + @Override + public void disconnect(String s) { + + } + + @Override + public void a(PacketPlayInSteerVehicle packetplayinsteervehicle) { + + } + + @Override + public void a(PacketPlayInFlying packetplayinflying) { + + } + + @Override + public void a(PacketPlayInBlockDig packetplayinblockdig) { + + } + + @Override + public void a(PacketPlayInBlockPlace packetplayinblockplace) { + + } + + @Override + public void a(PacketPlayInSpectate packetplayinspectate) { + + } + + @Override + public void a(PacketPlayInResourcePackStatus packetplayinresourcepackstatus) { + + } + + @Override + public void a(IChatBaseComponent ichatbasecomponent) { + + } + + @Override + public void sendPacket(Packet packet) { + + } + + @Override + public void a(PacketPlayInHeldItemSlot packetplayinhelditemslot) { + + } + + @Override + public void a(PacketPlayInChat packetplayinchat) { + + } + + @Override + public void chat(String s, boolean async) { + + } + + @Override + public void a(PacketPlayInArmAnimation packetplayinarmanimation) { + + } + + @Override + public void a(PacketPlayInEntityAction packetplayinentityaction) { + + } + + @Override + public void a(PacketPlayInUseEntity packetplayinuseentity) { + + } + + @Override + public void a(PacketPlayInClientCommand packetplayinclientcommand) { + + } + + @Override + public void a(PacketPlayInCloseWindow packetplayinclosewindow) { + + } + + @Override + public void a(PacketPlayInWindowClick packetplayinwindowclick) { + + } + + @Override + public void a(PacketPlayInEnchantItem packetplayinenchantitem) { + + } + + @Override + public void a(PacketPlayInSetCreativeSlot packetplayinsetcreativeslot) { + + } + + @Override + public void a(PacketPlayInUpdateSign packetplayinupdatesign) { + + } + + @Override + public void a(PacketPlayInKeepAlive packetplayinkeepalive) { + + } + + @Override + public void a(PacketPlayInAbilities packetplayinabilities) { + + } + + @Override + public void a(PacketPlayInTabComplete packetplayintabcomplete) { + + } + + @Override + public void a(PacketPlayInSettings packetplayinsettings) { + + } + + @Override + public void a(PacketPlayInCustomPayload packetplayincustompayload) { + + } + +} diff --git a/CombatTagPlusCompat-v1_17_R1/src/main/java/net/minelink/ctplus/compat/v1_17_R1/NpcPlayerHelperImpl.java b/CombatTagPlusCompat-v1_17_R1/src/main/java/net/minelink/ctplus/compat/v1_17_R1/NpcPlayerHelperImpl.java new file mode 100644 index 0000000..d0ee99e --- /dev/null +++ b/CombatTagPlusCompat-v1_17_R1/src/main/java/net/minelink/ctplus/compat/v1_17_R1/NpcPlayerHelperImpl.java @@ -0,0 +1,201 @@ +package net.minelink.ctplus.compat.v1_17_R1; + +import com.google.common.collect.Lists; +import com.mojang.datafixers.util.Pair; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.List; +import net.minecraft.nbt.NBTCompressedStreamTools; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.PacketPlayOutEntityEquipment; +import net.minecraft.network.protocol.game.PacketPlayOutPlayerInfo; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.EntityPlayer; +import net.minecraft.server.level.WorldServer; +import net.minecraft.world.entity.EnumItemSlot; +import net.minecraft.world.food.FoodMetaData; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.WorldNBTStorage; +import net.minelink.ctplus.compat.api.NpcIdentity; +import net.minelink.ctplus.compat.api.NpcPlayerHelper; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; + +public final class NpcPlayerHelperImpl implements NpcPlayerHelper { + + @Override + public Player spawn(Player player) { + NpcPlayer npcPlayer = NpcPlayer.valueOf(player); + WorldServer worldServer = ((CraftWorld) player.getWorld()).getHandle(); + Location l = player.getLocation(); + + npcPlayer.spawnIn(worldServer); + npcPlayer.setPositionRotation(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch()); + npcPlayer.d.a(worldServer); + npcPlayer.cD = 0; + + for (Object o : MinecraftServer.getServer().getPlayerList().getPlayers()) { + if (!(o instanceof EntityPlayer) || o instanceof NpcPlayer) continue; + + PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.a, npcPlayer); + ((EntityPlayer) o).b.sendPacket(packet); + } + + worldServer.addEntity(npcPlayer); + + return npcPlayer.getBukkitEntity(); + } + + @Override + public void despawn(Player player) { + EntityPlayer entity = ((CraftPlayer) player).getHandle(); + if (!(entity instanceof NpcPlayer)) { + throw new IllegalArgumentException(); + } + + for (Object o : MinecraftServer.getServer().getPlayerList().getPlayers()) { + if (!(o instanceof EntityPlayer) || o instanceof NpcPlayer) continue; + + PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.e, entity); + ((EntityPlayer) o).b.sendPacket(packet); + } + + WorldServer worldServer = MinecraftServer.getServer().getWorldServer(entity.getWorld().getDimensionKey()); + worldServer.getChunkProvider().removeEntity(entity); + worldServer.getPlayers().remove(entity); + removePlayerList(player); + } + + @Override + public boolean isNpc(Player player) { + return ((CraftPlayer) player).getHandle() instanceof NpcPlayer; + } + + @Override + public NpcIdentity getIdentity(Player player) { + if (!isNpc(player)) { + throw new IllegalArgumentException(); + } + + return ((NpcPlayer) ((CraftPlayer) player).getHandle()).getNpcIdentity(); + } + + @Override + public void updateEquipment(Player player) { + EntityPlayer entity = ((CraftPlayer) player).getHandle(); + + if (!(entity instanceof NpcPlayer)) { + throw new IllegalArgumentException(); + } + + for (EnumItemSlot slot : EnumItemSlot.values()) { + ItemStack item = entity.getEquipment(slot); + if (item == null) continue; + + // Set the attribute for this equipment to consider armor values and enchantments + // Actually getAttributeMap().a() is used with the previous item, to clear the Attributes + entity.getAttributeMap().a(item.a(slot)); + entity.getAttributeMap().b(item.a(slot)); + + // This is also called by super.tick(), but the flag this.bx is not public + List> list = Lists.newArrayList(); + list.add(Pair.of(slot, item)); + Packet packet = new PacketPlayOutEntityEquipment(entity.getId(), list); + entity.getWorldServer().getChunkProvider().broadcast(entity, packet); + } + } + + @Override + public void syncOffline(Player player) { + EntityPlayer entity = ((CraftPlayer) player).getHandle(); + + if (!(entity instanceof NpcPlayer)) { + throw new IllegalArgumentException(); + } + + NpcPlayer npcPlayer = (NpcPlayer) entity; + NpcIdentity identity = npcPlayer.getNpcIdentity(); + Player p = Bukkit.getPlayer(identity.getId()); + if (p != null && p.isOnline()) return; + + WorldNBTStorage worldStorage = (WorldNBTStorage) ((CraftWorld) Bukkit.getWorlds().get(0)).getHandle().getMinecraftServer().k; + NBTTagCompound playerNbt = worldStorage.getPlayerData(identity.getId().toString()); + if (playerNbt == null) return; + + // foodTickTimer is now private in 1.8.3 -- still private in 1.12 + Field foodTickTimerField; + int foodTickTimer; + + try { + foodTickTimerField = FoodMetaData.class.getDeclaredField("d"); + foodTickTimerField.setAccessible(true); + foodTickTimer = foodTickTimerField.getInt(entity.getFoodData()); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } + + playerNbt.setShort("Air", (short) entity.getAirTicks()); + // Health is now just a float; fractional is not stored separately. (1.12) + playerNbt.setFloat("Health", entity.getHealth()); + playerNbt.setFloat("AbsorptionAmount", entity.getAbsorptionHearts()); + playerNbt.setInt("XpTotal", entity.cj); + playerNbt.setInt("foodLevel", entity.getFoodData().getFoodLevel()); + playerNbt.setInt("foodTickTimer", foodTickTimer); + playerNbt.setFloat("foodSaturationLevel", entity.getFoodData().getSaturationLevel()); + playerNbt.setFloat("foodExhaustionLevel", entity.getFoodData().d()); + playerNbt.setShort("Fire", (short) entity.getFireTicks()); + playerNbt.set("Inventory", npcPlayer.getInventory().a(new NBTTagList())); + + File file1 = new File(worldStorage.getPlayerDir(), identity.getId().toString() + ".dat.tmp"); + File file2 = new File(worldStorage.getPlayerDir(), identity.getId().toString() + ".dat"); + + try { + NBTCompressedStreamTools.a(playerNbt, new FileOutputStream(file1)); + } catch (IOException e) { + throw new RuntimeException("Failed to save player data for " + identity.getName(), e); + } + + if ((!file2.exists() || file2.delete()) && !file1.renameTo(file2)) { + throw new RuntimeException("Failed to save player data for " + identity.getName()); + } + } + + @Override + public void createPlayerList(Player player) { + EntityPlayer p = ((CraftPlayer) player).getHandle(); + + for (WorldServer worldServer : MinecraftServer.getServer().getWorlds()) { + for (Object o : worldServer.getPlayers()) { + if (!(o instanceof NpcPlayer)) continue; + + NpcPlayer npcPlayer = (NpcPlayer) o; + PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo( + PacketPlayOutPlayerInfo.EnumPlayerInfoAction.a, npcPlayer); + p.b.sendPacket(packet); + } + } + } + + @Override + public void removePlayerList(Player player) { + EntityPlayer p = ((CraftPlayer) player).getHandle(); + + for (WorldServer worldServer : MinecraftServer.getServer().getWorlds()) { + for (Object o : worldServer.getPlayers()) { + if (!(o instanceof NpcPlayer)) continue; + + NpcPlayer npcPlayer = (NpcPlayer) o; + PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.e, npcPlayer); + p.b.sendPacket(packet); + } + } + } + +} diff --git a/CombatTagPlusWG-v7/pom.xml b/CombatTagPlusWG-v7/pom.xml index d7ca790..3f96a30 100644 --- a/CombatTagPlusWG-v7/pom.xml +++ b/CombatTagPlusWG-v7/pom.xml @@ -18,7 +18,7 @@ sk89q-repo - http://maven.sk89q.com/repo + https://maven.sk89q.com/repo diff --git a/pom.xml b/pom.xml index 6190a10..1ca5598 100644 --- a/pom.xml +++ b/pom.xml @@ -13,25 +13,26 @@ net.minelink CombatTagPlusParent pom - 1.3.3-SNAPSHOT + 1.4.0-SNAPSHOT UTF-8 UTF-8 - 1.8 - 1.8 + 16 + 16 CombatTagPlusCompat-API - CombatTagPlusCompat-v1_12_R1 - CombatTagPlusCompat-v1_13_R2 - CombatTagPlusCompat-v1_14_R1 - CombatTagPlusCompat-v1_15_R1 - CombatTagPlusCompat-v1_16_R1 - CombatTagPlusCompat-v1_16_R3 + + + + + + + CombatTagPlusCompat-v1_17_R1 CombatTagPlusHook - CombatTagPlusFactions-v2_7 + CombatTagPlusWG-v7 CombatTagPlus