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;
|
||||
|
||||
import de.bluecolored.bluemap.common.config.*;
|
||||
|
@ -75,6 +75,8 @@ public class BlueMapService implements Closeable {
|
||||
private final Map<Path, String> worldIds;
|
||||
private final Map<String, Storage> storages;
|
||||
|
||||
private volatile WebFilesManager webFilesManager;
|
||||
|
||||
private Map<String, World> worlds;
|
||||
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 {
|
||||
try {
|
||||
WebFilesManager webFilesManager = new WebFilesManager(configs.getWebappConfig().getWebroot());
|
||||
WebFilesManager webFilesManager = getWebFilesManager();
|
||||
|
||||
// update web-app files
|
||||
if (force || webFilesManager.filesNeedUpdate()) {
|
||||
@ -142,6 +155,7 @@ public synchronized void createOrUpdateWebApp(boolean force) throws Configuratio
|
||||
// update settings.json
|
||||
if (!configs.getWebappConfig().isUpdateSettingsFile()) {
|
||||
webFilesManager.loadSettings();
|
||||
webFilesManager.addFrom(configs.getWebappConfig());
|
||||
} else {
|
||||
webFilesManager.setFrom(configs.getWebappConfig());
|
||||
}
|
||||
|
@ -87,10 +87,22 @@ public void removeMap(String 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) {
|
||||
this.settings.setFrom(webappConfig);
|
||||
}
|
||||
|
||||
public void addFrom(WebappConfig webappConfig) {
|
||||
this.settings.addFrom(webappConfig);
|
||||
}
|
||||
|
||||
public boolean filesNeedUpdate() {
|
||||
return !Files.exists(webRoot.resolve("index.html"));
|
||||
}
|
||||
@ -156,6 +168,8 @@ private static class Settings {
|
||||
private int lowresSliderMin = 500;
|
||||
|
||||
private Set<String> maps = new HashSet<>();
|
||||
private Set<String> scripts = new HashSet<>();
|
||||
private Set<String> styles = new HashSet<>();
|
||||
|
||||
public void setFrom(WebappConfig config) {
|
||||
this.useCookies = config.isUseCookies();
|
||||
@ -165,16 +179,26 @@ public void setFrom(WebappConfig config) {
|
||||
|
||||
this.minZoomDistance = config.getMinZoomDistance();
|
||||
this.maxZoomDistance = config.getMaxZoomDistance();
|
||||
|
||||
|
||||
this.hiresSliderMax = config.getHiresSliderMax();
|
||||
this.hiresSliderDefault = config.getHiresSliderDefault();
|
||||
this.hiresSliderMin = config.getHiresSliderMin();
|
||||
|
||||
|
||||
this.lowresSliderMax = config.getLowresSliderMax();
|
||||
this.lowresSliderDefault = config.getLowresSliderDefault();
|
||||
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;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
@ -46,6 +70,11 @@ public WebAppImpl getWebApp() {
|
||||
return new WebAppImpl(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public de.bluecolored.bluemap.api.plugin.Plugin getPlugin() {
|
||||
return new PluginImpl(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<BlueMapMap> getMaps() {
|
||||
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;
|
||||
|
||||
import com.flowpowered.math.vector.Vector2i;
|
||||
import de.bluecolored.bluemap.api.BlueMapMap;
|
||||
import de.bluecolored.bluemap.api.BlueMapWorld;
|
||||
import de.bluecolored.bluemap.api.AssetStorage;
|
||||
import de.bluecolored.bluemap.api.markers.MarkerSet;
|
||||
import de.bluecolored.bluemap.common.plugin.Plugin;
|
||||
import de.bluecolored.bluemap.common.rendermanager.MapUpdateTask;
|
||||
@ -52,6 +77,11 @@ public BlueMapWorld getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssetStorage getAssetStorage() {
|
||||
return new AssetStorageImpl(unpack(map).getStorage(), getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, MarkerSet> 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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
import de.bluecolored.bluemap.api.WebApp;
|
||||
@ -42,6 +66,16 @@ public boolean getPlayerVisibility(UUID 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
|
||||
public String createImage(BufferedImage image, String path) throws IOException {
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
import de.bluecolored.bluemap.api.debug.DebugDump;
|
||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal"})
|
||||
@DebugDump
|
||||
@ -35,6 +61,8 @@ public class WebappConfig {
|
||||
private int lowresSliderDefault = 2000;
|
||||
private int lowresSliderMin = 500;
|
||||
|
||||
private Set<String> scripts = new HashSet<>();
|
||||
private Set<String> styles = new HashSet<>();
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
@ -95,4 +123,12 @@ public int getLowresSliderMin() {
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
@ -20,7 +44,7 @@ public class LivePlayersDataSupplier implements Supplier<String> {
|
||||
@Nullable private final String worldId;
|
||||
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.config = config;
|
||||
this.worldId = worldId;
|
||||
@ -46,8 +70,10 @@ public String get() {
|
||||
if (config.isHideSneaking() && player.isSneaking()) continue;
|
||||
if (config.getHiddenGameModes().contains(player.getGamemode().getId())) continue;
|
||||
if (config.isHideDifferentWorld() && !isCorrectWorld) continue;
|
||||
if (player.getSkyLight() < config.getHideBelowSkyLight()) continue;
|
||||
if (player.getBlockLight() < config.getHideBelowBlockLight()) continue;
|
||||
if (
|
||||
player.getSkyLight() < config.getHideBelowSkyLight() &&
|
||||
player.getBlockLight() < config.getHideBelowBlockLight()
|
||||
) continue;
|
||||
if (!this.playerFilter.test(player.getUuid())) continue;
|
||||
|
||||
json.beginObject();
|
||||
|
@ -45,7 +45,6 @@
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
import de.bluecolored.bluemap.core.map.BmMap;
|
||||
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.util.FileHelper;
|
||||
import de.bluecolored.bluemap.core.world.World;
|
||||
@ -223,19 +222,17 @@ public void load() throws IOException {
|
||||
}
|
||||
|
||||
//update webapp and settings
|
||||
blueMap.createOrUpdateWebApp(false);
|
||||
if (webappConfig.isEnabled())
|
||||
blueMap.createOrUpdateWebApp(false);
|
||||
|
||||
//start skin updater
|
||||
if (pluginConfig.isLivePlayerMarkers()) {
|
||||
this.skinUpdater = new PlayerSkinUpdater(
|
||||
webappConfig.getWebroot().resolve("assets").resolve("playerheads").toFile(),
|
||||
webappConfig.getWebroot().resolve("assets").resolve("steve.png").toFile()
|
||||
);
|
||||
this.skinUpdater = new PlayerSkinUpdater(this);
|
||||
serverInterface.registerListener(skinUpdater);
|
||||
}
|
||||
|
||||
//init timer
|
||||
daemonTimer = new Timer("BlueMap-Plugin-Daemon-Timer", true);
|
||||
daemonTimer = new Timer("BlueMap-Plugin-DaemonTimer", true);
|
||||
|
||||
//periodically save
|
||||
TimerTask saveTask = new TimerTask() {
|
||||
@ -318,6 +315,9 @@ public void run() {
|
||||
this.api = new BlueMapAPIImpl(this);
|
||||
this.api.register();
|
||||
|
||||
//save webapp settings again (for api-registered scripts and styles)
|
||||
this.getBlueMap().getWebFilesManager().saveSettings();
|
||||
|
||||
//done
|
||||
loaded = true;
|
||||
}
|
||||
@ -438,7 +438,7 @@ public void savePlayerStates() {
|
||||
Predicate.not(pluginState::isPlayerHidden)
|
||||
);
|
||||
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.write(dataSupplier.get());
|
||||
@ -555,6 +555,10 @@ public String getImplementationType() {
|
||||
return implementationType;
|
||||
}
|
||||
|
||||
public PlayerSkinUpdater getSkinUpdater() {
|
||||
return skinUpdater;
|
||||
}
|
||||
|
||||
private void initFileWatcherTasks() {
|
||||
for (BmMap map : maps.values()) {
|
||||
if (pluginState.getMapState(map).isUpdateEnabled()) {
|
||||
|
@ -114,9 +114,10 @@ public void init() {
|
||||
|
||||
LiteralCommandNode<S> debugCommand =
|
||||
literal("debug")
|
||||
.requires(requirements("bluemap.debug"))
|
||||
.requires(requirementsUnloaded("bluemap.debug"))
|
||||
|
||||
.then(literal("block")
|
||||
.requires(requirements("bluemap.debug"))
|
||||
.executes(this::debugBlockCommand)
|
||||
|
||||
.then(argument("world", StringArgumentType.string()).suggests(new WorldSuggestionProvider<>(plugin))
|
||||
@ -126,12 +127,14 @@ public void init() {
|
||||
.executes(this::debugBlockCommand))))))
|
||||
|
||||
.then(literal("flush")
|
||||
.requires(requirements("bluemap.debug"))
|
||||
.executes(this::debugFlushCommand)
|
||||
|
||||
.then(argument("world", StringArgumentType.string()).suggests(new WorldSuggestionProvider<>(plugin))
|
||||
.executes(this::debugFlushCommand)))
|
||||
|
||||
.then(literal("cache")
|
||||
.requires(requirements("bluemap.debug"))
|
||||
.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!"));
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-ReloadCommand").start();
|
||||
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..."));
|
||||
Logger.global.logError("Unexpected exception trying to save the world!", ex);
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-DebugFlushCommand").start();
|
||||
|
||||
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 below you: ", TextColor.WHITE, blockBelow)
|
||||
));
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-DebugBlockCommand").start();
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -534,7 +537,7 @@ public int stopCommand(CommandContext<S> context) {
|
||||
source.sendMessage(Text.of(TextColor.GREEN, "Render-Threads stopped!"));
|
||||
|
||||
plugin.save();
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-StopCommand").start();
|
||||
} else {
|
||||
source.sendMessage(Text.of(TextColor.RED, "Render-Threads are already stopped!"));
|
||||
return 0;
|
||||
@ -554,7 +557,7 @@ public int startCommand(CommandContext<S> context) {
|
||||
source.sendMessage(Text.of(TextColor.GREEN, "Render-Threads started!"));
|
||||
|
||||
plugin.save();
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-StartCommand").start();
|
||||
} else {
|
||||
source.sendMessage(Text.of(TextColor.RED, "Render-Threads are already running!"));
|
||||
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."));
|
||||
|
||||
plugin.save();
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-FreezeCommand").start();
|
||||
} else {
|
||||
source.sendMessage(Text.of(TextColor.RED, "This map is already frozen!"));
|
||||
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!"));
|
||||
|
||||
plugin.save();
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-UnfreezeCommand").start();
|
||||
} else {
|
||||
source.sendMessage(Text.of(TextColor.RED, "This map is not frozen!"));
|
||||
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..."));
|
||||
Logger.global.logError("Unexpected exception trying to save the world!", ex);
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-UpdateCommand").start();
|
||||
|
||||
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."));
|
||||
Logger.global.logError("Failed to purge map '" + map.getId() + "'!", e);
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-PurgeCommand").start();
|
||||
|
||||
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;
|
||||
|
||||
import de.bluecolored.bluemap.common.serverinterface.ServerEventListener;
|
||||
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.OutputStream;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@DebugDump
|
||||
public class PlayerSkinUpdater implements ServerEventListener {
|
||||
|
||||
private File storageFolder;
|
||||
private File defaultSkin;
|
||||
private final Plugin plugin;
|
||||
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 {
|
||||
this.storageFolder = storageFolder;
|
||||
this.defaultSkin = defaultSkin;
|
||||
this.skins = new ConcurrentHashMap<>();
|
||||
public PlayerSkinUpdater(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.skinUpdates = new ConcurrentHashMap<>();
|
||||
|
||||
FileUtils.forceMkdir(this.storageFolder);
|
||||
skinProvider = new MojangSkinProvider();
|
||||
playerMarkerIconFactory = new DefaultPlayerIconFactory();
|
||||
}
|
||||
|
||||
public void updateSkin(UUID playerUuid) {
|
||||
PlayerSkin skin = skins.get(playerUuid);
|
||||
public CompletableFuture<Void> updateSkin(final UUID playerUuid) {
|
||||
|
||||
if (skin == null) {
|
||||
skin = new PlayerSkin(playerUuid);
|
||||
skins.put(playerUuid, skin);
|
||||
}
|
||||
// only update if last update was longer then an hour ago
|
||||
long lastUpdate = skinUpdates.getOrDefault(playerUuid, 0L);
|
||||
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
|
||||
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() {
|
||||
return storageFolder;
|
||||
public SkinProvider getSkinProvider() {
|
||||
return skinProvider;
|
||||
}
|
||||
|
||||
public void setStorageFolder(File storageFolder) {
|
||||
this.storageFolder = storageFolder;
|
||||
public void setSkinProvider(SkinProvider skinProvider) {
|
||||
this.skinProvider = Objects.requireNonNull(skinProvider, "skinProvider can not be null");
|
||||
}
|
||||
|
||||
public File getDefaultSkin() {
|
||||
return defaultSkin;
|
||||
public PlayerIconFactory getPlayerMarkerIconFactory() {
|
||||
return playerMarkerIconFactory;
|
||||
}
|
||||
|
||||
public void setDefaultSkin(File defaultSkin) {
|
||||
this.defaultSkin = defaultSkin;
|
||||
public void setPlayerMarkerIconFactory(PlayerIconFactory playerMarkerIconFactory) {
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
import de.bluecolored.bluemap.common.webserver.HttpRequest;
|
||||
|
@ -25,6 +25,7 @@
|
||||
package de.bluecolored.bluemap.common.web;
|
||||
|
||||
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.HttpRequestHandler;
|
||||
import de.bluecolored.bluemap.common.webserver.HttpResponse;
|
||||
@ -35,10 +36,7 @@
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@ -77,13 +75,13 @@ public HttpResponse handle(HttpRequest request) {
|
||||
int lod = Integer.parseInt(tileMatcher.group(1));
|
||||
int x = Integer.parseInt(tileMatcher.group(2).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()) {
|
||||
TileData tileData = optTileData.get();
|
||||
if (optTileInfo.isPresent()) {
|
||||
TileInfo tileInfo = optTileInfo.get();
|
||||
|
||||
// check e-tag
|
||||
String eTag = calculateETag(path, tileData);
|
||||
String eTag = calculateETag(path, tileInfo);
|
||||
Set<String> etagStringSet = request.getHeader("If-None-Match");
|
||||
if (!etagStringSet.isEmpty()){
|
||||
if(etagStringSet.iterator().next().equals(eTag)) {
|
||||
@ -92,7 +90,7 @@ public HttpResponse handle(HttpRequest request) {
|
||||
}
|
||||
|
||||
// check modified-since
|
||||
long lastModified = tileData.getLastModified();
|
||||
long lastModified = tileInfo.getLastModified();
|
||||
Set<String> modStringSet = request.getHeader("If-Modified-Since");
|
||||
if (!modStringSet.isEmpty()){
|
||||
try {
|
||||
@ -103,7 +101,7 @@ public HttpResponse handle(HttpRequest request) {
|
||||
} catch (IllegalArgumentException ignored){}
|
||||
}
|
||||
|
||||
CompressedInputStream compressedIn = tileData.readMapTile();
|
||||
CompressedInputStream compressedIn = tileInfo.readMapTile();
|
||||
HttpResponse response = new HttpResponse(HttpStatusCode.OK);
|
||||
response.addHeader("ETag", eTag);
|
||||
if (lastModified > 0)
|
||||
@ -118,23 +116,13 @@ public HttpResponse handle(HttpRequest request) {
|
||||
}
|
||||
|
||||
// provide meta-data
|
||||
MetaType metaType = null;
|
||||
for (MetaType mt : MetaType.values()) {
|
||||
if (mt.getFilePath().equals(path)) {
|
||||
metaType = mt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
Optional<InputStream> optIn = mapStorage.readMeta(mapId, path);
|
||||
if (optIn.isPresent()) {
|
||||
CompressedInputStream compressedIn = new CompressedInputStream(optIn.get(), Compression.NONE);
|
||||
HttpResponse response = new HttpResponse(HttpStatusCode.OK);
|
||||
response.addHeader("Content-Type", ContentTypeRegistry.fromFileName(path));
|
||||
writeToResponse(compressedIn, response, request);
|
||||
return response;
|
||||
}
|
||||
|
||||
} catch (NumberFormatException | NoSuchElementException ignore){
|
||||
@ -148,8 +136,8 @@ public HttpResponse handle(HttpRequest request) {
|
||||
return response;
|
||||
}
|
||||
|
||||
private String calculateETag(String path, TileData tileData) {
|
||||
return Long.toHexString(tileData.getSize()) + Integer.toHexString(path.hashCode()) + Long.toHexString(tileData.getLastModified());
|
||||
private String calculateETag(String path, TileInfo tileInfo) {
|
||||
return Long.toHexString(tileInfo.getSize()) + Integer.toHexString(path.hashCode()) + Long.toHexString(tileInfo.getLastModified());
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -59,7 +59,7 @@ remove-caves-below-y: ${remove-caves-below-y}
|
||||
# Defaults to 10000 (disabled)
|
||||
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)
|
||||
# Changing this value requires a re-render of the map.
|
||||
# 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.
|
||||
# Possible values are: survival, creative, spectator, adventure
|
||||
hidden-gamemodes: [
|
||||
hidden-game-modes: [
|
||||
"spectator"
|
||||
]
|
||||
|
||||
@ -28,7 +28,10 @@ hide-invisible: true
|
||||
hide-sneaking: false
|
||||
|
||||
# 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)
|
||||
hide-below-sky-light: 0
|
||||
hide-below-block-light: 0
|
||||
|
@ -53,3 +53,15 @@ hires-slider-min: 0
|
||||
lowres-slider-max: 7000
|
||||
lowres-slider-default: 2000
|
||||
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.util.concurrent.TimeoutException
|
||||
|
||||
plugins {
|
||||
java
|
||||
@ -12,7 +13,11 @@ fun String.runCommand(): String = ProcessBuilder(split("\\s(?=(?:[^'\"`]*(['\"`]
|
||||
.redirectOutput(ProcessBuilder.Redirect.PIPE)
|
||||
.redirectError(ProcessBuilder.Redirect.PIPE)
|
||||
.start()
|
||||
.apply { waitFor(60, TimeUnit.SECONDS) }
|
||||
.apply {
|
||||
if (!waitFor(10, TimeUnit.SECONDS)) {
|
||||
throw TimeoutException("Failed to execute command: '" + this@runCommand + "'")
|
||||
}
|
||||
}
|
||||
.run {
|
||||
val error = errorStream.bufferedReader().readText().trim()
|
||||
if (error.isNotEmpty()) {
|
||||
|
@ -34,8 +34,6 @@
|
||||
import de.bluecolored.bluemap.core.map.lowres.LowresTileManager;
|
||||
import de.bluecolored.bluemap.core.resources.adapter.ResourcesGson;
|
||||
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.world.Grid;
|
||||
import de.bluecolored.bluemap.core.world.World;
|
||||
@ -50,6 +48,12 @@
|
||||
@DebugDump
|
||||
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 name;
|
||||
private final String worldId;
|
||||
@ -134,7 +138,7 @@ public synchronized void save() {
|
||||
|
||||
// only save texture gallery if not present in storage
|
||||
try {
|
||||
if (storage.readMeta(id, MetaType.TEXTURES).isEmpty())
|
||||
if (storage.readMeta(id, META_FILE_TEXTURES).isEmpty())
|
||||
saveTextureGallery();
|
||||
} catch (IOException e) {
|
||||
Logger.global.logError("Failed to read texture gallery", e);
|
||||
@ -142,9 +146,9 @@ public synchronized void save() {
|
||||
}
|
||||
|
||||
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()) {
|
||||
try (InputStream in = rstateData.get().decompress()){
|
||||
try (InputStream in = rstateData.get()){
|
||||
this.renderState.load(in);
|
||||
} catch (IOException 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() {
|
||||
try (OutputStream out = storage.writeMeta(id, MetaType.RENDER_STATE)) {
|
||||
try (OutputStream out = storage.writeMeta(id, META_FILE_RENDER_STATE)) {
|
||||
this.renderState.save(out);
|
||||
} catch (IOException 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 {
|
||||
TextureGallery gallery = null;
|
||||
Optional<CompressedInputStream> texturesData = storage.readMeta(id, MetaType.TEXTURES);
|
||||
Optional<InputStream> texturesData = storage.readMeta(id, META_FILE_TEXTURES);
|
||||
if (texturesData.isPresent()) {
|
||||
try (InputStream in = texturesData.get().decompress()){
|
||||
try (InputStream in = texturesData.get()){
|
||||
gallery = TextureGallery.readTexturesFile(in);
|
||||
} catch (IOException ex) {
|
||||
Logger.global.logError("Failed to load textures for map '" + getId() + "'!", ex);
|
||||
@ -174,7 +178,7 @@ private TextureGallery loadTextureGallery() throws IOException {
|
||||
}
|
||||
|
||||
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);
|
||||
} catch (IOException ex) {
|
||||
Logger.global.logError("Failed to save textures for map '" + getId() + "'!", ex);
|
||||
@ -188,7 +192,7 @@ public synchronized void resetTextureGallery() {
|
||||
|
||||
private void saveMapSettings() {
|
||||
try (
|
||||
OutputStream out = storage.writeMeta(id, MetaType.SETTINGS);
|
||||
OutputStream out = storage.writeMeta(id, META_FILE_SETTINGS);
|
||||
Writer writer = new OutputStreamWriter(out)
|
||||
) {
|
||||
ResourcesGson.addAdapter(new GsonBuilder())
|
||||
@ -202,7 +206,7 @@ private void saveMapSettings() {
|
||||
|
||||
public synchronized void saveMarkerState() {
|
||||
try (
|
||||
OutputStream out = storage.writeMeta(id, MetaType.MARKERS);
|
||||
OutputStream out = storage.writeMeta(id, META_FILE_MARKERS);
|
||||
Writer writer = new OutputStreamWriter(out)
|
||||
) {
|
||||
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());
|
||||
|
||||
// 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
|
||||
blockModel.initialize();
|
||||
|
@ -41,7 +41,7 @@ public class Metrics {
|
||||
private static final String METRICS_REPORT_URL = "https://metrics.bluecolored.de/bluemap/";
|
||||
|
||||
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) {
|
||||
|
@ -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.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
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<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 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;
|
||||
|
||||
@ -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;
|
||||
|
||||
public interface TileData {
|
||||
public interface TileInfo {
|
||||
|
||||
CompressedInputStream readMapTile() throws IOException;
|
||||
|
@ -97,7 +97,7 @@ public Optional<CompressedInputStream> readMapTile(String mapId, int lod, Vector
|
||||
}
|
||||
|
||||
@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;
|
||||
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 lastModified = Files.getLastModifiedTime(file).toMillis();
|
||||
|
||||
return Optional.of(new TileData() {
|
||||
return Optional.of(new TileInfo() {
|
||||
@Override
|
||||
public CompressedInputStream readMapTile() throws IOException {
|
||||
return FileStorage.this.readMapTile(mapId, lod, tile)
|
||||
@ -137,8 +137,8 @@ public void deleteMapTile(String mapId, int lod, Vector2i tile) throws IOExcepti
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream writeMeta(String mapId, MetaType metaType) throws IOException {
|
||||
Path file = getFilePath(mapId).resolve(metaType.getFilePath());
|
||||
public OutputStream writeMeta(String mapId, String name) throws IOException {
|
||||
Path file = getMetaFilePath(mapId, name);
|
||||
|
||||
OutputStream os = FileHelper.createFilepartOutputStream(file);
|
||||
os = new BufferedOutputStream(os);
|
||||
@ -147,20 +147,43 @@ public OutputStream writeMeta(String mapId, MetaType metaType) throws IOExceptio
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<CompressedInputStream> readMeta(String mapId, MetaType metaType) throws IOException {
|
||||
Path file = getFilePath(mapId).resolve(metaType.getFilePath());
|
||||
public Optional<InputStream> readMeta(String mapId, String name) throws IOException {
|
||||
Path file = getMetaFilePath(mapId, name);
|
||||
|
||||
if (!Files.exists(file)) return Optional.empty();
|
||||
|
||||
InputStream is = Files.newInputStream(file, StandardOpenOption.READ);
|
||||
is = new BufferedInputStream(is);
|
||||
|
||||
return Optional.of(new CompressedInputStream(is, Compression.NONE));
|
||||
return Optional.of(is);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteMeta(String mapId, MetaType metaType) throws IOException {
|
||||
Path file = getFilePath(mapId).resolve(metaType.getFilePath());
|
||||
public Optional<MetaInfo> readMetaInfo(String mapId, String name) throws IOException {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -199,4 +222,9 @@ public Path getFilePath(String 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 javax.sql.DataSource;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
@ -176,11 +173,11 @@ public Optional<CompressedInputStream> readMapTile(String mapId, int lod, Vector
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
try {
|
||||
TileData tileData = recoveringConnection(connection -> {
|
||||
TileInfo tileInfo = recoveringConnection(connection -> {
|
||||
ResultSet result = executeQuery(connection,
|
||||
//language=SQL
|
||||
"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 size = result.getLong("size");
|
||||
|
||||
return new TileData() {
|
||||
return new TileInfo() {
|
||||
@Override
|
||||
public CompressedInputStream readMapTile() throws IOException {
|
||||
return SQLStorage.this.readMapTile(mapId, lod, tile)
|
||||
@ -232,7 +229,7 @@ public long getLastModified() {
|
||||
}
|
||||
}, 2);
|
||||
|
||||
return Optional.ofNullable(tileData);
|
||||
return Optional.ofNullable(tileInfo);
|
||||
} catch (SQLException | NoSuchElementException ex) {
|
||||
throw new IOException(ex);
|
||||
}
|
||||
@ -263,7 +260,7 @@ public void deleteMapTile(String mapId, int lod, Vector2i tile) throws IOExcepti
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream writeMeta(String mapId, MetaType metaType) {
|
||||
public OutputStream writeMeta(String mapId, String name) {
|
||||
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
|
||||
return new WrappedOutputStream(byteOut, () -> {
|
||||
int mapFK = getMapFK(mapId);
|
||||
@ -280,7 +277,7 @@ public OutputStream writeMeta(String mapId, MetaType metaType) {
|
||||
"REPLACE INTO `bluemap_map_meta` (`map`, `key`, `value`) " +
|
||||
"VALUES (?, ?, ?)",
|
||||
mapFK,
|
||||
metaType.getTypeId(),
|
||||
escapeMetaName(name),
|
||||
dataBlob
|
||||
);
|
||||
} finally {
|
||||
@ -291,7 +288,7 @@ public OutputStream writeMeta(String mapId, MetaType metaType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<CompressedInputStream> readMeta(String mapId, MetaType metaType) throws IOException {
|
||||
public Optional<InputStream> readMeta(String mapId, String name) throws IOException {
|
||||
try {
|
||||
byte[] data = recoveringConnection(connection -> {
|
||||
ResultSet result = executeQuery(connection,
|
||||
@ -303,7 +300,7 @@ public Optional<CompressedInputStream> readMeta(String mapId, MetaType metaType)
|
||||
"WHERE m.`map_id` = ? " +
|
||||
"AND t.`key` = ?",
|
||||
mapId,
|
||||
metaType.getTypeId()
|
||||
escapeMetaName(name)
|
||||
);
|
||||
|
||||
if (result.next()) {
|
||||
@ -322,7 +319,50 @@ public Optional<CompressedInputStream> readMeta(String mapId, MetaType metaType)
|
||||
}
|
||||
|
||||
@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 {
|
||||
recoveringConnection(connection ->
|
||||
executeUpdate(connection,
|
||||
@ -334,7 +374,7 @@ public void deleteMeta(String mapId, MetaType metaType) throws IOException {
|
||||
"WHERE m.`map_id` = ? " +
|
||||
"AND t.`key` = ?",
|
||||
mapId,
|
||||
metaType.getTypeId()
|
||||
escapeMetaName(name)
|
||||
), 2);
|
||||
} catch (SQLException ex) {
|
||||
throw new IOException(ex);
|
||||
|
@ -69,7 +69,8 @@ public void renderMaps(BlueMapService blueMap, boolean watch, boolean forceRende
|
||||
//metrics report
|
||||
if (blueMap.getConfigs().getCoreConfig().isMetrics()) Metrics.sendReportAsync("cli");
|
||||
|
||||
blueMap.createOrUpdateWebApp(forceGenerateWebapp);
|
||||
if (blueMap.getConfigs().getWebappConfig().isEnabled())
|
||||
blueMap.createOrUpdateWebApp(forceGenerateWebapp);
|
||||
|
||||
//try load resources
|
||||
blueMap.getResourcePack();
|
||||
@ -161,7 +162,7 @@ public void run() {
|
||||
Logger.global.logInfo("Stopped.");
|
||||
};
|
||||
|
||||
Thread shutdownHook = new Thread(shutdown);
|
||||
Thread shutdownHook = new Thread(shutdown, "BlueMap-CLI-ShutdownHook");
|
||||
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
||||
|
||||
// wait until done, then shutdown if not watching
|
||||
|
@ -104,7 +104,7 @@ public void onInitialize() {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-Loading").start();
|
||||
});
|
||||
|
||||
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
||||
|
@ -106,7 +106,7 @@ public void onInitialize() {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-Loading").start();
|
||||
});
|
||||
|
||||
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
||||
|
@ -106,7 +106,7 @@ public void onInitialize() {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-Loading").start();
|
||||
});
|
||||
|
||||
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
||||
|
@ -106,7 +106,7 @@ public void onInitialize() {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-Loading").start();
|
||||
});
|
||||
|
||||
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
||||
|
@ -107,7 +107,7 @@ public void onInitialize() {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-Loading").start();
|
||||
});
|
||||
|
||||
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
||||
|
@ -107,7 +107,7 @@ public void onInitialize() {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-Loading").start();
|
||||
});
|
||||
|
||||
ServerLifecycleEvents.SERVER_STOPPING.register((MinecraftServer server) -> {
|
||||
|
@ -119,7 +119,7 @@ public void onServerStarted(FMLServerStartedEvent event) {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-Loading").start();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@ -119,7 +119,7 @@ public void onServerStarted(FMLServerStartedEvent event) {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-Loading").start();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@ -125,7 +125,7 @@ public void onServerStarted(FMLServerStartedEvent event) {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-Loading").start();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@ -124,7 +124,7 @@ public void onServerStarted(FMLServerStartedEvent event) {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-Loading").start();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@ -124,7 +124,7 @@ public void onServerStarted(ServerStartedEvent event) {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-Loading").start();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@ -125,7 +125,7 @@ public void onServerStarted(ServerStartedEvent event) {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-Loading").start();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@ -125,7 +125,7 @@ public void onServerStarted(ServerStartedEvent event) {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
}, "BlueMap-Plugin-Loading").start();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
Loading…
Reference in New Issue
Block a user