use of com.bergerkiller.generated.net.minecraft.server.level.EntityTrackerEntryHandle 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());
}
}
Aggregations