2020-04-20 12:50:28 +02:00
|
|
|
/*
|
|
|
|
* This file is part of BlueMap, licensed under the MIT License (MIT).
|
|
|
|
*
|
|
|
|
* Copyright (c) Blue (Lukas Rieger) <https://bluecolored.de>
|
|
|
|
* Copyright (c) contributors
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
|
|
* in the Software without restriction, including without limitation the rights
|
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
* THE SOFTWARE.
|
|
|
|
*/
|
2020-01-15 20:20:22 +01:00
|
|
|
package de.bluecolored.bluemap.common.plugin;
|
2020-01-13 17:13:20 +01:00
|
|
|
|
|
|
|
import java.io.DataInputStream;
|
2020-01-15 20:20:22 +01:00
|
|
|
import java.io.DataOutputStream;
|
2020-01-13 17:13:20 +01:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileInputStream;
|
2020-01-15 20:20:22 +01:00
|
|
|
import java.io.FileOutputStream;
|
2020-01-13 17:13:20 +01:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.net.URL;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Collection;
|
2020-01-15 20:20:22 +01:00
|
|
|
import java.util.HashMap;
|
2020-01-13 17:13:20 +01:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.UUID;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
import java.util.zip.GZIPInputStream;
|
2020-01-15 20:20:22 +01:00
|
|
|
import java.util.zip.GZIPOutputStream;
|
2020-01-13 17:13:20 +01:00
|
|
|
|
|
|
|
import org.apache.commons.io.FileUtils;
|
|
|
|
|
|
|
|
import com.flowpowered.math.vector.Vector2i;
|
|
|
|
|
2020-07-02 13:08:47 +02:00
|
|
|
import de.bluecolored.bluemap.common.BlueMapWebServer;
|
2020-01-15 20:20:22 +01:00
|
|
|
import de.bluecolored.bluemap.common.MapType;
|
|
|
|
import de.bluecolored.bluemap.common.RenderManager;
|
2020-04-10 17:16:47 +02:00
|
|
|
import de.bluecolored.bluemap.common.api.BlueMapAPIImpl;
|
2020-01-15 20:20:22 +01:00
|
|
|
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
2020-01-13 17:13:20 +01:00
|
|
|
import de.bluecolored.bluemap.core.config.ConfigManager;
|
|
|
|
import de.bluecolored.bluemap.core.config.MainConfig;
|
|
|
|
import de.bluecolored.bluemap.core.config.MainConfig.MapConfig;
|
|
|
|
import de.bluecolored.bluemap.core.logger.Logger;
|
|
|
|
import de.bluecolored.bluemap.core.mca.MCAWorld;
|
|
|
|
import de.bluecolored.bluemap.core.metrics.Metrics;
|
|
|
|
import de.bluecolored.bluemap.core.render.RenderSettings;
|
|
|
|
import de.bluecolored.bluemap.core.render.TileRenderer;
|
|
|
|
import de.bluecolored.bluemap.core.render.hires.HiresModelManager;
|
|
|
|
import de.bluecolored.bluemap.core.render.lowres.LowresModelManager;
|
2020-01-15 20:20:22 +01:00
|
|
|
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
|
2020-01-13 17:13:20 +01:00
|
|
|
import de.bluecolored.bluemap.core.resourcepack.ResourcePack;
|
|
|
|
import de.bluecolored.bluemap.core.web.WebFilesManager;
|
|
|
|
import de.bluecolored.bluemap.core.web.WebSettings;
|
|
|
|
import de.bluecolored.bluemap.core.world.SlicedWorld;
|
|
|
|
import de.bluecolored.bluemap.core.world.World;
|
|
|
|
|
|
|
|
public class Plugin {
|
|
|
|
|
|
|
|
public static final String PLUGIN_ID = "bluemap";
|
|
|
|
public static final String PLUGIN_NAME = "BlueMap";
|
2020-01-15 20:20:22 +01:00
|
|
|
|
2020-04-10 17:16:47 +02:00
|
|
|
private BlueMapAPIImpl api;
|
|
|
|
|
2020-01-15 20:20:22 +01:00
|
|
|
private String implementationType;
|
|
|
|
|
2020-01-13 17:13:20 +01:00
|
|
|
private ServerInterface serverInterface;
|
|
|
|
|
|
|
|
private MainConfig config;
|
|
|
|
private ResourcePack resourcePack;
|
|
|
|
|
|
|
|
private Map<UUID, World> worlds;
|
|
|
|
private Map<String, MapType> maps;
|
|
|
|
|
|
|
|
private MapUpdateHandler updateHandler;
|
|
|
|
|
|
|
|
private RenderManager renderManager;
|
|
|
|
private BlueMapWebServer webServer;
|
|
|
|
|
2020-01-21 21:15:37 +01:00
|
|
|
private Thread periodicalSaveThread;
|
2020-01-15 20:20:22 +01:00
|
|
|
private Thread metricsThread;
|
|
|
|
|
2020-01-13 17:13:20 +01:00
|
|
|
private boolean loaded = false;
|
|
|
|
|
2020-01-15 20:20:22 +01:00
|
|
|
public Plugin(String implementationType, ServerInterface serverInterface) {
|
|
|
|
this.implementationType = implementationType.toLowerCase();
|
2020-01-17 00:21:46 +01:00
|
|
|
|
2020-01-15 20:20:22 +01:00
|
|
|
this.serverInterface = serverInterface;
|
|
|
|
|
|
|
|
this.maps = new HashMap<>();
|
|
|
|
this.worlds = new HashMap<>();
|
2020-01-13 17:13:20 +01:00
|
|
|
}
|
|
|
|
|
2020-01-15 20:20:22 +01:00
|
|
|
public synchronized void load() throws IOException, ParseResourceException {
|
2020-01-13 17:13:20 +01:00
|
|
|
if (loaded) return;
|
|
|
|
unload(); //ensure nothing is left running (from a failed load or something)
|
|
|
|
|
|
|
|
//load configs
|
2020-01-15 20:20:22 +01:00
|
|
|
URL defaultSpongeConfig = Plugin.class.getResource("/bluemap-" + implementationType + ".conf");
|
|
|
|
URL spongeConfigDefaults = Plugin.class.getResource("/bluemap-" + implementationType + "-defaults.conf");
|
|
|
|
ConfigManager configManager = new ConfigManager(serverInterface.getConfigFolder(), defaultSpongeConfig, spongeConfigDefaults);
|
2020-01-13 17:13:20 +01:00
|
|
|
configManager.loadMainConfig();
|
|
|
|
config = configManager.getMainConfig();
|
|
|
|
|
|
|
|
//load resources
|
|
|
|
File defaultResourceFile = config.getDataPath().resolve("minecraft-client-" + ResourcePack.MINECRAFT_CLIENT_VERSION + ".jar").toFile();
|
|
|
|
File resourceExtensionsFile = config.getDataPath().resolve("resourceExtensions.zip").toFile();
|
|
|
|
File textureExportFile = config.getWebDataPath().resolve("textures.json").toFile();
|
|
|
|
|
|
|
|
if (!defaultResourceFile.exists()) {
|
2020-01-15 20:20:22 +01:00
|
|
|
if (config.isDownloadAccepted()) {
|
|
|
|
|
|
|
|
//download file
|
|
|
|
try {
|
|
|
|
Logger.global.logInfo("Downloading " + ResourcePack.MINECRAFT_CLIENT_URL + " to " + defaultResourceFile + " ...");
|
|
|
|
ResourcePack.downloadDefaultResource(defaultResourceFile);
|
|
|
|
} catch (IOException e) {
|
|
|
|
Logger.global.logError("Failed to download resources!", e);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
Logger.global.logWarning("BlueMap is missing important resources!");
|
|
|
|
Logger.global.logWarning("You need to accept the download of the required files in order of BlueMap to work!");
|
|
|
|
try { Logger.global.logWarning("Please check: " + configManager.getMainConfigFile().getCanonicalPath()); } catch (IOException ignored) {}
|
|
|
|
Logger.global.logInfo("If you have changed the config you can simply reload the plugin using: /bluemap reload");
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2020-01-13 17:13:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
resourceExtensionsFile.delete();
|
2020-01-15 20:20:22 +01:00
|
|
|
FileUtils.copyURLToFile(Plugin.class.getResource("/resourceExtensions.zip"), resourceExtensionsFile, 10000, 10000);
|
2020-01-13 17:13:20 +01:00
|
|
|
|
|
|
|
//find more resource packs
|
2020-01-15 20:20:22 +01:00
|
|
|
File resourcePackFolder = new File(serverInterface.getConfigFolder(), "resourcepacks");
|
2020-01-13 17:13:20 +01:00
|
|
|
resourcePackFolder.mkdirs();
|
|
|
|
File[] resourcePacks = resourcePackFolder.listFiles();
|
|
|
|
Arrays.sort(resourcePacks); //load resource packs in alphabetical order so you can reorder them by renaming
|
|
|
|
|
|
|
|
List<File> resources = new ArrayList<>(resourcePacks.length + 1);
|
|
|
|
resources.add(defaultResourceFile);
|
|
|
|
for (File file : resourcePacks) resources.add(file);
|
|
|
|
resources.add(resourceExtensionsFile);
|
|
|
|
|
|
|
|
resourcePack = new ResourcePack();
|
|
|
|
if (textureExportFile.exists()) resourcePack.loadTextureFile(textureExportFile);
|
|
|
|
resourcePack.load(resources);
|
|
|
|
resourcePack.saveTextureFile(textureExportFile);
|
|
|
|
|
|
|
|
configManager.loadResourceConfigs(resourcePack);
|
|
|
|
|
|
|
|
//load maps
|
|
|
|
for (MapConfig mapConfig : config.getMapConfigs()) {
|
|
|
|
String id = mapConfig.getId();
|
|
|
|
String name = mapConfig.getName();
|
|
|
|
|
|
|
|
File worldFolder = new File(mapConfig.getWorldPath());
|
|
|
|
if (!worldFolder.exists() || !worldFolder.isDirectory()) {
|
|
|
|
Logger.global.logError("Failed to load map '" + id + "': '" + worldFolder.getCanonicalPath() + "' does not exist or is no directory!", new IOException());
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
UUID worldUUID;
|
|
|
|
try {
|
2020-01-15 20:20:22 +01:00
|
|
|
worldUUID = serverInterface.getUUIDForWorld(worldFolder);
|
|
|
|
} catch (IOException e) {
|
|
|
|
Logger.global.logError("Failed to load map '" + id + "': Failed to get UUID for the world!", e);
|
2020-01-13 17:13:20 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
World world = worlds.get(worldUUID);
|
|
|
|
if (world == null) {
|
|
|
|
try {
|
2020-05-11 14:42:30 +02:00
|
|
|
world = MCAWorld.load(worldFolder.toPath(), worldUUID, configManager.getBlockIdConfig(), configManager.getBlockPropertiesConfig(), configManager.getBiomeConfig(), serverInterface.getWorldName(worldUUID), true);
|
2020-01-13 17:13:20 +01:00
|
|
|
worlds.put(worldUUID, world);
|
|
|
|
} catch (IOException e) {
|
|
|
|
Logger.global.logError("Failed to load map '" + id + "': Failed to read level.dat", e);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-16 15:31:33 +02:00
|
|
|
//slice world if configured
|
|
|
|
if (!mapConfig.getMin().equals(RenderSettings.DEFAULT_MIN) || !mapConfig.getMax().equals(RenderSettings.DEFAULT_MAX)) {
|
|
|
|
if (mapConfig.isRenderEdges()) {
|
|
|
|
world = new SlicedWorld(world, mapConfig.getMin(), mapConfig.getMax());
|
|
|
|
} else {
|
|
|
|
world = new SlicedWorld(
|
|
|
|
world,
|
|
|
|
mapConfig.getMin().min(mapConfig.getMin().sub(2, 2, 2)), // protect from int-overflow
|
|
|
|
mapConfig.getMax().max(mapConfig.getMax().add(2, 2, 2)) // protect from int-overflow
|
|
|
|
);
|
|
|
|
}
|
2020-01-13 17:13:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
HiresModelManager hiresModelManager = new HiresModelManager(
|
|
|
|
config.getWebDataPath().resolve(id).resolve("hires"),
|
|
|
|
resourcePack,
|
|
|
|
mapConfig,
|
2020-03-13 18:11:31 +01:00
|
|
|
new Vector2i(mapConfig.getHiresTileSize(), mapConfig.getHiresTileSize())
|
2020-01-13 17:13:20 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
LowresModelManager lowresModelManager = new LowresModelManager(
|
|
|
|
config.getWebDataPath().resolve(id).resolve("lowres"),
|
|
|
|
new Vector2i(mapConfig.getLowresPointsPerLowresTile(), mapConfig.getLowresPointsPerLowresTile()),
|
2020-01-18 16:42:34 +01:00
|
|
|
new Vector2i(mapConfig.getLowresPointsPerHiresTile(), mapConfig.getLowresPointsPerHiresTile()),
|
|
|
|
mapConfig.useGzipCompression()
|
2020-01-13 17:13:20 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
TileRenderer tileRenderer = new TileRenderer(hiresModelManager, lowresModelManager);
|
|
|
|
|
|
|
|
MapType mapType = new MapType(id, name, world, tileRenderer);
|
|
|
|
maps.put(id, mapType);
|
|
|
|
}
|
2020-04-19 20:12:37 +02:00
|
|
|
if (maps.isEmpty()) {
|
|
|
|
Logger.global.logWarning("There are no valid maps configured, please check your config! Disabling BlueMap...");
|
|
|
|
unload();
|
|
|
|
return;
|
|
|
|
}
|
2020-01-13 17:13:20 +01:00
|
|
|
|
|
|
|
//initialize render manager
|
|
|
|
renderManager = new RenderManager(config.getRenderThreadCount());
|
|
|
|
renderManager.start();
|
|
|
|
|
|
|
|
//load render-manager state
|
|
|
|
try {
|
|
|
|
File saveFile = config.getDataPath().resolve("rmstate").toFile();
|
|
|
|
saveFile.getParentFile().mkdirs();
|
|
|
|
if (saveFile.exists()) {
|
|
|
|
try (DataInputStream in = new DataInputStream(new GZIPInputStream(new FileInputStream(saveFile)))) {
|
|
|
|
renderManager.readState(in, getMapTypes());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (IOException ex) {
|
|
|
|
Logger.global.logError("Failed to load render-manager state!", ex);
|
|
|
|
}
|
|
|
|
|
2020-01-21 21:15:37 +01:00
|
|
|
//create periodical-save thread
|
|
|
|
periodicalSaveThread = new Thread(() -> {
|
|
|
|
try {
|
|
|
|
while (true) {
|
|
|
|
Thread.sleep(TimeUnit.MINUTES.toMillis(5));
|
|
|
|
try {
|
|
|
|
saveRenderManagerState();
|
|
|
|
} catch (IOException ex) {
|
|
|
|
Logger.global.logError("Failed to save render-manager state!", ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (InterruptedException ex){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
periodicalSaveThread.start();
|
|
|
|
|
2020-01-13 17:13:20 +01:00
|
|
|
//start map updater
|
2020-08-03 14:15:05 +02:00
|
|
|
this.updateHandler = new MapUpdateHandler(this);
|
2020-01-15 20:20:22 +01:00
|
|
|
serverInterface.registerListener(updateHandler);
|
2020-01-13 17:13:20 +01:00
|
|
|
|
|
|
|
//create/update webfiles
|
|
|
|
WebFilesManager webFilesManager = new WebFilesManager(config.getWebRoot());
|
|
|
|
if (webFilesManager.needsUpdate()) {
|
|
|
|
webFilesManager.updateFiles();
|
|
|
|
}
|
|
|
|
|
|
|
|
WebSettings webSettings = new WebSettings(config.getWebDataPath().resolve("settings.json").toFile());
|
2020-03-08 20:56:52 +01:00
|
|
|
webSettings.set(config.isUseCookies(), "useCookies");
|
|
|
|
webSettings.setAllMapsEnabled(false);
|
2020-01-13 17:13:20 +01:00
|
|
|
for (MapType map : maps.values()) {
|
2020-03-08 20:56:52 +01:00
|
|
|
webSettings.setMapEnabled(true, map.getId());
|
2020-01-13 17:13:20 +01:00
|
|
|
webSettings.setFrom(map.getTileRenderer(), map.getId());
|
2020-01-19 16:30:36 +01:00
|
|
|
webSettings.setFrom(map.getWorld(), map.getId());
|
2020-01-13 17:13:20 +01:00
|
|
|
}
|
|
|
|
int ordinal = 0;
|
|
|
|
for (MapConfig map : config.getMapConfigs()) {
|
|
|
|
if (!maps.containsKey(map.getId())) continue; //don't add not loaded maps
|
|
|
|
webSettings.setOrdinal(ordinal++, map.getId());
|
2020-01-19 16:30:36 +01:00
|
|
|
webSettings.setFrom(map, map.getId());
|
2020-01-13 17:13:20 +01:00
|
|
|
}
|
|
|
|
webSettings.save();
|
|
|
|
|
|
|
|
//start webserver
|
|
|
|
if (config.isWebserverEnabled()) {
|
2020-07-31 00:42:10 +02:00
|
|
|
webServer = new BlueMapWebServer(config, serverInterface);
|
2020-01-13 17:13:20 +01:00
|
|
|
webServer.updateWebfiles();
|
|
|
|
webServer.start();
|
|
|
|
}
|
|
|
|
|
|
|
|
//metrics
|
2020-01-15 20:20:22 +01:00
|
|
|
metricsThread = new Thread(() -> {
|
|
|
|
try {
|
|
|
|
Thread.sleep(TimeUnit.MINUTES.toMillis(1));
|
|
|
|
|
|
|
|
while (true) {
|
2020-02-09 23:01:15 +01:00
|
|
|
if (serverInterface.isMetricsEnabled(config.isMetricsEnabled())) Metrics.sendReport(this.implementationType);
|
2020-01-15 20:20:22 +01:00
|
|
|
Thread.sleep(TimeUnit.MINUTES.toMillis(30));
|
|
|
|
}
|
|
|
|
} catch (InterruptedException ex){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
metricsThread.start();
|
|
|
|
|
2020-01-13 17:13:20 +01:00
|
|
|
loaded = true;
|
2020-04-10 17:16:47 +02:00
|
|
|
|
|
|
|
//enable api
|
|
|
|
this.api = new BlueMapAPIImpl(this);
|
|
|
|
this.api.register();
|
2020-01-13 17:13:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public synchronized void unload() {
|
|
|
|
|
2020-04-10 17:16:47 +02:00
|
|
|
//disable api
|
|
|
|
if (api != null) api.unregister();
|
2020-04-19 20:12:37 +02:00
|
|
|
api = null;
|
2020-04-10 17:16:47 +02:00
|
|
|
|
2020-01-15 20:20:22 +01:00
|
|
|
//unregister listeners
|
|
|
|
serverInterface.unregisterAllListeners();
|
|
|
|
|
|
|
|
//stop scheduled threads
|
|
|
|
if (metricsThread != null) metricsThread.interrupt();
|
|
|
|
metricsThread = null;
|
|
|
|
|
2020-01-21 21:15:37 +01:00
|
|
|
if (periodicalSaveThread != null) periodicalSaveThread.interrupt();
|
|
|
|
periodicalSaveThread = null;
|
|
|
|
|
2020-01-15 20:20:22 +01:00
|
|
|
//stop services
|
|
|
|
if (renderManager != null) renderManager.stop();
|
|
|
|
if (webServer != null) webServer.close();
|
|
|
|
|
|
|
|
//save render-manager state
|
|
|
|
if (updateHandler != null) updateHandler.flushTileBuffer(); //first write all buffered tiles to the render manager to save them too
|
|
|
|
if (renderManager != null) {
|
|
|
|
try {
|
2020-01-21 21:15:37 +01:00
|
|
|
saveRenderManagerState();
|
2020-01-15 20:20:22 +01:00
|
|
|
} catch (IOException ex) {
|
|
|
|
Logger.global.logError("Failed to save render-manager state!", ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//save renders
|
|
|
|
for (MapType map : maps.values()) {
|
|
|
|
map.getTileRenderer().save();
|
|
|
|
}
|
|
|
|
|
|
|
|
//clear resources and configs
|
|
|
|
renderManager = null;
|
|
|
|
webServer = null;
|
|
|
|
updateHandler = null;
|
|
|
|
resourcePack = null;
|
|
|
|
config = null;
|
|
|
|
maps.clear();
|
|
|
|
worlds.clear();
|
|
|
|
|
|
|
|
loaded = false;
|
2020-01-13 17:13:20 +01:00
|
|
|
}
|
2020-01-21 21:15:37 +01:00
|
|
|
|
|
|
|
public void saveRenderManagerState() throws IOException {
|
|
|
|
File saveFile = config.getDataPath().resolve("rmstate").toFile();
|
|
|
|
saveFile.getParentFile().mkdirs();
|
|
|
|
if (saveFile.exists()) saveFile.delete();
|
|
|
|
saveFile.createNewFile();
|
|
|
|
|
|
|
|
try (DataOutputStream out = new DataOutputStream(new GZIPOutputStream(new FileOutputStream(saveFile)))) {
|
|
|
|
renderManager.writeState(out);
|
|
|
|
}
|
|
|
|
}
|
2020-01-13 17:13:20 +01:00
|
|
|
|
2020-01-15 20:20:22 +01:00
|
|
|
public synchronized void reload() throws IOException, ParseResourceException {
|
2020-01-13 17:13:20 +01:00
|
|
|
unload();
|
|
|
|
load();
|
|
|
|
}
|
|
|
|
|
|
|
|
public ServerInterface getServerInterface() {
|
|
|
|
return serverInterface;
|
|
|
|
}
|
|
|
|
|
|
|
|
public MainConfig getMainConfig() {
|
|
|
|
return config;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ResourcePack getResourcePack() {
|
|
|
|
return resourcePack;
|
|
|
|
}
|
|
|
|
|
|
|
|
public World getWorld(UUID uuid){
|
|
|
|
return worlds.get(uuid);
|
|
|
|
}
|
|
|
|
|
2020-04-07 21:04:46 +02:00
|
|
|
public Collection<World> getWorlds(){
|
|
|
|
return worlds.values();
|
|
|
|
}
|
|
|
|
|
2020-01-13 17:13:20 +01:00
|
|
|
public Collection<MapType> getMapTypes(){
|
|
|
|
return maps.values();
|
|
|
|
}
|
|
|
|
|
|
|
|
public RenderManager getRenderManager() {
|
|
|
|
return renderManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
public MapUpdateHandler getUpdateHandler() {
|
|
|
|
return updateHandler;
|
|
|
|
}
|
|
|
|
|
|
|
|
public BlueMapWebServer getWebServer() {
|
|
|
|
return webServer;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isLoaded() {
|
|
|
|
return loaded;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|