Search in sources :

Example 1 with Region

use of dev.frankheijden.insights.api.addons.Region in project Insights by InsightsPlugin.

the class CommandScanCache method handleScan.

/**
 * Checks the player's location for a cache and displays the distribution of items.
 */
public void handleScan(Player player, Set<? extends ScanObject<?>> items, boolean displayZeros) {
    Location loc = player.getLocation();
    Optional<Region> optionalRegion = plugin.getAddonManager().getRegion(loc);
    Optional<Storage> optionalStorage;
    // If a region is present, try to fetch cache of the region.
    if (optionalRegion.isPresent()) {
        optionalStorage = plugin.getAddonStorage().get(optionalRegion.get().getKey());
    } else {
        optionalStorage = plugin.getWorldStorage().getWorld(loc.getWorld().getUID()).get(ChunkUtils.getKey(loc.getChunk()));
    }
    if (optionalStorage.isPresent()) {
        var storage = optionalStorage.get();
        var messages = plugin.getMessages();
        // Check which items we need to display & sort them based on their name.
        ScanObject<?>[] displayItems = (items == null ? storage.keys() : items).stream().filter(item -> storage.count(item) != 0 || displayZeros).sorted(Comparator.comparing(ScanObject::name)).toArray(ScanObject[]::new);
        var footer = messages.getMessage(Messages.Key.SCANCACHE_RESULT_FOOTER).addTemplates(Messages.tagOf("area", optionalRegion.map(r -> plugin.getAddonManager().getAddon(r.getAddon()).getAreaName()).orElse("chunk")));
        var message = messages.createPaginatedMessage(messages.getMessage(Messages.Key.SCANCACHE_RESULT_HEADER), Messages.Key.SCANCACHE_RESULT_FORMAT, footer, displayItems, storage::count, item -> Component.text(EnumUtils.pretty(item.getObject())));
        plugin.getScanHistory().setHistory(player.getUniqueId(), message);
        message.sendTo(player, 0);
    } else {
        plugin.getMessages().getMessage(Messages.Key.SCANCACHE_NO_CACHE).sendTo(player);
    }
}
Also used : Arrays(java.util.Arrays) CommandPermission(cloud.commandframework.annotations.CommandPermission) EnumUtils(dev.frankheijden.insights.api.utils.EnumUtils) CommandMethod(cloud.commandframework.annotations.CommandMethod) Limit(dev.frankheijden.insights.api.config.limits.Limit) Set(java.util.Set) ChunkUtils(dev.frankheijden.insights.api.utils.ChunkUtils) Storage(dev.frankheijden.insights.api.concurrent.storage.Storage) ScanObject(dev.frankheijden.insights.api.objects.wrappers.ScanObject) Player(org.bukkit.entity.Player) HashSet(java.util.HashSet) Messages(dev.frankheijden.insights.api.config.Messages) InsightsCommand(dev.frankheijden.insights.api.commands.InsightsCommand) Region(dev.frankheijden.insights.api.addons.Region) Location(org.bukkit.Location) Component(net.kyori.adventure.text.Component) Optional(java.util.Optional) RTileEntityTypes(dev.frankheijden.insights.api.reflection.RTileEntityTypes) Constants(dev.frankheijden.insights.api.utils.Constants) Comparator(java.util.Comparator) Argument(cloud.commandframework.annotations.Argument) InsightsPlugin(dev.frankheijden.insights.api.InsightsPlugin) Storage(dev.frankheijden.insights.api.concurrent.storage.Storage) ScanObject(dev.frankheijden.insights.api.objects.wrappers.ScanObject) Region(dev.frankheijden.insights.api.addons.Region) Location(org.bukkit.Location)

Example 2 with Region

use of dev.frankheijden.insights.api.addons.Region in project Insights by InsightsPlugin.

the class InsightsListener method handleAddition.

