Skip to content

Instantly share code, notes, and snippets.

@Techcable
Last active September 29, 2022 07:11
Show Gist options
  • Save Techcable/d574a6e78ada3b8511bd to your computer and use it in GitHub Desktop.
Save Techcable/d574a6e78ada3b8511bd to your computer and use it in GitHub Desktop.
Change the name of a player using protocollib
/*
* The MIT License
* Copyright (c) 2015 Techcable
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import java.util.Map;
import java.util.WeakHashMap;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
/**
* This class allows you to change a player's nametag
* <p>
* It requires ProtocolLib and only works on 1.8-1.8.3
* If you need a 1.7 version, use TagAPI
* </p>
*
* @author Techcable
*/
public class NameChanger {
private final Map<Player, String> fakeNames = new WeakHashMap<Player, String>();
private final Plugin plugin;
public NameChanger(Plugin plugin) {
this.plugin = plugin;
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(this, PacketType.Play.Server.PLAYER_INFO) {
@Override
public void onPacketSending(PacketEvent event) {
if (event.getPacket().getPlayerInfoAction().read(0) != PlayerInfoAction.ADD_PLAYER) return;
List<PlayerInfoData> newPlayerInfoDataList = new ArrayList<PlayerInfoData>();
List<PlayerInfoData> playerInfoDataList = event.getPacket().getPlayerInfoDataLists().read(0);
for (PlayerInfoData playerInfoData : playerInfoDataList) {
if (playerInfoData == null || playerInfoData.getProfile() == null || Bukkit.getPlayer(playerInfoData.getProfile().getUUID()) == null) { //Unknown Player
newPlayerInfoDataList.add(playerInfoData);
continue;
}
WrappedGameProfile profile = playerInfoData.getProfile();
profile = profile.withName(getNameToSend(profile.getUUID()));
PlayerInfoData newPlayerInfoData = new PlayerInfoData(profile, playerInfoData.getPing(), playerInfoData.getGameMode(), playerInfoData.getDisplayName());
newPlayerInfoDataList.add(newPlayerInfoData);
}
event.getPacket().getPlayerInfoDataLists().write(0, newPlayerInfoDataList);
}
});
}
private String getNameToSend(UUID id) {
Player player = Bukkit.getPlayer(id);
if (!fakeNames.containsKey(player)) return player.getName();
return fakeNames.get(player);
}
/**
* Change the player's name to the provided string
* <br>
* The player may disappear for approximately 2 ticks after you change it
* </br>
* @param player player whos name to change
* @param fakeName the player's new name
*/
public void changeName(final Player player, String fakeName) {
fakeNames.put(player, fakeName);
refresh(player);
}
/**
* Reset the player's name to it's original value
* <br>
* The player may disappear for approximately 2 ticks after you change it
* </br>
* @param player player whos name to change back to the original value
*/
public void changeName(Player player, String fakeName) {
if (!fakeNames.containsKey(player))
fakeNames.remove(player);
refresh(player);
}
private void refresh(final Player player) {
for (final Player forWhom : player.getWorld().getPlayers()) {
if (player.equals(forWhom) || !player.getWorld().equals(forWhom.getWorld()) || !forWhom.canSee(player)) {
forWhom.hidePlayer(player);
new BukkitRunnable() {
@Override
public void run() {
forWhom.showPlayer(player);
}
}.runTaskLater(plugin, 2);
}
}
}
}
@remydimauro
Copy link

This works but the player's skin is left to default. Any way to fix this? Also, I have a player with a name that is 16 characters long. When I add a colour code to it, it kicks the player saying the input string is too long.

Copy link

ghost commented Sep 16, 2016

@Envici You need to clone the old properties to the new game profile. And you can use teams to have more than 16 characters in a name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment