Search in sources :

Example 1 with ScanObject

use of dev.frankheijden.insights.api.objects.wrappers.ScanObject 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 ScanObject

use of dev.frankheijden.insights.api.objects.wrappers.ScanObject 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 ScanObject

use of dev.frankheijden.insights.api.objects.wrappers.ScanObject 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 ScanObject

use of dev.frankheijden.insights.api.objects.wrappers.ScanObject in project Insights by InsightsPlugin.

the class InsightsPlaceholderExpansion method onPlaceholderRequest.

@Override
public String onPlaceholderRequest(Player player, String identifier) {
    if (identifier == null)
        return "";
    String[] args = identifier.split("_");
    switch(args[0].toLowerCase(Locale.ENGLISH)) {
        case "limits":
            if (args.length < 3)
                break;
            String itemString = StringUtils.join(args, "_", 2).toUpperCase(Locale.ENGLISH);
            final ScanObject<?> item;
            try {
                item = ScanObject.parse(itemString);
            } catch (IllegalArgumentException ex) {
                return "";
            }
            Location location = player.getLocation();
            World world = location.getWorld();
            UUID worldUid = world.getUID();
            LimitEnvironment env = new LimitEnvironment(player, world.getName());
            Optional<Limit> limitOptional = plugin.getLimits().getFirstLimit(item, env);
            if (!limitOptional.isPresent())
                break;
            Limit limit = limitOptional.get();
            switch(args[1].toLowerCase(Locale.ENGLISH)) {
                case "name":
                    return limit.getLimit(item).getName();
                case "max":
                    return String.valueOf(limit.getLimit(item).getLimit());
                case "count":
                    Optional<Region> regionOptional = plugin.getAddonManager().getRegion(location);
                    Optional<Storage> storageOptional;
                    if (regionOptional.isPresent()) {
                        Region region = regionOptional.get();
                        storageOptional = plugin.getAddonStorage().get(region.getKey());
                    } else {
                        long chunkKey = ChunkUtils.getKey(location);
                        storageOptional = plugin.getWorldStorage().getWorld(worldUid).get(chunkKey);
                    }
                    return storageOptional.map(storage -> String.valueOf(storage.count(limit, item))).orElse("");
                default:
                    break;
            }
            break;
        default:
            break;
    }
    return "";
}
Also used : Limit(dev.frankheijden.insights.api.config.limits.Limit) PlaceholderExpansion(me.clip.placeholderapi.expansion.PlaceholderExpansion) StringUtils(dev.frankheijden.insights.api.utils.StringUtils) 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) UUID(java.util.UUID) Region(dev.frankheijden.insights.api.addons.Region) Location(org.bukkit.Location) World(org.bukkit.World) Locale(java.util.Locale) LimitEnvironment(dev.frankheijden.insights.api.config.LimitEnvironment) Optional(java.util.Optional) InsightsPlugin(dev.frankheijden.insights.api.InsightsPlugin) World(org.bukkit.World) Storage(dev.frankheijden.insights.api.concurrent.storage.Storage) 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) Location(org.bukkit.Location)

Example 5 with ScanObject

use of dev.frankheijden.insights.api.objects.wrappers.ScanObject in project Insights by InsightsPlugin.

the class CommandScan method handleCustomScan.

@CommandMethod("custom <items>")
@CommandPermission("insights.scan.custom")
private void handleCustomScan(Player player, @Argument("radius") @Range(min = "0", max = "256") int radius, @Flag(value = "group-by-chunk", aliases = { "c" }) boolean groupByChunk, @Argument("items") ScanObject<?>[] items) {
    List<ScanObject<?>> scanObjects = Arrays.asList(items);
    boolean hasOnlyEntities = scanObjects.stream().allMatch(s -> s.getType() == ScanObject.Type.ENTITY);
    boolean hasOnlyMaterials = scanObjects.stream().allMatch(s -> s.getType() == ScanObject.Type.MATERIAL);
    ScanOptions options;
    if (hasOnlyEntities) {
        options = ScanOptions.entitiesOnly();
    } else if (hasOnlyMaterials) {
        options = ScanOptions.materialsOnly();
    } else {
        options = ScanOptions.scanOnly();
    }
    handleScan(player, radius, new HashSet<>(scanObjects), options, true, groupByChunk);
}
Also used : ScanObject(dev.frankheijden.insights.api.objects.wrappers.ScanObject) ScanOptions(dev.frankheijden.insights.api.concurrent.ScanOptions) CommandMethod(cloud.commandframework.annotations.CommandMethod) CommandPermission(cloud.commandframework.annotations.CommandPermission)

Aggregations

ScanObject (dev.frankheijden.insights.api.objects.wrappers.ScanObject)5 InsightsPlugin (dev.frankheijden.insights.api.InsightsPlugin)4 Region (dev.frankheijden.insights.api.addons.Region)4 Storage (dev.frankheijden.insights.api.concurrent.storage.Storage)4 Limit (dev.frankheijden.insights.api.config.limits.Limit)4 ChunkUtils (dev.frankheijden.insights.api.utils.ChunkUtils)4 Optional (java.util.Optional)4 Location (org.bukkit.Location)4 Player (org.bukkit.entity.Player)4 ScanOptions (dev.frankheijden.insights.api.concurrent.ScanOptions)3 LimitEnvironment (dev.frankheijden.insights.api.config.LimitEnvironment)3 Messages (dev.frankheijden.insights.api.config.Messages)3 StringUtils (dev.frankheijden.insights.api.utils.StringUtils)3 UUID (java.util.UUID)3 World (org.bukkit.World)3 CommandMethod (cloud.commandframework.annotations.CommandMethod)2 CommandPermission (cloud.commandframework.annotations.CommandPermission)2 AddonStorage (dev.frankheijden.insights.api.concurrent.storage.AddonStorage)2 ChunkStorage (dev.frankheijden.insights.api.concurrent.storage.ChunkStorage)2 DistributionStorage (dev.frankheijden.insights.api.concurrent.storage.DistributionStorage)2