Search in sources :

Example 6 with QueryResult

use of me.botsko.prism.actionlibs.QueryResult in project Prism-Bukkit by prism.

the class Prism method endExpiredQueryCaches.

/**
 * Clears the Query Cache.
 */
@SuppressWarnings("WeakerAccess")
public void endExpiredQueryCaches() {
    getServer().getScheduler().scheduleSyncRepeatingTask(this, () -> {
        final java.util.Date date = new java.util.Date();
        for (final Entry<String, QueryResult> query : cachedQueries.entrySet()) {
            final QueryResult result = query.getValue();
            final long diff = (date.getTime() - result.getQueryTime()) / 1000;
            if (diff >= 120) {
                cachedQueries.remove(query.getKey());
            }
        }
    }, 2400L, 2400L);
}
Also used : QueryResult(me.botsko.prism.actionlibs.QueryResult) Date(java.util.Date) Date(java.util.Date)

Example 7 with QueryResult

use of me.botsko.prism.actionlibs.QueryResult in project Prism-Bukkit by prism.

the class InspectorWand method showLocationHistory.

/**
 * Show the Location History for a player.
 *
 * @param player Player
 * @param loc    Location
 */
private void showLocationHistory(final Player player, final Location loc) {
    final Block block = loc.getBlock();
    final Block sibling = Utilities.getSiblingForDoubleLengthBlock(block);
    plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
        // Build params
        QueryParameters params;
        try {
            params = parameters.clone();
        } catch (final CloneNotSupportedException ex) {
            params = new QueryParameters();
            Prism.messenger.sendMessage(player, Prism.messenger.playerError("Error retrieving parameters. Checking with default parameters."));
        }
        params.setWorld(player.getWorld().getName());
        params.setSpecificBlockLocation(loc);
        // Do we need a second location? (For beds, doors, etc)
        if (sibling != null) {
            params.addSpecificBlockLocation(sibling.getLocation());
        }
        // Ignoring any actions via config?
        if (params.getActionTypes().size() == 0) {
            @SuppressWarnings("unchecked") final Collection<String> ignoreActions = (ArrayList<String>) plugin.getConfig().getList("prism.wands.inspect.ignore-actions");
            if (ignoreActions != null && !ignoreActions.isEmpty()) {
                for (final String ignore : ignoreActions) {
                    params.addActionType(ignore, MatchRule.EXCLUDE);
                }
            }
        }
        final QueryResult results = getResult(params, player);
        if (!results.getActionResults().isEmpty()) {
            final String blockname = Prism.getItems().getAlias(block.getType(), block.getBlockData());
            Prism.messenger.sendMessage(player, Prism.messenger.playerHeaderMsg(ReplaceableTextComponent.builder("inspector-wand-header").replace("<blockname>", blockname).replace("<x>", loc.getBlockX()).replace("<y>", loc.getBlockY()).replace("<z>", loc.getBlockY()).build().colorIfAbsent(NamedTextColor.GOLD)));
            Prism.messenger.sendMessage(player, Prism.messenger.playerHeaderMsg(Il8nHelper.formatMessage("lookup-header-message", results.getTotalResults(), 1, results.getTotalPages())));
            int resultCount = results.getIndexOfFirstResult();
            for (final me.botsko.prism.api.actions.Handler a : results.getPaginatedActionResults()) {
                final ActionMessage am = new ActionMessage(a);
                if (parameters.hasFlag(Flag.EXTENDED) || plugin.getConfig().getBoolean("prism.messenger.always-show-extended")) {
                    am.showExtended();
                }
                am.setResultIndex(resultCount);
                MiscUtils.sendClickableTpRecord(am, player);
                resultCount++;
            }
            MiscUtils.sendPageButtons(results, player);
        } else {
            final String space_name = (block.getType().equals(Material.AIR) ? "space" : block.getType().toString().replaceAll("_", " ").toLowerCase() + (block.getType().toString().endsWith("BLOCK") ? "" : " block"));
            Prism.messenger.sendMessage(player, Prism.messenger.playerError("No history for this " + space_name + " found."));
        }
    });
}
Also used : ArrayList(java.util.ArrayList) QueryParameters(me.botsko.prism.actionlibs.QueryParameters) QueryResult(me.botsko.prism.actionlibs.QueryResult) ActionMessage(me.botsko.prism.actionlibs.ActionMessage) Block(org.bukkit.block.Block)