protected boolean handleAddition(Player player, Location location, ScanObject<?> item, int delta, boolean included) {
    Optional<Region> regionOptional = plugin.getAddonManager().getRegion(location);
    var chunk = location.getChunk();
    var world = location.getWorld();
    UUID worldUid = world.getUID();
    long chunkKey = ChunkUtils.getKey(chunk);
    boolean queued;
    String area;
    LimitEnvironment env;
    if (regionOptional.isPresent()) {
        var region = regionOptional.get();
        queued = plugin.getAddonScanTracker().isQueued(region.getKey());
        area = plugin.getAddonManager().getAddon(region.getAddon()).getAreaName();
        env = new LimitEnvironment(player, world.getName(), region.getAddon());
    } else {
        queued = plugin.getWorldChunkScanTracker().isQueued(worldUid, chunkKey);
        area = "chunk";
        env = new LimitEnvironment(player, world.getName());
    }
    if (queued) {
        if (plugin.getSettings().canReceiveAreaScanNotifications(player)) {
            plugin.getMessages().getMessage(Messages.Key.AREA_SCAN_QUEUED).addTemplates(Messages.tagOf("area", area)).sendTo(player);
        }
        return true;
    }
    // Get the first (smallest) limit for the specific user (bypass permissions taken into account)
    Optional<Limit> limitOptional = plugin.getLimits().getFirstLimit(item, env);
    if (limitOptional.isEmpty())
        return false;
    var limit = limitOptional.get();
    var limitInfo = limit.getLimit(item);
    if (regionOptional.isEmpty() && limit.getSettings().isDisallowedPlacementOutsideRegion()) {
        plugin.getMessages().getMessage(Messages.Key.LIMIT_DISALLOWED_PLACEMENT).addTemplates(TagResolver.resolver(Messages.tagOf("name", limitInfo.getName()), Messages.tagOf("area", area))).sendTo(player);
        return true;
    }
    Consumer<Storage> storageConsumer = storage -> {
        // Only iff the block was included in the chunk AND its not a cuboid/area scan.
        if (included && regionOptional.isEmpty()) {
            storage.modify(item, -delta);
        }
        // Notify the user scan completed
        if (plugin.getSettings().canReceiveAreaScanNotifications(player)) {
            plugin.getMessages().getMessage(Messages.Key.AREA_SCAN_COMPLETED).sendTo(player);
        }
    };
    Optional<Storage> storageOptional;
    if (regionOptional.isPresent()) {
        storageOptional = handleAddonAddition(player, regionOptional.get(), storageConsumer);
    } else {
        storageOptional = handleChunkAddition(player, chunk, storageConsumer);
    }
    // If the storage is not present, cancel.
    if (storageOptional.isEmpty())
        return true;
    var storage = storageOptional.get();
    long count = storage.count(limit, item);
    // If count is beyond limit, act
    if (count + delta > limitInfo.getLimit()) {
        plugin.getMessages().getMessage(Messages.Key.LIMIT_REACHED).addTemplates(Messages.tagOf("limit", StringUtils.pretty(limitInfo.getLimit())), Messages.tagOf("name", limitInfo.getName()), Messages.tagOf("area", area)).sendTo(player);
        return true;
    }
    return false;
}
Also used : LimitInfo(dev.frankheijden.insights.api.config.limits.LimitInfo) StringUtils(dev.frankheijden.insights.api.utils.StringUtils) ScanTask(dev.frankheijden.insights.api.tasks.ScanTask) Storage(dev.frankheijden.insights.api.concurrent.storage.Storage) ScanObject(dev.frankheijden.insights.api.objects.wrappers.ScanObject) Player(org.bukkit.entity.Player) Level(java.util.logging.Level) ChunkStorage(dev.frankheijden.insights.api.concurrent.storage.ChunkStorage) Messages(dev.frankheijden.insights.api.config.Messages) ScanOptions(dev.frankheijden.insights.api.concurrent.ScanOptions) ChunkPart(dev.frankheijden.insights.api.objects.chunk.ChunkPart) Block(org.bukkit.block.Block) Location(org.bukkit.Location) World(org.bukkit.World) Chunk(org.bukkit.Chunk) InsightsPlugin(dev.frankheijden.insights.api.InsightsPlugin) TagResolver(net.kyori.adventure.text.minimessage.tag.resolver.TagResolver) Material(org.bukkit.Material) Listener(org.bukkit.event.Listener) Limit(dev.frankheijden.insights.api.config.limits.Limit) WorldStorage(dev.frankheijden.insights.api.concurrent.storage.WorldStorage) BlockState(org.bukkit.block.BlockState) InsightsBase(dev.frankheijden.insights.api.objects.InsightsBase) ChunkUtils(dev.frankheijden.insights.api.utils.ChunkUtils) UUID(java.util.UUID) EntityType(org.bukkit.entity.EntityType) Consumer(java.util.function.Consumer) List(java.util.List) Region(dev.frankheijden.insights.api.addons.Region) LimitEnvironment(dev.frankheijden.insights.api.config.LimitEnvironment) Optional(java.util.Optional) AddonStorage(dev.frankheijden.insights.api.concurrent.storage.AddonStorage) DistributionStorage(dev.frankheijden.insights.api.concurrent.storage.DistributionStorage) Storage(dev.frankheijden.insights.api.concurrent.storage.Storage) ChunkStorage(dev.frankheijden.insights.api.concurrent.storage.ChunkStorage) WorldStorage(dev.frankheijden.insights.api.concurrent.storage.WorldStorage) AddonStorage(dev.frankheijden.insights.api.concurrent.storage.AddonStorage) DistributionStorage(dev.frankheijden.insights.api.concurrent.storage.DistributionStorage) Region(dev.frankheijden.insights.api.addons.Region) LimitEnvironment(dev.frankheijden.insights.api.config.LimitEnvironment) Limit(dev.frankheijden.insights.api.config.limits.Limit) UUID(java.util.UUID)

Example 3 with Region

use of dev.frankheijden.insights.api.addons.Region in project Insights by InsightsPlugin.

the class InsightsListener method handleRemoval.

protected void handleRemoval(Player player, Location location, ScanObject<?> item, int delta, boolean included) {
    Optional<Region> regionOptional = plugin.getAddonManager().getRegion(location);
    Chunk chunk = location.getChunk();
    World world = location.getWorld();
    UUID worldUid = world.getUID();
    long chunkKey = ChunkUtils.getKey(chunk);
    UUID uuid = player.getUniqueId();
    boolean queued;
    LimitEnvironment env;
    Optional<Storage> storageOptional;
    if (regionOptional.isPresent()) {
        Region region = regionOptional.get();
        queued = plugin.getAddonScanTracker().isQueued(region.getKey());
        env = new LimitEnvironment(player, world.getName(), region.getAddon());
        storageOptional = plugin.getAddonStorage().get(region.getKey());
    } else {
        queued = plugin.getWorldChunkScanTracker().isQueued(worldUid, chunkKey);
        env = new LimitEnvironment(player, world.getName());
        storageOptional = plugin.getWorldStorage().getWorld(worldUid).get(chunkKey);
    }
    // Modify the area to account for the broken block.
    storageOptional.ifPresent(storage -> storage.modify(item, -delta));
    // Notify the user (if they have permission)
    if (player.hasPermission("insights.notifications")) {
        // If the area is queued, stop check here (notification will be displayed when it completes).
        if (queued)
            return;
        // Get the first (smallest) limit for the specific user (bypass permissions taken into account)
        Optional<Limit> limitOptional = plugin.getLimits().getFirstLimit(item, env);
        if (limitOptional.isEmpty())
            return;
        Limit limit = limitOptional.get();
        LimitInfo limitInfo = limit.getLimit(item);
        // Create a runnable for the notification.
        Consumer<Storage> notification = storage -> {
            long count = storage.count(limit, item);
            float progress = (float) count / limitInfo.getLimit();
            plugin.getNotifications().getCachedProgress(uuid, Messages.Key.LIMIT_NOTIFICATION).progress(progress).add(player).create().addTemplates(Messages.tagOf("name", limitInfo.getName()), Messages.tagOf("count", StringUtils.pretty(count)), Messages.tagOf("limit", StringUtils.pretty(limitInfo.getLimit()))).send();
        };
        // If the data is already stored, send the notification immediately.
        if (storageOptional.isPresent()) {
            notification.accept(storageOptional.get());
            return;
        }
        // Else, we need to scan the area first.
        Consumer<Storage> storageConsumer = storage -> {
            // Only if we're not scanning a cuboid (iff cuboid, the block is already removed from the chunk)
            if (included && regionOptional.isEmpty())
                storage.modify(item, -delta);
            // Notify the user
            notification.accept(storage);
        };
        if (regionOptional.isPresent()) {
            scanRegion(player, regionOptional.get(), storageConsumer);
        } else {
            plugin.getChunkContainerExecutor().submit(chunk).thenAccept(storageConsumer).exceptionally(th -> {
                plugin.getLogger().log(Level.SEVERE, th, th::getMessage);
                return null;
            });
        }
    }
}
Also used : LimitInfo(dev.frankheijden.insights.api.config.limits.LimitInfo) StringUtils(dev.frankheijden.insights.api.utils.StringUtils) ScanTask(dev.frankheijden.insights.api.tasks.ScanTask) Storage(dev.frankheijden.insights.api.concurrent.storage.Storage) ScanObject(dev.frankheijden.insights.api.objects.wrappers.ScanObject) Player(org.bukkit.entity.Player) Level(java.util.logging.Level) ChunkStorage(dev.frankheijden.insights.api.concurrent.storage.ChunkStorage) Messages(dev.frankheijden.insights.api.config.Messages) ScanOptions(dev.frankheijden.insights.api.concurrent.ScanOptions) ChunkPart(dev.frankheijden.insights.api.objects.chunk.ChunkPart) Block(org.bukkit.block.Block) Location(org.bukkit.Location) World(org.bukkit.World) Chunk(org.bukkit.Chunk) InsightsPlugin(dev.frankheijden.insights.api.InsightsPlugin) TagResolver(net.kyori.adventure.text.minimessage.tag.resolver.TagResolver) Material(org.bukkit.Material) Listener(org.bukkit.event.Listener) Limit(dev.frankheijden.insights.api.config.limits.Limit) WorldStorage(dev.frankheijden.insights.api.concurrent.storage.WorldStorage) BlockState(org.bukkit.block.BlockState) InsightsBase(dev.frankheijden.insights.api.objects.InsightsBase) ChunkUtils(dev.frankheijden.insights.api.utils.ChunkUtils) UUID(java.util.UUID) EntityType(org.bukkit.entity.EntityType) Consumer(java.util.function.Consumer) List(java.util.List) Region(dev.frankheijden.insights.api.addons.Region) LimitEnvironment(dev.frankheijden.insights.api.config.LimitEnvironment) Optional(java.util.Optional) AddonStorage(dev.frankheijden.insights.api.concurrent.storage.AddonStorage) DistributionStorage(dev.frankheijden.insights.api.concurrent.storage.DistributionStorage) Chunk(org.bukkit.Chunk) World(org.bukkit.World) LimitInfo(dev.frankheijden.insights.api.config.limits.LimitInfo) Storage(dev.frankheijden.insights.api.concurrent.storage.Storage) ChunkStorage(dev.frankheijden.insights.api.concurrent.storage.ChunkStorage) WorldStorage(dev.frankheijden.insights.api.concurrent.storage.WorldStorage) AddonStorage(dev.frankheijden.insights.api.concurrent.storage.AddonStorage) DistributionStorage(dev.frankheijden.insights.api.concurrent.storage.DistributionStorage) Region(dev.frankheijden.insights.api.addons.Region) LimitEnvironment(dev.frankheijden.insights.api.config.LimitEnvironment) Limit(dev.frankheijden.insights.api.config.limits.Limit) UUID(java.util.UUID)

