use of com.bergerkiller.bukkit.common.internal.hooks.EntityTrackerEntryHook in project BKCommonLib by bergerhealer.
the class CommonEntity method getNetworkController.
/**
* Gets the Entity Network Controller currently assigned to this Entity. If
* none is available, this method returns Null. If no custom network
* controller is set, this method returns a new
* {@link DefaultEntityNetworkController} instance.
*
* @return Entity Network Controller, or null if not available
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public EntityNetworkController<CommonEntity<T>> getNetworkController() {
if (this.handle.getWorld() == null) {
return null;
}
final EntityNetworkController result;
final Object entityTrackerEntry = Handle.getRaw(WorldUtil.getTrackerEntry(entity));
if (entityTrackerEntry == null) {
return null;
}
EntityTrackerEntryHook hook = EntityTypingHandler.INSTANCE.getEntityTrackerEntryHook(entityTrackerEntry);
if (hook != null) {
return CommonUtil.unsafeCast(hook.getController());
}
if (EntityTrackerEntryHandle.T.isType(entityTrackerEntry)) {
result = new DefaultEntityNetworkController();
result.bind(this, entityTrackerEntry);
} else {
result = new ExternalEntityNetworkController();
result.bind(this, entityTrackerEntry);
}
return result;
}
use of com.bergerkiller.bukkit.common.internal.hooks.EntityTrackerEntryHook in project BKCommonLib by bergerhealer.
the class CommonEntity method setNetworkController.
/**
* Sets an Entity Network Controller for this Entity. To stop tracking this
* minecart, pass in Null. To default back to the net.minecraft.server
* implementation, pass in a new {@link DefaultEntityNetworkController}
* instance.<br>
* <br>
* This method only works if the Entity world has previously been set.
*
* @param controller to set to
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public void setNetworkController(EntityNetworkController controller) {
if (getWorld() == null) {
throw new RuntimeException("Can not set the network controller when no world is known! (need to spawn it?)");
}
final EntityTracker tracker = WorldUtil.getTracker(getWorld());
final EntityTrackerEntryHandle storedEntry = tracker.getEntry(entity);
// Take care of null controllers - stop tracking
if (controller == null) {
tracker.stopTracking(entity);
return;
}
// Find a previous network controller that may have been set
EntityNetworkController oldController = null;
EntityTrackerEntryHook hook = EntityTypingHandler.INSTANCE.getEntityTrackerEntryHook(Handle.getRaw(storedEntry));
if (hook != null) {
oldController = (EntityNetworkController<CommonEntity<org.bukkit.entity.Entity>>) hook.getController();
if (oldController == controller) {
// No Change!
return;
}
}
// Store the previous viewers set for the entry before we swap the controllers
// This is required to respawn the entity if so required
List<Player> previousViewers;
if (storedEntry != null) {
previousViewers = new ArrayList<Player>(storedEntry.getViewers());
} else {
previousViewers = Collections.emptyList();
}
// The vanilla controller will simply send a destroy packet.
for (Player previousViewer : previousViewers) {
storedEntry.removeViewer(previousViewer);
}
// We fire the destroy packet right away to prevent that.
for (Player previousViewer : previousViewers) {
if (PlayerUtil.getEntityRemoveQueue(previousViewer).remove((Object) this.entity.getEntityId())) {
CommonPacket destroyPacket = PacketType.OUT_ENTITY_DESTROY.newInstanceSingle(this.entity.getEntityId());
PacketUtil.sendPacket(previousViewer, destroyPacket);
}
}
// Handle the onDetached() of the previous controller, if set
if (oldController != null) {
oldController.bind(null, storedEntry.getRaw());
}
// Purpur: enable or disable legacy tracking logic when controllers are/not used
if (EntityHandle.T.setLegacyTrackingEntity.isAvailable()) {
if (controller instanceof DefaultEntityNetworkController) {
EntityHandle.T.setLegacyTrackingEntity.invoker.invoke(getHandle(), Boolean.FALSE);
} else {
EntityHandle.T.setLegacyTrackingEntity.invoker.invoke(getHandle(), Boolean.TRUE);
}
}
final EntityTrackerEntryHandle newEntry;
if (controller instanceof DefaultEntityNetworkController) {
// Assign the default Entity Tracker Entry
if (EntityTrackerEntryHandle.T.isHandleType(storedEntry)) {
// Nothing to be done here
newEntry = storedEntry;
} else {
// Create a new unmodified, default server network entry
newEntry = EntityTypingHandler.INSTANCE.createEntityTrackerEntry(tracker, entity);
// Transfer data if needed
if (storedEntry != null) {
copyEntityTrackerEntry(storedEntry, newEntry);
}
}
} else if (controller instanceof ExternalEntityNetworkController) {
// Use the entry as stored by the external network controller
newEntry = EntityTrackerEntryHandle.createHandle(controller.getHandle());
// Be sure to refresh stats using the old entry
if (storedEntry != null && newEntry != null) {
copyEntityTrackerEntry(storedEntry, newEntry);
}
} else if (hook != null) {
// Use the previous hooked entry - hotswap the controller
newEntry = storedEntry;
newEntry.clearViewers();
} else {
EntityTrackerEntryHandle oldEntry = storedEntry;
if (oldEntry == null) {
oldEntry = EntityTypingHandler.INSTANCE.createEntityTrackerEntry(tracker, entity);
}
// Convert the original entry into a hooked entry
newEntry = EntityTrackerEntryHandle.createHandle(EntityTypingHandler.INSTANCE.hookEntityTrackerEntry(oldEntry.getRaw()));
}
// Attach the entry to the controller
controller.bind(this, newEntry.getRaw());
// Attach (new?) entry to the world
if (Handle.getRaw(storedEntry) != Handle.getRaw(newEntry)) {
tracker.setEntry(entity, newEntry);
}
// If this is a new entry entirely, perform a scan
if (storedEntry != null) {
for (Player previousViewer : previousViewers) {
newEntry.updatePlayer(previousViewer);
}
} else {
newEntry.scanPlayers(getWorld().getPlayers());
}
}
use of com.bergerkiller.bukkit.common.internal.hooks.EntityTrackerEntryHook in project BKCommonLib by bergerhealer.
the class EntityNetworkController method bind.
/**
* Binds this Entity Network Controller to an Entity. This is called from
* elsewhere, and should be ignored entirely.
*
* @param entity to bind with
* @param entityTrackerEntry to bind with
*/
public final void bind(T entity, Object entityTrackerEntry) {
if (this.entity != null) {
this.onDetached();
// calling callbacks in this controller.
if (this.entry != null) {
EntityTrackerEntryHook oldHook = EntityTypingHandler.INSTANCE.getEntityTrackerEntryHook(this.entry.getRaw());
if (oldHook != null && oldHook.getController() == this) {
EntityNetworkController<CommonEntity<?>> defaultController = CommonUtil.unsafeCast(new DefaultEntityNetworkController());
defaultController.bind(this.entity, this.entry.getRaw());
}
}
this.entity = null;
this.entry = null;
this.state = null;
}
if (entity == null) {
return;
}
this.entity = entity;
this.entry = EntityTrackerEntryHandle.createHandle(entityTrackerEntry);
this.state = this.entry.getState();
if (!CommonCapabilities.MULTIPLE_PASSENGERS) {
this.last_passenger_1_8_8 = entity.getPassenger();
}
EntityTrackerEntryHook hook = EntityTypingHandler.INSTANCE.getEntityTrackerEntryHook(this.entry.getRaw());
if (hook != null) {
hook.setController(this);
}
if (this.entity.isSpawned()) {
this.onAttached();
}
}
Aggregations