Write markers to map-storage and add option to periodically update markers and players to storage

This commit is contained in:
Lukas Rieger (Blue) 2022-07-30 15:31:42 +02:00
parent ca1d5cb50b
commit be04097ec5
No known key found for this signature in database
GPG Key ID: 2D09EC5ED2687FF2
6 changed files with 105 additions and 3 deletions

View File

@ -19,6 +19,9 @@ public class PluginConfig {
private boolean hideSneaking = false; private boolean hideSneaking = false;
private boolean hideDifferentWorld = false; private boolean hideDifferentWorld = false;
private int writeMarkersInterval = 0;
private int writePlayersInterval = 0;
private boolean skinDownload = true; private boolean skinDownload = true;
private int playerRenderLimit = -1; private int playerRenderLimit = -1;
@ -49,6 +52,14 @@ public boolean isHideDifferentWorld() {
return hideDifferentWorld; return hideDifferentWorld;
} }
public int getWriteMarkersInterval() {
return writeMarkersInterval;
}
public int getWritePlayersInterval() {
return writePlayersInterval;
}
public boolean isSkinDownload() { public boolean isSkinDownload() {
return skinDownload; return skinDownload;
} }

View File

@ -24,12 +24,14 @@
*/ */
package de.bluecolored.bluemap.common.plugin; package de.bluecolored.bluemap.common.plugin;
import de.bluecolored.bluemap.api.debug.DebugDump;
import de.bluecolored.bluemap.common.BlueMapConfigProvider; import de.bluecolored.bluemap.common.BlueMapConfigProvider;
import de.bluecolored.bluemap.common.BlueMapService; import de.bluecolored.bluemap.common.BlueMapService;
import de.bluecolored.bluemap.common.InterruptableReentrantLock; import de.bluecolored.bluemap.common.InterruptableReentrantLock;
import de.bluecolored.bluemap.common.MissingResourcesException; import de.bluecolored.bluemap.common.MissingResourcesException;
import de.bluecolored.bluemap.common.api.BlueMapAPIImpl; import de.bluecolored.bluemap.common.api.BlueMapAPIImpl;
import de.bluecolored.bluemap.common.config.*; import de.bluecolored.bluemap.common.config.*;
import de.bluecolored.bluemap.common.live.LivePlayersDataSupplier;
import de.bluecolored.bluemap.common.plugin.skins.PlayerSkinUpdater; import de.bluecolored.bluemap.common.plugin.skins.PlayerSkinUpdater;
import de.bluecolored.bluemap.common.rendermanager.MapUpdateTask; import de.bluecolored.bluemap.common.rendermanager.MapUpdateTask;
import de.bluecolored.bluemap.common.rendermanager.RenderManager; import de.bluecolored.bluemap.common.rendermanager.RenderManager;
@ -39,16 +41,19 @@
import de.bluecolored.bluemap.common.web.MapRequestHandler; import de.bluecolored.bluemap.common.web.MapRequestHandler;
import de.bluecolored.bluemap.common.web.RoutingRequestHandler; import de.bluecolored.bluemap.common.web.RoutingRequestHandler;
import de.bluecolored.bluemap.common.webserver.WebServer; import de.bluecolored.bluemap.common.webserver.WebServer;
import de.bluecolored.bluemap.api.debug.DebugDump;
import de.bluecolored.bluemap.core.debug.StateDumper; import de.bluecolored.bluemap.core.debug.StateDumper;
import de.bluecolored.bluemap.core.logger.Logger; import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.map.BmMap; import de.bluecolored.bluemap.core.map.BmMap;
import de.bluecolored.bluemap.core.metrics.Metrics; import de.bluecolored.bluemap.core.metrics.Metrics;
import de.bluecolored.bluemap.core.storage.MetaType;
import de.bluecolored.bluemap.core.world.World; import de.bluecolored.bluemap.core.world.World;
import org.spongepowered.configurate.gson.GsonConfigurationLoader; import org.spongepowered.configurate.gson.GsonConfigurationLoader;
import org.spongepowered.configurate.serialize.SerializationException; import org.spongepowered.configurate.serialize.SerializationException;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -226,6 +231,30 @@ public void run() {
}; };
daemonTimer.schedule(saveTask, TimeUnit.MINUTES.toMillis(2), TimeUnit.MINUTES.toMillis(2)); daemonTimer.schedule(saveTask, TimeUnit.MINUTES.toMillis(2), TimeUnit.MINUTES.toMillis(2));
//periodically save markers
int writeMarkersInterval = pluginConfig.getWriteMarkersInterval();
if (writeMarkersInterval > 0) {
TimerTask saveMarkersTask = new TimerTask() {
@Override
public void run() {
saveMarkerStates();
}
};
daemonTimer.schedule(saveMarkersTask, TimeUnit.SECONDS.toMillis(writeMarkersInterval), TimeUnit.SECONDS.toMillis(writeMarkersInterval));
}
//periodically save players
int writePlayersInterval = pluginConfig.getWritePlayersInterval();
if (writePlayersInterval > 0) {
TimerTask savePlayersTask = new TimerTask() {
@Override
public void run() {
savePlayerStates();
}
};
daemonTimer.schedule(savePlayersTask, TimeUnit.SECONDS.toMillis(writePlayersInterval), TimeUnit.SECONDS.toMillis(writePlayersInterval));
}
//periodically restart the file-watchers //periodically restart the file-watchers
TimerTask fileWatcherRestartTask = new TimerTask() { TimerTask fileWatcherRestartTask = new TimerTask() {
@Override @Override
@ -378,6 +407,35 @@ public synchronized void save() {
} }
} }
public void saveMarkerStates() {
if (maps != null) {
for (BmMap map : maps.values()) {
map.saveMarkerState();
}
}
}
public void savePlayerStates() {
if (maps != null) {
for (BmMap map : maps.values()) {
var dataSupplier = new LivePlayersDataSupplier(
serverInterface,
getConfigs().getPluginConfig(),
map.getWorldId(),
Predicate.not(pluginState::isPlayerHidden)
);
try (
OutputStream out = map.getStorage().writeMeta(map.getId(), MetaType.PLAYERS);
Writer writer = new OutputStreamWriter(out)
) {
writer.write(dataSupplier.get());
} catch (Exception ex) {
Logger.global.logError("Failed to save players for map '" + map.getId() + "'!", ex);
}
}
}
}
public synchronized void startWatchingMap(BmMap map) { public synchronized void startWatchingMap(BmMap map) {
stopWatchingMap(map); stopWatchingMap(map);

View File

@ -31,6 +31,20 @@ hide-sneaking: false
# Default is false # Default is false
hide-different-world: false hide-different-world: false
# The interval in seconds that the markers will be written to the map-storage.
# This is useful if you can't create a live-connection between the server and the webapp
# and the markers can only be updated via the map-storage.
# 0 or lower means that the markers will never be written to the map-storage.
# Default is 0
#write-markers-interval: 10
# The interval in seconds that the players will be written to the map-storage.
# This is useful if you can't create a live-connection between the server and the webapp
# and the players can only be updated via the map-storage.
# 0 or lower means that the players will never be written to the map-storage.
# Default is 0
#write-players-interval: 3
# Download the skin from mojang-serves when a player joins your server, so it can be used for the player-markers. # Download the skin from mojang-serves when a player joins your server, so it can be used for the player-markers.
# Default is true # Default is true
skin-download: true skin-download: true

View File

@ -25,6 +25,7 @@
package de.bluecolored.bluemap.core.map; package de.bluecolored.bluemap.core.map;
import com.flowpowered.math.vector.Vector2i; import com.flowpowered.math.vector.Vector2i;
import de.bluecolored.bluemap.api.markers.MarkerGson;
import de.bluecolored.bluemap.api.markers.MarkerSet; import de.bluecolored.bluemap.api.markers.MarkerSet;
import de.bluecolored.bluemap.api.debug.DebugDump; import de.bluecolored.bluemap.api.debug.DebugDump;
import de.bluecolored.bluemap.core.logger.Logger; import de.bluecolored.bluemap.core.logger.Logger;
@ -129,6 +130,7 @@ public void renderTile(Vector2i tile) {
public synchronized void save() { public synchronized void save() {
lowresModelManager.save(); lowresModelManager.save();
saveRenderState(); saveRenderState();
saveMarkerState();
} }
private void loadRenderState() throws IOException { private void loadRenderState() throws IOException {
@ -142,7 +144,7 @@ private void loadRenderState() throws IOException {
} }
} }
private void saveRenderState() { public synchronized void saveRenderState() {
try (OutputStream out = storage.writeMeta(id, MetaType.RENDER_STATE)) { try (OutputStream out = storage.writeMeta(id, MetaType.RENDER_STATE)) {
this.renderState.save(out); this.renderState.save(out);
} catch (IOException ex){ } catch (IOException ex){
@ -182,6 +184,17 @@ private void saveMapSettings() {
} }
} }
public synchronized void saveMarkerState() {
try (
OutputStream out = storage.writeMeta(id, MetaType.MARKERS);
Writer writer = new OutputStreamWriter(out)
) {
MarkerGson.INSTANCE.toJson(this.markerSets, writer);
} catch (Exception ex) {
Logger.global.logError("Failed to save markers for map '" + getId() + "'!", ex);
}
}
public String getId() { public String getId() {
return id; return id;
} }

View File

@ -28,7 +28,8 @@ public enum MetaType {
TEXTURES ("textures", "textures.json", "application/json"), TEXTURES ("textures", "textures.json", "application/json"),
SETTINGS ("settings", "settings.json", "application/json"), SETTINGS ("settings", "settings.json", "application/json"),
//MARKERS ("markers", "markers.json", "application/json"), MARKERS ("markers", "live/markers", "application/json"),
PLAYERS ("players", "live/players", "application/json"),
RENDER_STATE ("render_state", ".rstate", "application/octet-stream"); RENDER_STATE ("render_state", ".rstate", "application/octet-stream");
private final String typeId; private final String typeId;

View File

@ -80,6 +80,11 @@ public void renderMaps(BlueMapService blueMap, boolean watch, boolean forceRende
//load maps //load maps
Map<String, BmMap> maps = blueMap.getMaps(); Map<String, BmMap> maps = blueMap.getMaps();
//write static markers
for (BmMap map : maps.values()) {
}
//watcher //watcher
List<RegionFileWatchService> regionFileWatchServices = new ArrayList<>(); List<RegionFileWatchService> regionFileWatchServices = new ArrayList<>();
if (watch) { if (watch) {