Example 4 with Region

use of dev.frankheijden.insights.api.addons.Region in project Insights by InsightsPlugin.

the class InsightsListener method evaluateAddition.

protected void evaluateAddition(Player player, Location location, ScanObject<?> item, int delta) {
    Optional<Region> regionOptional = plugin.getAddonManager().getRegion(location);
    World world = location.getWorld();
    long chunkKey = ChunkUtils.getKey(location);
    UUID uuid = player.getUniqueId();
    LimitEnvironment env;
    Optional<Storage> storageOptional;
    if (regionOptional.isPresent()) {
        Region region = regionOptional.get();
        env = new LimitEnvironment(player, world.getName(), region.getAddon());
        storageOptional = plugin.getAddonStorage().get(region.getKey());
    } else {
        env = new LimitEnvironment(player, world.getName());
        storageOptional = plugin.getWorldStorage().getWorld(world.getUID()).get(chunkKey);
    }
    if (storageOptional.isEmpty())
        return;
    Storage storage = storageOptional.get();
    // If limit is not present, stop here
    Optional<Limit> limitOptional = plugin.getLimits().getFirstLimit(item, env);
    if (limitOptional.isEmpty())
        return;
    Limit limit = limitOptional.get();
    LimitInfo limitInfo = limit.getLimit(item);
    long count = storage.count(limit, item);
    // Notify the user (if they have permission)
    if (player.hasPermission("insights.notifications")) {
        float progress = (float) (count + delta) / limitInfo.getLimit();
        plugin.getNotifications().getCachedProgress(uuid, Messages.Key.LIMIT_NOTIFICATION).progress(progress).add(player).create().addTemplates(Messages.tagOf("name", limitInfo.getName()), Messages.tagOf("count", StringUtils.pretty(count + delta)), Messages.tagOf("limit", StringUtils.pretty(limitInfo.getLimit()))).send();
    }
}
Also used : Storage(dev.frankheijden.insights.api.concurrent.storage.Storage) ChunkStorage(dev.frankheijden.insights.api.concurrent.storage.ChunkStorage) WorldStorage(dev.frankheijden.insights.api.concurrent.storage.WorldStorage) AddonStorage(dev.frankheijden.insights.api.concurrent.storage.AddonStorage) DistributionStorage(dev.frankheijden.insights.api.concurrent.storage.DistributionStorage) Region(dev.frankheijden.insights.api.addons.Region) LimitEnvironment(dev.frankheijden.insights.api.config.LimitEnvironment) Limit(dev.frankheijden.insights.api.config.limits.Limit) World(org.bukkit.World) UUID(java.util.UUID) LimitInfo(dev.frankheijden.insights.api.config.limits.LimitInfo)

