Skip to content

Commit

Permalink
Added ability to specify specific block types in the purge command
Browse files Browse the repository at this point in the history
  • Loading branch information
Intelli committed May 13, 2024
1 parent b41e40a commit 5bc28b3
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 13 deletions.
10 changes: 7 additions & 3 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,20 @@ Purge old block data. Useful for freeing up space on your HDD if you don't need

| Command | Parameters |
| --- | --- |
| /co purge | `t:<time> r:<world>` |
| /co purge | `t:<time> r:<world> i:<include>` |

For example, `/co purge t:30d` will delete all data older than one month, and only keep the last 30 days of data.

> If used in-game, only data older than 30 days can be purged.
> If used from the console, only data older than 24 hours can be purged.
**Purging Worlds**
You can also optionally specify a world in CoreProtect v19+.
For example, `/co purge t:30d r:#world_nether` will delete all data older than one month in the Nether, without deleting data in any other worlds.
You can optionally specify a world in CoreProtect v19+.
For example, `/co purge t:30d r:#world_nether` will delete all data older than one month in the Nether, without removing data in any other worlds.

**Purging Blocks**
You can optionally specify block types in CoreProtect v23+.
For example, `/co purge t:30d i:stone,dirt` will delete all stone and dirt data older than one month, without removing other block data.

**MySQL Optimization**
In CoreProtect v2.15+, adding "#optimize" to the end of the command (e.g. `/co purge t:30d #optimize`) will also optimize your tables and reclaim disk space.
Expand Down
130 changes: 120 additions & 10 deletions src/main/java/net/coreprotect/command/PurgeCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;

import net.coreprotect.bukkit.BukkitAdapter;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.consumer.Consumer;
Expand All @@ -31,13 +36,20 @@ protected static void runCommand(final CommandSender player, boolean permission,
int resultc = args.length;
Location location = CommandHandler.parseLocation(player, args);
final Integer[] argRadius = CommandHandler.parseRadius(args, player, location);
final List<Integer> argAction = CommandHandler.parseAction(args);
final List<Object> argBlocks = CommandHandler.parseRestricted(player, args, argAction);
final Map<Object, Boolean> argExclude = CommandHandler.parseExcluded(player, args, argAction);
final List<String> argExcludeUsers = CommandHandler.parseExcludedUsers(player, args);
final long[] argTime = CommandHandler.parseTime(args);
final int argWid = CommandHandler.parseWorld(args, false, false);
final List<Integer> argAction = CommandHandler.parseAction(args);
final List<Integer> supportedActions = Arrays.asList();
long startTime = argTime[1] > 0 ? argTime[0] : 0;
long endTime = argTime[1] > 0 ? argTime[1] : argTime[0];

if (argBlocks == null || argExclude == null || argExcludeUsers == null) {
return;
}

if (ConfigHandler.converterRunning) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS));
return;
Expand Down Expand Up @@ -67,19 +79,85 @@ protected static void runCommand(final CommandSender player, boolean permission,
Chat.sendMessage(player, new ChatMessage(Phrase.build(Phrase.WORLD_NOT_FOUND, worldName)).build());
return;
}
if (player instanceof Player && endTime < 2592000) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_MINIMUM_TIME, "30", Selector.FIRST)); // 30 days
return;
}
else if (endTime < 86400) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_MINIMUM_TIME, "24", Selector.SECOND)); // 24 hours
return;
}
for (int action : argAction) {
if (!supportedActions.contains(action)) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ACTION_NOT_SUPPORTED));
// Functions.sendMessage(player, new ChatMessage("Please specify a valid purge action.").build());
return;
}
}
if (player instanceof Player && endTime < 2592000) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_MINIMUM_TIME, "30", Selector.FIRST)); // 30 days
return;

StringBuilder restrict = new StringBuilder();
String includeBlock = "";
String includeEntity = "";
boolean hasBlock = false;
boolean item = false;
boolean entity = false;
int restrictCount = 0;

if (argBlocks.size() > 0) {
StringBuilder includeListMaterial = new StringBuilder();
StringBuilder includeListEntity = new StringBuilder();

for (Object restrictTarget : argBlocks) {
String targetName = "";

if (restrictTarget instanceof Material) {
targetName = ((Material) restrictTarget).name();
if (includeListMaterial.length() == 0) {
includeListMaterial = includeListMaterial.append(Util.getBlockId(targetName, false));
}
else {
includeListMaterial.append(",").append(Util.getBlockId(targetName, false));
}

/* Include legacy IDs */
int legacyId = BukkitAdapter.ADAPTER.getLegacyBlockId((Material) restrictTarget);
if (legacyId > 0) {
includeListMaterial.append(",").append(legacyId);
}

targetName = ((Material) restrictTarget).name().toLowerCase(Locale.ROOT);
item = (!item ? !(((Material) restrictTarget).isBlock()) : item);
hasBlock = true;
}
else if (restrictTarget instanceof EntityType) {
targetName = ((EntityType) restrictTarget).name();
if (includeListEntity.length() == 0) {
includeListEntity = includeListEntity.append(Util.getEntityId(targetName, false));
}
else {
includeListEntity.append(",").append(Util.getEntityId(targetName, false));
}

targetName = ((EntityType) restrictTarget).name().toLowerCase(Locale.ROOT);
entity = true;
}

if (restrictCount == 0) {
restrict = restrict.append("" + targetName + "");
}
else {
restrict.append(", ").append(targetName);
}

restrictCount++;
}

includeBlock = includeListMaterial.toString();
includeEntity = includeListEntity.toString();
}
else if (endTime < 86400) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_MINIMUM_TIME, "24", Selector.SECOND)); // 24 hours

if (entity) {
Chat.sendMessage(player, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.ACTION_NOT_SUPPORTED));
return;
}

Expand All @@ -90,7 +168,12 @@ else if (endTime < 86400) {
break;
}
}

final StringBuilder restrictTargets = restrict;
final String includeBlockFinal = includeBlock;
final boolean optimize = optimizeCheck;
final boolean hasBlockRestriction = hasBlock;
final int restrictCountFinal = restrictCount;

class BasicThread implements Runnable {

Expand Down Expand Up @@ -123,6 +206,11 @@ public void run() {
else {
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_STARTED, "#global"));
}

if (hasBlockRestriction) {
Chat.sendGlobalMessage(player, Phrase.build(Phrase.ROLLBACK_INCLUDE, restrictTargets.toString(), Selector.FIRST, Selector.FIRST, (restrictCountFinal == 1 ? Selector.FIRST : Selector.SECOND))); // include
}

Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_NOTICE_1));
Chat.sendGlobalMessage(player, Phrase.build(Phrase.PURGE_NOTICE_2));

Expand Down Expand Up @@ -172,6 +260,7 @@ public void run() {

List<String> purgeTables = Arrays.asList("sign", "container", "item", "skull", "session", "chat", "command", "entity", "block");
List<String> worldTables = Arrays.asList("sign", "container", "item", "session", "chat", "command", "block");
List<String> restrictTables = Arrays.asList("block");
List<String> excludeTables = Arrays.asList("database_lock"); // don't insert data into these tables
for (String table : ConfigHandler.databaseTables) {
String tableName = table.replaceAll("_", " ");
Expand All @@ -198,11 +287,16 @@ public void run() {
try {
String timeLimit = "";
if (purgeTables.contains(table)) {
String blockRestriction = "";
if (hasBlockRestriction && restrictTables.contains(table)) {
blockRestriction = "type IN(" + includeBlockFinal + ") AND ";
}

if (argWid > 0 && worldTables.contains(table)) {
timeLimit = " WHERE (wid = '" + argWid + "' AND (time >= '" + timeEnd + "' OR time < '" + timeStart + "')) OR wid != '" + argWid + "'";
timeLimit = " WHERE (" + blockRestriction + "wid = '" + argWid + "' AND (time >= '" + timeEnd + "' OR time < '" + timeStart + "')) OR (" + blockRestriction + "wid != '" + argWid + "')";
}
else if (argWid == 0) {
timeLimit = " WHERE (time >= '" + timeEnd + "' OR time < '" + timeStart + "')";
timeLimit = " WHERE " + blockRestriction + "(time >= '" + timeEnd + "' OR time < '" + timeStart + "')";
}
}
query = "INSERT INTO " + purgePrefix + table + " SELECT " + columns + " FROM " + ConfigHandler.prefix + table + timeLimit;
Expand Down Expand Up @@ -256,6 +350,14 @@ else if (argWid == 0) {
try {
boolean purge = purgeTables.contains(table);

String blockRestriction = "";
if (hasBlockRestriction && restrictTables.contains(table)) {
blockRestriction = "type IN(" + includeBlockFinal + ") AND ";
}
else if (hasBlockRestriction) {
purge = false;
}

String worldRestriction = "";
if (argWid > 0 && worldTables.contains(table)) {
worldRestriction = " AND wid = '" + argWid + "'";
Expand All @@ -265,7 +367,7 @@ else if (argWid > 0) {
}

if (purge) {
query = "DELETE FROM " + purgePrefix + table + " WHERE time < '" + timeEnd + "' AND time >= '" + timeStart + "'" + worldRestriction;
query = "DELETE FROM " + purgePrefix + table + " WHERE " + blockRestriction + "time < '" + timeEnd + "' AND time >= '" + timeStart + "'" + worldRestriction;
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
preparedStmt.close();
Expand Down Expand Up @@ -315,6 +417,14 @@ else if (argWid > 0) {
try {
boolean purge = purgeTables.contains(table);

String blockRestriction = "";
if (hasBlockRestriction && restrictTables.contains(table)) {
blockRestriction = "type IN(" + includeBlockFinal + ") AND ";
}
else if (hasBlockRestriction) {
purge = false;
}

String worldRestriction = "";
if (argWid > 0 && worldTables.contains(table)) {
worldRestriction = " AND wid = '" + argWid + "'";
Expand All @@ -324,7 +434,7 @@ else if (argWid > 0) {
}

if (purge) {
query = "DELETE FROM " + ConfigHandler.prefix + table + " WHERE time < '" + timeEnd + "' AND time >= '" + timeStart + "'" + worldRestriction;
query = "DELETE FROM " + ConfigHandler.prefix + table + " WHERE " + blockRestriction + "time < '" + timeEnd + "' AND time >= '" + timeStart + "'" + worldRestriction;
preparedStmt = connection.prepareStatement(query);
preparedStmt.execute();
removed = removed + preparedStmt.getUpdateCount();
Expand Down

0 comments on commit 5bc28b3

Please sign in to comment.