diff --git a/src/main/java/xyz/ineanto/nicko/Nicko.java b/src/main/java/xyz/ineanto/nicko/Nicko.java index a0621bb..2d26f84 100644 --- a/src/main/java/xyz/ineanto/nicko/Nicko.java +++ b/src/main/java/xyz/ineanto/nicko/Nicko.java @@ -66,7 +66,7 @@ public class Nicko extends JavaPlugin { if (!MinecraftVersion.TRAILS_AND_TAILS.atOrAbove()) { getLogger().severe("This version (" + MinecraftVersion.getCurrentVersion().getVersion() + ") is not supported by Nicko!"); - getLogger().severe("As of version 1.0.7, Nicko only supports the latest two majors Minecraft versions. (Currently 1.20.X-1.21.X)"); + getLogger().severe("As of version 1.2.0, Nicko only supports the latest Minecraft versions. (Currently 1.21.3)"); dataStore.getStorage().setError(true); Bukkit.getPluginManager().disablePlugin(this); } diff --git a/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java b/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java index ed74d2f..ca22bd9 100644 --- a/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java +++ b/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java @@ -12,13 +12,11 @@ import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; import java.io.InputStream; import java.text.MessageFormat; import java.util.*; -import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; public class PlayerLanguage { private final MessageFormat formatter = new MessageFormat(""); - private final Logger logger = Logger.getLogger("I18N"); private final Nicko instance = Nicko.getInstance(); private final Pattern replacementPattern = Pattern.compile("(?ms)\\{\\d+}"); private final YamlConfig yamlConfig; diff --git a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java b/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java index 3fb5bd3..6af2f67 100644 --- a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java +++ b/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java @@ -4,18 +4,19 @@ import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; import com.mojang.authlib.properties.PropertyMap; import it.unimi.dsi.fastutil.ints.IntList; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.contents.PlainTextContents; 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.ClientboundRespawnPacket; -import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.network.protocol.game.*; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.phys.Vec3; import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Player; import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.appearance.ActionResult; @@ -25,8 +26,10 @@ import xyz.ineanto.nicko.mojang.MojangSkin; import xyz.ineanto.nicko.profile.NickoProfile; import java.io.IOException; +import java.util.EnumSet; import java.util.List; import java.util.Optional; +import java.util.Random; import java.util.concurrent.ExecutionException; /** @@ -47,10 +50,20 @@ public class InternalPacketSender implements PacketSender { public void sendEntityRespawn() { if (!profile.hasData()) return; - final Entity entityPlayer = (Entity) player; - final ClientboundRemoveEntitiesPacket destroy = new ClientboundRemoveEntitiesPacket(IntList.of(player.getEntityId())); - final ClientboundAddEntityPacket add = new ClientboundAddEntityPacket(entityPlayer, 0, entityPlayer.getOnPos()); + final ClientboundAddEntityPacket add = new ClientboundAddEntityPacket( + new Random().nextInt(9999), + player.getUniqueId(), + player.getX(), + player.getY(), + player.getZ(), + player.getPitch(), + player.getYaw(), + EntityType.PLAYER, + 0, + Vec3.ZERO, + player.getBodyYaw() + ); Bukkit.getOnlinePlayers().stream().filter(receiver -> receiver.getUniqueId() != player.getUniqueId()).forEach(receiver -> { sendPacket(destroy, player); @@ -60,7 +73,7 @@ public class InternalPacketSender implements PacketSender { @Override public ActionResult sendGameProfileUpdate(String name, boolean skinChange, boolean reset) { - final GameProfile gameProfile = ((ServerPlayer) player).gameProfile; + final GameProfile gameProfile = ((CraftPlayer) player).getProfile(); // TODO (Ineanto, 31/10/2024): Could this be refactored to get rid of the boolean? if (skinChange) { @@ -75,6 +88,7 @@ public class InternalPacketSender implements PacketSender { final PropertyMap properties = gameProfile.getProperties(); properties.get("textures").clear(); properties.put("textures", new Property("textures", skinResult.value(), skinResult.signature())); + ((CraftPlayer) player).getHandle().gameProfile = gameProfile; } else { return ActionResult.error(LanguageKey.Error.MOJANG_SKIN); } @@ -107,19 +121,46 @@ public class InternalPacketSender implements PacketSender { @Override public void sendPlayerRespawn() { - final ServerPlayer serverPlayer = (ServerPlayer) player; - final ServerLevel world = (ServerLevel) player.getWorld(); + final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + final ServerLevel level = serverPlayer.serverLevel(); - final ClientboundRespawnPacket respawn = new ClientboundRespawnPacket(serverPlayer.createCommonSpawnInfo(world), (byte) 0x03); + final ClientboundRespawnPacket respawn = new ClientboundRespawnPacket(serverPlayer.createCommonSpawnInfo(level), (byte) 0x03); sendPacket(respawn, player); } @Override public void sendTabListUpdate(String displayName) { + final ServerPlayer serverPlayer = (((CraftPlayer) player)).getHandle(); + final EnumSet actions = EnumSet.of( + ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, + ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT, + ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED, + ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME, + ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, + ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY); + + final List entries = List.of(new ClientboundPlayerInfoUpdatePacket.Entry( + player.getUniqueId(), + serverPlayer.gameProfile, + true, + player.getPing(), + serverPlayer.gameMode.getGameModeForPlayer(), + MutableComponent.create(new PlainTextContents.LiteralContents(displayName)), + 1, + null + )); + + final ClientboundPlayerInfoUpdatePacket update = new ClientboundPlayerInfoUpdatePacket(actions, entries); + final ClientboundPlayerInfoRemovePacket remove = new ClientboundPlayerInfoRemovePacket(List.of(player.getUniqueId())); + + Bukkit.getOnlinePlayers().forEach(onlinePlayer -> { + sendPacket(remove, onlinePlayer); + sendPacket(update, onlinePlayer); + }); } private void sendPacket(Packet packet, Player player) { - ((ServerPlayer) player).connection.send(packet); + (((CraftPlayer) player).getHandle()).connection.send(packet); } } diff --git a/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java b/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java index 9f1460f..bc75f78 100644 --- a/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java +++ b/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java @@ -4,7 +4,6 @@ import org.bukkit.entity.Player; import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.language.Language; import xyz.ineanto.nicko.storage.PlayerDataStore; -import xyz.ineanto.nicko.storage.name.PlayerNameStore; import java.util.Optional; import java.util.UUID; @@ -15,8 +14,6 @@ public class NickoProfile implements Cloneable { private static final Nicko instance = Nicko.getInstance(); private static final PlayerDataStore dataStore = instance.getDataStore(); - private final PlayerNameStore nameStore = instance.getNameStore(); - private String name; private String skin; private Language language;