Created
February 15, 2014 11:19
-
-
Save aadnk/9017880 to your computer and use it in GitHub Desktop.
A fake entity.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.comphenix.example; | |
import java.util.Collections; | |
import java.util.List; | |
import java.util.UUID; | |
import org.bukkit.Bukkit; | |
import org.bukkit.Location; | |
import org.bukkit.entity.Player; | |
import org.bukkit.plugin.Plugin; | |
import org.bukkit.scheduler.BukkitTask; | |
import com.comphenix.protocol.reflect.accessors.Accessors; | |
import com.comphenix.protocol.reflect.accessors.FieldAccessor; | |
import com.comphenix.protocol.utility.MinecraftReflection; | |
import com.comphenix.protocol.wrappers.WrappedDataWatcher; | |
import com.google.common.base.Preconditions; | |
import com.google.common.collect.Lists; | |
public class FakeEntity { | |
/** | |
* Retrieve the entity counter field used to generate a unique entity ID. | |
*/ | |
private static final FieldAccessor ENTITY_ID = Accessors.getFieldAccessor( | |
MinecraftReflection.getEntityClass(), "entityCount", true); | |
public List<Player> observers = Lists.newArrayList(); | |
private Location clientLocation; | |
private Location serverLocation; | |
private int entityId; | |
private String name; | |
private String uuid; | |
private WrappedDataWatcher watcher; | |
private boolean changed; | |
// Update task | |
private BukkitTask task; | |
public FakeEntity(Plugin plugin, Location location, String name) { | |
this.clientLocation = Preconditions.checkNotNull(location, "location cannot be NULL"); | |
this.serverLocation = clientLocation.clone(); | |
this.name = Preconditions.checkNotNull(name, "name cannot be NULL"); | |
this.uuid = UUID.randomUUID().toString(); | |
this.entityId = (Integer) ENTITY_ID.get(null); | |
this.watcher = new WrappedDataWatcher(); | |
this.watcher.setObject(0, (byte)0); | |
// Increment next entity ID | |
ENTITY_ID.set(null, entityId + 1); | |
// Background worker | |
Bukkit.getScheduler().runTaskTimer(plugin, new Runnable() { | |
@Override | |
public void run() { | |
updateEntity(); | |
} | |
}, 1, 1); | |
} | |
public void addObserver(Player player) { | |
notifySpawnEntity(player); | |
observers.add(player); | |
} | |
public void removeObserver(Player player) { | |
WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); | |
destroy.setEntities(new int[] { entityId }); | |
destroy.sendPacket(player); | |
observers.remove(player); | |
} | |
private void updateEntity() { | |
// Detect changes | |
if (changed) { | |
for (Player player : observers) { | |
notifySpawnEntity(player); | |
} | |
changed = false; | |
// Update location | |
} else if (!serverLocation.equals(clientLocation)) { | |
broadcastMoveEntity(); | |
clientLocation = serverLocation.clone(); | |
} | |
} | |
private void notifySpawnEntity(Player player) { | |
WrapperPlayServerNamedEntitySpawn spawned = new WrapperPlayServerNamedEntitySpawn(); | |
spawned.setEntityID(entityId); | |
spawned.setPosition(serverLocation.toVector()); | |
spawned.setPlayerName(name); | |
spawned.setPlayerUUID(uuid); | |
spawned.setYaw(serverLocation.getYaw()); | |
spawned.setPitch(serverLocation.getPitch()); | |
spawned.setMetadata(watcher); | |
spawned.sendPacket(player); | |
} | |
private void broadcastMoveEntity() { | |
WrapperPlayServerEntityMoveLook move = new WrapperPlayServerEntityMoveLook(); | |
move.setEntityID(entityId); | |
move.setDx(serverLocation.getX() - clientLocation.getX()); | |
move.setDy(serverLocation.getY() - clientLocation.getY()); | |
move.setDz(serverLocation.getZ() - clientLocation.getZ()); | |
move.setYaw(serverLocation.getYaw()); | |
move.setPitch(serverLocation.getPitch()); | |
for (Player player : observers) { | |
move.sendPacket(player); | |
} | |
} | |
/** | |
* Destroy the current entity. | |
*/ | |
public void destroy() { | |
task.cancel(); | |
for (Player player : Lists.newArrayList(observers)) { | |
removeObserver(player); | |
} | |
} | |
public int getEntityId() { | |
return entityId; | |
} | |
/** | |
* Retrieve an immutable view of every player observing this entity. | |
* @return Every observer. | |
*/ | |
public List<Player> getObservers() { | |
return Collections.unmodifiableList(observers); | |
} | |
public Location getLocation() { | |
return serverLocation; | |
} | |
public void setLocation(Location location) { | |
this.serverLocation = location; | |
} | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
this.changed = true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
any chance to update it for 1.15.2? :P