Search in sources :

Example 1 with EntityTrackerEntryHook

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;
}
Also used : EntityTrackerEntryHook(com.bergerkiller.bukkit.common.internal.hooks.EntityTrackerEntryHook)

Example 2 with EntityTrackerEntryHook

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());
    }
}
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)

Example 3 with EntityTrackerEntryHook

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();
    }
}
Also used : EntityTrackerEntryHook(com.bergerkiller.bukkit.common.internal.hooks.EntityTrackerEntryHook) CommonEntity(com.bergerkiller.bukkit.common.entity.CommonEntity)

Aggregations

EntityTrackerEntryHook (com.bergerkiller.bukkit.common.internal.hooks.EntityTrackerEntryHook)3 CommonEntity (com.bergerkiller.bukkit.common.entity.CommonEntity)1 CommonPlayer (com.bergerkiller.bukkit.common.entity.type.CommonPlayer)1 CommonPacket (com.bergerkiller.bukkit.common.protocol.CommonPacket)1 EntityTracker (com.bergerkiller.bukkit.common.wrappers.EntityTracker)1 EntityTrackerEntryHandle (com.bergerkiller.generated.net.minecraft.server.level.EntityTrackerEntryHandle)1 org.bukkit.entity (org.bukkit.entity)1