mirror of
https://github.com/BlueMap-Minecraft/BlueMap.git
synced 2025-02-23 07:51:43 +01:00
Add stuff
This commit is contained in:
parent
6e78587d6f
commit
6d53bce0dd
@ -1 +1 @@
|
|||||||
Subproject commit 3949ebcb565ecf44bd106daf69582d76d8cfbca1
|
Subproject commit 5b4093e404de85f98a1ce620282d1d5314f49c90
|
@ -1 +1 @@
|
|||||||
Subproject commit df59cdfc78227c45f0826b4112d80586bd54454f
|
Subproject commit e6059e90512c6550d7a63bca17be29f53ab10efc
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common;
|
package de.bluecolored.bluemap.common;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.common.config.*;
|
import de.bluecolored.bluemap.common.config.*;
|
||||||
|
@ -75,6 +75,8 @@ public class BlueMapService implements Closeable {
|
|||||||
private final Map<Path, String> worldIds;
|
private final Map<Path, String> worldIds;
|
||||||
private final Map<String, Storage> storages;
|
private final Map<String, Storage> storages;
|
||||||
|
|
||||||
|
private volatile WebFilesManager webFilesManager;
|
||||||
|
|
||||||
private Map<String, World> worlds;
|
private Map<String, World> worlds;
|
||||||
private Map<String, BmMap> maps;
|
private Map<String, BmMap> maps;
|
||||||
|
|
||||||
@ -130,9 +132,20 @@ public String getWorldId(Path worldFolder) throws IOException {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WebFilesManager getWebFilesManager() {
|
||||||
|
if (webFilesManager == null) {
|
||||||
|
synchronized (this) {
|
||||||
|
if (webFilesManager == null)
|
||||||
|
webFilesManager = new WebFilesManager(configs.getWebappConfig().getWebroot());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return webFilesManager;
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized void createOrUpdateWebApp(boolean force) throws ConfigurationException {
|
public synchronized void createOrUpdateWebApp(boolean force) throws ConfigurationException {
|
||||||
try {
|
try {
|
||||||
WebFilesManager webFilesManager = new WebFilesManager(configs.getWebappConfig().getWebroot());
|
WebFilesManager webFilesManager = getWebFilesManager();
|
||||||
|
|
||||||
// update web-app files
|
// update web-app files
|
||||||
if (force || webFilesManager.filesNeedUpdate()) {
|
if (force || webFilesManager.filesNeedUpdate()) {
|
||||||
@ -142,6 +155,7 @@ public synchronized void createOrUpdateWebApp(boolean force) throws Configuratio
|
|||||||
// update settings.json
|
// update settings.json
|
||||||
if (!configs.getWebappConfig().isUpdateSettingsFile()) {
|
if (!configs.getWebappConfig().isUpdateSettingsFile()) {
|
||||||
webFilesManager.loadSettings();
|
webFilesManager.loadSettings();
|
||||||
|
webFilesManager.addFrom(configs.getWebappConfig());
|
||||||
} else {
|
} else {
|
||||||
webFilesManager.setFrom(configs.getWebappConfig());
|
webFilesManager.setFrom(configs.getWebappConfig());
|
||||||
}
|
}
|
||||||
|
@ -87,10 +87,22 @@ public void removeMap(String mapId) {
|
|||||||
this.settings.maps.remove(mapId);
|
this.settings.maps.remove(mapId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<String> getScripts() {
|
||||||
|
return this.settings.scripts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getStyles() {
|
||||||
|
return this.settings.styles;
|
||||||
|
}
|
||||||
|
|
||||||
public void setFrom(WebappConfig webappConfig) {
|
public void setFrom(WebappConfig webappConfig) {
|
||||||
this.settings.setFrom(webappConfig);
|
this.settings.setFrom(webappConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addFrom(WebappConfig webappConfig) {
|
||||||
|
this.settings.addFrom(webappConfig);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean filesNeedUpdate() {
|
public boolean filesNeedUpdate() {
|
||||||
return !Files.exists(webRoot.resolve("index.html"));
|
return !Files.exists(webRoot.resolve("index.html"));
|
||||||
}
|
}
|
||||||
@ -156,6 +168,8 @@ private static class Settings {
|
|||||||
private int lowresSliderMin = 500;
|
private int lowresSliderMin = 500;
|
||||||
|
|
||||||
private Set<String> maps = new HashSet<>();
|
private Set<String> maps = new HashSet<>();
|
||||||
|
private Set<String> scripts = new HashSet<>();
|
||||||
|
private Set<String> styles = new HashSet<>();
|
||||||
|
|
||||||
public void setFrom(WebappConfig config) {
|
public void setFrom(WebappConfig config) {
|
||||||
this.useCookies = config.isUseCookies();
|
this.useCookies = config.isUseCookies();
|
||||||
@ -165,16 +179,26 @@ public void setFrom(WebappConfig config) {
|
|||||||
|
|
||||||
this.minZoomDistance = config.getMinZoomDistance();
|
this.minZoomDistance = config.getMinZoomDistance();
|
||||||
this.maxZoomDistance = config.getMaxZoomDistance();
|
this.maxZoomDistance = config.getMaxZoomDistance();
|
||||||
|
|
||||||
this.hiresSliderMax = config.getHiresSliderMax();
|
this.hiresSliderMax = config.getHiresSliderMax();
|
||||||
this.hiresSliderDefault = config.getHiresSliderDefault();
|
this.hiresSliderDefault = config.getHiresSliderDefault();
|
||||||
this.hiresSliderMin = config.getHiresSliderMin();
|
this.hiresSliderMin = config.getHiresSliderMin();
|
||||||
|
|
||||||
this.lowresSliderMax = config.getLowresSliderMax();
|
this.lowresSliderMax = config.getLowresSliderMax();
|
||||||
this.lowresSliderDefault = config.getLowresSliderDefault();
|
this.lowresSliderDefault = config.getLowresSliderDefault();
|
||||||
this.lowresSliderMin = config.getLowresSliderMin();
|
this.lowresSliderMin = config.getLowresSliderMin();
|
||||||
|
|
||||||
|
this.styles.clear();
|
||||||
|
this.scripts.clear();
|
||||||
|
|
||||||
|
addFrom(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addFrom(WebappConfig config) {
|
||||||
|
this.scripts.addAll(config.getScripts());
|
||||||
|
this.styles.addAll(config.getStyles());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package de.bluecolored.bluemap.common.api;
|
||||||
|
|
||||||
|
import de.bluecolored.bluemap.api.AssetStorage;
|
||||||
|
import de.bluecolored.bluemap.core.storage.Storage;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class AssetStorageImpl implements AssetStorage {
|
||||||
|
|
||||||
|
private static final String ASSET_PATH = "live/assets/";
|
||||||
|
|
||||||
|
private final Storage storage;
|
||||||
|
private final String mapId;
|
||||||
|
|
||||||
|
public AssetStorageImpl(Storage storage, String mapId) {
|
||||||
|
this.storage = storage;
|
||||||
|
this.mapId = mapId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream writeAsset(String name) throws IOException {
|
||||||
|
return storage.writeMeta(mapId, ASSET_PATH + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<InputStream> readAsset(String name) throws IOException {
|
||||||
|
return storage.readMeta(mapId, ASSET_PATH + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean assetExists(String name) throws IOException {
|
||||||
|
return storage.readMetaInfo(mapId, ASSET_PATH + name).isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAssetUrl(String name) {
|
||||||
|
return "maps/" + mapId + "/" + Storage.escapeMetaName(ASSET_PATH + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteAsset(String name) throws IOException {
|
||||||
|
storage.deleteMeta(mapId, ASSET_PATH + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.api;
|
package de.bluecolored.bluemap.common.api;
|
||||||
|
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
@ -46,6 +70,11 @@ public WebAppImpl getWebApp() {
|
|||||||
return new WebAppImpl(plugin);
|
return new WebAppImpl(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public de.bluecolored.bluemap.api.plugin.Plugin getPlugin() {
|
||||||
|
return new PluginImpl(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<BlueMapMap> getMaps() {
|
public Collection<BlueMapMap> getMaps() {
|
||||||
return plugin.getMaps().values().stream()
|
return plugin.getMaps().values().stream()
|
||||||
|
@ -1,8 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.api;
|
package de.bluecolored.bluemap.common.api;
|
||||||
|
|
||||||
import com.flowpowered.math.vector.Vector2i;
|
import com.flowpowered.math.vector.Vector2i;
|
||||||
import de.bluecolored.bluemap.api.BlueMapMap;
|
import de.bluecolored.bluemap.api.BlueMapMap;
|
||||||
import de.bluecolored.bluemap.api.BlueMapWorld;
|
import de.bluecolored.bluemap.api.BlueMapWorld;
|
||||||
|
import de.bluecolored.bluemap.api.AssetStorage;
|
||||||
import de.bluecolored.bluemap.api.markers.MarkerSet;
|
import de.bluecolored.bluemap.api.markers.MarkerSet;
|
||||||
import de.bluecolored.bluemap.common.plugin.Plugin;
|
import de.bluecolored.bluemap.common.plugin.Plugin;
|
||||||
import de.bluecolored.bluemap.common.rendermanager.MapUpdateTask;
|
import de.bluecolored.bluemap.common.rendermanager.MapUpdateTask;
|
||||||
@ -52,6 +77,11 @@ public BlueMapWorld getWorld() {
|
|||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AssetStorage getAssetStorage() {
|
||||||
|
return new AssetStorageImpl(unpack(map).getStorage(), getId());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, MarkerSet> getMarkerSets() {
|
public Map<String, MarkerSet> getMarkerSets() {
|
||||||
return unpack(map).getMarkerSets();
|
return unpack(map).getMarkerSets();
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.api;
|
package de.bluecolored.bluemap.common.api;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.api.BlueMapMap;
|
import de.bluecolored.bluemap.api.BlueMapMap;
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
package de.bluecolored.bluemap.common.api;
|
||||||
|
|
||||||
|
|
||||||
|
import de.bluecolored.bluemap.api.plugin.PlayerIconFactory;
|
||||||
|
import de.bluecolored.bluemap.api.plugin.SkinProvider;
|
||||||
|
import de.bluecolored.bluemap.common.plugin.Plugin;
|
||||||
|
|
||||||
|
public class PluginImpl implements de.bluecolored.bluemap.api.plugin.Plugin {
|
||||||
|
|
||||||
|
private final Plugin plugin;
|
||||||
|
|
||||||
|
public PluginImpl(Plugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkinProvider getSkinProvider() {
|
||||||
|
return plugin.getSkinUpdater().getSkinProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkinProvider(SkinProvider skinProvider) {
|
||||||
|
plugin.getSkinUpdater().setSkinProvider(skinProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlayerIconFactory getPlayerMarkerIconFactory() {
|
||||||
|
return plugin.getSkinUpdater().getPlayerMarkerIconFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPlayerMarkerIconFactory(PlayerIconFactory playerMarkerIconFactory) {
|
||||||
|
plugin.getSkinUpdater().setPlayerMarkerIconFactory(playerMarkerIconFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Plugin getPlugin() {
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.api;
|
package de.bluecolored.bluemap.common.api;
|
||||||
|
|
||||||
import com.flowpowered.math.vector.Vector2i;
|
import com.flowpowered.math.vector.Vector2i;
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.api;
|
package de.bluecolored.bluemap.common.api;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.api.WebApp;
|
import de.bluecolored.bluemap.api.WebApp;
|
||||||
@ -42,6 +66,16 @@ public boolean getPlayerVisibility(UUID player) {
|
|||||||
return !plugin.getPluginState().isPlayerHidden(player);
|
return !plugin.getPluginState().isPlayerHidden(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerScript(String url) {
|
||||||
|
plugin.getBlueMap().getWebFilesManager().getScripts().add(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerStyle(String url) {
|
||||||
|
plugin.getBlueMap().getWebFilesManager().getStyles().add(url);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String createImage(BufferedImage image, String path) throws IOException {
|
public String createImage(BufferedImage image, String path) throws IOException {
|
||||||
path = path.replaceAll("[^a-zA-Z0-9_.\\-/]", "_");
|
path = path.replaceAll("[^a-zA-Z0-9_.\\-/]", "_");
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.config;
|
package de.bluecolored.bluemap.common.config;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.api.debug.DebugDump;
|
import de.bluecolored.bluemap.api.debug.DebugDump;
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.config;
|
package de.bluecolored.bluemap.common.config;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.config;
|
package de.bluecolored.bluemap.common.config;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.api.debug.DebugDump;
|
import de.bluecolored.bluemap.api.debug.DebugDump;
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.config;
|
package de.bluecolored.bluemap.common.config;
|
||||||
|
|
||||||
import com.flowpowered.math.vector.Vector2i;
|
import com.flowpowered.math.vector.Vector2i;
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.config;
|
package de.bluecolored.bluemap.common.config;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.api.debug.DebugDump;
|
import de.bluecolored.bluemap.api.debug.DebugDump;
|
||||||
|
@ -1,10 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.config;
|
package de.bluecolored.bluemap.common.config;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.api.debug.DebugDump;
|
import de.bluecolored.bluemap.api.debug.DebugDump;
|
||||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal"})
|
@SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal"})
|
||||||
@DebugDump
|
@DebugDump
|
||||||
@ -35,6 +61,8 @@ public class WebappConfig {
|
|||||||
private int lowresSliderDefault = 2000;
|
private int lowresSliderDefault = 2000;
|
||||||
private int lowresSliderMin = 500;
|
private int lowresSliderMin = 500;
|
||||||
|
|
||||||
|
private Set<String> scripts = new HashSet<>();
|
||||||
|
private Set<String> styles = new HashSet<>();
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
@ -95,4 +123,12 @@ public int getLowresSliderMin() {
|
|||||||
return lowresSliderMin;
|
return lowresSliderMin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<String> getScripts() {
|
||||||
|
return scripts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getStyles() {
|
||||||
|
return styles;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.config;
|
package de.bluecolored.bluemap.common.config;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.api.debug.DebugDump;
|
import de.bluecolored.bluemap.api.debug.DebugDump;
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.config.typeserializer;
|
package de.bluecolored.bluemap.common.config.typeserializer;
|
||||||
|
|
||||||
import com.flowpowered.math.vector.Vector2i;
|
import com.flowpowered.math.vector.Vector2i;
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.live;
|
package de.bluecolored.bluemap.common.live;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.api.gson.MarkerGson;
|
import de.bluecolored.bluemap.api.gson.MarkerGson;
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.live;
|
package de.bluecolored.bluemap.common.live;
|
||||||
|
|
||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
@ -20,7 +44,7 @@ public class LivePlayersDataSupplier implements Supplier<String> {
|
|||||||
@Nullable private final String worldId;
|
@Nullable private final String worldId;
|
||||||
private final Predicate<UUID> playerFilter;
|
private final Predicate<UUID> playerFilter;
|
||||||
|
|
||||||
public LivePlayersDataSupplier(ServerInterface server, PluginConfig config, String worldId, Predicate<UUID> playerFilter) {
|
public LivePlayersDataSupplier(ServerInterface server, PluginConfig config, @Nullable String worldId, Predicate<UUID> playerFilter) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.worldId = worldId;
|
this.worldId = worldId;
|
||||||
@ -46,8 +70,10 @@ public String get() {
|
|||||||
if (config.isHideSneaking() && player.isSneaking()) continue;
|
if (config.isHideSneaking() && player.isSneaking()) continue;
|
||||||
if (config.getHiddenGameModes().contains(player.getGamemode().getId())) continue;
|
if (config.getHiddenGameModes().contains(player.getGamemode().getId())) continue;
|
||||||
if (config.isHideDifferentWorld() && !isCorrectWorld) continue;
|
if (config.isHideDifferentWorld() && !isCorrectWorld) continue;
|
||||||
if (player.getSkyLight() < config.getHideBelowSkyLight()) continue;
|
if (
|
||||||
if (player.getBlockLight() < config.getHideBelowBlockLight()) continue;
|
player.getSkyLight() < config.getHideBelowSkyLight() &&
|
||||||
|
player.getBlockLight() < config.getHideBelowBlockLight()
|
||||||
|
) continue;
|
||||||
if (!this.playerFilter.test(player.getUuid())) continue;
|
if (!this.playerFilter.test(player.getUuid())) continue;
|
||||||
|
|
||||||
json.beginObject();
|
json.beginObject();
|
||||||
|
@ -45,7 +45,6 @@
|
|||||||
import de.bluecolored.bluemap.core.logger.Logger;
|
import de.bluecolored.bluemap.core.logger.Logger;
|
||||||
import de.bluecolored.bluemap.core.map.BmMap;
|
import de.bluecolored.bluemap.core.map.BmMap;
|
||||||
import de.bluecolored.bluemap.core.metrics.Metrics;
|
import de.bluecolored.bluemap.core.metrics.Metrics;
|
||||||
import de.bluecolored.bluemap.core.storage.MetaType;
|
|
||||||
import de.bluecolored.bluemap.core.storage.Storage;
|
import de.bluecolored.bluemap.core.storage.Storage;
|
||||||
import de.bluecolored.bluemap.core.util.FileHelper;
|
import de.bluecolored.bluemap.core.util.FileHelper;
|
||||||
import de.bluecolored.bluemap.core.world.World;
|
import de.bluecolored.bluemap.core.world.World;
|
||||||
@ -223,19 +222,17 @@ public void load() throws IOException {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//update webapp and settings
|
//update webapp and settings
|
||||||
blueMap.createOrUpdateWebApp(false);
|
if (webappConfig.isEnabled())
|
||||||
|
blueMap.createOrUpdateWebApp(false);
|
||||||
|
|
||||||
//start skin updater
|
//start skin updater
|
||||||
if (pluginConfig.isLivePlayerMarkers()) {
|
if (pluginConfig.isLivePlayerMarkers()) {
|
||||||
this.skinUpdater = new PlayerSkinUpdater(
|
this.skinUpdater = new PlayerSkinUpdater(this);
|
||||||
webappConfig.getWebroot().resolve("assets").resolve("playerheads").toFile(),
|
|
||||||
webappConfig.getWebroot().resolve("assets").resolve("steve.png").toFile()
|
|
||||||
);
|
|
||||||
serverInterface.registerListener(skinUpdater);
|
serverInterface.registerListener(skinUpdater);
|
||||||
}
|
}
|
||||||
|
|
||||||
//init timer
|
//init timer
|
||||||
daemonTimer = new Timer("BlueMap-Plugin-Daemon-Timer", true);
|
daemonTimer = new Timer("BlueMap-Plugin-DaemonTimer", true);
|
||||||
|
|
||||||
//periodically save
|
//periodically save
|
||||||
TimerTask saveTask = new TimerTask() {
|
TimerTask saveTask = new TimerTask() {
|
||||||
@ -318,6 +315,9 @@ public void run() {
|
|||||||
this.api = new BlueMapAPIImpl(this);
|
this.api = new BlueMapAPIImpl(this);
|
||||||
this.api.register();
|
this.api.register();
|
||||||
|
|
||||||
|
//save webapp settings again (for api-registered scripts and styles)
|
||||||
|
this.getBlueMap().getWebFilesManager().saveSettings();
|
||||||
|
|
||||||
//done
|
//done
|
||||||
loaded = true;
|
loaded = true;
|
||||||
}
|
}
|
||||||
@ -438,7 +438,7 @@ public void savePlayerStates() {
|
|||||||
Predicate.not(pluginState::isPlayerHidden)
|
Predicate.not(pluginState::isPlayerHidden)
|
||||||
);
|
);
|
||||||
try (
|
try (
|
||||||
OutputStream out = map.getStorage().writeMeta(map.getId(), MetaType.PLAYERS);
|
OutputStream out = map.getStorage().writeMeta(map.getId(), BmMap.META_FILE_PLAYERS);
|
||||||
Writer writer = new OutputStreamWriter(out)
|
Writer writer = new OutputStreamWriter(out)
|
||||||
) {
|
) {
|
||||||
writer.write(dataSupplier.get());
|
writer.write(dataSupplier.get());
|
||||||
@ -555,6 +555,10 @@ public String getImplementationType() {
|
|||||||
return implementationType;
|
return implementationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PlayerSkinUpdater getSkinUpdater() {
|
||||||
|
return skinUpdater;
|
||||||
|
}
|
||||||
|
|
||||||
private void initFileWatcherTasks() {
|
private void initFileWatcherTasks() {
|
||||||
for (BmMap map : maps.values()) {
|
for (BmMap map : maps.values()) {
|
||||||
if (pluginState.getMapState(map).isUpdateEnabled()) {
|
if (pluginState.getMapState(map).isUpdateEnabled()) {
|
||||||
|
@ -114,9 +114,10 @@ public void init() {
|
|||||||
|
|
||||||
LiteralCommandNode<S> debugCommand =
|
LiteralCommandNode<S> debugCommand =
|
||||||
literal("debug")
|
literal("debug")
|
||||||
.requires(requirements("bluemap.debug"))
|
.requires(requirementsUnloaded("bluemap.debug"))
|
||||||
|
|
||||||
.then(literal("block")
|
.then(literal("block")
|
||||||
|
.requires(requirements("bluemap.debug"))
|
||||||
.executes(this::debugBlockCommand)
|
.executes(this::debugBlockCommand)
|
||||||
|
|
||||||
.then(argument("world", StringArgumentType.string()).suggests(new WorldSuggestionProvider<>(plugin))
|
.then(argument("world", StringArgumentType.string()).suggests(new WorldSuggestionProvider<>(plugin))
|
||||||
@ -126,12 +127,14 @@ public void init() {
|
|||||||
.executes(this::debugBlockCommand))))))
|
.executes(this::debugBlockCommand))))))
|
||||||
|
|
||||||
.then(literal("flush")
|
.then(literal("flush")
|
||||||
|
.requires(requirements("bluemap.debug"))
|
||||||
.executes(this::debugFlushCommand)
|
.executes(this::debugFlushCommand)
|
||||||
|
|
||||||
.then(argument("world", StringArgumentType.string()).suggests(new WorldSuggestionProvider<>(plugin))
|
.then(argument("world", StringArgumentType.string()).suggests(new WorldSuggestionProvider<>(plugin))
|
||||||
.executes(this::debugFlushCommand)))
|
.executes(this::debugFlushCommand)))
|
||||||
|
|
||||||
.then(literal("cache")
|
.then(literal("cache")
|
||||||
|
.requires(requirements("bluemap.debug"))
|
||||||
.executes(this::debugClearCacheCommand))
|
.executes(this::debugClearCacheCommand))
|
||||||
|
|
||||||
|
|
||||||
@ -397,7 +400,7 @@ public int reloadCommand(CommandContext<S> context) {
|
|||||||
|
|
||||||
source.sendMessage(Text.of(TextColor.RED, "There was an error reloading BlueMap! See the console for details!"));
|
source.sendMessage(Text.of(TextColor.RED, "There was an error reloading BlueMap! See the console for details!"));
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-ReloadCommand").start();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,7 +451,7 @@ public int debugFlushCommand(CommandContext<S> context) {
|
|||||||
source.sendMessage(Text.of(TextColor.RED, "There was an unexpected exception trying to save the world. Please check the console for more details..."));
|
source.sendMessage(Text.of(TextColor.RED, "There was an unexpected exception trying to save the world. Please check the console for more details..."));
|
||||||
Logger.global.logError("Unexpected exception trying to save the world!", ex);
|
Logger.global.logError("Unexpected exception trying to save the world!", ex);
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-DebugFlushCommand").start();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -502,7 +505,7 @@ public int debugBlockCommand(CommandContext<S> context) {
|
|||||||
Text.of(TextColor.GOLD, "Block at you: ", TextColor.WHITE, block),
|
Text.of(TextColor.GOLD, "Block at you: ", TextColor.WHITE, block),
|
||||||
Text.of(TextColor.GOLD, "Block below you: ", TextColor.WHITE, blockBelow)
|
Text.of(TextColor.GOLD, "Block below you: ", TextColor.WHITE, blockBelow)
|
||||||
));
|
));
|
||||||
}).start();
|
}, "BlueMap-Plugin-DebugBlockCommand").start();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -534,7 +537,7 @@ public int stopCommand(CommandContext<S> context) {
|
|||||||
source.sendMessage(Text.of(TextColor.GREEN, "Render-Threads stopped!"));
|
source.sendMessage(Text.of(TextColor.GREEN, "Render-Threads stopped!"));
|
||||||
|
|
||||||
plugin.save();
|
plugin.save();
|
||||||
}).start();
|
}, "BlueMap-Plugin-StopCommand").start();
|
||||||
} else {
|
} else {
|
||||||
source.sendMessage(Text.of(TextColor.RED, "Render-Threads are already stopped!"));
|
source.sendMessage(Text.of(TextColor.RED, "Render-Threads are already stopped!"));
|
||||||
return 0;
|
return 0;
|
||||||
@ -554,7 +557,7 @@ public int startCommand(CommandContext<S> context) {
|
|||||||
source.sendMessage(Text.of(TextColor.GREEN, "Render-Threads started!"));
|
source.sendMessage(Text.of(TextColor.GREEN, "Render-Threads started!"));
|
||||||
|
|
||||||
plugin.save();
|
plugin.save();
|
||||||
}).start();
|
}, "BlueMap-Plugin-StartCommand").start();
|
||||||
} else {
|
} else {
|
||||||
source.sendMessage(Text.of(TextColor.RED, "Render-Threads are already running!"));
|
source.sendMessage(Text.of(TextColor.RED, "Render-Threads are already running!"));
|
||||||
return 0;
|
return 0;
|
||||||
@ -595,7 +598,7 @@ public int freezeCommand(CommandContext<S> context) {
|
|||||||
source.sendMessage(Text.of(TextColor.GRAY, "Any currently scheduled updates for this map have been cancelled."));
|
source.sendMessage(Text.of(TextColor.GRAY, "Any currently scheduled updates for this map have been cancelled."));
|
||||||
|
|
||||||
plugin.save();
|
plugin.save();
|
||||||
}).start();
|
}, "BlueMap-Plugin-FreezeCommand").start();
|
||||||
} else {
|
} else {
|
||||||
source.sendMessage(Text.of(TextColor.RED, "This map is already frozen!"));
|
source.sendMessage(Text.of(TextColor.RED, "This map is already frozen!"));
|
||||||
return 0;
|
return 0;
|
||||||
@ -627,7 +630,7 @@ public int unfreezeCommand(CommandContext<S> context) {
|
|||||||
source.sendMessage(Text.of(TextColor.GREEN, "Map ", TextColor.WHITE, mapString, TextColor.GREEN, " is no longer frozen and will be automatically updated!"));
|
source.sendMessage(Text.of(TextColor.GREEN, "Map ", TextColor.WHITE, mapString, TextColor.GREEN, " is no longer frozen and will be automatically updated!"));
|
||||||
|
|
||||||
plugin.save();
|
plugin.save();
|
||||||
}).start();
|
}, "BlueMap-Plugin-UnfreezeCommand").start();
|
||||||
} else {
|
} else {
|
||||||
source.sendMessage(Text.of(TextColor.RED, "This map is not frozen!"));
|
source.sendMessage(Text.of(TextColor.RED, "This map is not frozen!"));
|
||||||
return 0;
|
return 0;
|
||||||
@ -737,7 +740,7 @@ public int updateCommand(CommandContext<S> context, boolean force) {
|
|||||||
source.sendMessage(Text.of(TextColor.RED, "There was an unexpected exception trying to save the world. Please check the console for more details..."));
|
source.sendMessage(Text.of(TextColor.RED, "There was an unexpected exception trying to save the world. Please check the console for more details..."));
|
||||||
Logger.global.logError("Unexpected exception trying to save the world!", ex);
|
Logger.global.logError("Unexpected exception trying to save the world!", ex);
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-UpdateCommand").start();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -810,7 +813,7 @@ public int purgeCommand(CommandContext<S> context) {
|
|||||||
source.sendMessage(Text.of(TextColor.RED, "There was an error trying to purge '" + map.getId() + "', see console for details."));
|
source.sendMessage(Text.of(TextColor.RED, "There was an error trying to purge '" + map.getId() + "', see console for details."));
|
||||||
Logger.global.logError("Failed to purge map '" + map.getId() + "'!", e);
|
Logger.global.logError("Failed to purge map '" + map.getId() + "'!", e);
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-PurgeCommand").start();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
package de.bluecolored.bluemap.common.plugin.skins;
|
||||||
|
|
||||||
|
import de.bluecolored.bluemap.api.plugin.PlayerIconFactory;
|
||||||
|
import de.bluecolored.bluemap.core.logger.Logger;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class DefaultPlayerIconFactory implements PlayerIconFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BufferedImage apply(UUID uuid, BufferedImage in) {
|
||||||
|
BufferedImage head;
|
||||||
|
|
||||||
|
BufferedImage layer1 = in.getSubimage(8, 8, 8, 8);
|
||||||
|
BufferedImage layer2 = in.getSubimage(40, 8, 8, 8);
|
||||||
|
|
||||||
|
try {
|
||||||
|
head = new BufferedImage(48, 48, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D g = head.createGraphics();
|
||||||
|
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
||||||
|
g.drawImage(layer1, 4, 4, 40, 40, null);
|
||||||
|
g.drawImage(layer2, 0, 0, 48, 48, null);
|
||||||
|
} catch (Throwable t) { // There might be problems with headless servers when loading the graphics class, so we catch every exception and error on purpose here
|
||||||
|
Logger.global.noFloodWarning("headless-graphics-fail",
|
||||||
|
"Could not access Graphics2D to render player-skin texture. Try adding '-Djava.awt.headless=true' to your startup flags or ignore this warning.");
|
||||||
|
head = new BufferedImage(8, 8, in.getType());
|
||||||
|
layer1.copyData(head.getRaster());
|
||||||
|
}
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package de.bluecolored.bluemap.common.plugin.skins;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import de.bluecolored.bluemap.api.plugin.SkinProvider;
|
||||||
|
import de.bluecolored.bluemap.core.logger.Logger;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MojangSkinProvider implements SkinProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<BufferedImage> load(UUID playerUUID) throws IOException {
|
||||||
|
try (Reader reader = requestProfileJson(playerUUID)) {
|
||||||
|
JsonParser parser = new JsonParser();
|
||||||
|
String textureInfoJson = readTextureInfoJson(parser.parse(reader));
|
||||||
|
String textureUrl = readTextureUrl(parser.parse(textureInfoJson));
|
||||||
|
return Optional.of(ImageIO.read(new URL(textureUrl)));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Logger.global.logDebug("Failed to load skin from mojang for player: '" + playerUUID + "' - " + ex);
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Reader requestProfileJson(UUID playerUUID) throws IOException {
|
||||||
|
URL url = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + playerUUID);
|
||||||
|
return new InputStreamReader(url.openStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readTextureInfoJson(JsonElement json) throws IOException {
|
||||||
|
try {
|
||||||
|
JsonArray properties = json.getAsJsonObject().getAsJsonArray("properties");
|
||||||
|
|
||||||
|
for (JsonElement element : properties) {
|
||||||
|
if (element.getAsJsonObject().get("name").getAsString().equals("textures")) {
|
||||||
|
return new String(Base64.getDecoder().decode(element.getAsJsonObject().get("value").getAsString().getBytes()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IOException("No texture info found!");
|
||||||
|
} catch (NullPointerException | IllegalStateException | ClassCastException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readTextureUrl(JsonElement json) throws IOException {
|
||||||
|
try {
|
||||||
|
return json.getAsJsonObject()
|
||||||
|
.getAsJsonObject("textures")
|
||||||
|
.getAsJsonObject("SKIN")
|
||||||
|
.get("url").getAsString();
|
||||||
|
} catch (NullPointerException | IllegalStateException | ClassCastException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,159 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
package de.bluecolored.bluemap.common.plugin.skins;
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import de.bluecolored.bluemap.api.debug.DebugDump;
|
|
||||||
import de.bluecolored.bluemap.core.logger.Logger;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.*;
|
|
||||||
|
|
||||||
@DebugDump
|
|
||||||
public class PlayerSkin {
|
|
||||||
|
|
||||||
private final UUID uuid;
|
|
||||||
private long lastUpdate;
|
|
||||||
|
|
||||||
public PlayerSkin(UUID uuid) {
|
|
||||||
this.uuid = uuid;
|
|
||||||
this.lastUpdate = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(File storageFolder, File fallback) {
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
if (lastUpdate > 0 && lastUpdate + 600000 > now) return; // only update if skin is older than 10 minutes
|
|
||||||
|
|
||||||
lastUpdate = now;
|
|
||||||
|
|
||||||
new Thread(() -> {
|
|
||||||
BufferedImage head = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Future<BufferedImage> futureSkin = loadSkin();
|
|
||||||
BufferedImage skin = futureSkin.get(10, TimeUnit.SECONDS);
|
|
||||||
head = createHead(skin);
|
|
||||||
} catch (ExecutionException | TimeoutException e) {
|
|
||||||
Logger.global.logDebug("Failed to load player-skin from mojang-servers: " + e);
|
|
||||||
} catch (InterruptedException ignore) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (head == null) head = ImageIO.read(fallback);
|
|
||||||
ImageIO.write(head, "png", new File(storageFolder, uuid.toString() + ".png"));
|
|
||||||
} catch (IOException e) {
|
|
||||||
Logger.global.logError("Failed to write player-head image!", e);
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BufferedImage createHead(BufferedImage skinTexture) {
|
|
||||||
BufferedImage head;
|
|
||||||
|
|
||||||
BufferedImage layer1 = skinTexture.getSubimage(8, 8, 8, 8);
|
|
||||||
BufferedImage layer2 = skinTexture.getSubimage(40, 8, 8, 8);
|
|
||||||
|
|
||||||
try {
|
|
||||||
head = new BufferedImage(48, 48, BufferedImage.TYPE_INT_ARGB);
|
|
||||||
Graphics2D g = head.createGraphics();
|
|
||||||
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
|
||||||
g.drawImage(layer1, 4, 4, 40, 40, null);
|
|
||||||
g.drawImage(layer2, 0, 0, 48, 48, null);
|
|
||||||
} catch (Throwable t) { // There might be problems with headless servers when loading the graphics class, so we catch every exception and error on purpose here
|
|
||||||
Logger.global.noFloodWarning("headless-graphics-fail",
|
|
||||||
"Could not access Graphics2D to render player-skin texture. Try adding '-Djava.awt.headless=true' to your startup flags or ignore this warning.");
|
|
||||||
head = new BufferedImage(8, 8, skinTexture.getType());
|
|
||||||
layer1.copyData(head.getRaster());
|
|
||||||
}
|
|
||||||
|
|
||||||
return head;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<BufferedImage> loadSkin() {
|
|
||||||
CompletableFuture<BufferedImage> image = new CompletableFuture<>();
|
|
||||||
|
|
||||||
new Thread(() -> {
|
|
||||||
try {
|
|
||||||
JsonParser parser = new JsonParser();
|
|
||||||
try (Reader reader = requestProfileJson()) {
|
|
||||||
String textureInfoJson = readTextureInfoJson(parser.parse(reader));
|
|
||||||
String textureUrl = readTextureUrl(parser.parse(textureInfoJson));
|
|
||||||
image.complete(ImageIO.read(new URL(textureUrl)));
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
image.completeExceptionally(e);
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Reader requestProfileJson() throws IOException {
|
|
||||||
URL url = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + this.uuid);
|
|
||||||
return new InputStreamReader(url.openStream());
|
|
||||||
}
|
|
||||||
|
|
||||||
private String readTextureInfoJson(JsonElement json) throws IOException {
|
|
||||||
try {
|
|
||||||
JsonArray properties = json.getAsJsonObject().getAsJsonArray("properties");
|
|
||||||
|
|
||||||
for (JsonElement element : properties) {
|
|
||||||
if (element.getAsJsonObject().get("name").getAsString().equals("textures")) {
|
|
||||||
return new String(Base64.getDecoder().decode(element.getAsJsonObject().get("value").getAsString().getBytes()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IOException("No texture info found!");
|
|
||||||
} catch (NullPointerException | IllegalStateException | ClassCastException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private String readTextureUrl(JsonElement json) throws IOException {
|
|
||||||
try {
|
|
||||||
return json.getAsJsonObject()
|
|
||||||
.getAsJsonObject("textures")
|
|
||||||
.getAsJsonObject("SKIN")
|
|
||||||
.get("url").getAsString();
|
|
||||||
} catch (NullPointerException | IllegalStateException | ClassCastException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -24,62 +24,105 @@
|
|||||||
*/
|
*/
|
||||||
package de.bluecolored.bluemap.common.plugin.skins;
|
package de.bluecolored.bluemap.common.plugin.skins;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.common.serverinterface.ServerEventListener;
|
|
||||||
import de.bluecolored.bluemap.api.debug.DebugDump;
|
import de.bluecolored.bluemap.api.debug.DebugDump;
|
||||||
import org.apache.commons.io.FileUtils;
|
import de.bluecolored.bluemap.api.plugin.PlayerIconFactory;
|
||||||
|
import de.bluecolored.bluemap.api.plugin.SkinProvider;
|
||||||
|
import de.bluecolored.bluemap.common.plugin.Plugin;
|
||||||
|
import de.bluecolored.bluemap.common.serverinterface.ServerEventListener;
|
||||||
|
import de.bluecolored.bluemap.core.BlueMap;
|
||||||
|
import de.bluecolored.bluemap.core.logger.Logger;
|
||||||
|
import de.bluecolored.bluemap.core.map.BmMap;
|
||||||
|
|
||||||
import java.io.File;
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.CompletionException;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@DebugDump
|
@DebugDump
|
||||||
public class PlayerSkinUpdater implements ServerEventListener {
|
public class PlayerSkinUpdater implements ServerEventListener {
|
||||||
|
|
||||||
private File storageFolder;
|
private final Plugin plugin;
|
||||||
private File defaultSkin;
|
private final Map<UUID, Long> skinUpdates;
|
||||||
|
|
||||||
private final Map<UUID, PlayerSkin> skins;
|
private SkinProvider skinProvider;
|
||||||
|
private PlayerIconFactory playerMarkerIconFactory;
|
||||||
|
|
||||||
public PlayerSkinUpdater(File storageFolder, File defaultSkin) throws IOException {
|
public PlayerSkinUpdater(Plugin plugin) {
|
||||||
this.storageFolder = storageFolder;
|
this.plugin = plugin;
|
||||||
this.defaultSkin = defaultSkin;
|
this.skinUpdates = new ConcurrentHashMap<>();
|
||||||
this.skins = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
FileUtils.forceMkdir(this.storageFolder);
|
skinProvider = new MojangSkinProvider();
|
||||||
|
playerMarkerIconFactory = new DefaultPlayerIconFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateSkin(UUID playerUuid) {
|
public CompletableFuture<Void> updateSkin(final UUID playerUuid) {
|
||||||
PlayerSkin skin = skins.get(playerUuid);
|
|
||||||
|
|
||||||
if (skin == null) {
|
// only update if last update was longer then an hour ago
|
||||||
skin = new PlayerSkin(playerUuid);
|
long lastUpdate = skinUpdates.getOrDefault(playerUuid, 0L);
|
||||||
skins.put(playerUuid, skin);
|
long now = System.currentTimeMillis();
|
||||||
}
|
if (now - lastUpdate < TimeUnit.HOURS.toMillis(1)) return CompletableFuture.completedFuture(null);
|
||||||
|
skinUpdates.put(playerUuid, now);
|
||||||
|
|
||||||
skin.update(storageFolder, defaultSkin);
|
// do the update async
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
try {
|
||||||
|
return skinProvider.load(playerUuid);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new CompletionException("The skin provider threw an exception while loading the skin for UUID: '" + playerUuid + "'!", e);
|
||||||
|
}
|
||||||
|
}, BlueMap.THREAD_POOL).thenAcceptAsync(skin -> {
|
||||||
|
if (skin.isEmpty()) {
|
||||||
|
Logger.global.logDebug("No player-skin provided for UUID: " + playerUuid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, BmMap> maps = plugin.getMaps();
|
||||||
|
if (maps == null) {
|
||||||
|
Logger.global.logDebug("Could not update skin, since the plugin seems not to be ready.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedImage playerHead = playerMarkerIconFactory.apply(playerUuid, skin.get());
|
||||||
|
|
||||||
|
for (BmMap map : maps.values()) {
|
||||||
|
try (OutputStream out = map.getStorage().writeMeta(map.getId(), "live/assets/playerheads/" + playerUuid + ".png")) {
|
||||||
|
ImageIO.write(playerHead, "png", out);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Logger.global.logError("Failed to write player skin to storage: " + playerUuid, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, BlueMap.THREAD_POOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerJoin(UUID playerUuid) {
|
public void onPlayerJoin(UUID playerUuid) {
|
||||||
updateSkin(playerUuid);
|
updateSkin(playerUuid).exceptionally(ex -> {
|
||||||
|
Logger.global.logError("Failed to update player skin: " + playerUuid, ex);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getStorageFolder() {
|
public SkinProvider getSkinProvider() {
|
||||||
return storageFolder;
|
return skinProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStorageFolder(File storageFolder) {
|
public void setSkinProvider(SkinProvider skinProvider) {
|
||||||
this.storageFolder = storageFolder;
|
this.skinProvider = Objects.requireNonNull(skinProvider, "skinProvider can not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getDefaultSkin() {
|
public PlayerIconFactory getPlayerMarkerIconFactory() {
|
||||||
return defaultSkin;
|
return playerMarkerIconFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultSkin(File defaultSkin) {
|
public void setPlayerMarkerIconFactory(PlayerIconFactory playerMarkerIconFactory) {
|
||||||
this.defaultSkin = defaultSkin;
|
this.playerMarkerIconFactory = Objects.requireNonNull(playerMarkerIconFactory, "playerMarkerIconFactory can not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.rendermanager;
|
package de.bluecolored.bluemap.common.rendermanager;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.core.map.BmMap;
|
import de.bluecolored.bluemap.core.map.BmMap;
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.serverinterface;
|
package de.bluecolored.bluemap.common.serverinterface;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.serverinterface;
|
package de.bluecolored.bluemap.common.serverinterface;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.api.debug.DebugDump;
|
import de.bluecolored.bluemap.api.debug.DebugDump;
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.web;
|
package de.bluecolored.bluemap.common.web;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.common.webserver.HttpRequest;
|
import de.bluecolored.bluemap.common.webserver.HttpRequest;
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.web;
|
package de.bluecolored.bluemap.common.web;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.common.webserver.HttpRequest;
|
import de.bluecolored.bluemap.common.webserver.HttpRequest;
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
package de.bluecolored.bluemap.common.web;
|
package de.bluecolored.bluemap.common.web;
|
||||||
|
|
||||||
import com.flowpowered.math.vector.Vector2i;
|
import com.flowpowered.math.vector.Vector2i;
|
||||||
|
import de.bluecolored.bluemap.api.ContentTypeRegistry;
|
||||||
import de.bluecolored.bluemap.common.webserver.HttpRequest;
|
import de.bluecolored.bluemap.common.webserver.HttpRequest;
|
||||||
import de.bluecolored.bluemap.common.webserver.HttpRequestHandler;
|
import de.bluecolored.bluemap.common.webserver.HttpRequestHandler;
|
||||||
import de.bluecolored.bluemap.common.webserver.HttpResponse;
|
import de.bluecolored.bluemap.common.webserver.HttpResponse;
|
||||||
@ -35,10 +36,7 @@
|
|||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.*;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@ -77,13 +75,13 @@ public HttpResponse handle(HttpRequest request) {
|
|||||||
int lod = Integer.parseInt(tileMatcher.group(1));
|
int lod = Integer.parseInt(tileMatcher.group(1));
|
||||||
int x = Integer.parseInt(tileMatcher.group(2).replace("/", ""));
|
int x = Integer.parseInt(tileMatcher.group(2).replace("/", ""));
|
||||||
int z = Integer.parseInt(tileMatcher.group(3).replace("/", ""));
|
int z = Integer.parseInt(tileMatcher.group(3).replace("/", ""));
|
||||||
Optional<TileData> optTileData = mapStorage.readMapTileData(mapId, lod, new Vector2i(x, z));
|
Optional<TileInfo> optTileInfo = mapStorage.readMapTileInfo(mapId, lod, new Vector2i(x, z));
|
||||||
|
|
||||||
if (optTileData.isPresent()) {
|
if (optTileInfo.isPresent()) {
|
||||||
TileData tileData = optTileData.get();
|
TileInfo tileInfo = optTileInfo.get();
|
||||||
|
|
||||||
// check e-tag
|
// check e-tag
|
||||||
String eTag = calculateETag(path, tileData);
|
String eTag = calculateETag(path, tileInfo);
|
||||||
Set<String> etagStringSet = request.getHeader("If-None-Match");
|
Set<String> etagStringSet = request.getHeader("If-None-Match");
|
||||||
if (!etagStringSet.isEmpty()){
|
if (!etagStringSet.isEmpty()){
|
||||||
if(etagStringSet.iterator().next().equals(eTag)) {
|
if(etagStringSet.iterator().next().equals(eTag)) {
|
||||||
@ -92,7 +90,7 @@ public HttpResponse handle(HttpRequest request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check modified-since
|
// check modified-since
|
||||||
long lastModified = tileData.getLastModified();
|
long lastModified = tileInfo.getLastModified();
|
||||||
Set<String> modStringSet = request.getHeader("If-Modified-Since");
|
Set<String> modStringSet = request.getHeader("If-Modified-Since");
|
||||||
if (!modStringSet.isEmpty()){
|
if (!modStringSet.isEmpty()){
|
||||||
try {
|
try {
|
||||||
@ -103,7 +101,7 @@ public HttpResponse handle(HttpRequest request) {
|
|||||||
} catch (IllegalArgumentException ignored){}
|
} catch (IllegalArgumentException ignored){}
|
||||||
}
|
}
|
||||||
|
|
||||||
CompressedInputStream compressedIn = tileData.readMapTile();
|
CompressedInputStream compressedIn = tileInfo.readMapTile();
|
||||||
HttpResponse response = new HttpResponse(HttpStatusCode.OK);
|
HttpResponse response = new HttpResponse(HttpStatusCode.OK);
|
||||||
response.addHeader("ETag", eTag);
|
response.addHeader("ETag", eTag);
|
||||||
if (lastModified > 0)
|
if (lastModified > 0)
|
||||||
@ -118,23 +116,13 @@ public HttpResponse handle(HttpRequest request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// provide meta-data
|
// provide meta-data
|
||||||
MetaType metaType = null;
|
Optional<InputStream> optIn = mapStorage.readMeta(mapId, path);
|
||||||
for (MetaType mt : MetaType.values()) {
|
if (optIn.isPresent()) {
|
||||||
if (mt.getFilePath().equals(path)) {
|
CompressedInputStream compressedIn = new CompressedInputStream(optIn.get(), Compression.NONE);
|
||||||
metaType = mt;
|
HttpResponse response = new HttpResponse(HttpStatusCode.OK);
|
||||||
break;
|
response.addHeader("Content-Type", ContentTypeRegistry.fromFileName(path));
|
||||||
}
|
writeToResponse(compressedIn, response, request);
|
||||||
}
|
return response;
|
||||||
|
|
||||||
if (metaType != null) {
|
|
||||||
Optional<CompressedInputStream> optIn = mapStorage.readMeta(mapId, metaType);
|
|
||||||
if (optIn.isPresent()) {
|
|
||||||
CompressedInputStream compressedIn = optIn.get();
|
|
||||||
HttpResponse response = new HttpResponse(HttpStatusCode.OK);
|
|
||||||
response.addHeader("Content-Type", metaType.getContentType());
|
|
||||||
writeToResponse(compressedIn, response, request);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (NumberFormatException | NoSuchElementException ignore){
|
} catch (NumberFormatException | NoSuchElementException ignore){
|
||||||
@ -148,8 +136,8 @@ public HttpResponse handle(HttpRequest request) {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String calculateETag(String path, TileData tileData) {
|
private String calculateETag(String path, TileInfo tileInfo) {
|
||||||
return Long.toHexString(tileData.getSize()) + Integer.toHexString(path.hashCode()) + Long.toHexString(tileData.getLastModified());
|
return Long.toHexString(tileInfo.getSize()) + Integer.toHexString(path.hashCode()) + Long.toHexString(tileInfo.getLastModified());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeToResponse(CompressedInputStream data, HttpResponse response, HttpRequest request) throws IOException {
|
private void writeToResponse(CompressedInputStream data, HttpResponse response, HttpRequest request) throws IOException {
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.web;
|
package de.bluecolored.bluemap.common.web;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.common.webserver.*;
|
import de.bluecolored.bluemap.common.webserver.*;
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
package de.bluecolored.bluemap.common.webserver;
|
package de.bluecolored.bluemap.common.webserver;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -59,7 +59,7 @@ remove-caves-below-y: ${remove-caves-below-y}
|
|||||||
# Defaults to 10000 (disabled)
|
# Defaults to 10000 (disabled)
|
||||||
cave-detection-ocean-floor: -5
|
cave-detection-ocean-floor: -5
|
||||||
|
|
||||||
# With this value set to true, BlueMap uses the block-light value instead of the sky-light value to "detect caves".
|
# With this value set to true, BlueMap also uses the block-light value (additionally to the sky-light) to "detect caves".
|
||||||
# (See: remove-caves-below-y)
|
# (See: remove-caves-below-y)
|
||||||
# Changing this value requires a re-render of the map.
|
# Changing this value requires a re-render of the map.
|
||||||
# Default is false
|
# Default is false
|
||||||
|
@ -10,7 +10,7 @@ live-player-markers: true
|
|||||||
|
|
||||||
# A list of gamemodes that will prevent a player from appearing on the map.
|
# A list of gamemodes that will prevent a player from appearing on the map.
|
||||||
# Possible values are: survival, creative, spectator, adventure
|
# Possible values are: survival, creative, spectator, adventure
|
||||||
hidden-gamemodes: [
|
hidden-game-modes: [
|
||||||
"spectator"
|
"spectator"
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -28,7 +28,10 @@ hide-invisible: true
|
|||||||
hide-sneaking: false
|
hide-sneaking: false
|
||||||
|
|
||||||
# Hides the player if they are in a sky or block-light level below the given number.
|
# Hides the player if they are in a sky or block-light level below the given number.
|
||||||
# E.g. if you set this to 1, then the player will be hidden on the map if they are in absolute darkness
|
# BOTH values have to be below the threshold for the player to be hidden!
|
||||||
|
# E.g. if you set both to 1, then the player will be hidden on the map if they are in absolute darkness
|
||||||
|
# Or, if you want players only be visible on the surface you set the sky-threshold to something between 1 and 15
|
||||||
|
# and the block-threshold to 16
|
||||||
# Default is 0 (don't hide the player)
|
# Default is 0 (don't hide the player)
|
||||||
hide-below-sky-light: 0
|
hide-below-sky-light: 0
|
||||||
hide-below-block-light: 0
|
hide-below-block-light: 0
|
||||||
|
@ -53,3 +53,15 @@ hires-slider-min: 0
|
|||||||
lowres-slider-max: 7000
|
lowres-slider-max: 7000
|
||||||
lowres-slider-default: 2000
|
lowres-slider-default: 2000
|
||||||
lowres-slider-min: 500
|
lowres-slider-min: 500
|
||||||
|
|
||||||
|
# Here you can add URLs to custom scripts (js) so they will be loaded by the webapp
|
||||||
|
# You can place them somewhere in bluemap's webroot and add the (relative) link here
|
||||||
|
scripts: [
|
||||||
|
#"js/my-custom-script.js"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Here you can add URLs to custom styles (css) so they will be loaded by the webapp
|
||||||
|
# You can place them somewhere in bluemap's webroot and add the (relative) link here
|
||||||
|
styles: [
|
||||||
|
#"css/my-custom-style.css"
|
||||||
|
]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import java.util.concurrent.TimeoutException
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
java
|
java
|
||||||
@ -12,7 +13,11 @@ fun String.runCommand(): String = ProcessBuilder(split("\\s(?=(?:[^'\"`]*(['\"`]
|
|||||||
.redirectOutput(ProcessBuilder.Redirect.PIPE)
|
.redirectOutput(ProcessBuilder.Redirect.PIPE)
|
||||||
.redirectError(ProcessBuilder.Redirect.PIPE)
|
.redirectError(ProcessBuilder.Redirect.PIPE)
|
||||||
.start()
|
.start()
|
||||||
.apply { waitFor(60, TimeUnit.SECONDS) }
|
.apply {
|
||||||
|
if (!waitFor(10, TimeUnit.SECONDS)) {
|
||||||
|
throw TimeoutException("Failed to execute command: '" + this@runCommand + "'")
|
||||||
|
}
|
||||||
|
}
|
||||||
.run {
|
.run {
|
||||||
val error = errorStream.bufferedReader().readText().trim()
|
val error = errorStream.bufferedReader().readText().trim()
|
||||||
if (error.isNotEmpty()) {
|
if (error.isNotEmpty()) {
|
||||||
|
@ -34,8 +34,6 @@
|
|||||||
import de.bluecolored.bluemap.core.map.lowres.LowresTileManager;
|
import de.bluecolored.bluemap.core.map.lowres.LowresTileManager;
|
||||||
import de.bluecolored.bluemap.core.resources.adapter.ResourcesGson;
|
import de.bluecolored.bluemap.core.resources.adapter.ResourcesGson;
|
||||||
import de.bluecolored.bluemap.core.resources.resourcepack.ResourcePack;
|
import de.bluecolored.bluemap.core.resources.resourcepack.ResourcePack;
|
||||||
import de.bluecolored.bluemap.core.storage.CompressedInputStream;
|
|
||||||
import de.bluecolored.bluemap.core.storage.MetaType;
|
|
||||||
import de.bluecolored.bluemap.core.storage.Storage;
|
import de.bluecolored.bluemap.core.storage.Storage;
|
||||||
import de.bluecolored.bluemap.core.world.Grid;
|
import de.bluecolored.bluemap.core.world.Grid;
|
||||||
import de.bluecolored.bluemap.core.world.World;
|
import de.bluecolored.bluemap.core.world.World;
|
||||||
@ -50,6 +48,12 @@
|
|||||||
@DebugDump
|
@DebugDump
|
||||||
public class BmMap {
|
public class BmMap {
|
||||||
|
|
||||||
|
public static final String META_FILE_SETTINGS = "settings.json";
|
||||||
|
public static final String META_FILE_TEXTURES = "textures.json";
|
||||||
|
public static final String META_FILE_RENDER_STATE = ".rstate";
|
||||||
|
public static final String META_FILE_MARKERS = "live/players.json";
|
||||||
|
public static final String META_FILE_PLAYERS = "live/players.json";
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final String worldId;
|
private final String worldId;
|
||||||
@ -134,7 +138,7 @@ public synchronized void save() {
|
|||||||
|
|
||||||
// only save texture gallery if not present in storage
|
// only save texture gallery if not present in storage
|
||||||
try {
|
try {
|
||||||
if (storage.readMeta(id, MetaType.TEXTURES).isEmpty())
|
if (storage.readMeta(id, META_FILE_TEXTURES).isEmpty())
|
||||||
saveTextureGallery();
|
saveTextureGallery();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Logger.global.logError("Failed to read texture gallery", e);
|
Logger.global.logError("Failed to read texture gallery", e);
|
||||||
@ -142,9 +146,9 @@ public synchronized void save() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadRenderState() throws IOException {
|
private void loadRenderState() throws IOException {
|
||||||
Optional<CompressedInputStream> rstateData = storage.readMeta(id, MetaType.RENDER_STATE);
|
Optional<InputStream> rstateData = storage.readMeta(id, META_FILE_RENDER_STATE);
|
||||||
if (rstateData.isPresent()) {
|
if (rstateData.isPresent()) {
|
||||||
try (InputStream in = rstateData.get().decompress()){
|
try (InputStream in = rstateData.get()){
|
||||||
this.renderState.load(in);
|
this.renderState.load(in);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.global.logWarning("Failed to load render-state for map '" + getId() + "': " + ex);
|
Logger.global.logWarning("Failed to load render-state for map '" + getId() + "': " + ex);
|
||||||
@ -153,7 +157,7 @@ private void loadRenderState() throws IOException {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void saveRenderState() {
|
public synchronized void saveRenderState() {
|
||||||
try (OutputStream out = storage.writeMeta(id, MetaType.RENDER_STATE)) {
|
try (OutputStream out = storage.writeMeta(id, META_FILE_RENDER_STATE)) {
|
||||||
this.renderState.save(out);
|
this.renderState.save(out);
|
||||||
} catch (IOException ex){
|
} catch (IOException ex){
|
||||||
Logger.global.logError("Failed to save render-state for map: '" + this.id + "'!", ex);
|
Logger.global.logError("Failed to save render-state for map: '" + this.id + "'!", ex);
|
||||||
@ -162,9 +166,9 @@ public synchronized void saveRenderState() {
|
|||||||
|
|
||||||
private TextureGallery loadTextureGallery() throws IOException {
|
private TextureGallery loadTextureGallery() throws IOException {
|
||||||
TextureGallery gallery = null;
|
TextureGallery gallery = null;
|
||||||
Optional<CompressedInputStream> texturesData = storage.readMeta(id, MetaType.TEXTURES);
|
Optional<InputStream> texturesData = storage.readMeta(id, META_FILE_TEXTURES);
|
||||||
if (texturesData.isPresent()) {
|
if (texturesData.isPresent()) {
|
||||||
try (InputStream in = texturesData.get().decompress()){
|
try (InputStream in = texturesData.get()){
|
||||||
gallery = TextureGallery.readTexturesFile(in);
|
gallery = TextureGallery.readTexturesFile(in);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.global.logError("Failed to load textures for map '" + getId() + "'!", ex);
|
Logger.global.logError("Failed to load textures for map '" + getId() + "'!", ex);
|
||||||
@ -174,7 +178,7 @@ private TextureGallery loadTextureGallery() throws IOException {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void saveTextureGallery() {
|
private void saveTextureGallery() {
|
||||||
try (OutputStream out = storage.writeMeta(id, MetaType.TEXTURES)) {
|
try (OutputStream out = storage.writeMeta(id, META_FILE_TEXTURES)) {
|
||||||
this.textureGallery.writeTexturesFile(this.resourcePack, out);
|
this.textureGallery.writeTexturesFile(this.resourcePack, out);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Logger.global.logError("Failed to save textures for map '" + getId() + "'!", ex);
|
Logger.global.logError("Failed to save textures for map '" + getId() + "'!", ex);
|
||||||
@ -188,7 +192,7 @@ public synchronized void resetTextureGallery() {
|
|||||||
|
|
||||||
private void saveMapSettings() {
|
private void saveMapSettings() {
|
||||||
try (
|
try (
|
||||||
OutputStream out = storage.writeMeta(id, MetaType.SETTINGS);
|
OutputStream out = storage.writeMeta(id, META_FILE_SETTINGS);
|
||||||
Writer writer = new OutputStreamWriter(out)
|
Writer writer = new OutputStreamWriter(out)
|
||||||
) {
|
) {
|
||||||
ResourcesGson.addAdapter(new GsonBuilder())
|
ResourcesGson.addAdapter(new GsonBuilder())
|
||||||
@ -202,7 +206,7 @@ private void saveMapSettings() {
|
|||||||
|
|
||||||
public synchronized void saveMarkerState() {
|
public synchronized void saveMarkerState() {
|
||||||
try (
|
try (
|
||||||
OutputStream out = storage.writeMeta(id, MetaType.MARKERS);
|
OutputStream out = storage.writeMeta(id, META_FILE_MARKERS);
|
||||||
Writer writer = new OutputStreamWriter(out)
|
Writer writer = new OutputStreamWriter(out)
|
||||||
) {
|
) {
|
||||||
MarkerGson.INSTANCE.toJson(this.markerSets, writer);
|
MarkerGson.INSTANCE.toJson(this.markerSets, writer);
|
||||||
|
@ -201,7 +201,7 @@ private void createElementFace(Element element, Direction faceDir, VectorM3f c0,
|
|||||||
int blockLight = Math.max(blockLightData.getBlockLight(), facedLightData.getBlockLight());
|
int blockLight = Math.max(blockLightData.getBlockLight(), facedLightData.getBlockLight());
|
||||||
|
|
||||||
// filter out faces that are in a "cave" that should not be rendered
|
// filter out faces that are in a "cave" that should not be rendered
|
||||||
if (isCave && (renderSettings.isCaveDetectionUsesBlockLight() ? blockLight : sunLight) == 0f) return;
|
if (isCave && (renderSettings.isCaveDetectionUsesBlockLight() ? Math.max(blockLight, sunLight) : sunLight) == 0f) return;
|
||||||
|
|
||||||
// initialize the faces
|
// initialize the faces
|
||||||
blockModel.initialize();
|
blockModel.initialize();
|
||||||
|
@ -41,7 +41,7 @@ public class Metrics {
|
|||||||
private static final String METRICS_REPORT_URL = "https://metrics.bluecolored.de/bluemap/";
|
private static final String METRICS_REPORT_URL = "https://metrics.bluecolored.de/bluemap/";
|
||||||
|
|
||||||
public static void sendReportAsync(String implementation) {
|
public static void sendReportAsync(String implementation) {
|
||||||
new Thread(() -> sendReport(implementation)).start();
|
new Thread(() -> sendReport(implementation), "BlueMap-Plugin-SendMetricsReport").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendReport(String implementation) {
|
public static void sendReport(String implementation) {
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package de.bluecolored.bluemap.core.storage;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public interface MetaInfo {
|
||||||
|
|
||||||
|
InputStream readMeta() throws IOException;
|
||||||
|
|
||||||
|
long getSize();
|
||||||
|
|
||||||
|
}
|
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
package de.bluecolored.bluemap.core.storage;
|
|
||||||
|
|
||||||
public enum MetaType {
|
|
||||||
|
|
||||||
TEXTURES ("textures", "textures.json", "application/json"),
|
|
||||||
SETTINGS ("settings", "settings.json", "application/json"),
|
|
||||||
MARKERS ("markers", "live/markers", "application/json"),
|
|
||||||
PLAYERS ("players", "live/players", "application/json"),
|
|
||||||
RENDER_STATE ("render_state", ".rstate", "application/octet-stream");
|
|
||||||
|
|
||||||
private final String typeId;
|
|
||||||
private final String filePath;
|
|
||||||
private final String contentType;
|
|
||||||
|
|
||||||
MetaType(String typeId, String filePath, String contentType) {
|
|
||||||
this.typeId = typeId;
|
|
||||||
this.filePath = filePath;
|
|
||||||
this.contentType = contentType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTypeId() {
|
|
||||||
return typeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFilePath() {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getContentType() {
|
|
||||||
return contentType;
|
|
||||||
}
|
|
||||||
}
|
|
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@ -39,15 +40,17 @@ public abstract class Storage implements Closeable {
|
|||||||
|
|
||||||
public abstract Optional<CompressedInputStream> readMapTile(String mapId, int lod, Vector2i tile) throws IOException;
|
public abstract Optional<CompressedInputStream> readMapTile(String mapId, int lod, Vector2i tile) throws IOException;
|
||||||
|
|
||||||
public abstract Optional<TileData> readMapTileData(String mapId, int lod, Vector2i tile) throws IOException;
|
public abstract Optional<TileInfo> readMapTileInfo(String mapId, int lod, Vector2i tile) throws IOException;
|
||||||
|
|
||||||
public abstract void deleteMapTile(String mapId, int lod, Vector2i tile) throws IOException;
|
public abstract void deleteMapTile(String mapId, int lod, Vector2i tile) throws IOException;
|
||||||
|
|
||||||
public abstract OutputStream writeMeta(String mapId, MetaType metaType) throws IOException;
|
public abstract OutputStream writeMeta(String mapId, String name) throws IOException;
|
||||||
|
|
||||||
public abstract Optional<CompressedInputStream> readMeta(String mapId, MetaType metaType) throws IOException;
|
public abstract Optional<InputStream> readMeta(String mapId, String name) throws IOException;
|
||||||
|
|
||||||
public abstract void deleteMeta(String mapId, MetaType metaType) throws IOException;
|
public abstract Optional<MetaInfo> readMetaInfo(String mapId, String name) throws IOException;
|
||||||
|
|
||||||
|
public abstract void deleteMeta(String mapId, String name) throws IOException;
|
||||||
|
|
||||||
public abstract void purgeMap(String mapId) throws IOException;
|
public abstract void purgeMap(String mapId) throws IOException;
|
||||||
|
|
||||||
@ -115,4 +118,8 @@ public Storage getStorage() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String escapeMetaName(String name) {
|
||||||
|
return name.replaceAll("[^\\w\\d.\\-_/]", "_").replace("..", "_.");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public interface TileData {
|
public interface TileInfo {
|
||||||
|
|
||||||
CompressedInputStream readMapTile() throws IOException;
|
CompressedInputStream readMapTile() throws IOException;
|
||||||
|
|
@ -97,7 +97,7 @@ public Optional<CompressedInputStream> readMapTile(String mapId, int lod, Vector
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<TileData> readMapTileData(String mapId, int lod, Vector2i tile) throws IOException {
|
public Optional<TileInfo> readMapTileInfo(String mapId, int lod, Vector2i tile) throws IOException {
|
||||||
Compression compression = lod == 0 ? this.hiresCompression : Compression.NONE;
|
Compression compression = lod == 0 ? this.hiresCompression : Compression.NONE;
|
||||||
Path file = getFilePath(mapId, lod, tile);
|
Path file = getFilePath(mapId, lod, tile);
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ public Optional<TileData> readMapTileData(String mapId, int lod, Vector2i tile)
|
|||||||
final long size = Files.size(file);
|
final long size = Files.size(file);
|
||||||
final long lastModified = Files.getLastModifiedTime(file).toMillis();
|
final long lastModified = Files.getLastModifiedTime(file).toMillis();
|
||||||
|
|
||||||
return Optional.of(new TileData() {
|
return Optional.of(new TileInfo() {
|
||||||
@Override
|
@Override
|
||||||
public CompressedInputStream readMapTile() throws IOException {
|
public CompressedInputStream readMapTile() throws IOException {
|
||||||
return FileStorage.this.readMapTile(mapId, lod, tile)
|
return FileStorage.this.readMapTile(mapId, lod, tile)
|
||||||
@ -137,8 +137,8 @@ public void deleteMapTile(String mapId, int lod, Vector2i tile) throws IOExcepti
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OutputStream writeMeta(String mapId, MetaType metaType) throws IOException {
|
public OutputStream writeMeta(String mapId, String name) throws IOException {
|
||||||
Path file = getFilePath(mapId).resolve(metaType.getFilePath());
|
Path file = getMetaFilePath(mapId, name);
|
||||||
|
|
||||||
OutputStream os = FileHelper.createFilepartOutputStream(file);
|
OutputStream os = FileHelper.createFilepartOutputStream(file);
|
||||||
os = new BufferedOutputStream(os);
|
os = new BufferedOutputStream(os);
|
||||||
@ -147,20 +147,43 @@ public OutputStream writeMeta(String mapId, MetaType metaType) throws IOExceptio
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<CompressedInputStream> readMeta(String mapId, MetaType metaType) throws IOException {
|
public Optional<InputStream> readMeta(String mapId, String name) throws IOException {
|
||||||
Path file = getFilePath(mapId).resolve(metaType.getFilePath());
|
Path file = getMetaFilePath(mapId, name);
|
||||||
|
|
||||||
if (!Files.exists(file)) return Optional.empty();
|
if (!Files.exists(file)) return Optional.empty();
|
||||||
|
|
||||||
InputStream is = Files.newInputStream(file, StandardOpenOption.READ);
|
InputStream is = Files.newInputStream(file, StandardOpenOption.READ);
|
||||||
is = new BufferedInputStream(is);
|
is = new BufferedInputStream(is);
|
||||||
|
|
||||||
return Optional.of(new CompressedInputStream(is, Compression.NONE));
|
return Optional.of(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteMeta(String mapId, MetaType metaType) throws IOException {
|
public Optional<MetaInfo> readMetaInfo(String mapId, String name) throws IOException {
|
||||||
Path file = getFilePath(mapId).resolve(metaType.getFilePath());
|
Path file = getMetaFilePath(mapId, name);
|
||||||
|
|
||||||
|
if (!Files.exists(file)) return Optional.empty();
|
||||||
|
|
||||||
|
final long size = Files.size(file);
|
||||||
|
|
||||||
|
return Optional.of(new MetaInfo() {
|
||||||
|
@Override
|
||||||
|
public InputStream readMeta() throws IOException {
|
||||||
|
return FileStorage.this.readMeta(mapId, name)
|
||||||
|
.orElseThrow(() -> new IOException("Meta no longer present!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteMeta(String mapId, String name) throws IOException {
|
||||||
|
Path file = getMetaFilePath(mapId, name);
|
||||||
Files.deleteIfExists(file);
|
Files.deleteIfExists(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,4 +222,9 @@ public Path getFilePath(String mapId) {
|
|||||||
return root.resolve(mapId);
|
return root.resolve(mapId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Path getMetaFilePath(String mapId, String name) {
|
||||||
|
return getFilePath(mapId).resolve(escapeMetaName(name)
|
||||||
|
.replace("/", root.getFileSystem().getSeparator()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,10 +37,7 @@
|
|||||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.*;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
@ -176,11 +173,11 @@ public Optional<CompressedInputStream> readMapTile(String mapId, int lod, Vector
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<TileData> readMapTileData(final String mapId, int lod, final Vector2i tile) throws IOException {
|
public Optional<TileInfo> readMapTileInfo(final String mapId, int lod, final Vector2i tile) throws IOException {
|
||||||
Compression compression = lod == 0 ? this.hiresCompression : Compression.NONE;
|
Compression compression = lod == 0 ? this.hiresCompression : Compression.NONE;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TileData tileData = recoveringConnection(connection -> {
|
TileInfo tileInfo = recoveringConnection(connection -> {
|
||||||
ResultSet result = executeQuery(connection,
|
ResultSet result = executeQuery(connection,
|
||||||
//language=SQL
|
//language=SQL
|
||||||
"SELECT t.`changed`, LENGTH(t.`data`) as 'size' " +
|
"SELECT t.`changed`, LENGTH(t.`data`) as 'size' " +
|
||||||
@ -205,7 +202,7 @@ public Optional<TileData> readMapTileData(final String mapId, int lod, final Vec
|
|||||||
final long lastModified = result.getTimestamp("changed").getTime();
|
final long lastModified = result.getTimestamp("changed").getTime();
|
||||||
final long size = result.getLong("size");
|
final long size = result.getLong("size");
|
||||||
|
|
||||||
return new TileData() {
|
return new TileInfo() {
|
||||||
@Override
|
@Override
|
||||||
public CompressedInputStream readMapTile() throws IOException {
|
public CompressedInputStream readMapTile() throws IOException {
|
||||||
return SQLStorage.this.readMapTile(mapId, lod, tile)
|
return SQLStorage.this.readMapTile(mapId, lod, tile)
|
||||||
@ -232,7 +229,7 @@ public long getLastModified() {
|
|||||||
}
|
}
|
||||||
}, 2);
|
}, 2);
|
||||||
|
|
||||||
return Optional.ofNullable(tileData);
|
return Optional.ofNullable(tileInfo);
|
||||||
} catch (SQLException | NoSuchElementException ex) {
|
} catch (SQLException | NoSuchElementException ex) {
|
||||||
throw new IOException(ex);
|
throw new IOException(ex);
|
||||||
}
|
}
|
||||||
@ -263,7 +260,7 @@ public void deleteMapTile(String mapId, int lod, Vector2i tile) throws IOExcepti
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OutputStream writeMeta(String mapId, MetaType metaType) {
|
public OutputStream writeMeta(String mapId, String name) {
|
||||||
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
|
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
|
||||||
return new WrappedOutputStream(byteOut, () -> {
|
return new WrappedOutputStream(byteOut, () -> {
|
||||||
int mapFK = getMapFK(mapId);
|
int mapFK = getMapFK(mapId);
|
||||||
@ -280,7 +277,7 @@ public OutputStream writeMeta(String mapId, MetaType metaType) {
|
|||||||
"REPLACE INTO `bluemap_map_meta` (`map`, `key`, `value`) " +
|
"REPLACE INTO `bluemap_map_meta` (`map`, `key`, `value`) " +
|
||||||
"VALUES (?, ?, ?)",
|
"VALUES (?, ?, ?)",
|
||||||
mapFK,
|
mapFK,
|
||||||
metaType.getTypeId(),
|
escapeMetaName(name),
|
||||||
dataBlob
|
dataBlob
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
@ -291,7 +288,7 @@ public OutputStream writeMeta(String mapId, MetaType metaType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<CompressedInputStream> readMeta(String mapId, MetaType metaType) throws IOException {
|
public Optional<InputStream> readMeta(String mapId, String name) throws IOException {
|
||||||
try {
|
try {
|
||||||
byte[] data = recoveringConnection(connection -> {
|
byte[] data = recoveringConnection(connection -> {
|
||||||
ResultSet result = executeQuery(connection,
|
ResultSet result = executeQuery(connection,
|
||||||
@ -303,7 +300,7 @@ public Optional<CompressedInputStream> readMeta(String mapId, MetaType metaType)
|
|||||||
"WHERE m.`map_id` = ? " +
|
"WHERE m.`map_id` = ? " +
|
||||||
"AND t.`key` = ?",
|
"AND t.`key` = ?",
|
||||||
mapId,
|
mapId,
|
||||||
metaType.getTypeId()
|
escapeMetaName(name)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result.next()) {
|
if (result.next()) {
|
||||||
@ -322,7 +319,50 @@ public Optional<CompressedInputStream> readMeta(String mapId, MetaType metaType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteMeta(String mapId, MetaType metaType) throws IOException {
|
public Optional<MetaInfo> readMetaInfo(String mapId, String name) throws IOException {
|
||||||
|
try {
|
||||||
|
MetaInfo tileInfo = recoveringConnection(connection -> {
|
||||||
|
ResultSet result = executeQuery(connection,
|
||||||
|
//language=SQL
|
||||||
|
"SELECT LENGTH(t.`value`) as 'size' " +
|
||||||
|
"FROM `bluemap_map_meta` t " +
|
||||||
|
" INNER JOIN `bluemap_map` m " +
|
||||||
|
" ON t.`map` = m.`id` " +
|
||||||
|
"WHERE m.`map_id` = ? " +
|
||||||
|
"AND t.`key` = ?",
|
||||||
|
mapId,
|
||||||
|
escapeMetaName(name)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.next()) {
|
||||||
|
final long size = result.getLong("size");
|
||||||
|
|
||||||
|
return new MetaInfo() {
|
||||||
|
@Override
|
||||||
|
public InputStream readMeta() throws IOException {
|
||||||
|
return SQLStorage.this.readMeta(mapId, name)
|
||||||
|
.orElseThrow(() -> new IOException("Tile no longer present!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, 2);
|
||||||
|
|
||||||
|
return Optional.ofNullable(tileInfo);
|
||||||
|
} catch (SQLException | NoSuchElementException ex) {
|
||||||
|
throw new IOException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteMeta(String mapId, String name) throws IOException {
|
||||||
try {
|
try {
|
||||||
recoveringConnection(connection ->
|
recoveringConnection(connection ->
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,
|
||||||
@ -334,7 +374,7 @@ public void deleteMeta(String mapId, MetaType metaType) throws IOException {
|
|||||||
"WHERE m.`map_id` = ? " +
|
"WHERE m.`map_id` = ? " +
|
||||||
"AND t.`key` = ?",
|
"AND t.`key` = ?",
|
||||||
mapId,
|
mapId,
|
||||||
metaType.getTypeId()
|
escapeMetaName(name)
|
||||||
), 2);
|
), 2);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
throw new IOException(ex);
|
throw new IOException(ex);
|
||||||
|
@ -69,7 +69,8 @@ public void renderMaps(BlueMapService blueMap, boolean watch, boolean forceRende
|
|||||||
//metrics report
|
//metrics report
|
||||||
if (blueMap.getConfigs().getCoreConfig().isMetrics()) Metrics.sendReportAsync("cli");
|
if (blueMap.getConfigs().getCoreConfig().isMetrics()) Metrics.sendReportAsync("cli");
|
||||||
|
|
||||||
blueMap.createOrUpdateWebApp(forceGenerateWebapp);
|
if (blueMap.getConfigs().getWebappConfig().isEnabled())
|
||||||
|
blueMap.createOrUpdateWebApp(forceGenerateWebapp);
|
||||||
|
|
||||||
//try load resources
|
//try load resources
|
||||||
blueMap.getResourcePack();
|
blueMap.getResourcePack();
|
||||||
@ -161,7 +162,7 @@ public void run() {
|
|||||||
Logger.global.logInfo("Stopped.");
|
Logger.global.logInfo("Stopped.");
|
||||||
};
|
};
|
||||||
|
|
||||||
Thread shutdownHook = new Thread(shutdown);
|
Thread shutdownHook = new Thread(shutdown, "BlueMap-CLI-ShutdownHook");
|
||||||
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
||||||
|
|
||||||
// wait until done, then shutdown if not watching
|
// wait until done, then shutdown if not watching
|
||||||
|
@ -104,7 +104,7 @@ public void onInitialize() {
|
|||||||
Logger.global.logError("Failed to load bluemap!", e);
|
Logger.global.logError("Failed to load bluemap!", e);
|
||||||
pluginInstance.unload();
|
pluginInstance.unload();
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-Loading").start();
|
||||||
});
|
});
|
||||||
|
|
||||||
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
||||||
|
@ -106,7 +106,7 @@ public void onInitialize() {
|
|||||||
Logger.global.logError("Failed to load bluemap!", e);
|
Logger.global.logError("Failed to load bluemap!", e);
|
||||||
pluginInstance.unload();
|
pluginInstance.unload();
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-Loading").start();
|
||||||
});
|
});
|
||||||
|
|
||||||
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
||||||
|
@ -106,7 +106,7 @@ public void onInitialize() {
|
|||||||
Logger.global.logError("Failed to load bluemap!", e);
|
Logger.global.logError("Failed to load bluemap!", e);
|
||||||
pluginInstance.unload();
|
pluginInstance.unload();
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-Loading").start();
|
||||||
});
|
});
|
||||||
|
|
||||||
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
||||||
|
@ -106,7 +106,7 @@ public void onInitialize() {
|
|||||||
Logger.global.logError("Failed to load bluemap!", e);
|
Logger.global.logError("Failed to load bluemap!", e);
|
||||||
pluginInstance.unload();
|
pluginInstance.unload();
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-Loading").start();
|
||||||
});
|
});
|
||||||
|
|
||||||
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
||||||
|
@ -107,7 +107,7 @@ public void onInitialize() {
|
|||||||
Logger.global.logError("Failed to load bluemap!", e);
|
Logger.global.logError("Failed to load bluemap!", e);
|
||||||
pluginInstance.unload();
|
pluginInstance.unload();
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-Loading").start();
|
||||||
});
|
});
|
||||||
|
|
||||||
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
||||||
|
@ -107,7 +107,7 @@ public void onInitialize() {
|
|||||||
Logger.global.logError("Failed to load bluemap!", e);
|
Logger.global.logError("Failed to load bluemap!", e);
|
||||||
pluginInstance.unload();
|
pluginInstance.unload();
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-Loading").start();
|
||||||
});
|
});
|
||||||
|
|
||||||
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
||||||
|
@ -119,7 +119,7 @@ public void onServerStarted(FMLServerStartedEvent event) {
|
|||||||
Logger.global.logError("Failed to load bluemap!", e);
|
Logger.global.logError("Failed to load bluemap!", e);
|
||||||
pluginInstance.unload();
|
pluginInstance.unload();
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-Loading").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
@ -119,7 +119,7 @@ public void onServerStarted(FMLServerStartedEvent event) {
|
|||||||
Logger.global.logError("Failed to load bluemap!", e);
|
Logger.global.logError("Failed to load bluemap!", e);
|
||||||
pluginInstance.unload();
|
pluginInstance.unload();
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-Loading").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
@ -125,7 +125,7 @@ public void onServerStarted(FMLServerStartedEvent event) {
|
|||||||
Logger.global.logError("Failed to load bluemap!", e);
|
Logger.global.logError("Failed to load bluemap!", e);
|
||||||
pluginInstance.unload();
|
pluginInstance.unload();
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-Loading").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
@ -124,7 +124,7 @@ public void onServerStarted(FMLServerStartedEvent event) {
|
|||||||
Logger.global.logError("Failed to load bluemap!", e);
|
Logger.global.logError("Failed to load bluemap!", e);
|
||||||
pluginInstance.unload();
|
pluginInstance.unload();
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-Loading").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
@ -124,7 +124,7 @@ public void onServerStarted(ServerStartedEvent event) {
|
|||||||
Logger.global.logError("Failed to load bluemap!", e);
|
Logger.global.logError("Failed to load bluemap!", e);
|
||||||
pluginInstance.unload();
|
pluginInstance.unload();
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-Loading").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
@ -125,7 +125,7 @@ public void onServerStarted(ServerStartedEvent event) {
|
|||||||
Logger.global.logError("Failed to load bluemap!", e);
|
Logger.global.logError("Failed to load bluemap!", e);
|
||||||
pluginInstance.unload();
|
pluginInstance.unload();
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-Loading").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
@ -125,7 +125,7 @@ public void onServerStarted(ServerStartedEvent event) {
|
|||||||
Logger.global.logError("Failed to load bluemap!", e);
|
Logger.global.logError("Failed to load bluemap!", e);
|
||||||
pluginInstance.unload();
|
pluginInstance.unload();
|
||||||
}
|
}
|
||||||
}).start();
|
}, "BlueMap-Plugin-Loading").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
Loading…
Reference in New Issue
Block a user