Search in sources :

Example 1 with MapDisplayTile

use of com.bergerkiller.bukkit.common.map.MapDisplayTile in project BKCommonLib by bergerhealer.

the class MapDisplayItemMapIdUpdater method updateMapIds.

public void updateMapIds() {
    // Remove non-existing maps from the internal mapping
    if (controller.idGenerationCounter > GENERATION_COUNTER_CLEANUP_INTERVAL) {
        controller.idGenerationCounter = 0;
        // Find all map UUIDs that exist on the server
        HashSet<MapUUID> validUUIDs = new HashSet<MapUUID>();
        for (Set<EntityItemFrameHandle> itemFrameSet : controller.itemFrameEntities.values()) {
            for (EntityItemFrameHandle itemFrame : itemFrameSet) {
                MapUUID mapUUID = controller.getItemFrameMapUUID(itemFrame);
                if (mapUUID != null) {
                    validUUIDs.add(mapUUID);
                }
            }
        }
        for (Player player : Bukkit.getOnlinePlayers()) {
            PlayerInventory inv = player.getInventory();
            for (int i = 0; i < inv.getSize(); i++) {
                ItemStack item = inv.getItem(i);
                UUID mapUUID = CommonMapUUIDStore.getMapUUID(item);
                if (mapUUID != null) {
                    validUUIDs.add(new MapUUID(mapUUID));
                }
            }
        }
        // Perform the cleanup (synchronized access required!)
        controller.cleanupUnusedUUIDs(validUUIDs);
    }
    // Refresh items known to clients when Map Ids are re-assigned
    // Swap around the tmp and main set every tick
    final SetMultimap<UUID, MapUUID> dirtyMaps = controller.swapDirtyMapUUIDs();
    if (!dirtyMaps.isEmpty()) {
        // This will result in new SetItemSlot packets being sent, refreshing the map Id
        for (Player player : Bukkit.getOnlinePlayers()) {
            PlayerInventory inv = player.getInventory();
            for (int i = 0; i < inv.getSize(); i++) {
                ItemStack item = inv.getItem(i);
                UUID uuid = CommonMapUUIDStore.getMapUUID(item);
                if (dirtyMaps.containsKey(uuid)) {
                    inv.setItem(i, item.clone());
                }
            }
        }
        // Refresh all item frames that display this map
        // This will result in a new EntityMetadata packets being sent, refreshing the map Id
        // After updating all item frames, resend the maps
        dirtyMaps.keySet().stream().map(controller.maps::get).filter(Objects::nonNull).forEach(info -> {
            // Refresh item of all affected item frames
            // This re-sends metadata packets
            final Set<MapUUID> mapUUIDs = dirtyMaps.get(info.getUniqueId());
            for (ItemFrameInfo itemFrameInfo : info.getItemFrames()) {
                if (mapUUIDs.contains(itemFrameInfo.lastMapUUID)) {
                    itemFrameInfo.itemFrameHandle.refreshItem();
                }
            }
            // Resend map data for all affected tiles
            for (MapSession session : info.getSessions()) {
                for (MapDisplayTile tile : session.tiles) {
                    if (mapUUIDs.contains(tile.getMapTileUUID())) {
                        session.onlineOwners.forEach(o -> o.sendDirtyTile(tile));
                    }
                }
            }
        });
        // Done processing, wipe
        dirtyMaps.clear();
    }
}
Also used : Player(org.bukkit.entity.Player) PlayerInventory(org.bukkit.inventory.PlayerInventory) MapSession(com.bergerkiller.bukkit.common.map.MapSession) ItemFrameInfo(com.bergerkiller.bukkit.common.map.binding.ItemFrameInfo) MapUUID(com.bergerkiller.bukkit.common.map.util.MapUUID) EntityItemFrameHandle(com.bergerkiller.generated.net.minecraft.world.entity.decoration.EntityItemFrameHandle) ItemStack(org.bukkit.inventory.ItemStack) MapUUID(com.bergerkiller.bukkit.common.map.util.MapUUID) UUID(java.util.UUID) HashSet(java.util.HashSet) MapDisplayTile(com.bergerkiller.bukkit.common.map.MapDisplayTile)

Example 2 with MapDisplayTile

use of com.bergerkiller.bukkit.common.map.MapDisplayTile in project BKCommonLib by bergerhealer.

the class MapDisplayInfo method loadTiles.

/**
 * Loads the tiles in a Map Display. This also removes tiles in the display
 * that don't actually exist.
 *
 * @param session The session of the map display
 * @param initialize Whether the tiles are initialized, and contents are not yet drawn
 */
