Improve file/folder access and creation for a better reliabillity

This commit is contained in:
Blue (Lukas Rieger) 2021-03-28 18:56:26 +02:00
parent 5b5293f29d
commit a23178f772
No known key found for this signature in database
GPG Key ID: 904C4995F9E1F800
17 changed files with 206 additions and 283 deletions

View File

@ -24,29 +24,11 @@
*/ */
package de.bluecolored.bluemap.common; package de.bluecolored.bluemap.common;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.io.FileUtils;
import com.flowpowered.math.vector.Vector2i; import com.flowpowered.math.vector.Vector2i;
import de.bluecolored.bluemap.common.plugin.Plugin; import de.bluecolored.bluemap.common.plugin.Plugin;
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface; import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
import de.bluecolored.bluemap.core.MinecraftVersion; import de.bluecolored.bluemap.core.MinecraftVersion;
import de.bluecolored.bluemap.core.config.ConfigManager; import de.bluecolored.bluemap.core.config.*;
import de.bluecolored.bluemap.core.config.CoreConfig;
import de.bluecolored.bluemap.core.config.MapConfig;
import de.bluecolored.bluemap.core.config.RenderConfig;
import de.bluecolored.bluemap.core.config.WebServerConfig;
import de.bluecolored.bluemap.core.logger.Logger; import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.mca.MCAWorld; import de.bluecolored.bluemap.core.mca.MCAWorld;
import de.bluecolored.bluemap.core.render.RenderSettings; import de.bluecolored.bluemap.core.render.RenderSettings;
@ -58,6 +40,12 @@
import de.bluecolored.bluemap.core.web.WebSettings; import de.bluecolored.bluemap.core.web.WebSettings;
import de.bluecolored.bluemap.core.world.SlicedWorld; import de.bluecolored.bluemap.core.world.SlicedWorld;
import de.bluecolored.bluemap.core.world.World; import de.bluecolored.bluemap.core.world.World;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.*;
/** /**
* This is the attempt to generalize as many actions as possible to have CLI and Plugins run on the same general setup-code. * This is the attempt to generalize as many actions as possible to have CLI and Plugins run on the same general setup-code.
@ -219,19 +207,23 @@ private synchronized void loadWorldsAndMaps() throws IOException, InterruptedExc
maps = Collections.unmodifiableMap(maps); maps = Collections.unmodifiableMap(maps);
} }
public synchronized ResourcePack getResourcePack() throws IOException, MissingResourcesException, InterruptedException { public synchronized ResourcePack getResourcePack() throws IOException, InterruptedException {
if (resourcePack == null) { if (resourcePack == null) {
File defaultResourceFile = new File(getCoreConfig().getDataFolder(), "minecraft-client-" + minecraftVersion.getVersionString() + ".jar"); File defaultResourceFile = new File(getCoreConfig().getDataFolder(), "minecraft-client-" + minecraftVersion.getVersionString() + ".jar");
File resourceExtensionsFile = new File(getCoreConfig().getDataFolder(), "resourceExtensions.zip"); File resourceExtensionsFile = new File(getCoreConfig().getDataFolder(), "resourceExtensions.zip");
File textureExportFile = new File(getRenderConfig().getWebRoot(), "data" + File.separator + "textures.json"); File textureExportFile = new File(getRenderConfig().getWebRoot(), "data" + File.separator + "textures.json");
File resourcePackFolder = new File(configFolder, "resourcepacks");
FileUtils.forceMkdir(resourcePackFolder);
if (!defaultResourceFile.exists()) { if (!defaultResourceFile.exists()) {
if (getCoreConfig().isDownloadAccepted()) { if (getCoreConfig().isDownloadAccepted()) {
//download file //download file
try { try {
Logger.global.logInfo("Downloading " + minecraftVersion.getClientDownloadUrl() + " to " + defaultResourceFile + " ..."); Logger.global.logInfo("Downloading " + minecraftVersion.getClientDownloadUrl() + " to " + defaultResourceFile + " ...");
FileUtils.forceMkdirParent(defaultResourceFile);
FileUtils.copyURLToFile(new URL(minecraftVersion.getClientDownloadUrl()), defaultResourceFile, 10000, 10000); FileUtils.copyURLToFile(new URL(minecraftVersion.getClientDownloadUrl()), defaultResourceFile, 10000, 10000);
} catch (IOException e) { } catch (IOException e) {
throw new IOException("Failed to download resources!", e); throw new IOException("Failed to download resources!", e);
@ -244,18 +236,18 @@ public synchronized ResourcePack getResourcePack() throws IOException, MissingRe
Logger.global.logInfo("Loading resources..."); Logger.global.logInfo("Loading resources...");
resourceExtensionsFile.delete(); if (resourceExtensionsFile.exists()) FileUtils.forceDelete(resourceExtensionsFile);
FileUtils.forceMkdirParent(resourceExtensionsFile);
FileUtils.copyURLToFile(Plugin.class.getResource("/de/bluecolored/bluemap/" + minecraftVersion.getResourcePrefix() + "/resourceExtensions.zip"), resourceExtensionsFile, 10000, 10000); FileUtils.copyURLToFile(Plugin.class.getResource("/de/bluecolored/bluemap/" + minecraftVersion.getResourcePrefix() + "/resourceExtensions.zip"), resourceExtensionsFile, 10000, 10000);
//find more resource packs //find more resource packs
File resourcePackFolder = new File(configFolder, "resourcepacks");
resourcePackFolder.mkdirs();
File[] resourcePacks = resourcePackFolder.listFiles(); File[] resourcePacks = resourcePackFolder.listFiles();
if (resourcePacks == null) resourcePacks = new File[0];
Arrays.sort(resourcePacks); //load resource packs in alphabetical order so you can reorder them by renaming Arrays.sort(resourcePacks); //load resource packs in alphabetical order so you can reorder them by renaming
List<File> resources = new ArrayList<>(resourcePacks.length + 1); List<File> resources = new ArrayList<>(resourcePacks.length + 1);
resources.add(defaultResourceFile); resources.add(defaultResourceFile);
for (File file : resourcePacks) resources.add(file); resources.addAll(Arrays.asList(resourcePacks));
resources.add(resourceExtensionsFile); resources.add(resourceExtensionsFile);
try { try {
@ -272,7 +264,7 @@ public synchronized ResourcePack getResourcePack() throws IOException, MissingRe
return resourcePack; return resourcePack;
} }
public synchronized ConfigManager getConfigManager() throws IOException { public synchronized ConfigManager getConfigManager() {
return configManager; return configManager;
} }

View File

@ -58,11 +58,10 @@ public void updateFiles() throws IOException {
ZipEntry zipEntry = entries.nextElement(); ZipEntry zipEntry = entries.nextElement();
if (zipEntry.isDirectory()) { if (zipEntry.isDirectory()) {
File dir = new File(webRoot, zipEntry.getName()); File dir = new File(webRoot, zipEntry.getName());
if (!dir.mkdirs()) { FileUtils.forceMkdir(dir);
Logger.global.logWarning("Failed to create directory: " + dir);
}
} else { } else {
File target = new File(webRoot, zipEntry.getName()); File target = new File(webRoot, zipEntry.getName());
FileUtils.forceMkdirParent(target);
FileUtils.copyInputStreamToFile(zipFile.getInputStream(zipEntry), target); FileUtils.copyInputStreamToFile(zipFile.getInputStream(zipEntry), target);
} }
} }

View File

@ -24,22 +24,6 @@
*/ */
package de.bluecolored.bluemap.common.api; package de.bluecolored.bluemap.common.api;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import javax.imageio.ImageIO;
import de.bluecolored.bluemap.api.BlueMapAPI; import de.bluecolored.bluemap.api.BlueMapAPI;
import de.bluecolored.bluemap.api.BlueMapMap; import de.bluecolored.bluemap.api.BlueMapMap;
import de.bluecolored.bluemap.api.BlueMapWorld; import de.bluecolored.bluemap.api.BlueMapWorld;
@ -50,6 +34,17 @@
import de.bluecolored.bluemap.core.BlueMap; import de.bluecolored.bluemap.core.BlueMap;
import de.bluecolored.bluemap.core.logger.Logger; import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.world.World; import de.bluecolored.bluemap.core.world.World;
import org.apache.commons.io.FileUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ExecutionException;
public class BlueMapAPIImpl extends BlueMapAPI { public class BlueMapAPIImpl extends BlueMapAPI {
@ -109,9 +104,8 @@ public String createImage(BufferedImage image, String path) throws IOException {
Path imagePath = webDataRoot.resolve(Paths.get(IMAGE_ROOT_PATH, path.replace("/", separator) + ".png")).toAbsolutePath(); Path imagePath = webDataRoot.resolve(Paths.get(IMAGE_ROOT_PATH, path.replace("/", separator) + ".png")).toAbsolutePath();
File imageFile = imagePath.toFile(); File imageFile = imagePath.toFile();
imageFile.getParentFile().mkdirs(); if (imageFile.exists()) FileUtils.forceDelete(imageFile);
imageFile.delete(); de.bluecolored.bluemap.core.util.FileUtils.createFile(imageFile);
imageFile.createNewFile();
if (!ImageIO.write(image, "png", imagePath.toFile())) if (!ImageIO.write(image, "png", imagePath.toFile()))
throw new IOException("The format 'png' is not supported!"); throw new IOException("The format 'png' is not supported!");

View File

@ -24,25 +24,20 @@
*/ */
package de.bluecolored.bluemap.common.api.marker; package de.bluecolored.bluemap.common.api.marker;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import de.bluecolored.bluemap.api.marker.MarkerAPI; import de.bluecolored.bluemap.api.marker.MarkerAPI;
import de.bluecolored.bluemap.api.marker.MarkerSet; import de.bluecolored.bluemap.api.marker.MarkerSet;
import de.bluecolored.bluemap.common.api.BlueMapAPIImpl; import de.bluecolored.bluemap.common.api.BlueMapAPIImpl;
import de.bluecolored.bluemap.core.logger.Logger; import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.util.FileUtils;
import ninja.leaping.configurate.ConfigurationNode; import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.gson.GsonConfigurationLoader; import ninja.leaping.configurate.gson.GsonConfigurationLoader;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class MarkerAPIImpl implements MarkerAPI { public class MarkerAPIImpl implements MarkerAPI {
private BlueMapAPIImpl api; private BlueMapAPIImpl api;
@ -98,15 +93,12 @@ public synchronized void load() throws IOException {
} }
private synchronized void load(boolean overwriteChanges) throws IOException { private synchronized void load(boolean overwriteChanges) throws IOException {
if (!markerFile.exists()) { Set<String> externallyRemovedSets = new HashSet<>(markerSets.keySet());
markerFile.getParentFile().mkdirs();
markerFile.createNewFile();
}
if (markerFile.exists() && markerFile.isFile()) {
GsonConfigurationLoader loader = GsonConfigurationLoader.builder().setFile(markerFile).build(); GsonConfigurationLoader loader = GsonConfigurationLoader.builder().setFile(markerFile).build();
ConfigurationNode node = loader.load(); ConfigurationNode node = loader.load();
Set<String> externallyRemovedSets = new HashSet<>(markerSets.keySet());
for (ConfigurationNode markerSetNode : node.getNode("markerSets").getChildrenList()) { for (ConfigurationNode markerSetNode : node.getNode("markerSets").getChildrenList()) {
String setId = markerSetNode.getNode("id").getString(); String setId = markerSetNode.getNode("id").getString();
if (setId == null) { if (setId == null) {
@ -131,6 +123,7 @@ private synchronized void load(boolean overwriteChanges) throws IOException {
Logger.global.logDebug("Marker-API: Failed to load marker-set '" + setId + ": " + ex); Logger.global.logDebug("Marker-API: Failed to load marker-set '" + setId + ": " + ex);
} }
} }
}
if (overwriteChanges) { if (overwriteChanges) {
for (String setId : externallyRemovedSets) { for (String setId : externallyRemovedSets) {
@ -145,6 +138,8 @@ private synchronized void load(boolean overwriteChanges) throws IOException {
public synchronized void save() throws IOException { public synchronized void save() throws IOException {
load(false); load(false);
FileUtils.createFile(markerFile);
GsonConfigurationLoader loader = GsonConfigurationLoader.builder().setFile(markerFile).build(); GsonConfigurationLoader loader = GsonConfigurationLoader.builder().setFile(markerFile).build();
ConfigurationNode node = loader.createEmptyNode(); ConfigurationNode node = loader.createEmptyNode();

View File

@ -37,6 +37,7 @@
import de.bluecolored.bluemap.core.logger.Logger; import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.metrics.Metrics; import de.bluecolored.bluemap.core.metrics.Metrics;
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException; import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
import de.bluecolored.bluemap.core.util.FileUtils;
import de.bluecolored.bluemap.core.web.FileRequestHandler; import de.bluecolored.bluemap.core.web.FileRequestHandler;
import de.bluecolored.bluemap.core.webserver.HttpRequestHandler; import de.bluecolored.bluemap.core.webserver.HttpRequestHandler;
import de.bluecolored.bluemap.core.webserver.WebServer; import de.bluecolored.bluemap.core.webserver.WebServer;
@ -110,6 +111,7 @@ public void load() throws IOException, ParseResourceException {
//create and start webserver //create and start webserver
if (webServerConfig.isWebserverEnabled()) { if (webServerConfig.isWebserverEnabled()) {
FileUtils.mkDirs(webServerConfig.getWebRoot());
HttpRequestHandler requestHandler = new FileRequestHandler(webServerConfig.getWebRoot().toPath(), "BlueMap v" + BlueMap.VERSION); HttpRequestHandler requestHandler = new FileRequestHandler(webServerConfig.getWebRoot().toPath(), "BlueMap v" + BlueMap.VERSION);
//inject live api if enabled //inject live api if enabled
@ -120,7 +122,7 @@ public void load() throws IOException, ParseResourceException {
webServer = new WebServer( webServer = new WebServer(
webServerConfig.getWebserverPort(), webServerConfig.getWebserverPort(),
webServerConfig.getWebserverMaxConnections(), webServerConfig.getWebserverMaxConnections(),
webServerConfig.getWebserverBindAdress(), webServerConfig.getWebserverBindAddress(),
requestHandler, requestHandler,
false false
); );
@ -305,8 +307,8 @@ public void unload() {
public void saveRenderManagerState() throws IOException { public void saveRenderManagerState() throws IOException {
File saveFile = getRenderManagerSaveFile(); File saveFile = getRenderManagerSaveFile();
if (saveFile.exists()) saveFile.delete(); if (saveFile.exists()) FileUtils.delete(saveFile);
saveFile.createNewFile(); FileUtils.createFile(saveFile);
try (DataOutputStream out = new DataOutputStream(new GZIPOutputStream(new FileOutputStream(saveFile)))) { try (DataOutputStream out = new DataOutputStream(new GZIPOutputStream(new FileOutputStream(saveFile)))) {
renderManager.writeState(out); renderManager.writeState(out);
@ -356,11 +358,7 @@ public RenderManager getRenderManager() {
public File getRenderManagerSaveFile() throws IOException { public File getRenderManagerSaveFile() throws IOException {
if (blueMap == null) return null; if (blueMap == null) return null;
return new File(blueMap.getCoreConfig().getDataFolder(), "rmstate");
File saveFile = new File(blueMap.getCoreConfig().getDataFolder(), "rmstate");
saveFile.getParentFile().mkdirs();
return saveFile;
} }
public MapUpdateHandler getUpdateHandler() { public MapUpdateHandler getUpdateHandler() {

View File

@ -24,11 +24,18 @@
*/ */
package de.bluecolored.bluemap.core.config; package de.bluecolored.bluemap.core.config;
import java.io.BufferedReader; import com.google.common.base.Preconditions;
import java.io.File; import de.bluecolored.bluemap.core.BlueMap;
import java.io.IOException; import de.bluecolored.bluemap.core.logger.Logger;
import java.io.InputStream; import de.bluecolored.bluemap.core.resourcepack.ResourcePack;
import java.io.InputStreamReader; import de.bluecolored.bluemap.core.resourcepack.ResourcePack.Resource;
import de.bluecolored.bluemap.core.util.FileUtils;
import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.gson.GsonConfigurationLoader;
import ninja.leaping.configurate.hocon.HoconConfigurationLoader;
import ninja.leaping.configurate.loader.ConfigurationLoader;
import java.io.*;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
@ -37,17 +44,6 @@
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.google.common.base.Preconditions;
import de.bluecolored.bluemap.core.BlueMap;
import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.resourcepack.ResourcePack;
import de.bluecolored.bluemap.core.resourcepack.ResourcePack.Resource;
import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.gson.GsonConfigurationLoader;
import ninja.leaping.configurate.hocon.HoconConfigurationLoader;
import ninja.leaping.configurate.loader.ConfigurationLoader;
public class ConfigManager { public class ConfigManager {
private static final Set<Placeholder> CONFIG_PLACEHOLDERS = new HashSet<>(); private static final Set<Placeholder> CONFIG_PLACEHOLDERS = new HashSet<>();
@ -76,7 +72,7 @@ public ConfigurationNode loadOrCreate(File configFile, URL defaultConfig, URL de
ConfigurationNode configNode; ConfigurationNode configNode;
if (!configFile.exists()) { if (!configFile.exists()) {
configFile.getParentFile().mkdirs(); FileUtils.mkDirsParent(configFile);
if (defaultConfig != null) { if (defaultConfig != null) {
//load content of default config //load content of default config

View File

@ -24,11 +24,11 @@
*/ */
package de.bluecolored.bluemap.core.config; package de.bluecolored.bluemap.core.config;
import ninja.leaping.configurate.ConfigurationNode;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import ninja.leaping.configurate.ConfigurationNode;
public class CoreConfig { public class CoreConfig {
private boolean downloadAccepted = false; private boolean downloadAccepted = false;
@ -57,7 +57,6 @@ public CoreConfig(ConfigurationNode node) throws IOException {
} }
public File getDataFolder() { public File getDataFolder() {
if (!dataFolder.exists()) dataFolder.mkdirs();
return dataFolder; return dataFolder;
} }

View File

@ -24,13 +24,13 @@
*/ */
package de.bluecolored.bluemap.core.config; package de.bluecolored.bluemap.core.config;
import ninja.leaping.configurate.ConfigurationNode;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import ninja.leaping.configurate.ConfigurationNode;
public class RenderConfig { public class RenderConfig {
private File webRoot = new File("web"); private File webRoot = new File("web");
@ -56,7 +56,6 @@ public RenderConfig(ConfigurationNode node) throws IOException {
} }
public File getWebRoot() { public File getWebRoot() {
if (!webRoot.exists()) webRoot.mkdirs();
return webRoot; return webRoot;
} }

View File

@ -24,19 +24,19 @@
*/ */
package de.bluecolored.bluemap.core.config; package de.bluecolored.bluemap.core.config;
import ninja.leaping.configurate.ConfigurationNode;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import ninja.leaping.configurate.ConfigurationNode;
public class WebServerConfig { public class WebServerConfig {
private boolean enabled = true; private boolean enabled = true;
private File webRoot = new File("web"); private File webRoot = new File("web");
private InetAddress bindAdress = null; private InetAddress bindAddress = null;
private int port = 8100; private int port = 8100;
private int maxConnections = 100; private int maxConnections = 100;
@ -52,13 +52,13 @@ public WebServerConfig(ConfigurationNode node) throws IOException {
webRoot = ConfigManager.toFolder(webRootString); webRoot = ConfigManager.toFolder(webRootString);
//ip //ip
String bindAdressString = node.getNode("ip").getString(""); String bindAddressString = node.getNode("ip").getString("");
if (bindAdressString.isEmpty() || bindAdressString.equals("0.0.0.0") || bindAdressString.equals("::0")) { if (bindAddressString.isEmpty() || bindAddressString.equals("0.0.0.0") || bindAddressString.equals("::0")) {
bindAdress = new InetSocketAddress(0).getAddress(); // 0.0.0.0 bindAddress = new InetSocketAddress(0).getAddress(); // 0.0.0.0
} else if (bindAdressString.equals("#getLocalHost")) { } else if (bindAddressString.equals("#getLocalHost")) {
bindAdress = InetAddress.getLocalHost(); bindAddress = InetAddress.getLocalHost();
} else { } else {
bindAdress = InetAddress.getByName(bindAdressString); bindAddress = InetAddress.getByName(bindAddressString);
} }
//port //port
@ -75,12 +75,11 @@ public boolean isWebserverEnabled() {
} }
public File getWebRoot() { public File getWebRoot() {
if (!webRoot.exists()) webRoot.mkdirs();
return webRoot; return webRoot;
} }
public InetAddress getWebserverBindAdress() { public InetAddress getWebserverBindAddress() {
return bindAdress; return bindAddress;
} }
public int getWebserverPort() { public int getWebserverPort() {

View File

@ -24,17 +24,13 @@
*/ */
package de.bluecolored.bluemap.core.logger; package de.bluecolored.bluemap.core.logger;
import de.bluecolored.bluemap.core.util.FileUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.NoSuchFileException;
import java.nio.file.Paths;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.logging.SimpleFormatter; import java.util.logging.*;
import org.apache.commons.lang3.exception.ExceptionUtils;
public class LoggerLogger extends AbstractLogger { public class LoggerLogger extends AbstractLogger {
private static LoggerLogger instance = null; private static LoggerLogger instance = null;
@ -67,18 +63,11 @@ public static LoggerLogger getInstance() {
public void addFileHandler(String filename, boolean append) { public void addFileHandler(String filename, boolean append) {
try { try {
File file = new File(filename);
FileUtils.mkDirsParent(file);
FileHandler fHandler = new FileHandler(filename, append); FileHandler fHandler = new FileHandler(filename, append);
fHandler.setFormatter(formatter); fHandler.setFormatter(formatter);
this.logger.addHandler(fHandler); this.logger.addHandler(fHandler);
} catch (NoSuchFileException e) {
// Directory may not exist. Create it and try again.
File parent = Paths.get(e.getFile()).getParent().toFile();
if (!parent.exists()) {
parent.mkdirs();
addFileHandler(filename, append);
} else {
de.bluecolored.bluemap.core.logger.Logger.global.logError("Error while opening log file!", e);
}
} catch (IOException e) { } catch (IOException e) {
de.bluecolored.bluemap.core.logger.Logger.global.logError("Error while opening log file!", e); de.bluecolored.bluemap.core.logger.Logger.global.logError("Error while opening log file!", e);
} }

View File

@ -24,23 +24,9 @@
*/ */
package de.bluecolored.bluemap.core.render.hires; package de.bluecolored.bluemap.core.render.hires;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.GZIPOutputStream;
import com.flowpowered.math.vector.Vector2i; import com.flowpowered.math.vector.Vector2i;
import com.flowpowered.math.vector.Vector3d; import com.flowpowered.math.vector.Vector3d;
import com.flowpowered.math.vector.Vector3i; import com.flowpowered.math.vector.Vector3i;
import de.bluecolored.bluemap.core.logger.Logger; import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.render.RenderSettings; import de.bluecolored.bluemap.core.render.RenderSettings;
import de.bluecolored.bluemap.core.render.WorldTile; import de.bluecolored.bluemap.core.render.WorldTile;
@ -48,6 +34,14 @@
import de.bluecolored.bluemap.core.util.AABB; import de.bluecolored.bluemap.core.util.AABB;
import de.bluecolored.bluemap.core.util.FileUtils; import de.bluecolored.bluemap.core.util.FileUtils;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.GZIPOutputStream;
public class HiresModelManager { public class HiresModelManager {
private Path fileRoot; private Path fileRoot;
@ -90,10 +84,7 @@ private void save(HiresModel model, String modelJson){
File file = getFile(model.getTile(), useGzip); File file = getFile(model.getTile(), useGzip);
try { try {
if (!file.exists()){ FileUtils.createFile(file);
file.getParentFile().mkdirs();
file.createNewFile();
}
OutputStream os = new FileOutputStream(file); OutputStream os = new FileOutputStream(file);
if (useGzip) os = new GZIPOutputStream(os); if (useGzip) os = new GZIPOutputStream(os);

View File

@ -24,12 +24,14 @@
*/ */
package de.bluecolored.bluemap.core.render.lowres; package de.bluecolored.bluemap.core.render.lowres;
import java.io.File; import com.flowpowered.math.vector.Vector2i;
import java.io.FileOutputStream; import com.flowpowered.math.vector.Vector3f;
import java.io.IOException; import de.bluecolored.bluemap.core.threejs.BufferGeometry;
import java.io.OutputStream; import de.bluecolored.bluemap.core.util.FileUtils;
import java.io.OutputStreamWriter; import de.bluecolored.bluemap.core.util.MathUtils;
import java.io.PrintWriter; import de.bluecolored.bluemap.core.util.ModelUtils;
import java.io.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -40,14 +42,6 @@
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
import com.flowpowered.math.vector.Vector2i;
import com.flowpowered.math.vector.Vector3f;
import de.bluecolored.bluemap.core.threejs.BufferGeometry;
import de.bluecolored.bluemap.core.util.FileUtils;
import de.bluecolored.bluemap.core.util.MathUtils;
import de.bluecolored.bluemap.core.util.ModelUtils;
public class LowresModel { public class LowresModel {
private UUID world; private UUID world;
@ -109,10 +103,7 @@ public void save(File file, boolean force, boolean useGzip) throws IOException {
} }
synchronized (fileLock) { synchronized (fileLock) {
if (!file.exists()){ FileUtils.createFile(file);
file.getParentFile().mkdirs();
file.createNewFile();
}
try { try {
FileUtils.waitForFile(file, 10, TimeUnit.SECONDS); FileUtils.waitForFile(file, 10, TimeUnit.SECONDS);

View File

@ -24,6 +24,13 @@
*/ */
package de.bluecolored.bluemap.core.render.lowres; package de.bluecolored.bluemap.core.render.lowres;
import com.flowpowered.math.vector.*;
import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.render.hires.HiresModel;
import de.bluecolored.bluemap.core.threejs.BufferGeometry;
import de.bluecolored.bluemap.core.util.FileUtils;
import org.apache.commons.io.IOUtils;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
@ -38,19 +45,6 @@
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import org.apache.commons.io.IOUtils;
import com.flowpowered.math.vector.Vector2i;
import com.flowpowered.math.vector.Vector3d;
import com.flowpowered.math.vector.Vector3f;
import com.flowpowered.math.vector.Vector3i;
import com.flowpowered.math.vector.Vector4f;
import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.render.hires.HiresModel;
import de.bluecolored.bluemap.core.threejs.BufferGeometry;
import de.bluecolored.bluemap.core.util.FileUtils;
public class LowresModelManager { public class LowresModelManager {
private Path fileRoot; private Path fileRoot;
@ -196,15 +190,11 @@ private LowresModel getModel(UUID world, Vector2i tile) {
} catch (IllegalArgumentException | IOException ex){ } catch (IllegalArgumentException | IOException ex){
Logger.global.logError("Failed to load lowres model: " + modelFile, ex); Logger.global.logError("Failed to load lowres model: " + modelFile, ex);
modelFile.delete(); try {
FileUtils.delete(modelFile);
/* } catch (IOException ex2) {
File brokenFile = modelFile.toPath().getParent().resolve(modelFile.getName() + ".broken").toFile(); Logger.global.logError("Failed to delete lowres-file: " + modelFile, ex2);
if (brokenFile.exists()) brokenFile.delete();
if (!modelFile.renameTo(brokenFile)) {
modelFile.delete();
} }
*/
} }
} }

View File

@ -24,32 +24,16 @@
*/ */
package de.bluecolored.bluemap.core.resourcepack; package de.bluecolored.bluemap.core.resourcepack;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import javax.imageio.ImageIO;
import com.flowpowered.math.vector.Vector4f; import com.flowpowered.math.vector.Vector4f;
import com.google.gson.Gson; import com.google.gson.*;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonStreamParser;
import de.bluecolored.bluemap.core.logger.Logger; import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.resourcepack.fileaccess.FileAccess; import de.bluecolored.bluemap.core.resourcepack.fileaccess.FileAccess;
import de.bluecolored.bluemap.core.util.FileUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
/** /**
* A {@link TextureGallery} is managing {@link Texture}s and their id's and path's.<br> * A {@link TextureGallery} is managing {@link Texture}s and their id's and path's.<br>
@ -131,9 +115,8 @@ public void saveTextureFile(File file) throws IOException {
.create(); .create();
String json = gson.toJson(root); String json = gson.toJson(root);
file.delete(); if (file.exists()) FileUtils.delete(file);
file.getParentFile().mkdirs(); FileUtils.createFile(file);
file.createNewFile();
try (FileWriter fileWriter = new FileWriter(file)) { try (FileWriter fileWriter = new FileWriter(file)) {
fileWriter.append(json); fileWriter.append(json);

View File

@ -24,7 +24,10 @@
*/ */
package de.bluecolored.bluemap.core.util; package de.bluecolored.bluemap.core.util;
import com.flowpowered.math.vector.Vector2i;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -32,12 +35,31 @@
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import com.flowpowered.math.vector.Vector2i;
public class FileUtils { public class FileUtils {
private FileUtils(){} private FileUtils(){}
public static void delete(File file) throws IOException {
if (file.exists()) org.apache.commons.io.FileUtils.forceDelete(file);
}
public static void mkDirs(File directory) throws IOException {
org.apache.commons.io.FileUtils.forceMkdir(directory);
}
public static void mkDirsParent(File file) throws IOException {
org.apache.commons.io.FileUtils.forceMkdirParent(file);
}
public static void createFile(File file) throws IOException {
if (!file.exists()) {
org.apache.commons.io.FileUtils.forceMkdirParent(file);
if (!file.createNewFile()) throw new IOException("Could not create file '" + file + "'!");
} else {
if (!file.isFile()) throw new IOException("File '" + file + "' exists but is not a normal file!");
}
}
public static File coordsToFile(Path root, Vector2i coords, String fileType){ public static File coordsToFile(Path root, Vector2i coords, String fileType){
String path = "x" + coords.getX() + "z" + coords.getY(); String path = "x" + coords.getX() + "z" + coords.getY();
char[] cs = path.toCharArray(); char[] cs = path.toCharArray();

View File

@ -24,33 +24,29 @@
*/ */
package de.bluecolored.bluemap.core.web; package de.bluecolored.bluemap.core.web;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.stream.Collectors;
import com.flowpowered.math.vector.Vector2i; import com.flowpowered.math.vector.Vector2i;
import com.flowpowered.math.vector.Vector3f; import com.flowpowered.math.vector.Vector3f;
import de.bluecolored.bluemap.core.config.MapConfig; import de.bluecolored.bluemap.core.config.MapConfig;
import de.bluecolored.bluemap.core.render.TileRenderer; import de.bluecolored.bluemap.core.render.TileRenderer;
import de.bluecolored.bluemap.core.util.FileUtils;
import de.bluecolored.bluemap.core.util.MathUtils; import de.bluecolored.bluemap.core.util.MathUtils;
import de.bluecolored.bluemap.core.world.World; import de.bluecolored.bluemap.core.world.World;
import ninja.leaping.configurate.ConfigurationNode; import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.gson.GsonConfigurationLoader; import ninja.leaping.configurate.gson.GsonConfigurationLoader;
import ninja.leaping.configurate.loader.ConfigurationLoader; import ninja.leaping.configurate.loader.ConfigurationLoader;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.stream.Collectors;
public class WebSettings { public class WebSettings {
private ConfigurationLoader<? extends ConfigurationNode> configLoader; private ConfigurationLoader<? extends ConfigurationNode> configLoader;
private ConfigurationNode rootNode; private ConfigurationNode rootNode;
public WebSettings(File settingsFile) throws IOException { public WebSettings(File settingsFile) throws IOException {
FileUtils.createFile(settingsFile);
if (!settingsFile.exists()) {
settingsFile.getParentFile().mkdirs();
settingsFile.createNewFile();
}
configLoader = GsonConfigurationLoader.builder() configLoader = GsonConfigurationLoader.builder()
.setFile(settingsFile) .setFile(settingsFile)

View File

@ -24,35 +24,9 @@
*/ */
package de.bluecolored.bluemap.cli; package de.bluecolored.bluemap.cli;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.time.DurationFormatUtils;
import com.flowpowered.math.GenericMath; import com.flowpowered.math.GenericMath;
import com.flowpowered.math.vector.Vector2i; import com.flowpowered.math.vector.Vector2i;
import de.bluecolored.bluemap.common.*;
import de.bluecolored.bluemap.common.BlueMapService;
import de.bluecolored.bluemap.common.MapType;
import de.bluecolored.bluemap.common.MissingResourcesException;
import de.bluecolored.bluemap.common.RenderManager;
import de.bluecolored.bluemap.common.RenderTask;
import de.bluecolored.bluemap.core.BlueMap; import de.bluecolored.bluemap.core.BlueMap;
import de.bluecolored.bluemap.core.MinecraftVersion; import de.bluecolored.bluemap.core.MinecraftVersion;
import de.bluecolored.bluemap.core.config.WebServerConfig; import de.bluecolored.bluemap.core.config.WebServerConfig;
@ -60,11 +34,19 @@
import de.bluecolored.bluemap.core.logger.LoggerLogger; import de.bluecolored.bluemap.core.logger.LoggerLogger;
import de.bluecolored.bluemap.core.metrics.Metrics; import de.bluecolored.bluemap.core.metrics.Metrics;
import de.bluecolored.bluemap.core.render.hires.HiresModelManager; import de.bluecolored.bluemap.core.render.hires.HiresModelManager;
import de.bluecolored.bluemap.core.util.FileUtils;
import de.bluecolored.bluemap.core.web.FileRequestHandler; import de.bluecolored.bluemap.core.web.FileRequestHandler;
import de.bluecolored.bluemap.core.web.WebSettings; import de.bluecolored.bluemap.core.web.WebSettings;
import de.bluecolored.bluemap.core.webserver.HttpRequestHandler; import de.bluecolored.bluemap.core.webserver.HttpRequestHandler;
import de.bluecolored.bluemap.core.webserver.WebServer; import de.bluecolored.bluemap.core.webserver.WebServer;
import de.bluecolored.bluemap.core.world.World; import de.bluecolored.bluemap.core.world.World;
import org.apache.commons.cli.*;
import org.apache.commons.lang3.time.DurationFormatUtils;
import java.io.*;
import java.util.Collection;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class BlueMapCLI { public class BlueMapCLI {
@ -137,7 +119,10 @@ public void renderMaps(BlueMapService blueMap, boolean forceRender, boolean forc
currentTask.getMapType().getTileRenderer().save(); currentTask.getMapType().getTileRenderer().save();
} }
try {
Logger.global.logInfo("Saving render-state ..."); Logger.global.logInfo("Saving render-state ...");
FileUtils.createFile(rmstate);
try ( try (
OutputStream os = new GZIPOutputStream(new FileOutputStream(rmstate)); OutputStream os = new GZIPOutputStream(new FileOutputStream(rmstate));
DataOutputStream dos = new DataOutputStream(os); DataOutputStream dos = new DataOutputStream(os);
@ -145,6 +130,7 @@ public void renderMaps(BlueMapService blueMap, boolean forceRender, boolean forc
renderManager.writeState(dos); renderManager.writeState(dos);
Logger.global.logInfo("Render saved and stopped! Restart the render (without using -f) to resume."); Logger.global.logInfo("Render saved and stopped! Restart the render (without using -f) to resume.");
}
} catch (IOException ex) { } catch (IOException ex) {
Logger.global.logError("Failed to save render-state!", ex); Logger.global.logError("Failed to save render-state!", ex);
} }
@ -215,7 +201,7 @@ public void renderMaps(BlueMapService blueMap, boolean forceRender, boolean forc
renderManager.stop(); renderManager.stop();
//render finished, so remove render state file //render finished, so remove render state file
rmstate.delete(); FileUtils.delete(rmstate);
for (MapType map : blueMap.getMaps().values()) { for (MapType map : blueMap.getMaps().values()) {
webSettings.set(startTime, "maps", map.getId(), "last-render"); webSettings.set(startTime, "maps", map.getId(), "last-render");
@ -234,12 +220,13 @@ public void startWebserver(BlueMapService blueMap, boolean verbose) throws IOExc
Logger.global.logInfo("Starting webserver ..."); Logger.global.logInfo("Starting webserver ...");
WebServerConfig config = blueMap.getWebServerConfig(); WebServerConfig config = blueMap.getWebServerConfig();
FileUtils.mkDirs(config.getWebRoot());
HttpRequestHandler requestHandler = new FileRequestHandler(config.getWebRoot().toPath(), "BlueMap v" + BlueMap.VERSION); HttpRequestHandler requestHandler = new FileRequestHandler(config.getWebRoot().toPath(), "BlueMap v" + BlueMap.VERSION);
WebServer webServer = new WebServer( WebServer webServer = new WebServer(
config.getWebserverPort(), config.getWebserverPort(),
config.getWebserverMaxConnections(), config.getWebserverMaxConnections(),
config.getWebserverBindAdress(), config.getWebserverBindAddress(),
requestHandler, requestHandler,
verbose verbose
); );
@ -270,7 +257,7 @@ public static void main(String[] args) {
File configFolder = new File("."); File configFolder = new File(".");
if (cmd.hasOption("c")) { if (cmd.hasOption("c")) {
configFolder = new File(cmd.getOptionValue("c")); configFolder = new File(cmd.getOptionValue("c"));
configFolder.mkdirs(); FileUtils.mkDirs(configFolder);
} }
//minecraft version //minecraft version
@ -328,6 +315,9 @@ public static void main(String[] args) {
blueMap.getRenderConfig(); blueMap.getRenderConfig();
blueMap.getWebServerConfig(); blueMap.getWebServerConfig();
//create resourcepacks folder
FileUtils.mkDirs(new File(configFolder, "resourcepacks"));
//print help //print help
BlueMapCLI.printHelp(); BlueMapCLI.printHelp();
System.exit(1); System.exit(1);