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);
}
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."));
}
});
}
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."));
}
}
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);
}
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")));
}
});
}
Aggregations