Example 8 with QueryResult

use of me.botsko.prism.actionlibs.QueryResult in project Prism-Bukkit by prism.

the class RestoreWand method restore.

protected void restore(Player player, Location loc) {
    final Block block = loc.getBlock();
    QueryParameters params = checkQueryParams(block, parameters, player);
    params.setProcessType(PrismProcessType.RESTORE);
    final QueryResult results = getResult(params, player);
    if (!results.getActionResults().isEmpty()) {
        final Previewable rb = new Restore(plugin, player, results.getActionResults(), params, new PrismApplierCallback());
        rb.apply();
    } else {
        final String space_name = (block.getType().equals(Material.AIR) ? "space" : block.getType().toString().replaceAll("_", " ").toLowerCase() + (block.getType().toString().endsWith("BLOCK") ? "" : " block"));
        Prism.messenger.sendMessage(player, Prism.messenger.playerError("Nothing to restore for this " + space_name + " found."));
    }
}
Also used : QueryResult(me.botsko.prism.actionlibs.QueryResult) PrismApplierCallback(me.botsko.prism.appliers.PrismApplierCallback) Block(org.bukkit.block.Block) Previewable(me.botsko.prism.appliers.Previewable) QueryParameters(me.botsko.prism.actionlibs.QueryParameters) Restore(me.botsko.prism.appliers.Restore)

Example 9 with QueryResult

use of me.botsko.prism.actionlibs.QueryResult in project Prism-Bukkit by prism.

the class SqlSelectQueryBuilder method executeSelect.