Example 5 with Region

use of dev.frankheijden.insights.api.addons.Region in project Insights by InsightsPlugin.

the class PistonListener method handlePistonBlock.

private boolean handlePistonBlock(Block from, Block to) {
    Optional<Region> regionOptional = plugin.getAddonManager().getRegion(to.getLocation());
    // Always allow piston pushes within the same chunk
    if (regionOptional.isEmpty() && BlockUtils.isSameChunk(from, to))
        return false;
    Material material = from.getType();
    Optional<Limit> limitOptional = plugin.getLimits().getFirstLimit(material, limit -> true);
    // If no limit is present, allow the block to be moved.
    if (limitOptional.isEmpty())
        return false;
    Chunk chunk = to.getChunk();
    UUID worldUid = chunk.getWorld().getUID();
    long chunkKey = ChunkUtils.getKey(chunk);
    boolean queued;
    Optional<Storage> storageOptional;
    if (regionOptional.isPresent()) {
        String key = regionOptional.get().getKey();
        queued = plugin.getAddonScanTracker().isQueued(key);
        storageOptional = plugin.getAddonStorage().get(key);
    } else {
        queued = plugin.getWorldChunkScanTracker().isQueued(worldUid, chunkKey);
        storageOptional = plugin.getWorldStorage().getWorld(worldUid).get(chunkKey);
    }
    // If the area is already queued, cancel the event and wait for the area to complete scanning.
    if (queued)
        return true;
    // If the storage is not present, scan it & cancel the event.
    if (storageOptional.isEmpty()) {
        if (regionOptional.isPresent()) {
            Region region = regionOptional.get();
            plugin.getAddonScanTracker().add(region.getAddon());
            List<ChunkPart> chunkParts = region.toChunkParts();
            ScanTask.scan(plugin, chunkParts, chunkParts.size(), ScanOptions.scanOnly(), info -> {
            }, storage -> {
                plugin.getAddonScanTracker().remove(region.getAddon());
                plugin.getAddonStorage().put(region.getKey(), storage);
            });
        } else {
            plugin.getChunkContainerExecutor().submit(chunk);
        }
        return true;
    }
    // Else, the storage is present, and we can apply a limit.
    Storage storage = storageOptional.get();
    Limit limit = limitOptional.get();
    LimitInfo limitInfo = limit.getLimit(material);
    // Cache doesn't need to updated here just yet, needs to be done in MONITOR event phase.
    return storage.count(limit, ScanObject.of(material)) + 1 > limitInfo.getLimit();
}
Also used : Material(org.bukkit.Material) Chunk(org.bukkit.Chunk) LimitInfo(dev.frankheijden.insights.api.config.limits.LimitInfo) Storage(dev.frankheijden.insights.api.concurrent.storage.Storage) Region(dev.frankheijden.insights.api.addons.Region) Limit(dev.frankheijden.insights.api.config.limits.Limit) ChunkPart(dev.frankheijden.insights.api.objects.chunk.ChunkPart) UUID(java.util.UUID)

Aggregations

Region (dev.frankheijden.insights.api.addons.Region)8 Storage (dev.frankheijden.insights.api.concurrent.storage.Storage)8 Limit (dev.frankheijden.insights.api.config.limits.Limit)8 InsightsPlugin (dev.frankheijden.insights.api.InsightsPlugin)6 ScanObject (dev.frankheijden.insights.api.objects.wrappers.ScanObject)6 ChunkUtils (dev.frankheijden.insights.api.utils.ChunkUtils)6 Optional (java.util.Optional)6 UUID (java.util.UUID)6 Location (org.bukkit.Location)6 Player (org.bukkit.entity.Player)6 LimitEnvironment (dev.frankheijden.insights.api.config.LimitEnvironment)5 Messages (dev.frankheijden.insights.api.config.Messages)5 LimitInfo (dev.frankheijden.insights.api.config.limits.LimitInfo)5 World (org.bukkit.World)5 AddonStorage (dev.frankheijden.insights.api.concurrent.storage.AddonStorage)4 ChunkStorage (dev.frankheijden.insights.api.concurrent.storage.ChunkStorage)4 DistributionStorage (dev.frankheijden.insights.api.concurrent.storage.DistributionStorage)4 WorldStorage (dev.frankheijden.insights.api.concurrent.storage.WorldStorage)4 ChunkPart (dev.frankheijden.insights.api.objects.chunk.ChunkPart)4 StringUtils (dev.frankheijden.insights.api.utils.StringUtils)4