use of org.cubeengine.module.log.action.BaseAction in project modules-extra by CubeEngine.
the class QueryResults method redo.
public void redo(LogAttachment attachment, boolean preview) {
// Find the newest entry at a location
Map<Coordinate, Redoable> finalBlock = new HashMap<>();
Map<Coordinate, LinkedList<Redoable>> blockChanges = new HashMap<>();
TreeSet<Redoable> filteredLogs = new TreeSet<>();
for (BaseAction logEntry : this.logEntries) {
if (// can redo
logEntry instanceof Redoable) {
if (logEntry.coord.getWorld() == null) {
continue;
}
if (((Redoable) logEntry).isBlockBound()) {
if (((Redoable) logEntry).isStackable()) {
LinkedList<Redoable> changes = blockChanges.get(logEntry.coord);
if (changes == null) {
changes = new LinkedList<>();
blockChanges.put(logEntry.coord, changes);
}
changes.add((Redoable) logEntry);
} else {
// Clear blockChanges when new final block
blockChanges.remove(logEntry.coord);
finalBlock.put(logEntry.coord, (Redoable) logEntry);
}
} else {
// Not a block change at the location -> do rollback
filteredLogs.add((Redoable) logEntry);
}
}
}
// Finished filtering! Merge back together...
for (LinkedList<Redoable> entries : blockChanges.values()) {
filteredLogs.addAll(entries);
}
filteredLogs.addAll(finalBlock.values());
// Start Rollback 1st Round
Set<Redoable> rollbackRound2 = new LinkedHashSet<>();
for (// Rollback normal blocks
Redoable logEntry : // Rollback normal blocks
filteredLogs.descendingSet()) {
if (!logEntry.redo(attachment, false, // Redo failed (cannot set yet (torches etc)) try again later
preview)) {
rollbackRound2.add(logEntry);
}
}
ShowParameter show = new ShowParameter();
// Start Rollback 2nd Round (Attachables etc.)
for (// Rollback attached blocks
Redoable logEntry : // Rollback attached blocks
rollbackRound2) {
if (!logEntry.redo(attachment, true, preview)) {
attachment.getHolder().sendTranslated(NEGATIVE, "Could not Redo:");
((BaseAction) logEntry).showAction(attachment.getHolder(), show);
CubeEngine.getLog().warn("Could not redo!");
}
}
}
use of org.cubeengine.module.log.action.BaseAction in project modules-extra by CubeEngine.
the class QueryResults method rollback.
public void rollback(LogAttachment attachment, boolean preview) {
// Find the oldest entry at a location
Map<Coordinate, Rollbackable> finalBlock = new HashMap<>();
Map<Coordinate, LinkedList<Rollbackable>> blockChanges = new HashMap<>();
TreeSet<Rollbackable> filteredLogs = new TreeSet<>();
for (BaseAction logEntry : this.logEntries.descendingSet()) {
if (// can rollback
logEntry instanceof Rollbackable) {
if (logEntry.coord.getWorld() == null) {
continue;
}
if (logEntry instanceof DeathMonster && !this.lookup.getQueryParameter().containsAction(DeathMonster.class)) {
// ignoring Monster-respawning when not explicitly wanted
continue;
}
if (((Rollbackable) logEntry).isBlockBound()) {
if (((Rollbackable) logEntry).isStackable()) {
LinkedList<Rollbackable> changes = blockChanges.get(logEntry.coord);
if (changes == null) {
changes = new LinkedList<>();
blockChanges.put(logEntry.coord, changes);
}
changes.add((Rollbackable) logEntry);
} else {
// Clear blockChanges when new final block
blockChanges.remove(logEntry.coord);
finalBlock.put(logEntry.coord, (Rollbackable) logEntry);
}
} else {
// Not a block change at the location -> do rollback
filteredLogs.add((Rollbackable) logEntry);
}
}
}
// Finished filtering! Merge back together...
for (LinkedList<Rollbackable> entries : blockChanges.values()) {
filteredLogs.addAll(entries);
}
filteredLogs.addAll(finalBlock.values());
// Start Rollback 1st Round
Set<Rollbackable> rollbackRound2 = new LinkedHashSet<>();
// Rollback normal blocks
for (Rollbackable logEntry : filteredLogs.descendingSet()) {
if (!logEntry.rollback(attachment, false, preview)) {
// Rollback failed (cannot set yet (torches etc)) try again later
rollbackRound2.add(logEntry);
}
}
ShowParameter show = new ShowParameter();
// Start Rollback 2nd Round (Attachables etc.)
for (// Rollback attached blocks
Rollbackable logEntry : // Rollback attached blocks
rollbackRound2) {
if (!logEntry.rollback(attachment, true, preview)) {
attachment.getHolder().sendTranslated(NEGATIVE, "Could not Rollback:");
((BaseAction) logEntry).showAction(attachment.getHolder(), show);
CubeEngine.getLog().warn("Could not rollback!");
}
}
}
use of org.cubeengine.module.log.action.BaseAction in project modules-extra by CubeEngine.
the class QueryManager method prepareLookupQuery.
public void prepareLookupQuery(final Lookup lookup, final User user, QueryAction action) {
if (this.cleanUpRunning) {
switch(action) {
case SHOW:
user.sendTranslated(NEUTRAL, "Lookups cannot return all data while cleaning up the database!");
break;
case ROLLBACK:
case REDO:
case ROLLBACK_PREVIEW:
case REDO_PREVIEW:
user.sendTranslated(NEGATIVE, "This action is not possible while cleaning up the database!");
user.sendTranslated(NEUTRAL, "Please wait");
return;
}
}
final QueryParameter params = lookup.getQueryParameter();
BasicDBObject query = new BasicDBObject();
if (// has world
params.world != null) {
query.append("coord.world-uuid", params.world.getUID().toString());
if (params.location1 != null) {
Vector3i loc1 = params.location1;
if (// has area
params.location2 != null) {
Vector3i loc2 = params.location2;
boolean locX = loc1.x < loc2.x;
boolean locY = loc1.y < loc2.y;
boolean locZ = loc1.z < loc2.z;
query.append("coord.vector.x", new BasicDBObject("$gte", locX ? loc1.x : loc2.x).append("$lte", locX ? loc2.x : loc1.x)).append("coord.vector.y", new BasicDBObject("$gte", locY ? loc1.y : loc2.y).append("$lte", locX ? loc2.y : loc1.y)).append("coord.vector.z", new BasicDBObject("$gte", locZ ? loc1.z : loc2.z).append("$lte", locX ? loc2.z : loc1.z));
} else if (// has single location
params.radius == null) {
query.append("coord.vector.x", loc1.x).append("coord.vector.y", loc1.y).append("coord.vector.z", loc1.z);
} else // has radius
{
query.append("coord.vector.x", new BasicDBObject(QueryOperators.GTE, loc1.x - params.radius).append("$lte", loc1.x + params.radius)).append("coord.vector.y", new BasicDBObject("$gte", loc1.y - params.radius).append("$lte", loc1.y + params.radius)).append("coord.vector.z", new BasicDBObject("$gte", loc1.z - params.radius).append("$lte", loc1.z + params.radius));
}
}
}
if (!params.actions.isEmpty()) {
boolean include = params.includeActions();
Collection<String> actions = new HashSet<>();
for (Entry<Class<? extends BaseAction>, Boolean> entry : params.actions.entrySet()) {
if (!include || entry.getValue()) {
actions.add(entry.getKey().getName());
}
}
if (!include) {
query.append("action", new BasicDBObject("$nin", actions));
} else {
query.append("action", new BasicDBObject("$in", actions));
}
}
if (// has since / before / from-to
params.hasTime()) {
if (// before
params.from_since == null) {
query.append("date", new BasicDBObject("$lte", params.to_before));
} else if (// since
params.to_before == null) {
query.append("date", new BasicDBObject("$gte", params.from_since));
} else // from - to
{
query.append("date", new BasicDBObject("$gte", params.from_since).append("$lte", params.to_before));
}
}
if (!params.blocks.isEmpty()) {
// Start filter blocks:
boolean include = params.includeBlocks();
List<DBObject> list = new ArrayList<>();
List<String> mList = new ArrayList<>();
for (Entry<BlockSection, Boolean> data : params.blocks.entrySet()) {
if (// all exclude OR only include
!include || data.getValue()) {
BlockSection block = data.getKey();
if (block.data == null) {
mList.add(block.material.name());
} else {
list.add(new BasicDBObject("material", block.material.name()).append("data", block.data));
}
}
}
List<BasicDBObject> blockQuery = new ArrayList<>();
if (!list.isEmpty()) {
BasicDBObject dboL = new BasicDBObject("$in", list);
blockQuery.add(new BasicDBObject("old-block", dboL));
blockQuery.add(new BasicDBObject("new-block", dboL));
}
if (!mList.isEmpty()) {
BasicDBObject dboML = new BasicDBObject("$in", mList);
blockQuery.add(new BasicDBObject("old-block.material", dboML));
blockQuery.add(new BasicDBObject("new-block.material", dboML));
}
if (include) {
query.append("$or", blockQuery);
} else {
query.append("$not", new BasicDBObject("$or", blockQuery));
}
}
if (!params.users.isEmpty()) {
// Start filter users:
boolean include = params.includeUsers();
List<String> players = new ArrayList<>();
for (Entry<UUID, Boolean> data : params.users.entrySet()) {
if (// all exclude OR only include
!include || data.getValue()) {
players.add(data.getKey().toString());
}
}
if (include) {
query.append("player.uuid", new BasicDBObject("$in", players));
} else {
query.append("player.uuid", new BasicDBObject("$nin", players));
}
}
// TODO finish queryParams
this.module.getLog().debug("{}: Select Query queued!", user.getDisplayName());
this.queuedLookups.offer(new QueuedSqlParams(lookup, user, query, action));
if (this.futureLookup == null || this.futureLookup.isDone()) {
this.futureLookup = lookupExecutor.submit(lookupRunner);
}
}
use of org.cubeengine.module.log.action.BaseAction in project modules-extra by CubeEngine.
the class QueryResults method show.
@SuppressWarnings("deprecation")
public void show(User user, QueryParameter parameter, ShowParameter show) {
user.updateInventory();
if (this.logEntries.isEmpty()) {
parameter.showNoLogsFound(user);
return;
}
if (show.pagelimit == -1) {
show.pagelimit = this.logEntries.size();
}
if (// prevent showing too much logs
show.pagelimit > 80) {
show.pagelimit = 80;
}
// rounded up
int totalPages = (this.logEntries.size() + show.pagelimit - 1) / show.pagelimit;
user.sendTranslated(POSITIVE, "{amount} distinct logs ({amount} pages)", this.logEntries.size(), totalPages);
Iterator<BaseAction> entries = this.logEntries.iterator();
BaseAction entry = entries.next();
BaseAction lastAttach = entry;
TreeSet<BaseAction> compressedEntries = new TreeSet<>();
if (show.compress) {
// add first entry
compressedEntries.add(entry);
while (entries.hasNext()) {
BaseAction next = entries.next();
if (// can be compressed ?
lastAttach.canAttach(next)) {
entry.attach(next);
lastAttach = next;
} else // no more compression -> move on to next entry
{
entry = next;
lastAttach = entry;
compressedEntries.add(entry);
}
}
if (compressedEntries.size() < this.logEntries.size()) {
// rounded up
totalPages = (compressedEntries.size() + show.pagelimit - 1) / show.pagelimit;
if (totalPages > 1) {
user.sendTranslated(POSITIVE, "Compressed into {amount} logs! ({amount} pages)", compressedEntries.size(), totalPages);
} else {
user.sendTranslated(POSITIVE, "Compressed into {amount} logs!", compressedEntries.size());
}
}
} else {
compressedEntries.addAll(this.logEntries);
}
if (show.page > totalPages) {
return;
}
int showing = show.pagelimit;
if (showing > compressedEntries.size()) {
showing = compressedEntries.size();
} else if (compressedEntries.size() - ((show.page - 1) * show.pagelimit) < show.pagelimit) {
showing = compressedEntries.size() - ((show.page - 1) * show.pagelimit);
}
if (show.page == 1) {
user.sendTranslated(POSITIVE, "Showing {integer} most recent logs:", showing);
} else {
user.sendTranslated(POSITIVE, "Showing {integer} logs (Page {integer}):", showing, show.page);
}
int i = 0;
int cpage = 1;
NavigableSet<BaseAction> navigableSet;
if (show.reverseOrder) {
navigableSet = compressedEntries.descendingSet();
} else {
navigableSet = compressedEntries;
}
CubeEngine.getLog().info("Showing {}/{}/{} logentries to {} (page {})", showing, navigableSet.size(), this.logEntries.size(), user.getDisplayName(), show.page);
for (BaseAction action : navigableSet) {
if (cpage == show.page) {
try {
action.showAction(user, show);
} catch (Exception e) {
module.getLog().error(e, "An error occurred while showing LogEntries!");
user.sendTranslated(CRITICAL, "Internal Error! Could not show LogEntry");
}
}
i++;
if (i % show.pagelimit == 0) {
cpage++;
}
if (action.hasAttached()) {
action.getAttached().clear();
}
}
}
Aggregations