@Override
public QueryResult executeSelect(TimeTaken eventTimer) {
    final List<Handler> actions = new ArrayList<>();
    // Build conditions based off final args
    final String query = getQuery(parameters, shouldGroup);
    eventTimer.recordTimedEvent("query started");
    try (Connection conn = Prism.getPrismDataSource().getDataSource().getConnection();
        PreparedStatement s = conn.prepareStatement(query);
        ResultSet rs = s.executeQuery()) {
        RecordingManager.failedDbConnectionCount = 0;
        eventTimer.recordTimedEvent("query returned, building results");
        Map<Integer, String> worldsInverse = new HashMap<>();
        for (final Entry<String, Integer> entry : Prism.prismWorlds.entrySet()) {
            worldsInverse.put(entry.getValue(), entry.getKey());
        }
        while (rs.next()) {
            if (rs.getString(3) == null) {
                continue;
            }
            // Convert action ID to name
            // Performance-wise this is a lot faster than table joins
            // and the cache data should always be available
            int actionId = rs.getInt(3);
            String actionName = "";
            for (final Entry<String, Integer> entry : Prism.prismActions.entrySet()) {
                if (entry.getValue() == actionId) {
                    actionName = entry.getKey();
                }
            }
            if (actionName.isEmpty()) {
                Prism.warn("Record contains action ID that doesn't exist in cache: " + actionId + ", cacheSize=" + Prism.prismActions.size());
                continue;
            }
            // Get the action handler
            final ActionTypeImpl actionType = Prism.getActionRegistry().getAction(actionName);
            if (actionType == null) {
                continue;
            }
            long rowId = 0;
            try {
                final Handler baseHandler = Prism.getHandlerRegistry().create(actionType.getHandler());
                // Convert world ID to name
                // Performance-wise this is typically a lot faster than
                // table joins
                rowId = rs.getLong(1);
                // Set all shared values
                baseHandler.setActionType(actionType);
                baseHandler.setId(rowId);
                baseHandler.setUnixEpoch(rs.getLong(2));
                String worldName = worldsInverse.getOrDefault(rs.getInt(5), "");
                baseHandler.setWorld(Bukkit.getWorld(worldName));
                baseHandler.setX(rs.getInt(6));
                baseHandler.setY(rs.getInt(7));
                baseHandler.setZ(rs.getInt(8));
                int blockId = rs.getInt(9);
                int blockSubId = rs.getInt(10);
                int oldBlockId = rs.getInt(11);
                int oldBlockSubId = rs.getInt(12);
                String extraData = rs.getString(13);
                boolean validBlockId = false;
                boolean validOldBlockId = false;
                MaterialState current = Prism.getItems().idsToMaterial(blockId, blockSubId, false);
                if (current != null) {
                    ItemStack item = current.asItem();
                    BlockData block = current.asBlockData();
                    if (block != null) {
                        validBlockId = true;
                        baseHandler.setMaterial(block.getMaterial());
                        baseHandler.setBlockData(block);
                        baseHandler.setDurability((short) 0);
                    } else if (item != null) {
                        validBlockId = true;
                        baseHandler.setMaterial(item.getType());
                        BlockData newData;
                        try {
                            newData = Bukkit.createBlockData(item.getType());
                        } catch (IllegalArgumentException e) {
                            // This exception occurs, for example, with "ItemStack{DIAMOND_LEGGINGS x 1}"
                            Prism.debug("IllegalArgumentException for record #" + rowId + " calling createBlockData for " + item.toString());
                            newData = null;
                        }
                        baseHandler.setBlockData(newData);
                        baseHandler.setDurability((short) ItemUtils.getItemDamage(item));
                    }
                }
                MaterialState old = Prism.getItems().idsToMaterial(oldBlockId, oldBlockSubId, false);
                if (old != null) {
                    ItemStack oldItem = old.asItem();
                    BlockData oldBlock = old.asBlockData();
                    validOldBlockId = true;
                    if (oldBlock != null) {
                        baseHandler.setOldMaterial(oldBlock.getMaterial());
                        baseHandler.setOldBlockData(oldBlock);
                        baseHandler.setOldDurability((short) 0);
                    } else {
                        baseHandler.setOldMaterial(oldItem.getType());
                        baseHandler.setOldBlockData(Bukkit.createBlockData(oldItem.getType()));
                        baseHandler.setOldDurability((short) ItemUtils.getItemDamage(oldItem));
                    }
                }
                if (!validBlockId && !validOldBlockId) {
                    // Entry could not be converted to a block or an item
                    boolean logWarning;
                    // The current item is likely a spawn or death event for an entity, for example, a cow or horse
                    logWarning = blockId != 0 || oldBlockId != 0 || extraData == null || !extraData.contains("entity_name");
                    if (logWarning) {
                        String itemMetadataDesc;
                        if (extraData == null) {
                            itemMetadataDesc = "";
                        } else {
                            itemMetadataDesc = ", metadata=" + extraData;
                        }
                        if (blockId > 0) {
                            Prism.warn("Unable to convert record #" + rowId + " to material: " + "block_id=" + blockId + ", block_subid=" + blockSubId + itemMetadataDesc);
                        } else if (oldBlockId > 0) {
                            Prism.warn("Unable to convert record #" + rowId + " to material: " + "old_block_id=" + oldBlockId + ", old_block_subid=" + oldBlockSubId + itemMetadataDesc);
                        } else {
                            Prism.warn("Unable to convert record #" + rowId + " to material: " + "block_id=0, old_block_id=0" + itemMetadataDesc);
                        }
                    }
                }
                // data
                try {
                    baseHandler.deserialize(extraData);
                } catch (JsonSyntaxException e) {
                    if (Prism.isDebug()) {
                        Prism.warn("Deserialization Error: " + e.getLocalizedMessage(), e);
                    }
                }
                // player
                baseHandler.setSourceName(rs.getString(4));
                // player_uuid
                try {
                    // Calls UUID.fromString, must handle potential exceptions
                    OfflinePlayer offline = Bukkit.getOfflinePlayer(SqlPlayerIdentificationHelper.uuidFromDbString(rs.getString(14)));
                    // Fake player
                    if (offline.hasPlayedBefore()) {
                        baseHandler.setUuid(offline.getUniqueId());
                    }
                } catch (IllegalArgumentException | NullPointerException e) {
                // Not a valid uuid
                }
                // Set aggregate counts if a lookup
                int aggregated = 0;
                if (shouldGroup) {
                    aggregated = rs.getInt(15);
                }
                baseHandler.setAggregateCount(aggregated);
                actions.add(baseHandler);
            } catch (final SQLException e) {
                Prism.warn("Ignoring data from record #" + rowId + " because it caused an error:", e);
            }
        }
    } catch (NullPointerException e) {
        if (RecordingManager.failedDbConnectionCount == 0) {
            Prism.log("Prism database error. Connection missing. Leaving actions to log in queue.");
            Prism.debug(e.getMessage());
        }
        RecordingManager.failedDbConnectionCount++;
        return new QueryResult(actions, parameters);
    } catch (SQLException e) {
        Prism.getPrismDataSource().handleDataSourceException(e);
    }
    return new QueryResult(actions, parameters);
}
Also used : HashMap(java.util.HashMap) SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) QueryResult(me.botsko.prism.actionlibs.QueryResult) ResultSet(java.sql.ResultSet) OfflinePlayer(org.bukkit.OfflinePlayer) BlockData(org.bukkit.block.data.BlockData) Connection(java.sql.Connection) Handler(me.botsko.prism.api.actions.Handler) PreparedStatement(java.sql.PreparedStatement) JsonSyntaxException(com.google.gson.JsonSyntaxException) ItemStack(org.bukkit.inventory.ItemStack) ActionTypeImpl(me.botsko.prism.actionlibs.ActionTypeImpl) MaterialState(me.botsko.prism.api.objects.MaterialState)

