@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 Object storedEntry = tracker.getEntry(entity);
// Properly handle a previously set controller
if (storedEntry instanceof NMSEntityTrackerEntry) {
final EntityNetworkController oldController = ((NMSEntityTrackerEntry) storedEntry).getController();
if (oldController == controller) {
return;
} else if (oldController != null) {
oldController.onDetached();
}
}
// Take care of null controllers - stop tracking
if (controller == null) {
tracker.stopTracking(entity);
return;
}
final Object newEntry;
if (controller instanceof DefaultEntityNetworkController) {
// Assign the default Entity Tracker Entry
if (EntityTrackerEntryRef.TEMPLATE.isType(storedEntry)) {
// Nothing to be done here
newEntry = storedEntry;
} else {
// Create a new entry
final CommonEntityType type = CommonEntityType.byEntity(entity);
newEntry = new EntityTrackerEntry(getHandle(Entity.class), type.networkViewDistance, type.networkUpdateInterval, type.networkIsMobile);
// Transfer data if needed
if (storedEntry != null) {
EntityTrackerEntryRef.TEMPLATE.transfer(storedEntry, newEntry);
}
}
} else if (controller instanceof ExternalEntityNetworkController) {
// Use the entry as stored by the external network controller
newEntry = controller.getHandle();
// Be sure to refresh stats using the old entry
if (storedEntry != null && newEntry != null) {
EntityTrackerEntryRef.TEMPLATE.transfer(storedEntry, newEntry);
}
} else {
// Assign a new Entity Tracker Entry with controller capabilities
if (storedEntry instanceof NMSEntityTrackerEntry) {
// Use the previous entry - hotswap the controller
newEntry = storedEntry;
EntityTrackerEntryRef.viewers.get(newEntry).clear();
} else {
// Create a new entry from scratch
newEntry = new NMSEntityTrackerEntry(this.getEntity());
// Transfer possible information over
if (storedEntry != null) {
EntityTrackerEntryRef.TEMPLATE.transfer(storedEntry, newEntry);
}
}
}
// Attach the entry to the controller
controller.bind(this, newEntry);
// Attach (new?) entry to the world
if (storedEntry != newEntry) {
tracker.setEntry(entity, newEntry);
// Make sure to update the viewers
EntityTrackerEntryRef.scanPlayers(newEntry, getWorld().getPlayers());
}
}