Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
An alternative to TagAPI.
package com.comphenix.example;
import java.util.Arrays;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import com.comphenix.protocol.events.ListenerPriority;
import com.google.common.base.Joiner;
// Test plugin
public class ExampleMod extends JavaPlugin {
private LookupNameManager manager;
@Override
public void onEnable() {
manager = new LookupNameManager(this);
manager.start(ListenerPriority.NORMAL);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length < 2) {
sender.sendMessage(ChatColor.RED + "Must specify target player and new name.");
return true;
}
@SuppressWarnings("deprecation")
Player target = getServer().getPlayer(args[0]);
String name = Joiner.on(" ").join(Arrays.copyOfRange(args, 1, args.length));
if (target == null) {
sender.sendMessage(ChatColor.RED + "Cannot find player '" + args[0] + "'");
return true;
}
manager.setGlobalName(target, name);
sender.sendMessage(ChatColor.YELLOW + "Renamed " + target + " to " + name);
return true;
}
}
package com.comphenix.example;
import java.util.Map;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.events.ListenerPriority;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Maps;
import com.google.common.collect.Table;
public class LookupNameManager extends NameManager {
// Observing Client -> Entity -> Name
private Table<String, String, String> clientName = HashBasedTable.create();
// Fallback name in case the per-client name is missing
private Map<String, String> globalName = Maps.newHashMap();
// Remove outdated entries
protected boolean autoCleanup = true;
protected Listener bukkitListener;
/**
* Construct a new lookup handler.
* @param manager - the name manager.
*/
public LookupNameManager(Plugin plugin) {
super(plugin);
}
/**
* Start the handler and the associated name mananger.
* @param priority - the listener priority.
*/
public void start(ListenerPriority priority) {
super.start(priority);
registerBukkit();
}
private void registerBukkit() {
Plugin owner = getPlugin();
owner.getServer().getPluginManager().registerEvents(bukkitListener = new Listener() {
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e) {
if (!autoCleanup)
return;
// Clean up table
String removed = e.getPlayer().getName();
clientName.rowKeySet().remove(removed);
clientName.columnKeySet().remove(removed);
globalName.remove(removed);
}
}, owner);
}
/**
* Invoked when we're intercepting the name of an observed entity.
* @param client - the client that is receiving the name.
* @param observedEntity - the entity whose name we are sending.
* @param observedName - the current name of the entity.
* @return The new name of the entity. Use NULL for no change.
*/
public final String handleName(Player client, Player observedEntity, String observedName) {
String changed = clientName.get(client.getName(), observedEntity.getName());
// Fall back to the global name change
if (changed == null) {
changed = globalName.get(observedEntity.getName());
}
return changed;
}
/**
* Set the global name of a given entity.
* <p>
* This will be overridden by {@link #setClientName(Player, Player, String)} for individual clients.
* @param observedEntity - the player entity to rename.
* @param observedName - the new name of this entity.
* @return The previous altered name, or NULL.
*/
public String setGlobalName(Player observedEntity, String observedName) {
checkGlobal(observedEntity);
String original = globalName.put(observedEntity.getName(), observedName);
// See if we need to update the entity
if (!Objects.equal(original, observedName))
updateEntity(null, observedEntity);
return original;
}
/**
* Set the visible name of a player entity for a given client.
* @param client - the client that will see the name change.
* @param observedEntity - the player entity to rename.
* @param observedName - the new name of this entity.
* @return The previous altered name, or NULL.
*/
public String setClientName(Player client, Player observedEntity, String observedName) {
checkClient(client, observedEntity);
String original = clientName.put(client.getName(),
observedEntity.getName(), observedName);
// See if we need to update the entity
if (!Objects.equal(original, observedName))
updateEntity(client, observedEntity);
return original;
}
/**
* Reset the visible name of an entity to the default globally.
* @param observedEntity - the entity whose name will be reset.
* @return The removed custom name, or NULL.
*/
public String resetGlobalName(Player observedEntity) {
checkGlobal(observedEntity);
String removed = globalName.remove(observedEntity.getName());
// Trigger a name update
if (removed != null)
updateEntity(null, observedEntity);
return removed;
}
/**
* Reset the visible name of an entity to the default for a client.
* @param client - the client we're resetting.
* @param observedEntity - the entity whose name will be reset.
* @return The removed custom name, or NULL.
*/
public String resetClientName(Player client, Player observedEntity) {
checkClient(client, observedEntity);
String removed = clientName.remove(client.getName(), observedEntity.getName());
// Trigger a name update
if (removed != null)
updateEntity(client, observedEntity);
return removed;
}
// Throw on NULL
private void checkGlobal(Player observedEntity) {
if (!isStarted())
throw new IllegalStateException("Name mananger hasn't started yet.");
Preconditions.checkNotNull(observedEntity, "observedEntity cannot be NULL");
}
// Here too
private void checkClient(Player client, Player observedEntity) {
Preconditions.checkNotNull(client, "client cannot be NULL");
checkGlobal(observedEntity);
}
/**
* Determine if this handler has started.
* @return TRUE if it has, FALSE otherwise.
*/
public boolean isStarted() {
return bukkitListener != null && super.isStarted();
}
/**
* Determine if we automatically remove logged out entires.
* @return TRUE if we do, FALSE otherwise.
*/
public boolean isAutoCleanup() {
return autoCleanup;
}
/**
* Set whether or not we automatically remove entries of logged out players.
* @param autoCleanup - TRUE to auto-clean, FALSE otherwise.
*/
public void setAutoCleanup(boolean autoCleanup) {
this.autoCleanup = autoCleanup;
}
/**
* Close the current lookup handler and the associated manager.
*/
public void close() {
if (isStarted()) {
HandlerList.unregisterAll(bukkitListener);
super.close();
bukkitListener = null;
}
}
}
package com.comphenix.example;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.google.common.base.Preconditions;
/**
* Represents a name manager.
* @author Kristian
*/
public abstract class NameManager {
protected ProtocolManager manager;
// Listeners
protected PacketAdapter packetListener;
// The parent plugin
protected final Plugin plugin;
/**
* Construct a new player renamer.
* @param plugin - the plugin.
*/
public NameManager(Plugin plugin) {
this.plugin = Preconditions.checkNotNull(plugin, "plugin cannot be NULL.");
}
/**
* Start the player renamer component.
* @param priority - the priority of our player modification.
*/
public void start(ListenerPriority priority) {
if (isStarted()) {
throw new IllegalStateException("Cannot start renamer twice.");
}
registerProtocolLib(priority);
}
private void registerProtocolLib(ListenerPriority priority) {
this.manager = ProtocolLibrary.getProtocolManager();
manager.addPacketListener(packetListener =
new PacketAdapter(plugin, priority, PacketType.Play.Server.NAMED_ENTITY_SPAWN) {
@Override
public void onPacketSending(PacketEvent event) {
Player observed = (Player) event.getPacket().getEntityModifier(event).read(0);
// Determine if we are
if (MinecraftReflection.isUsingNetty()) {
handleNetty(event, observed);
} else {
handleLegacy(event, observed);
}
}
});
}
/**
* Process a spawn player packet in version 1.7.2 and above.
* @param event - the packet event.
* @param observed - the observed player entity.
*/
private void handleNetty(PacketEvent event, Player observed) {
WrappedGameProfile profile = event.getPacket().getGameProfiles().read(0);
String name = handleName(event.getPlayer(), observed, profile.getName());
// Update the displayed name
if (name != null) {
event.getPacket().getGameProfiles().write(0, profile.withName(StringUtils.abbreviate(name, 16)));
}
}
// As above, only for 1.6.4 and below
private void handleLegacy(PacketEvent event, Player observed) {
String name = handleName(event.getPlayer(), observed, event.getPacket().getStrings().read(0));
// As above
if (name != null) {
event.getPacket().getStrings().write(0, StringUtils.abbreviate(name, 16));
}
}
/**
* Trigger an entity update.
* @param client - the client that will recieve the update.
* @param observerEntity - the observed entity to update.
*/
protected void updateEntity(Player client, Player observerEntity) {
// A list of the players we will update
List<Player> trackers = client != null ?
Arrays.asList(client) : manager.getEntityTrackers(observerEntity);
manager.updateEntity(observerEntity, trackers);
}
/**
* Invoked when we're intercepting the name of an observed entity.
* @param client - the client that is receiving the name.
* @param observedEntity - the entity whose name we are sending.
* @param observedName - the current name of the entity.
* @return The new name of the entity. Use NULL for no change.
*/
public abstract String handleName(Player client, Player observedEntity, String observedName);
/**
* Retrieve the owner plugin.
* @return The owner.
*/
public Plugin getPlugin() {
return plugin;
}
/**
* Determine if we're currently renaming players.
* @return TRUE if we are, FALSE otherwise.
*/
public boolean isStarted() {
return packetListener != null;
}
public void close() {
if (packetListener != null) {
manager.removePacketListener(packetListener);
packetListener = null;
packetListener = null;
}
}
}
@steffansk1997
Copy link

steffansk1997 commented Nov 16, 2014

Does this change a players skin?

@mineyannik
Copy link

mineyannik commented Jan 1, 2015

Doesn't work on Minecraft 1.8.

Please update!

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