Example 10 with QueryResult

use of me.botsko.prism.actionlibs.QueryResult in project Prism-Bukkit by prism.

the class RollbackCommand method handle.

@Override
public void handle(final CallInfo call) {
    final QueryParameters parameters = PreprocessArgs.process(plugin, call.getSender(), call.getArgs(), PrismProcessType.ROLLBACK, 1, !plugin.getConfig().getBoolean("prism.queries.never-use-defaults"));
    if (parameters == null) {
        return;
    }
    parameters.setProcessType(PrismProcessType.ROLLBACK);
    parameters.setStringFromRawArgs(call.getArgs(), 1);
    StringBuilder defaultsReminder = checkIfDefaultUsed(parameters);
    Prism.messenger.sendMessage(call.getSender(), Prism.messenger.playerSubduedHeaderMsg(ReplaceableTextComponent.builder("rollback-prepare").replace("<defaults>", defaultsReminder).build()));
    plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
        final ActionsQuery aq = new ActionsQuery(plugin);
        final QueryResult results = aq.lookup(parameters, call.getSender());
        if (!results.getActionResults().isEmpty()) {
            Prism.messenger.sendMessage(call.getSender(), Prism.messenger.playerHeaderMsg(Il8nHelper.getMessage("rollback-start")));
            // Perform rollback on the main thread
            plugin.getServer().getScheduler().runTask(plugin, () -> {
                final Rollback rb = new Rollback(plugin, call.getSender(), results.getActionResults(), parameters, new PrismApplierCallback());
                rb.apply();
            });
        } else {
            Prism.messenger.sendMessage(call.getSender(), Prism.messenger.playerError(Il8nHelper.getMessage("rollback-error")));
        }
    });
}
Also used : QueryResult(me.botsko.prism.actionlibs.QueryResult) PrismApplierCallback(me.botsko.prism.appliers.PrismApplierCallback) ActionsQuery(me.botsko.prism.actionlibs.ActionsQuery) QueryParameters(me.botsko.prism.actionlibs.QueryParameters) Rollback(me.botsko.prism.appliers.Rollback)

Aggregations

QueryResult (me.botsko.prism.actionlibs.QueryResult)15 QueryParameters (me.botsko.prism.actionlibs.QueryParameters)12 ActionsQuery (me.botsko.prism.actionlibs.ActionsQuery)9 Handler (me.botsko.prism.api.actions.Handler)6 ActionMessage (me.botsko.prism.actionlibs.ActionMessage)5 PrismApplierCallback (me.botsko.prism.appliers.PrismApplierCallback)5 SubHandler (me.botsko.prism.commandlibs.SubHandler)5 Block (org.bukkit.block.Block)5 ArrayList (java.util.ArrayList)4 Previewable (me.botsko.prism.appliers.Previewable)3 Player (org.bukkit.entity.Player)3 List (java.util.List)2 Restore (me.botsko.prism.appliers.Restore)2 Rollback (me.botsko.prism.appliers.Rollback)2 Audience (net.kyori.adventure.audience.Audience)2 JsonSyntaxException (com.google.gson.JsonSyntaxException)1 Connection (java.sql.Connection)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1