use of com.bergerkiller.bukkit.common.map.binding.ItemFrameInfo 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);
}
}
}
}
use of com.bergerkiller.bukkit.common.map.binding.ItemFrameInfo in project BKCommonLib by bergerhealer.
the class CommonMapController method onChunkEntitiesLoaded.
private void onChunkEntitiesLoaded(Chunk chunk) {
World world = chunk.getWorld();
Set<IntVector2> dependingChunks;
{
Map<IntVector2, Set<IntVector2>> dependencies = this.itemFrameClusterDependencies.get(world);
if (dependencies == null || (dependingChunks = dependencies.remove(new IntVector2(chunk))) == null) {
return;
}
}
boolean wasClustersByWorldCacheEnabled = this.itemFrameClustersByWorldEnabled;
try {
this.itemFrameClustersByWorldEnabled = true;
for (IntVector2 depending : dependingChunks) {
// Check this depending chunk is still loaded with all entities inside
// If not, then when it loads the cluster will be revived then
Chunk dependingChunk = WorldUtil.getChunk(world, depending.x, depending.z);
if (dependingChunk == null || !WorldUtil.isChunkEntitiesLoaded(dependingChunk)) {
continue;
}
// Quicker than iterating all item frames on the world
for (Entity entity : ChunkUtil.getEntities(dependingChunk)) {
if (!(entity instanceof ItemFrame)) {
continue;
}
// Recalculate UUID, this will re-discover the cluster
// May also revive other item frames that were part of the same cluster
// Note that if this chunk being loaded contained item frames part of the cluster,
// the cluster is already revived. Entity add handling occurs prior.
ItemFrameInfo frameInfo = this.itemFrames.get(entity.getEntityId());
if (frameInfo != null) {
frameInfo.onChunkDependencyLoaded();
}
}
}
} finally {
this.itemFrameClustersByWorldEnabled = wasClustersByWorldCacheEnabled;
if (!wasClustersByWorldCacheEnabled) {
itemFrameClustersByWorld.clear();
}
}
}
use of com.bergerkiller.bukkit.common.map.binding.ItemFrameInfo in project BKCommonLib by bergerhealer.
the class CommonMapController method getInfo.
/**
* Gets the Map display information for a map item displayed in an item frame.
* All frames showing the same map will return the same {@link #MapDisplayInfo}.
* If the item frame does not show a map, null is returned.
*
* @param itemFrame to get the map information for
* @return map display info
*/
public synchronized MapDisplayInfo getInfo(ItemFrame itemFrame) {
ItemFrameInfo frameInfo = itemFrames.get(itemFrame.getEntityId());
if (frameInfo != null) {
if (frameInfo.lastMapUUID == null) {
return null;
}
MapDisplayInfo info = maps.get(frameInfo.lastMapUUID.getUUID());
if (info == null) {
info = new MapDisplayInfo(this, frameInfo.lastMapUUID.getUUID());
maps.put(frameInfo.lastMapUUID.getUUID(), info);
mapsValues.add(info);
}
return info;
}
return getInfo(getItemFrameItem(itemFrame));
}
use of com.bergerkiller.bukkit.common.map.binding.ItemFrameInfo in project BKCommonLib by bergerhealer.
the class CommonMapController method findClusterItemFrames.
/**
* Looks up all item frame information loaded of a particular item frame cluster
*
* @param world World the cluster is in
* @param cluster Item frame cluster
* @return List of item frame info
*/
public List<ItemFrameInfo> findClusterItemFrames(ItemFrameCluster cluster) {
if (!cluster.world.isLoaded()) {
return Collections.emptyList();
}
List<ItemFrameInfo> result = new ArrayList<>(cluster.coordinates.size());
for (Entity entity : WorldUtil.getEntities(cluster.world.getLoadedWorld(), null, cluster.min_coord.x + 0.01, cluster.min_coord.y + 0.01, cluster.min_coord.z + 0.01, cluster.max_coord.x + 0.99, cluster.max_coord.y + 0.99, cluster.max_coord.z + 0.99)) {
if (!(entity instanceof ItemFrame)) {
continue;
}
ItemFrameInfo itemFrame = this.getItemFrame(entity.getEntityId());
if (itemFrame == null) {
continue;
}
if (!cluster.coordinates.contains(itemFrame.coordinates)) {
continue;
}
result.add(itemFrame);
}
return result;
}
use of com.bergerkiller.bukkit.common.map.binding.ItemFrameInfo 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();
}
}
Aggregations