Search in sources :

Example 11 with EntityTrackerEntryHandle

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());
    }
}
Also used : EntityTrackerEntryHandle(com.bergerkiller.generated.net.minecraft.server.level.EntityTrackerEntryHandle) CommonPlayer(com.bergerkiller.bukkit.common.entity.type.CommonPlayer) EntityTracker(com.bergerkiller.bukkit.common.wrappers.EntityTracker) EntityTrackerEntryHook(com.bergerkiller.bukkit.common.internal.hooks.EntityTrackerEntryHook) CommonPacket(com.bergerkiller.bukkit.common.protocol.CommonPacket) org.bukkit.entity(org.bukkit.entity)

Aggregations

EntityTrackerEntryHandle (com.bergerkiller.generated.net.minecraft.server.level.EntityTrackerEntryHandle)11 EntityTracker (com.bergerkiller.bukkit.common.wrappers.EntityTracker)5 EntityHandle (com.bergerkiller.generated.net.minecraft.world.entity.EntityHandle)4 ArrayList (java.util.ArrayList)4 Entity (org.bukkit.entity.Entity)3 ExtendedEntity (com.bergerkiller.bukkit.common.bases.ExtendedEntity)2 CommonPacket (com.bergerkiller.bukkit.common.protocol.CommonPacket)2 EntityTrackerEntryStateHandle (com.bergerkiller.generated.net.minecraft.server.level.EntityTrackerEntryStateHandle)2 LinkedList (java.util.LinkedList)2 List (java.util.List)2 World (org.bukkit.World)2 CommonPlayer (com.bergerkiller.bukkit.common.entity.type.CommonPlayer)1 EntityTrackerEntryHook (com.bergerkiller.bukkit.common.internal.hooks.EntityTrackerEntryHook)1 org.bukkit.entity (org.bukkit.entity)1 Player (org.bukkit.entity.Player)1