Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@
</dependencies>

<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<directory>src</directory>
<filtering>true</filtering>
</resource>
</resources>
Expand Down
133 changes: 36 additions & 97 deletions src/de/seblii/serverbackup/DynamicBackup.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,124 +8,63 @@
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.logging.Level;

public class DynamicBackup implements Listener {

List<Chunk> chunks = Collections.synchronizedList(new ArrayList<>());
public boolean isSaving = false;

@EventHandler
public void onPlayerMove(PlayerMoveEvent e) {
if (ServerBackup.getInstance().getConfig().getBoolean("DynamicBackup")) {
if (e.getFrom().getChunk() != e.getTo().getChunk()) {
int regX = e.getTo().getChunk().getX() >> 5;
int regZ = e.getTo().getChunk().getZ() >> 5;

Bukkit.getScheduler().runTaskAsynchronously(ServerBackup.getInstance(), new Runnable() {

@Override
public void run() {
String chunkInf = "Data." + e.getTo().getWorld().getName() + ".Chunk." + "r." + regX + "."
+ regZ + ".mca";

if (!Bukkit.getWorldContainer().toString().equalsIgnoreCase(".")) {
chunkInf = "Data." + Bukkit.getWorldContainer() + "\\" + e.getTo().getWorld().getName()
+ ".Chunk." + "r." + regX + "." + regZ + ".mca";
}

if (!chunks.contains(e.getTo().getChunk())) {
if (!ServerBackup.getInstance().bpInf.contains(chunkInf)) {
chunks.add(e.getTo().getChunk());
ServerBackup.getInstance().bpInf.set(chunkInf, chunks.get(chunks.size() - 1).getX());
ServerBackup.getInstance().bpInf.set(chunkInf, chunks.get(chunks.size() - 1).getZ());
if (ServerBackup.getInstance().getConfig().getBoolean("DynamicBackup") && (e.getFrom().getChunk() != Objects.requireNonNull(e.getTo()).getChunk())) {
// region X & Y (mca file)
Chunk chunk = e.getTo().getChunk();
int regX = chunk.getX() >> 5;
int regZ = chunk.getZ() >> 5;

saveChanges();
try {
chunks.remove(e.getTo().getChunk());
} catch (ArrayIndexOutOfBoundsException ex) {
}
} else {
chunks.add(e.getTo().getChunk());
ServerBackup.getInstance().bpInf.set(chunkInf, chunks.get(chunks.size() - 1).getWorld());

saveChanges();
try {
chunks.remove(e.getTo().getChunk());
} catch (ArrayIndexOutOfBoundsException ex) {
}
}
}
}

Bukkit.getScheduler().runTaskAsynchronously(ServerBackup.getInstance(), () -> {
String chunkInf = getChunkInfoPath(Objects.requireNonNull(e.getTo().getWorld()).getName(), regX, regZ);
addChunkToBackupInfo(chunk, chunkInf, e.getPlayer().getName(), chunk.getWorld().getName());
});
}
}
}

public void saveChanges() {
if (!isSaving) {
isSaving = true;

Bukkit.getScheduler().runTaskLaterAsynchronously(ServerBackup.getInstance(), new Runnable() {

@Override
public void run() {
ServerBackup.getInstance().saveBpInf();
if (ServerBackup.getInstance().getConfig().getBoolean("SendLogMessages")) {
Bukkit.getLogger().log(Level.INFO, "DynamicBP: file saved.");
}

isSaving = false;
}

}, 20 * 5);
}
}

@EventHandler
public void onJoin(PlayerJoinEvent e) {
if (ServerBackup.getInstance().getConfig().getBoolean("DynamicBackup")) {
Player p = e.getPlayer();
Chunk chunk = p.getLocation().getChunk();
int regX = chunk.getX() >> 5;
int regZ = chunk.getZ() >> 5;

int regX = p.getLocation().getChunk().getX() >> 5;
int regZ = p.getLocation().getChunk().getZ() >> 5;

Bukkit.getScheduler().runTaskAsynchronously(ServerBackup.getInstance(), new Runnable() {

@Override
public void run() {
String chunkInf = "Data." + p.getLocation().getWorld().getName() + ".Chunk." + "r." + regX + "."
+ regZ + ".mca";
Bukkit.getScheduler().runTaskAsynchronously(ServerBackup.getInstance(), () -> {
String chunkInf = getChunkInfoPath(Objects.requireNonNull(p.getLocation().getWorld()).getName(), regX, regZ);

if (!Bukkit.getWorldContainer().toString().equalsIgnoreCase(".")) {
chunkInf = "Data." + Bukkit.getWorldContainer() + "\\" + p.getLocation().getWorld().getName()
+ ".Chunk." + "r." + regX + "." + regZ + ".mca";
}

if (!chunks.contains(p.getLocation().getChunk())) {
if (!ServerBackup.getInstance().bpInf.contains(chunkInf)) {
chunks.add(p.getLocation().getChunk());
ServerBackup.getInstance().bpInf.set(chunkInf + ".X", p.getLocation().getChunk().getX());
ServerBackup.getInstance().bpInf.set(chunkInf + ".Z", p.getLocation().getChunk().getZ());

ServerBackup.getInstance().saveBpInf();
chunks.remove(p.getLocation().getChunk());
} else {
chunks.add(p.getLocation().getChunk());
ServerBackup.getInstance().bpInf.set(chunkInf, p.getLocation().getChunk().getWorld());
addChunkToBackupInfo(chunk, chunkInf, p.getName(), chunk.getWorld().getName());
});
}
}

ServerBackup.getInstance().saveBpInf();
chunks.remove(p.getLocation().getChunk());
}
}
}
private static String getChunkInfoPath(String worldName, int regX, int regZ) {
String chunkInf = "Data." + worldName + ".Chunk." + "r." + regX + "."
+ regZ + ".mca";

});
if (!Bukkit.getWorldContainer().toString().equalsIgnoreCase(".")) {
chunkInf = "Data." + Bukkit.getWorldContainer() + "\\" + worldName
+ ".Chunk." + "r." + regX + "." + regZ + ".mca";
}
return chunkInf;
}

}
private static void addChunkToBackupInfo(Chunk chunk, String chunkInf, String playerName, String worldName) {
if (!ServerBackup.getInstance().bpInf.contains(chunkInf)) {
ServerBackup.getInstance().bpInf.set(chunkInf + ".chunkX", chunk.getX());
ServerBackup.getInstance().bpInf.set(chunkInf + ".chunkZ", chunk.getZ());
ServerBackup.getInstance().bpInf.set(chunkInf + ".triggeredBy", playerName);
ServerBackup.getInstance().saveBackupInfoChanges();
Bukkit.getLogger().log(Level.INFO, "Region {0}, {1} added to backup set for {2}.",
new Object[]{chunk.getX() >> 5, chunk.getZ() >> 5, worldName});
}
}
}
23 changes: 20 additions & 3 deletions src/de/seblii/serverbackup/ServerBackup.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import de.seblii.serverbackup.commands.SBCommand;
import org.apache.commons.io.FileUtils;
import org.bstats.MetricsBase;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.SimplePie;
import org.bstats.charts.SingleLineChart;
Expand Down Expand Up @@ -33,6 +32,7 @@
public class ServerBackup extends JavaPlugin implements Listener {

private static ServerBackup sb;
private boolean isSaving;

public static ServerBackup getInstance() {
return sb;
Expand Down Expand Up @@ -340,13 +340,16 @@ public void saveCloud() {
public void loadBpInf() {
if (!backupInfo.exists()) {
try {
backupInfo.createNewFile();
boolean fileLoaded = backupInfo.createNewFile();
if (fileLoaded) {
getLogger().info("New backupInfo.yml file created.");
}
} catch (IOException e) {
e.printStackTrace();
}
}

saveBpInf();
saveBackupInfoChanges();
}

public void saveBpInf() {
Expand Down Expand Up @@ -530,4 +533,18 @@ public void onJoin(PlayerJoinEvent e) {
}
}

public void saveBackupInfoChanges() {
if (!isSaving) {
isSaving = true;

Bukkit.getScheduler().runTaskLaterAsynchronously(ServerBackup.getInstance(), () -> {
ServerBackup.getInstance().saveBpInf();
if (ServerBackup.getInstance().getConfig().getBoolean("SendLogMessages")) {
Bukkit.getLogger().log(Level.INFO, "DynamicBP: file saved.");
}

isSaving = false;
}, 100);
}
}
}
128 changes: 70 additions & 58 deletions src/de/seblii/serverbackup/ZipManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
Expand Down Expand Up @@ -59,78 +60,89 @@ public void zip() throws IOException {

try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(p))) {
Path pp = Paths.get(sourceFilePath);
Files.walk(pp).filter(path -> !Files.isDirectory(path)).forEach(path -> {
if (!path.toString().contains(ServerBackup.getInstance().getConfig().getString("BackupDestination")
.replaceAll("/", ""))) {
ZipEntry zipEntry = new ZipEntry(pp.relativize(path).toString());

for (String blacklist : ServerBackup.getInstance().getConfig().getStringList("Blacklist")) {
File bl = new File(blacklist);

if (bl.isDirectory()) {
if (path.toFile().getParent().toString().startsWith(bl.toString())
|| path.toFile().getParent().toString().startsWith(".\\" + bl.toString())) {
return;
}
} else {
if (path.equals(new File(blacklist).toPath())
|| path.equals(new File(".\\" + blacklist).toPath())) {
sender.sendMessage("Found '" + path.toString() + "' in blacklist. Skipping file.");
return;
try (Stream<Path> walk = Files.walk(pp)) {
walk.filter(path -> !Files.isDirectory(path)).forEach(path -> {
if (!path.toString().contains(ServerBackup.getInstance().getConfig().getString("BackupDestination")
.replaceAll("/", ""))) {
ZipEntry zipEntry = new ZipEntry(pp.relativize(path).toString());

for (String blacklist : ServerBackup.getInstance().getConfig().getStringList("Blacklist")) {
File bl = new File(blacklist);

if (bl.isDirectory()) {
if (path.toFile().getParent().toString().startsWith(bl.toString())
|| path.toFile().getParent().toString().startsWith(".\\" + bl.toString())) {
return;
}
} else {
if (path.equals(new File(blacklist).toPath())
|| path.equals(new File(".\\" + blacklist).toPath())) {
sender.sendMessage("Found '" + path.toString() + "' in blacklist. Skipping file.");
return;
}
}
}
}

if (!fullBackup) {
if (ServerBackup.getInstance().getConfig().getBoolean("DynamicBackup")) {
if (path.getParent().toString().endsWith("region")
|| path.getParent().toString().endsWith("entities")
|| path.getParent().toString().endsWith("poi")) {
boolean found = false;
if (ServerBackup.getInstance().bpInf
.contains("Data." + path.getParent().getParent().toString() + ".Chunk."
+ path.getFileName().toString())) {
found = true;
if (!fullBackup) {
if (ServerBackup.getInstance().getConfig().getBoolean("DynamicBackup")) {
if (path.getParent().toString().endsWith("region")
|| path.getParent().toString().endsWith("entities")
|| path.getParent().toString().endsWith("poi")) {
boolean found = false;
String worldName;

// Nether/The End regions were not backed up due to extra nested DIM folder, solves that case.
if (path.toString().contains("DIM1") || path.toString().contains("DIM-1")) {
worldName = path.getParent().getParent().getParent().toString();
} else {
worldName = path.getParent().getParent().toString();
}

if (ServerBackup.getInstance().bpInf
.contains("Data." + worldName + ".Chunk."
+ path.getFileName().toString())) {
found = true;
}

if (!found)
return;
}

if (!found)
return;
}
}
}

try {
if (sendDebugMsg) {
if (ServerBackup.getInstance().getConfig().getBoolean("SendLogMessages")) {
ServerBackup.getInstance().getLogger().log(Level.INFO,
"Zipping '" + path.toString() + "'");
try {
if (sendDebugMsg) {
if (ServerBackup.getInstance().getConfig().getBoolean("SendLogMessages")) {
ServerBackup.getInstance().getLogger().log(Level.INFO,
"Zipping '" + path.toString() + "'");

if (Bukkit.getConsoleSender() != sender) {
sender.sendMessage("Zipping '" + path.toString());
if (Bukkit.getConsoleSender() != sender) {
sender.sendMessage("Zipping '" + path.toString());
}
}
}
}

zs.putNextEntry(zipEntry);
zs.putNextEntry(zipEntry);

if (System.getProperty("os.name").startsWith("Windows")
&& path.toString().contains("session.lock")) {
} else {
try {
Files.copy(path, zs);
} catch (IOException e) {
e.printStackTrace();
if (System.getProperty("os.name").startsWith("Windows")
&& path.toString().contains("session.lock")) {
} else {
try {
Files.copy(path, zs);
} catch (IOException e) {
e.printStackTrace();
}
}
}

zs.closeEntry();
} catch (IOException e) {
e.printStackTrace();
ServerBackup.getInstance().getLogger().log(Level.WARNING, "Error while zipping files.");
return;
zs.closeEntry();
} catch (IOException e) {
e.printStackTrace();
ServerBackup.getInstance().getLogger().log(Level.WARNING, "Error while zipping files.");
return;
}
}
}
});
});
}
} catch (IOException e) {
e.printStackTrace();
ServerBackup.getInstance().getLogger().log(Level.WARNING, "Error while zipping files.");
Expand Down Expand Up @@ -167,7 +179,7 @@ public void zip() throws IOException {
targetFilePath = targetFilePath.split("backup")[0] + "dynamic-backup"
+ targetFilePath.split("backup")[1];

ServerBackup.getInstance().saveBpInf();
ServerBackup.getInstance().saveBackupInfoChanges();
}
}
}
Expand Down