public void loadTiles(MapSession session, boolean initialize) {
    // Collect all tile x/y coordinates into a long hashset
    LongHashSet tile_coords = new LongHashSet();
    for (ItemFrameInfo itemFrame : this.itemFrames) {
        MapUUID uuid = itemFrame.lastMapUUID;
        if (uuid != null) {
            tile_coords.add(uuid.getTileX(), uuid.getTileY());
        }
    }
    tile_coords.add(0, 0);
    if (initialize) {
        // Wipe previous tiles when initializing
        session.tiles.clear();
    } else {
        // Remove tiles from the display that are no longer present
        // Remove existing tiles from the set at the same time
        // We are left with a set containing tiles that must be added
        Iterator<MapDisplayTile> iter = session.tiles.iterator();
        while (iter.hasNext()) {
            MapDisplayTile tile = iter.next();
            if (!tile_coords.remove(tile.tileX, tile.tileY)) {
                iter.remove();
            }
        }
    }
    // Add all remaining tiles to the display
    LongHashSet.LongIterator iter = tile_coords.longIterator();
    while (iter.hasNext()) {
        long coord = iter.next();
        MapDisplayTile newTile = new MapDisplayTile(this.uuid, MathUtil.longHashMsw(coord), MathUtil.longHashLsw(coord));
        session.tiles.add(newTile);
        // Send map packets for the added tile
        if (!initialize) {
            for (MapSession.Owner owner : session.onlineOwners) {
                owner.sendDirtyTile(newTile);
            }
        }
    }
}
Also used : LongHashSet(com.bergerkiller.bukkit.common.wrappers.LongHashSet) MapSession(com.bergerkiller.bukkit.common.map.MapSession) MapUUID(com.bergerkiller.bukkit.common.map.util.MapUUID) MapDisplayTile(com.bergerkiller.bukkit.common.map.MapDisplayTile)

Example 3 with MapDisplayTile

use of com.bergerkiller.bukkit.common.map.MapDisplayTile in project BKCommonLib by bergerhealer.

the class MapDisplayInfo method addTileIfMissing.

/**
 * Adds a new display tile to already running displays.
 * Does nothing if the display is going to be reset, or no display sessions exist.
 * Since tile 0,0 is always added by the display, that tile is ignored.
 *
 * @param tileX
 * @param tileY
 */
public void addTileIfMissing(int tileX, int tileY) {
    if (this.sessions.isEmpty() || (tileX == 0 && tileY == 0)) {
        return;
    }
    if ((tileX << 7) >= this.desiredWidth) {
        return;
    }
    if ((tileY << 7) >= this.desiredHeight) {
        return;
    }
    for (MapSession session : this.sessions) {
        if (session.refreshResolutionRequested) {
            continue;
        }
        if (session.display.containsTile(tileX, tileY)) {
            continue;
        }
        MapDisplayTile newTile = new MapDisplayTile(this.uuid, tileX, tileY);
        session.tiles.add(newTile);
        for (MapSession.Owner owner : session.onlineOwners) {
            owner.sendDirtyTile(newTile);
        }
    }
}
Also used : MapSession(com.bergerkiller.bukkit.common.map.MapSession) MapDisplayTile(com.bergerkiller.bukkit.common.map.MapDisplayTile)

Example 4 with MapDisplayTile

use of com.bergerkiller.bukkit.common.map.MapDisplayTile in project BKCommonLib by bergerhealer.

the class MapDisplayMarkers method synchronize.

public void synchronize(MapSession session) {
    if (markersByTile.isEmpty()) {
        // skip
        return;
    }
    for (MapDisplayTile displayedTile : session.tiles) {
        MapDisplayMarkerTile tile = markersByTile.get(displayedTile.tile);
        if (tile == null || !tile.isChanged()) {
            continue;
        }
        // Has changes, verify whether all owners have received them
        MapDisplayTile.Update mapUpdate = null;
        for (MapSession.Owner owner : session.onlineOwners) {
            // Already synchronized during map content update
            if (tile.isSynchronized(owner.player)) {
                continue;
            }
            // Requires update, ask the tile to do this
            if (mapUpdate == null) {
                mapUpdate = new MapDisplayTile.Update(displayedTile.tile, displayedTile.getMapId());
                APPLIER.apply(mapUpdate.packet.getRaw(), tile);
            } else {
                mapUpdate = mapUpdate.clone();
            }
            // Send to this player
            PacketUtil.sendPacket(owner.player, mapUpdate.packet, false);
        }
    }
    // Go by all tiles and clean them up
    Iterator<MapDisplayMarkerTile> iter = markersByTile.values().iterator();
    while (iter.hasNext()) {
        MapDisplayMarkerTile tile = iter.next();
        if (tile.isEmpty()) {
            iter.remove();
        } else {
            tile.setChanged(false);
        }
    }
}
Also used : MapSession(com.bergerkiller.bukkit.common.map.MapSession) MapDisplayTile(com.bergerkiller.bukkit.common.map.MapDisplayTile)

Aggregations

MapDisplayTile (com.bergerkiller.bukkit.common.map.MapDisplayTile)4 MapSession (com.bergerkiller.bukkit.common.map.MapSession)4 MapUUID (com.bergerkiller.bukkit.common.map.util.MapUUID)2 ItemFrameInfo (com.bergerkiller.bukkit.common.map.binding.ItemFrameInfo)1 LongHashSet (com.bergerkiller.bukkit.common.wrappers.LongHashSet)1 EntityItemFrameHandle (com.bergerkiller.generated.net.minecraft.world.entity.decoration.EntityItemFrameHandle)1 HashSet (java.util.HashSet)1 UUID (java.util.UUID)1 Player (org.bukkit.entity.Player)1 ItemStack (org.bukkit.inventory.ItemStack)1 PlayerInventory (org.bukkit.inventory.PlayerInventory)1