Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #Functioning class PlayerSkinUpdater:
- public class PlayerSkinUpdater implements Listener {
- private final JavaPlugin plugin;
- private final Map<UUID, GameProfile> fakeProfileMap = new HashMap<>();
- private final Map<UUID, String> originalNames = new HashMap<>();
- private final Map<UUID, Map<UUID, Boolean>> playerVisibilityState = new HashMap<>();
- private final SkinFetcher skinFetcher = new SkinFetcher();
- private final Map<UUID, Set<UUID>> playersTriggeredSkinUpdate = new HashMap<>();
- private static final String HARDCODED_SKIN_VALUE = "...";
- private static final String HARDCODED_SKIN_SIGNATURE = "...";
- public PlayerSkinUpdater(JavaPlugin plugin) {
- this.plugin = plugin;
- setupPacketListeners();
- startProximityChecker();
- }
- private void startProximityChecker() {
- Bukkit.getScheduler().runTaskTimer(plugin, () -> {
- for (Player player : Bukkit.getOnlinePlayers()) {
- checkNearbyPlayers(player);
- }
- }, 10L, 10L); // Check every half second
- }
- private void checkNearbyPlayers(Player player) {
- double visibleDistance = 162.0; // Distance within which players see each other's real profile
- double checkDistance = 140.0; // Distance within which players see each other's real profile
- Location playerLocation = player.getLocation();
- playerVisibilityState.putIfAbsent(player.getUniqueId(), new HashMap<>());
- Map<UUID, Boolean> playerStates = playerVisibilityState.get(player.getUniqueId());
- for (Player other : Bukkit.getOnlinePlayers()) {
- if (player.equals(other)) continue;
- Location otherLocation = other.getLocation();
- boolean isInRange = playerLocation.getWorld().equals(otherLocation.getWorld()) &&
- playerLocation.distance(otherLocation) <= visibleDistance;
- boolean checkRange = playerLocation.getWorld().equals(otherLocation.getWorld()) &&
- playerLocation.distance(otherLocation) <= checkDistance;
- boolean currentlyVisible = playerStates.getOrDefault(other.getUniqueId(), false);
- if (checkRange) {
- // Player is now in range, restore their original profile
- playerStates.put(other.getUniqueId(), true);
- restoreOriginalSkinAndName(other);
- removeFakeProfileFromTablist(other, player);
- } else if (isInRange && !currentlyVisible) {
- // Player is now in range, restore their original profile
- playerStates.put(other.getUniqueId(), true);
- restoreOriginalSkinAndName(other);
- removeFakeProfileFromTablist(other, player);
- } else if (!isInRange && currentlyVisible) {
- // Player is now out of range, add their fake profile back
- playerStates.put(other.getUniqueId(), false);
- updateTablistSkin(other, HARDCODED_SKIN_VALUE, HARDCODED_SKIN_SIGNATURE);
- addFakeProfileToTablist(other, player);
- }
- }
- }
- private void setupPacketListeners() {
- ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
- protocolManager.addPacketListener(new PacketAdapter(plugin,
- ListenerPriority.MONITOR,
- PacketType.Play.Server.NAMED_ENTITY_SPAWN) {
- @Override
- public void onPacketSending(PacketEvent event) {
- try {
- PacketContainer packet = event.getPacket();
- Player observer = event.getPlayer();
- UUID spawnedPlayerUUID = packet.getUUIDs().read(0);
- if (spawnedPlayerUUID != null) {
- Player spawnedPlayer = Bukkit.getPlayer(spawnedPlayerUUID);
- if (spawnedPlayer != null && observer != null && !observer.equals(spawnedPlayer)) {
- Bukkit.getScheduler().runTask(plugin, () -> {
- handlePlayerVisibility(observer, spawnedPlayer);
- playerVisibilityState.computeIfAbsent(observer.getUniqueId(), k -> new HashMap<>())
- .put(spawnedPlayer.getUniqueId(), true);
- });
- }
- }
- } catch (Exception e) {
- plugin.getLogger().warning("Error in NAMED_ENTITY_SPAWN handler: " + e.getMessage());
- }
- }
- });
- }
- private void handlePlayerVisibility(Player observer, Player spawnedPlayer) {
- if (observer.equals(spawnedPlayer)) return;
- playersTriggeredSkinUpdate.putIfAbsent(observer.getUniqueId(), new HashSet<>());
- Set<UUID> triggeredSkinUpdates = playersTriggeredSkinUpdate.get(observer.getUniqueId());
- boolean isNearby = observer.getLocation().distance(spawnedPlayer.getLocation()) <= 16.0;
- if (!triggeredSkinUpdates.contains(spawnedPlayer.getUniqueId())) {
- if (isNearby) {
- restoreOriginalSkinAndName(spawnedPlayer);
- } else {
- updateTablistSkin(spawnedPlayer, HARDCODED_SKIN_VALUE, HARDCODED_SKIN_SIGNATURE);
- }
- triggeredSkinUpdates.add(spawnedPlayer.getUniqueId());
- Bukkit.getScheduler().runTaskLater(plugin, () -> triggeredSkinUpdates.remove(spawnedPlayer.getUniqueId()), 2L);
- }
- }
- private void addFakeProfileToTablist(Player target, Player viewer) {
- GameProfile fakeProfile = fakeProfileMap.get(target.getUniqueId());
- if (fakeProfile == null) return;
- ServerPlayer viewerServerPlayer = ((CraftPlayer) viewer).getHandle();
- ClientboundPlayerInfoUpdatePacket addPacket = new ClientboundPlayerInfoUpdatePacket(
- EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER),
- List.of(new ServerPlayer(
- ((CraftServer) Bukkit.getServer()).getServer(),
- viewerServerPlayer.getLevel(),
- fakeProfile
- ))
- );
- viewerServerPlayer.connection.send(addPacket);
- }
- private void removeFakeProfileFromTablist(Player target, Player viewer) {
- GameProfile fakeProfile = fakeProfileMap.get(target.getUniqueId());
- if (fakeProfile == null) return;
- ServerPlayer viewerServerPlayer = ((CraftPlayer) viewer).getHandle();
- ClientboundPlayerInfoRemovePacket removePacket = new ClientboundPlayerInfoRemovePacket(
- List.of(fakeProfile.getId())
- );
- viewerServerPlayer.connection.send(removePacket);
- }
- @EventHandler
- public void onPlayerTeleport(PlayerTeleportEvent event) {
- Player teleportedPlayer = event.getPlayer();
- Location destination = event.getTo();
- if (destination == null) return;
- Bukkit.getScheduler().runTask(plugin, () -> {
- for (Player other : Bukkit.getOnlinePlayers()) {
- if (teleportedPlayer.equals(other)) continue;
- Location otherLocation = other.getLocation();
- double renderDistance = 8.1 * 16; // Blocks
- double visibleDistance = 6.0 * 16; // Blocks
- boolean isInRenderDistance = destination.getWorld().equals(otherLocation.getWorld()) &&
- destination.distance(otherLocation) <= renderDistance;
- boolean isInVisibleDistance = destination.getWorld().equals(otherLocation.getWorld()) &&
- destination.distance(otherLocation) <= visibleDistance;
- if (isInVisibleDistance) {
- // Trigger skin update for both players
- updateTablistSkin(other, HARDCODED_SKIN_VALUE, HARDCODED_SKIN_SIGNATURE);
- }
- if (isInRenderDistance) {
- restoreOriginalSkinAndName(other);
- }
- }
- });
- }
- private void restoreOriginalSkinAndName(Player player) {
- String originalName = originalNames.getOrDefault(player.getUniqueId(), player.getName());
- GameProfile fakeProfile = fakeProfileMap.get(player.getUniqueId());
- if (fakeProfile != null) {
- String originalSkinValue = getOriginalSkinValue(player);
- String originalSkinSignature = getOriginalSkinSignature(player);
- // Only update if we have valid skin data
- if (originalSkinValue != null && originalSkinSignature != null) {
- updatePlayerSkin(player, originalSkinValue, originalSkinSignature);
- }
- }
- }
- public void updatePlayerSkin(Player player, String skinValue, String skinSignature) {
- Bukkit.getScheduler().runTask(plugin, () -> {
- try {
- ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
- GameProfile gameProfile = serverPlayer.getGameProfile();
- // Update the skin texture on the game profile
- gameProfile.getProperties().removeAll("textures");
- gameProfile.getProperties().put("textures", new Property("textures", skinValue, skinSignature));
- // Respawn the player to apply the skin change
- respawnPlayer(player);
- } catch (Exception e) {
- plugin.getLogger().severe("Error updating skin for " + player.getName() + ": " + e.getMessage());
- e.printStackTrace();
- }
- });
- }
- private void respawnPlayer(Player player) {
- ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
- // Send a player removal packet to all clients
- ClientboundPlayerInfoRemovePacket removePacket = new ClientboundPlayerInfoRemovePacket(
- List.of(serverPlayer.getGameProfile().getId())
- );
- // Send a player spawn packet to all clients
- ClientboundPlayerInfoUpdatePacket addPacket = new ClientboundPlayerInfoUpdatePacket(
- EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER),
- List.of(serverPlayer)
- );
- for (Player online : Bukkit.getOnlinePlayers()) {
- ServerPlayer onlinePlayer = ((CraftPlayer) online).getHandle();
- onlinePlayer.connection.send(removePacket);
- onlinePlayer.connection.send(addPacket);
- }
- }
- private String getOriginalSkinValue(Player player) {
- SkinFetcher.SkinData skinData = skinFetcher.getOriginalSkin(player.getUniqueId());
- return skinData != null ? skinData.getValue() : "";
- }
- private String getOriginalSkinSignature(Player player) {
- SkinFetcher.SkinData skinData = skinFetcher.getOriginalSkin(player.getUniqueId());
- return skinData != null ? skinData.getSignature() : "";
- }
- public void updateTablistSkin(Player player, String skinValue, String skinSignature) {
- if (player == null || skinValue == null || skinSignature == null) {
- plugin.getLogger().warning("Invalid input parameters for skin update");
- return;
- }
- Bukkit.getScheduler().runTask(plugin, () -> {
- try {
- ServerPlayer originalServerPlayer = ((CraftPlayer) player).getHandle();
- GameProfile originalProfile = originalServerPlayer.getGameProfile();
- // Remove any existing fake profile for this player
- removePlayerFromTablist(player);
- // Create an encrypted name for the fake profile
- String encryptedName = createEncryptedName(player);
- // Create a new fake profile ONLY for tablist
- GameProfile fakeProfile = new GameProfile(originalProfile.getId(), encryptedName);
- // Add the new skin texture
- fakeProfile.getProperties().put("textures", new Property("textures", skinValue, skinSignature));
- // Store the fake profile for later removal
- fakeProfileMap.put(player.getUniqueId(), fakeProfile);
- // Create remove packet for the original profile
- ClientboundPlayerInfoRemovePacket removePacket = new ClientboundPlayerInfoRemovePacket(
- List.of(originalProfile.getId())
- );
- // Create add packet with the fake profile
- ClientboundPlayerInfoUpdatePacket addPacket = new ClientboundPlayerInfoUpdatePacket(
- EnumSet.of(
- ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER,
- ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED
- ),
- Collections.singletonList(
- new ServerPlayer(
- ((CraftServer) Bukkit.getServer()).getServer(),
- originalServerPlayer.getLevel(),
- fakeProfile
- )
- )
- );
- // Send packets to all online players
- for (Player online : Bukkit.getOnlinePlayers()) {
- ServerPlayer onlineServerPlayer = ((CraftPlayer) online).getHandle();
- // Ensure the packet is only sent to OTHER players
- if (online.getUniqueId().equals(player.getUniqueId())) {
- continue;
- }
- onlineServerPlayer.connection.send(removePacket);
- onlineServerPlayer.connection.send(addPacket);
- }
- plugin.getLogger().info("Attempted tablist skin update for " + player.getName());
- } catch (Exception e) {
- plugin.getLogger().severe("Error updating tablist skin for " + player.getName() + ": " + e.getMessage());
- e.printStackTrace();
- }
- });
- }
- private void removePlayerFromTablist(Player player) {
- GameProfile fakeProfile = fakeProfileMap.remove(player.getUniqueId());
- if (fakeProfile != null) {
- ClientboundPlayerInfoRemovePacket removePacket = new ClientboundPlayerInfoRemovePacket(
- List.of(fakeProfile.getId())
- );
- // Send remove packet to all online players EXCEPT the player being removed
- for (Player online : Bukkit.getOnlinePlayers()) {
- if (online.getUniqueId().equals(player.getUniqueId())) {
- continue;
- }
- ServerPlayer onlineServerPlayer = ((CraftPlayer) online).getHandle();
- onlineServerPlayer.connection.send(removePacket);
- }
- }
- }
- private String createEncryptedName(Player player) {
- if (!originalNames.containsKey(player)) {
- ServerPlayer originalServerPlayer = ((CraftPlayer) player).getHandle();
- GameProfile originalProfile = originalServerPlayer.getGameProfile();
- originalNames.put(originalProfile.getId(), player.getName());
- }
- // Create an encrypted name using magic color codes
- return ChatColor.translateAlternateColorCodes('&', "&k" + player.getName());
- }
- }
- #Skin fetching class SkinFetcher:
- public class SkinFetcher {
- private static final String MOJANG_API_URL = "https://sessionserver.mojang.com/session/minecraft/profile/";
- private final Map<UUID, SkinData> skinCache = new ConcurrentHashMap<>();
- public static class SkinData {
- private final String value;
- private final String signature;
- public SkinData(String value, String signature) {
- this.value = value;
- this.signature = signature;
- }
- public String getValue() {
- return value;
- }
- public String getSignature() {
- return signature;
- }
- }
- // Fetches the original skin value for a player
- public SkinData getOriginalSkin(UUID playerUUID) {
- // Check cache first
- if (skinCache.containsKey(playerUUID)) {
- return skinCache.get(playerUUID);
- }
- try {
- // Query Mojang's API
- HttpURLConnection connection = (HttpURLConnection) new URL(MOJANG_API_URL + playerUUID.toString().replace("-", "")).openConnection();
- connection.setRequestMethod("GET");
- connection.setConnectTimeout(5000);
- connection.setReadTimeout(5000);
- try (InputStreamReader reader = new InputStreamReader(connection.getInputStream())) {
- JsonObject response = JsonParser.parseReader(reader).getAsJsonObject();
- // Check if "properties" array exists and has at least one element
- if (!response.has("properties") || response.getAsJsonArray("properties").size() == 0) {
- throw new IllegalStateException("No properties found for player UUID: " + playerUUID);
- }
- JsonObject properties = response.getAsJsonArray("properties").get(0).getAsJsonObject();
- // Ensure both "value" and "signature" are present
- if (!properties.has("value") || !properties.has("signature")) {
- throw new IllegalStateException("Skin data missing for player UUID: " + playerUUID);
- }
- String value = properties.get("value").getAsString();
- String signature = properties.get("signature").getAsString();
- SkinData skinData = new SkinData(value, signature);
- skinCache.put(playerUUID, skinData); // Cache the result
- return null;
- }
- } catch (Exception e) {
- // Log and handle error
- return null; // Return null if fetching fails
- }
- }
- }
- #Booting Main class TabListSpigot:
- public class TabListSpigot extends JavaPlugin implements Listener {
- // Hardcoded skin values - replace these with the actual skin data you want to use
- private static final String HARDCODED_SKIN_VALUE = "...";
- private static final String HARDCODED_SKIN_SIGNATURE = "...";
- private PlayerSkinUpdater skinUpdater;
- @Override
- public void onEnable() {
- if (getServer().getPluginManager().getPlugin("ProtocolLib") == null) {
- getLogger().severe("ProtocolLib not found! Disabling plugin...");
- getServer().getPluginManager().disablePlugin(this);
- return;
- }
- // Initialize the PlayerSkinUpdater
- skinUpdater = new PlayerSkinUpdater(this);
- // Register event listener
- getServer().getPluginManager().registerEvents(this, this);
- getServer().getPluginManager().registerEvents(skinUpdater, this);
- // Optional: Log that the plugin is enabled
- getLogger().info("TabListSpigot plugin has been enabled!");
- }
- @Override
- public void onDisable() {
- // Optional: Log that the plugin is being disabled
- getLogger().info("TabListSpigot plugin is shutting down!");
- }
- @EventHandler
- public void onPlayerJoin(PlayerJoinEvent event) {
- Player joinedPlayer = event.getPlayer();
- // Log when a player joins
- getLogger().info("Player " + joinedPlayer.getName() + " has joined.");
- // Update tablist for the joined player
- skinUpdater.updateTablistSkin(joinedPlayer, HARDCODED_SKIN_VALUE, HARDCODED_SKIN_SIGNATURE);
- // Update tablist for ALL existing online players to see the new player
- updateTablistForAllPlayers(joinedPlayer);
- }
- private void updateTablistForAllPlayers(Player newPlayer) {
- // Update existing online players' tablist to see the new player with encrypted name
- for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
- if (onlinePlayer.getUniqueId().equals(newPlayer.getUniqueId())) {
- continue; // Skip the new player
- }
- // Update the tablist view for each existing player
- skinUpdater.updateTablistSkin(onlinePlayer,
- HARDCODED_SKIN_VALUE,
- HARDCODED_SKIN_SIGNATURE
- );
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement