From ca5ad04ff75db404dc7dea01985977b6082fc536 Mon Sep 17 00:00:00 2001 From: JRoy Date: Mon, 11 May 2020 03:03:18 -0400 Subject: [PATCH 1/8] Finish backup tasks before disabling plugin --- Essentials/src/com/earth2me/essentials/Backup.java | 4 ++++ Essentials/src/com/earth2me/essentials/Essentials.java | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/Essentials/src/com/earth2me/essentials/Backup.java b/Essentials/src/com/earth2me/essentials/Backup.java index 6f4020acce8..f30c59a9146 100644 --- a/Essentials/src/com/earth2me/essentials/Backup.java +++ b/Essentials/src/com/earth2me/essentials/Backup.java @@ -52,6 +52,10 @@ private synchronized void startTask() { } } + public boolean isActive() { + return active; + } + @Override public void run() { if (active) { diff --git a/Essentials/src/com/earth2me/essentials/Essentials.java b/Essentials/src/com/earth2me/essentials/Essentials.java index e8d714eb06b..fc4b1e066a5 100644 --- a/Essentials/src/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/com/earth2me/essentials/Essentials.java @@ -381,6 +381,13 @@ public void onDisable() { getUserMap().getUUIDMap().shutdown(); HandlerList.unregisterAll(this); + while (getBackup().isActive()) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } } @Override From 5d2b822cb2b05ca573b18747659b02977484feae Mon Sep 17 00:00:00 2001 From: JRoy Date: Mon, 11 May 2020 03:13:08 -0400 Subject: [PATCH 2/8] Don't schedule new tasks when we're shutting down --- Essentials/src/com/earth2me/essentials/Backup.java | 10 +++++++++- Essentials/src/com/earth2me/essentials/Essentials.java | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Essentials/src/com/earth2me/essentials/Backup.java b/Essentials/src/com/earth2me/essentials/Backup.java index f30c59a9146..f021264e6f2 100644 --- a/Essentials/src/com/earth2me/essentials/Backup.java +++ b/Essentials/src/com/earth2me/essentials/Backup.java @@ -7,6 +7,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; @@ -20,6 +21,7 @@ public class Backup implements Runnable { private transient boolean running = false; private transient int taskId = -1; private transient boolean active = false; + private final AtomicBoolean pendingShutdown = new AtomicBoolean(false); public Backup(final IEssentials ess) { this.ess = ess; @@ -56,6 +58,10 @@ public boolean isActive() { return active; } + public void setPendingShutdown(boolean shutdown) { + pendingShutdown.set(shutdown); + } + @Override public void run() { if (active) { @@ -113,7 +119,9 @@ public void run() { LOGGER.log(Level.INFO, tl("backupFinished")); } } - ess.scheduleSyncDelayedTask(new BackupEnableSaveTask()); + if (!pendingShutdown.get()) { + ess.scheduleSyncDelayedTask(new BackupEnableSaveTask()); + } } }); } diff --git a/Essentials/src/com/earth2me/essentials/Essentials.java b/Essentials/src/com/earth2me/essentials/Essentials.java index fc4b1e066a5..9db68241cdd 100644 --- a/Essentials/src/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/com/earth2me/essentials/Essentials.java @@ -313,6 +313,7 @@ public void onEnable() { handleCrash(ex); throw ex; } + getBackup().setPendingShutdown(false); } @Override @@ -362,6 +363,7 @@ private void registerListeners(PluginManager pm) { @Override public void onDisable() { + getBackup().setPendingShutdown(true); for (User user : getOnlineUsers()) { if (user.isVanished()) { user.setVanished(false); From 27dfa7b7b99b1bac04039d867ddd639b5b217f3c Mon Sep 17 00:00:00 2001 From: JRoy Date: Mon, 11 May 2020 03:13:39 -0400 Subject: [PATCH 3/8] Add config option to run backup task even when players are offline --- Essentials/src/com/earth2me/essentials/Backup.java | 4 ++-- Essentials/src/com/earth2me/essentials/ISettings.java | 2 ++ Essentials/src/com/earth2me/essentials/Settings.java | 5 +++++ Essentials/src/config.yml | 2 ++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Essentials/src/com/earth2me/essentials/Backup.java b/Essentials/src/com/earth2me/essentials/Backup.java index f021264e6f2..1cfe6daf179 100644 --- a/Essentials/src/com/earth2me/essentials/Backup.java +++ b/Essentials/src/com/earth2me/essentials/Backup.java @@ -26,7 +26,7 @@ public class Backup implements Runnable { public Backup(final IEssentials ess) { this.ess = ess; server = ess.getServer(); - if (!ess.getOnlinePlayers().isEmpty()) { + if (!ess.getOnlinePlayers().isEmpty() || ess.getSettings().isAlwaysRunBackup()) { ess.runTaskAsynchronously(this::startTask); } } @@ -112,7 +112,7 @@ class BackupEnableSaveTask implements Runnable { @Override public void run() { server.dispatchCommand(cs, "save-on"); - if (ess.getOnlinePlayers().isEmpty()) { + if (!ess.getSettings().isAlwaysRunBackup() && ess.getOnlinePlayers().isEmpty()) { stopTask(); } active = false; diff --git a/Essentials/src/com/earth2me/essentials/ISettings.java b/Essentials/src/com/earth2me/essentials/ISettings.java index a5393f0f208..7a91de7e86c 100644 --- a/Essentials/src/com/earth2me/essentials/ISettings.java +++ b/Essentials/src/com/earth2me/essentials/ISettings.java @@ -32,6 +32,8 @@ public interface ISettings extends IConf { long getBackupInterval(); + boolean isAlwaysRunBackup(); + String getChatFormat(String group); int getChatRadius(); diff --git a/Essentials/src/com/earth2me/essentials/Settings.java b/Essentials/src/com/earth2me/essentials/Settings.java index 487b1bc9e91..53e974e3dc8 100644 --- a/Essentials/src/com/earth2me/essentials/Settings.java +++ b/Essentials/src/com/earth2me/essentials/Settings.java @@ -425,6 +425,11 @@ public String getBackupCommand() { return config.getString("backup.command", null); } + @Override + public boolean isAlwaysRunBackup() { + return config.getBoolean("backup.always-run-backup", false); + } + private final Map chatFormats = Collections.synchronizedMap(new HashMap<>()); @Override diff --git a/Essentials/src/config.yml b/Essentials/src/config.yml index 31a699d9071..c11077304ea 100644 --- a/Essentials/src/config.yml +++ b/Essentials/src/config.yml @@ -371,6 +371,8 @@ unprotected-sign-names: backup: # Interval in minutes. interval: 30 + # If true, the backup task will run even if there are no players online. + always-run-backup: false # Unless you add a valid backup command or script here, this feature will be useless. # Use 'save-all' to simply force regular world saving without backup. #command: 'rdiff-backup World1 backups/World1' From adb2e6d51392ba2efd2e8111a8a2465bf5585861 Mon Sep 17 00:00:00 2001 From: JRoy Date: Mon, 11 May 2020 08:38:23 -0400 Subject: [PATCH 4/8] Change config node --- Essentials/src/com/earth2me/essentials/Settings.java | 2 +- Essentials/src/config.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Essentials/src/com/earth2me/essentials/Settings.java b/Essentials/src/com/earth2me/essentials/Settings.java index 53e974e3dc8..5f155168595 100644 --- a/Essentials/src/com/earth2me/essentials/Settings.java +++ b/Essentials/src/com/earth2me/essentials/Settings.java @@ -427,7 +427,7 @@ public String getBackupCommand() { @Override public boolean isAlwaysRunBackup() { - return config.getBoolean("backup.always-run-backup", false); + return config.getBoolean("backup.always-run", false); } private final Map chatFormats = Collections.synchronizedMap(new HashMap<>()); diff --git a/Essentials/src/config.yml b/Essentials/src/config.yml index c11077304ea..e07130415cb 100644 --- a/Essentials/src/config.yml +++ b/Essentials/src/config.yml @@ -372,7 +372,7 @@ backup: # Interval in minutes. interval: 30 # If true, the backup task will run even if there are no players online. - always-run-backup: false + always-run: false # Unless you add a valid backup command or script here, this feature will be useless. # Use 'save-all' to simply force regular world saving without backup. #command: 'rdiff-backup World1 backups/World1' From 6cc4e3bbef50b6275204ec5e276a22eaca56886f Mon Sep 17 00:00:00 2001 From: JRoy Date: Mon, 11 May 2020 09:15:45 -0400 Subject: [PATCH 5/8] Use future because sleeping is scary! --- Essentials/src/com/earth2me/essentials/Backup.java | 9 +++++++-- .../src/com/earth2me/essentials/Essentials.java | 11 ++++------- Essentials/src/messages.properties | 1 + 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Essentials/src/com/earth2me/essentials/Backup.java b/Essentials/src/com/earth2me/essentials/Backup.java index 1cfe6daf179..ada804d0eb3 100644 --- a/Essentials/src/com/earth2me/essentials/Backup.java +++ b/Essentials/src/com/earth2me/essentials/Backup.java @@ -7,6 +7,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; @@ -22,6 +23,7 @@ public class Backup implements Runnable { private transient int taskId = -1; private transient boolean active = false; private final AtomicBoolean pendingShutdown = new AtomicBoolean(false); + private transient CompletableFuture taskLock = null; public Backup(final IEssentials ess) { this.ess = ess; @@ -54,8 +56,8 @@ private synchronized void startTask() { } } - public boolean isActive() { - return active; + public CompletableFuture getTaskLock() { + return taskLock; } public void setPendingShutdown(boolean shutdown) { @@ -68,6 +70,7 @@ public void run() { return; } active = true; + taskLock = new CompletableFuture<>(); final String command = ess.getSettings().getBackupCommand(); if (command == null || "".equals(command)) { return; @@ -76,6 +79,7 @@ public void run() { final CommandSender cs = server.getConsoleSender(); server.dispatchCommand(cs, "save-all"); active = false; + taskLock.complete(new Object()); return; } LOGGER.log(Level.INFO, tl("backupStarted")); @@ -116,6 +120,7 @@ public void run() { stopTask(); } active = false; + taskLock.complete(new Object()); LOGGER.log(Level.INFO, tl("backupFinished")); } } diff --git a/Essentials/src/com/earth2me/essentials/Essentials.java b/Essentials/src/com/earth2me/essentials/Essentials.java index 9db68241cdd..9a4f584ebb1 100644 --- a/Essentials/src/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/com/earth2me/essentials/Essentials.java @@ -372,6 +372,10 @@ public void onDisable() { user.stopTransaction(); } cleanupOpenInventories(); + if (getBackup().getTaskLock() != null && !getBackup().getTaskLock().isDone()) { + LOGGER.log(Level.SEVERE, tl("backupInProgress")); + getBackup().getTaskLock().join(); + } if (i18n != null) { i18n.onDisable(); } @@ -383,13 +387,6 @@ public void onDisable() { getUserMap().getUUIDMap().shutdown(); HandlerList.unregisterAll(this); - while (getBackup().isActive()) { - try { - Thread.sleep(10); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } } @Override diff --git a/Essentials/src/messages.properties b/Essentials/src/messages.properties index e1ac8b79916..5119353e897 100644 --- a/Essentials/src/messages.properties +++ b/Essentials/src/messages.properties @@ -27,6 +27,7 @@ backOther=\u00a76Returned\u00a7c {0}\u00a76 to previous location. backupDisabled=\u00a74An external backup script has not been configured. backupFinished=\u00a76Backup finished. backupStarted=\u00a76Backup started. +backupInProgress=\u00a76An external backup script is currently in progress! Halting plugin disable until finished. backUsageMsg=\u00a76Returning to previous location. balance=\u00a7aBalance\:\u00a7c {0} balanceOther=\u00a7aBalance of {0}\u00a7a\:\u00a7c {1} From 9247c8b1764dc7f4acf852ef246a92178047fe8d Mon Sep 17 00:00:00 2001 From: JRoy Date: Mon, 11 May 2020 10:15:58 -0400 Subject: [PATCH 6/8] Yell and shame users using the /reload command --- Essentials/src/com/earth2me/essentials/Essentials.java | 6 +++++- Essentials/src/messages.properties | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Essentials/src/com/earth2me/essentials/Essentials.java b/Essentials/src/com/earth2me/essentials/Essentials.java index d1328210202..bb8b96c7c4e 100644 --- a/Essentials/src/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/com/earth2me/essentials/Essentials.java @@ -364,13 +364,17 @@ private void registerListeners(PluginManager pm) { @Override public void onDisable() { + boolean stopping = ServerState.isStopping(); + if (!stopping) { + LOGGER.log(Level.SEVERE, tl("serverReloading")); + } getBackup().setPendingShutdown(true); for (User user : getOnlineUsers()) { if (user.isVanished()) { user.setVanished(false); user.sendMessage(tl("unvanishedReload")); } - if (ServerState.isStopping()) { + if (stopping) { user.setLastLocation(); if (!user.isHidden()) { user.setLastLogout(System.currentTimeMillis()); diff --git a/Essentials/src/messages.properties b/Essentials/src/messages.properties index 5119353e897..48282efa359 100644 --- a/Essentials/src/messages.properties +++ b/Essentials/src/messages.properties @@ -485,6 +485,7 @@ seenOnline=\u00a76Player\u00a7c {0} \u00a76has been \u00a7aonline\u00a76 since \ sellBulkPermission=\u00a76You do not have permission to bulk sell. sellHandPermission=\u00a76You do not have permission to hand sell. serverFull=Server is full\! +serverReloading=There's a good chance you're probably reloading your server right now. If that's the case, why do you hate yourself? Except no support from the Essentials team when using /reload serverTotal=\u00a76Server Total\:\u00a7c {0} serverUnsupported=You are running an unsupported server version! setBal=\u00a7aYour balance was set to {0}. From b30dbc20e26343cc499cc0e5a9aa87f0963b0701 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 11 May 2020 11:42:09 -0400 Subject: [PATCH 7/8] Update Essentials/src/messages.properties Co-authored-by: md678685 <1917406+md678685@users.noreply.github.com> --- Essentials/src/messages.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/src/messages.properties b/Essentials/src/messages.properties index 48282efa359..aa523c86489 100644 --- a/Essentials/src/messages.properties +++ b/Essentials/src/messages.properties @@ -485,7 +485,7 @@ seenOnline=\u00a76Player\u00a7c {0} \u00a76has been \u00a7aonline\u00a76 since \ sellBulkPermission=\u00a76You do not have permission to bulk sell. sellHandPermission=\u00a76You do not have permission to hand sell. serverFull=Server is full\! -serverReloading=There's a good chance you're probably reloading your server right now. If that's the case, why do you hate yourself? Except no support from the Essentials team when using /reload +serverReloading=There's a good chance you're probably reloading your server right now. If that's the case, why do you hate yourself? Expect no support from the EssentialsX team when using /reload. serverTotal=\u00a76Server Total\:\u00a7c {0} serverUnsupported=You are running an unsupported server version! setBal=\u00a7aYour balance was set to {0}. From 55fdc45422ef9746b45f931c747afe4562fd601b Mon Sep 17 00:00:00 2001 From: md678685 <1917406+md678685@users.noreply.github.com> Date: Mon, 11 May 2020 16:50:51 +0100 Subject: [PATCH 8/8] Update Essentials/src/messages.properties --- Essentials/src/messages.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/src/messages.properties b/Essentials/src/messages.properties index aa523c86489..94238a8a6b3 100644 --- a/Essentials/src/messages.properties +++ b/Essentials/src/messages.properties @@ -485,7 +485,7 @@ seenOnline=\u00a76Player\u00a7c {0} \u00a76has been \u00a7aonline\u00a76 since \ sellBulkPermission=\u00a76You do not have permission to bulk sell. sellHandPermission=\u00a76You do not have permission to hand sell. serverFull=Server is full\! -serverReloading=There's a good chance you're probably reloading your server right now. If that's the case, why do you hate yourself? Expect no support from the EssentialsX team when using /reload. +serverReloading=There's a good chance you're reloading your server right now. If that's the case, why do you hate yourself? Expect no support from the EssentialsX team when using /reload. serverTotal=\u00a76Server Total\:\u00a7c {0} serverUnsupported=You are running an unsupported server version! setBal=\u00a7aYour balance was set to {0}.