Search in sources :

Example 1 with MapSession

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

the class CommonMapController method storeDynamicMapId.

/**
 * Figures out a new Map Id and prepares the display of a map with this new Id.
 * This method is only suitable for dynamically generated map Ids.
 *
 * @param mapUUID to store
 * @return map Id that was assigned
 */
private synchronized short storeDynamicMapId(MapUUID mapUUID) {
    // Null safety check
    if (mapUUID == null) {
        return -1;
    }
    // If the UUID is static, do not store anything and return the static Id instead
    short staticMapid = CommonMapUUIDStore.getStaticMapId(mapUUID.getUUID());
    if (staticMapid != -1) {
        return staticMapid;
    }
    // Increment this counter. The Map Id updater task will clean up unused maps every 1000 cycles.
    idGenerationCounter++;
    // Figure out a free Map Id we can use
    for (int mapidValue = 0; mapidValue < Short.MAX_VALUE; mapidValue++) {
        if (!mapUUIDById.contains(mapidValue)) {
            // Check if the Map Id was changed compared to before
            boolean idChanged = mapIdByUUID.containsKey(mapUUID);
            // Store in mapping
            mapUUIDById.put(mapidValue, mapUUID);
            mapIdByUUID.put(mapUUID, Short.valueOf((short) mapidValue));
            // Invalidate display if it exists
            MapDisplayInfo mapInfo = maps.get(mapUUID.getUUID());
            if (mapInfo != null) {
                for (MapSession session : mapInfo.sessions) {
                    session.display.invalidate();
                }
            }
            if (idChanged) {
                dirtyMapUUIDSet.add(mapUUID.getUUID());
            }
            return (short) mapidValue;
        }
    }
    return -1;
}
Also used : MapSession(com.bergerkiller.bukkit.common.map.MapSession)

Example 2 with MapSession

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

the class CommonMapController method handleMapShowEvent.

