-
-
Notifications
You must be signed in to change notification settings - Fork 1k
/
Copy pathBackup.java
132 lines (119 loc) · 4.77 KB
/
Backup.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package com.earth2me.essentials;
import net.ess3.api.IEssentials;
import net.ess3.provider.SchedulingProvider;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
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 static com.earth2me.essentials.I18n.tl;
public class Backup implements Runnable {
private transient final Server server;
private transient final IEssentials ess;
private final AtomicBoolean pendingShutdown = new AtomicBoolean(false);
private transient boolean running = false;
private transient SchedulingProvider.EssentialsTask task = null;
private transient boolean active = false;
private transient CompletableFuture<Object> taskLock = null;
public Backup(final IEssentials ess) {
this.ess = ess;
server = ess.getServer();
if (!ess.getOnlinePlayers().isEmpty() || ess.getSettings().isAlwaysRunBackup()) {
ess.runTaskAsynchronously(this::startTask);
}
}
public void onPlayerJoin() {
startTask();
}
public synchronized void stopTask() {
running = false;
if (task != null) {
task.cancel();
}
task = null;
}
private synchronized void startTask() {
if (!running) {
final long interval = ess.getSettings().getBackupInterval() * 1200; // minutes -> ticks
if (interval < 1200) {
return;
}
task = ess.scheduleGlobalRepeatingTask(this, interval, interval);
running = true;
}
}
public CompletableFuture<Object> getTaskLock() {
return taskLock;
}
public void setPendingShutdown(final boolean shutdown) {
pendingShutdown.set(shutdown);
}
@Override
public void run() {
if (active) {
return;
}
final String command = ess.getSettings().getBackupCommand();
if (command == null || "".equals(command)) {
return;
}
active = true;
taskLock = new CompletableFuture<>();
if ("save-all".equalsIgnoreCase(command)) {
final CommandSender cs = server.getConsoleSender();
server.dispatchCommand(cs, "save-all");
active = false;
taskLock.complete(new Object());
return;
}
ess.getLogger().log(Level.INFO, tl("backupStarted"));
final CommandSender cs = server.getConsoleSender();
server.dispatchCommand(cs, "save-all");
server.dispatchCommand(cs, "save-off");
ess.runTaskAsynchronously(() -> {
try {
final ProcessBuilder childBuilder = new ProcessBuilder(command.split(" "));
childBuilder.redirectErrorStream(true);
childBuilder.directory(ess.getDataFolder().getParentFile().getParentFile());
final Process child = childBuilder.start();
ess.runTaskAsynchronously(() -> {
try {
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(child.getInputStream()))) {
String line;
do {
line = reader.readLine();
if (line != null) {
ess.getLogger().log(Level.INFO, line);
}
} while (line != null);
}
} catch (final IOException ex) {
ess.getLogger().log(Level.SEVERE, "An error occurred while reading backup child process", ex);
}
});
child.waitFor();
} catch (final InterruptedException | IOException ex) {
ess.getLogger().log(Level.SEVERE, "An error occurred while building the backup child process", ex);
} finally {
class BackupEnableSaveTask implements Runnable {
@Override
public void run() {
server.dispatchCommand(cs, "save-on");
if (!ess.getSettings().isAlwaysRunBackup() && ess.getOnlinePlayers().isEmpty()) {
stopTask();
}
active = false;
taskLock.complete(new Object());
ess.getLogger().log(Level.INFO, tl("backupFinished"));
}
}
if (!pendingShutdown.get()) {
ess.scheduleGlobalDelayedTask(new BackupEnableSaveTask());
}
}
});
}
}