mirror of https://github.com/Minestom/Minestom.git
165 lines
7.3 KiB
Java
165 lines
7.3 KiB
Java
package net.minestom.server.registry;
|
|
|
|
import com.google.gson.Gson;
|
|
|
|
import java.io.BufferedInputStream;
|
|
import java.io.File;
|
|
import java.io.FileReader;
|
|
import java.io.IOException;
|
|
import java.net.URL;
|
|
import java.nio.file.*;
|
|
import java.nio.file.attribute.BasicFileAttributes;
|
|
import java.util.stream.Collectors;
|
|
|
|
/**
|
|
* Responsible for making sure Minestom has the necessary files to run (notably registry files)
|
|
*/
|
|
public class ResourceGatherer {
|
|
|
|
public static final File DATA_FOLDER = new File("./minecraft_data/");
|
|
private static final File TMP_FOLDER = new File("./.minestom_tmp/");
|
|
|
|
/**
|
|
* Checks if registry/ folder is present
|
|
* If it is not, download the minecraft server jar, run the data generator and extract the wanted files
|
|
* If it is already present, directly return
|
|
*/
|
|
public static void ensureResourcesArePresent(File minecraftFolderOverride) throws IOException {
|
|
if(DATA_FOLDER.exists()) {
|
|
return;
|
|
}
|
|
System.out.println(DATA_FOLDER +" folder does not exist. Minestom will now generate the necessary files.");
|
|
|
|
if(!TMP_FOLDER.exists() && !TMP_FOLDER.mkdirs()) {
|
|
throw new IOException("Failed to create tmp folder.");
|
|
}
|
|
|
|
final String version = "1.15.2"; // TODO: Do not hardcode
|
|
|
|
System.out.println("Starting download of Minecraft server jar for version "+version+" from Mojang servers...");
|
|
File minecraftFolder = getMinecraftFolder(minecraftFolderOverride);
|
|
if(!minecraftFolder.exists()) {
|
|
throw new IOException("Could not find Minecraft installation folder, attempted location "+minecraftFolder+". If this location is not the correct one, please supply the correct one as argument of ResourceGatherer#ensureResourcesArePresent");
|
|
}
|
|
File serverJar = downloadServerJar(minecraftFolder, version);
|
|
System.out.println("Download complete.");
|
|
|
|
runDataGenerator(serverJar);
|
|
|
|
moveAndCleanup(version);
|
|
System.out.println("Resource gathering done!");
|
|
}
|
|
|
|
private static void moveAndCleanup(String version) throws IOException {
|
|
Path dataFolderPath = DATA_FOLDER.toPath();
|
|
Path tmpFolderPath = TMP_FOLDER.toPath();
|
|
Path generatedFolder = tmpFolderPath.resolve("generated");
|
|
System.out.println("Data generator successful, removing server jar");
|
|
Files.delete(tmpFolderPath.resolve("server_"+version+".jar"));
|
|
System.out.println("Removal successful, now moving data to "+DATA_FOLDER);
|
|
Files.walkFileTree(tmpFolderPath, new SimpleFileVisitor<>() {
|
|
|
|
@Override
|
|
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
|
Path relativePath = generatedFolder.relativize(dir);
|
|
if(dir.startsWith(generatedFolder)) { // don't copy logs
|
|
Path resolvedPath = dataFolderPath.resolve(relativePath);
|
|
System.out.println("> Creating sub-folder "+relativePath);
|
|
Files.createDirectories(resolvedPath);
|
|
}
|
|
return FileVisitResult.CONTINUE;
|
|
}
|
|
|
|
@Override
|
|
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
|
System.out.println("> Deleting folder "+dir);
|
|
Files.delete(dir);
|
|
return FileVisitResult.CONTINUE;
|
|
}
|
|
|
|
@Override
|
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
|
Path relativePath = generatedFolder.relativize(file);
|
|
if(file.startsWith(generatedFolder)) { // don't copy logs
|
|
Path resolvedPath = dataFolderPath.resolve(relativePath);
|
|
System.out.println("> Moving "+relativePath);
|
|
Files.move(file, resolvedPath);
|
|
} else {
|
|
System.out.println("> Deleting "+relativePath);
|
|
Files.delete(file);
|
|
}
|
|
return FileVisitResult.CONTINUE;
|
|
}
|
|
});
|
|
}
|
|
|
|
private static void runDataGenerator(File serverJar) throws IOException {
|
|
ProcessBuilder dataGenerator = new ProcessBuilder("java", "-cp", serverJar.getName(), "net.minecraft.data.Main", "--all", "--server", "--dev");
|
|
dataGenerator.directory(TMP_FOLDER);
|
|
dataGenerator.inheritIO();
|
|
System.out.println("Now running data generator with options '--dev', '--server', '--all'");
|
|
System.out.println("Executing: "+dataGenerator.command().stream().collect(Collectors.joining(" ")));
|
|
System.out.println("Minestom will now wait for it to finish, here's its output:");
|
|
Process dataGeneratorProcess = dataGenerator.start();
|
|
try {
|
|
int resultCode = dataGeneratorProcess.waitFor();
|
|
if(resultCode != 0) {
|
|
throw new IOException("Data generator finished with non-zero return code "+resultCode);
|
|
}
|
|
} catch (InterruptedException e) {
|
|
throw new IOException("Data generator was interrupted.", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Finds the URL for the server jar inside the versions/ folder of the game installation and download the .jar file from there
|
|
* @param minecraftFolder
|
|
* @param version
|
|
* @return
|
|
*/
|
|
private static File downloadServerJar(File minecraftFolder, String version) throws IOException {
|
|
File versionInfoFile = new File(minecraftFolder, "versions/"+version+"/"+version+".json");
|
|
if(!versionInfoFile.exists()) {
|
|
throw new IOException("Could not find "+version+".json in your Minecraft installation. Make sure to launch this version at least once before running Minestom");
|
|
}
|
|
|
|
try(FileReader fileReader = new FileReader(versionInfoFile)) {
|
|
Gson gson = new Gson();
|
|
VersionInfo versionInfo = gson.fromJson(fileReader, VersionInfo.class);
|
|
VersionInfo.DownloadObject serverJarInfo = versionInfo.getDownloadableFiles().get("server");
|
|
String downloadURL = serverJarInfo.getUrl();
|
|
|
|
System.out.println("Found URL, starting download from "+downloadURL+"...");
|
|
return download(version, downloadURL);
|
|
}
|
|
}
|
|
|
|
private static File download(String version, String url) throws IOException {
|
|
File target = new File(TMP_FOLDER, "server_"+version+".jar");
|
|
try(BufferedInputStream in = new BufferedInputStream(new URL(url).openStream())) {
|
|
Files.copy(in, target.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
|
} catch (IOException e) {
|
|
throw new IOException("Failed to download Minecraft server jar.", e);
|
|
}
|
|
return target;
|
|
}
|
|
|
|
private static File getMinecraftFolder(File minecraftFolderOverride) {
|
|
if(minecraftFolderOverride != null) {
|
|
return minecraftFolderOverride;
|
|
}
|
|
|
|
// https://help.minecraft.net/hc/en-us/articles/360035131551-Where-are-Minecraft-files-stored-
|
|
String os = System.getProperty("os.name").toLowerCase();
|
|
if(os.contains("win")) {
|
|
String user = System.getProperty("user.name");
|
|
return new File("C:/Users/"+user+"/AppData/Roaming/.minecraft/");
|
|
}
|
|
if(os.contains("mac")) {
|
|
return new File("~/Library/Application Support/minecraft");
|
|
}
|
|
|
|
return new File("~/.minecraft");
|
|
}
|
|
}
|