private synchronized void handleMapShowEvent(MapShowEvent event) {
    // Check if there are other map displays that should be shown to the player automatically
    // This uses the 'isGlobal()' property of the display
    MapDisplayInfo info = CommonMapController.this.getInfo(event.getMapUUID());
    boolean hasDisplay = false;
    if (info != null) {
        for (MapSession session : info.sessions) {
            if (session.display.isGlobal()) {
                session.display.addOwner(event.getPlayer());
                hasDisplay = true;
                break;
            }
        }
    }
    // When defined in the NBT of the item, construct the Map Display automatically
    CommonTagCompound tag = ItemUtil.getMetaTag(event.getMapItem(), false);
    if (tag != null && !hasDisplay) {
        String pluginName = tag.getValue("mapDisplayPlugin", String.class);
        String displayClassName = tag.getValue("mapDisplayClass", String.class);
        if (pluginName != null && displayClassName != null) {
            Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName);
            Class<?> displayClass = null;
            if (plugin != null) {
                try {
                    displayClass = plugin.getClass().getClassLoader().loadClass(displayClassName);
                    if (!MapDisplay.class.isAssignableFrom(displayClass)) {
                        displayClass = null;
                    }
                } catch (ClassNotFoundException e) {
                }
            }
            if (displayClass != null && !event.hasDisplay()) {
                try {
                    MapDisplay display = (MapDisplay) displayClass.newInstance();
                    event.setDisplay((JavaPlugin) plugin, display);
                    ;
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    CommonUtil.callEvent(event);
}
Also used : MapDisplay(com.bergerkiller.bukkit.common.map.MapDisplay) CommonTagCompound(com.bergerkiller.bukkit.common.nbt.CommonTagCompound) MapSession(com.bergerkiller.bukkit.common.map.MapSession) Plugin(org.bukkit.plugin.Plugin) JavaPlugin(org.bukkit.plugin.java.JavaPlugin)

Example 3 with MapSession

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

the class CommonMapController method onDisable.

/**
 * Cleans up all running map displays and de-initializes all map display logic
 */
public void onDisable(CommonPlugin plugin) {
    if (this.isEnabled) {
        this.isEnabled = false;
        // If reloading, save current map id state to avoid glitches
        CommonMapReloadFile.save(plugin, reloadFile -> {
            // Add static reserved / dynamic map ids
            for (Map.Entry<MapUUID, Integer> entry : mapIdByUUID.entrySet()) {
                MapUUID mapUUID = entry.getKey();
                if (mapUUID.isStaticUUID()) {
                    reloadFile.staticReservedIds.add(entry.getValue());
                } else {
                    reloadFile.addDynamicMapId(mapUUID, entry.getValue());
                }
            }
            // Add information about all item frames and what display they displayed last
            for (Map.Entry<Integer, ItemFrameInfo> entry : itemFrames.entrySet()) {
                ItemFrameInfo info = entry.getValue();
                if (info.lastMapUUID != null) {
                    reloadFile.addItemFrameDisplayUUID(entry.getKey().intValue(), info.lastMapUUID);
                }
            }
        });
        for (MapDisplayInfo map : this.mapsValues.cloneAsIterable()) {
            for (MapSession session : new ArrayList<MapSession>(map.getSessions())) {
                session.display.setRunning(false);
            }
        }
    }
}
Also used : MapDisplayInfo(com.bergerkiller.bukkit.common.map.binding.MapDisplayInfo) ArrayList(java.util.ArrayList) MapSession(com.bergerkiller.bukkit.common.map.MapSession) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap) IntHashMap(com.bergerkiller.bukkit.common.wrappers.IntHashMap) HashMap(java.util.HashMap) OutputTypeMap(com.bergerkiller.mountiplex.reflection.util.OutputTypeMap) ItemFrameInfo(com.bergerkiller.bukkit.common.map.binding.ItemFrameInfo) MapUUID(com.bergerkiller.bukkit.common.map.util.MapUUID)

Example 4 with MapSession

use of com.bergerkiller.bukkit.common.map.MapSession 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 5 with MapSession

use of com.bergerkiller.bukkit.common.map.MapSession 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)

Aggregations

MapSession (com.bergerkiller.bukkit.common.map.MapSession)11 MapUUID (com.bergerkiller.bukkit.common.map.util.MapUUID)5 MapDisplayTile (com.bergerkiller.bukkit.common.map.MapDisplayTile)4 ItemFrameInfo (com.bergerkiller.bukkit.common.map.binding.ItemFrameInfo)3 MapDisplayInfo (com.bergerkiller.bukkit.common.map.binding.MapDisplayInfo)3 UUID (java.util.UUID)3 Player (org.bukkit.entity.Player)3 ItemStack (org.bukkit.inventory.ItemStack)3 PlayerInventory (org.bukkit.inventory.PlayerInventory)3 MapDisplay (com.bergerkiller.bukkit.common.map.MapDisplay)2 DataWatcher (com.bergerkiller.bukkit.common.wrappers.DataWatcher)2 Plugin (org.bukkit.plugin.Plugin)2 JavaPlugin (org.bukkit.plugin.java.JavaPlugin)2 CommonPlugin (com.bergerkiller.bukkit.common.internal.CommonPlugin)1 MapDisplayProperties (com.bergerkiller.bukkit.common.map.MapDisplayProperties)1 CommonTagCompound (com.bergerkiller.bukkit.common.nbt.CommonTagCompound)1 IntHashMap (com.bergerkiller.bukkit.common.wrappers.IntHashMap)1 LongHashSet (com.bergerkiller.bukkit.common.wrappers.LongHashSet)1 EntityItemFrameHandle (com.bergerkiller.generated.net.minecraft.world.entity.decoration.EntityItemFrameHandle)1 OutputTypeMap (com.bergerkiller.mountiplex.reflection.util.OutputTypeMap)1