Skip to content

Commit

Permalink
Merge branch 'master' of github.com:phybros/servertap
Browse files Browse the repository at this point in the history
  • Loading branch information
phybros committed Dec 15, 2021
2 parents f786784 + ad4c2f0 commit a64a325
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/main/java/io/servertap/PluginEntrypoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,9 @@ public void onEnable() {
post("server/whitelist", ServerApi::whitelistPost);
get("worlds", ServerApi::worldsGet);
post("worlds/save", ServerApi::saveAllWorlds);
get("worlds/download", ServerApi::downloadWorlds);
get("worlds/:uuid", ServerApi::worldGet);
get("worlds/:uuid/download", ServerApi::downloadWorld);
post("worlds/:uuid/save", ServerApi::saveWorld);
get("scoreboard", ServerApi::scoreboardGet);
get("scoreboard/:name", ServerApi::objectiveGet);
Expand Down
119 changes: 112 additions & 7 deletions src/main/java/io/servertap/api/v1/ServerApi.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package io.servertap.api.v1;

import com.google.gson.Gson;
import io.javalin.http.BadRequestResponse;
import io.javalin.http.Context;
import io.javalin.http.NotFoundResponse;
import io.javalin.http.ServiceUnavailableResponse;
import io.javalin.http.*;
import io.javalin.plugin.json.JavalinJson;
import io.javalin.plugin.openapi.annotations.*;
import io.servertap.Constants;
Expand All @@ -14,16 +11,15 @@
import io.servertap.api.v1.models.*;
import io.servertap.mojang.api.MojangApiService;
import io.servertap.mojang.api.models.NameChange;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.bukkit.BanList;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.plugin.Plugin;
import org.bukkit.scoreboard.ScoreboardManager;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.*;
import java.lang.management.ManagementFactory;
import java.math.BigDecimal;
import java.nio.file.Paths;
Expand All @@ -33,6 +29,8 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ServerApi {

Expand Down Expand Up @@ -206,6 +204,113 @@ public static void saveWorld(Context ctx) {
ctx.json("success");
}

private static void addFolderToZip(File folder, ZipOutputStream zip, String baseName, String rootName) throws IOException {
File[] files = folder.listFiles();
assert files != null;
for (File file : files) {
if (file.isDirectory()) {
if(rootName == null) {
addFolderToZip(file, zip, baseName, folder.getName());
} else {
addFolderToZip(file, zip, baseName, rootName);
}
} else {
String name = file.getAbsolutePath().substring(baseName.length())
// Trim first slash (absolute path)
.replaceFirst("^" + File.separator, "");
// Join path and folder name
if(rootName == null) {
name = folder.getName() + File.separator + name;
} else {
name = rootName + File.separator + name;
}
ZipEntry zipEntry = new ZipEntry(name);
zip.putNextEntry(zipEntry);
IOUtils.copy(new FileInputStream(file), zip);
zip.closeEntry();
}
}
}

@OpenApi(
path = "/v1/worlds/:uuid/download",
summary = "Downloads a ZIP compressed archive of the world's folder",
method = HttpMethod.GET,
tags = {"Server"},
headers = {
@OpenApiParam(name = "key")
},
pathParams = {
@OpenApiParam(name = "uuid", description = "The UUID of the World to download")
},
responses = {
@OpenApiResponse(status = "200", content = @OpenApiContent(type = "application/zip")),
}
)
public static void downloadWorld(Context ctx) throws IOException {
org.bukkit.Server bukkitServer = Bukkit.getServer();

UUID worldUUID = ValidationUtils.safeUUID(ctx.pathParam("uuid"));
if (worldUUID == null) {
throw new BadRequestResponse(Constants.INVALID_UUID);
}

org.bukkit.World world = bukkitServer.getWorld(worldUUID);

if (world != null) {
File folder = world.getWorldFolder();

// Set headers for proper zip download
ctx.header("Content-Disposition", "attachment; filename=\"" + folder.getName() + ".zip\"");
ctx.header("Content-Type", "application/zip");


ZipOutputStream zip = new ZipOutputStream(ctx.res.getOutputStream());
addFolderToZip(folder, zip, folder.getAbsolutePath(), null);
zip.close();
} else {
throw new NotFoundResponse(Constants.WORLD_NOT_FOUND);
}
}

@OpenApi(
path = "/v1/worlds/download",
summary = "Downloads a ZIP compressed archive of all the worlds' folders",
method = HttpMethod.GET,
tags = {"Server"},
headers = {
@OpenApiParam(name = "key")
},
responses = {
@OpenApiResponse(status = "200", content = @OpenApiContent(type = "application/zip")),
}
)
public static void downloadWorlds(Context ctx) throws IOException {
org.bukkit.Server bukkitServer = Bukkit.getServer();

Plugin pluginInstance = bukkitServer.getPluginManager().getPlugin("ServerTap");

ctx.header("Content-Disposition", "attachment; filename=\"worlds.zip\"");
ctx.header("Content-Type", "application/zip");

ZipOutputStream zip = new ZipOutputStream(ctx.res.getOutputStream());

for (org.bukkit.World world : Bukkit.getWorlds()) {
try {

File folder = world.getWorldFolder();

addFolderToZip(folder, zip, folder.getAbsolutePath(), null);

} catch (Exception e) {
// Just warn about the issue
log.warning(String.format("Couldn't save World %s %s", world.getName(), e.getMessage()));
throw new InternalServerErrorResponse("Couldn't download world " + world.getName() + ": " + e.getMessage());
}
}
zip.close();
}

@OpenApi(
path = "/v1/chat/broadcast",
method = HttpMethod.POST,
Expand Down

0 comments on commit a64a325

Please sign in to comment.