Add option to pause rendering if a set amout of players is online

This commit is contained in:
Blue (Lukas Rieger) 2021-09-18 14:04:03 +02:00
parent 93ae59708e
commit 4806458f9d
No known key found for this signature in database
GPG Key ID: 904C4995F9E1F800
22 changed files with 160 additions and 28 deletions

View File

@ -29,6 +29,7 @@ import de.bluecolored.bluemap.common.InterruptableReentrantLock;
import de.bluecolored.bluemap.common.MissingResourcesException;
import de.bluecolored.bluemap.common.api.BlueMapAPIImpl;
import de.bluecolored.bluemap.common.live.LiveAPIRequestHandler;
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
import de.bluecolored.bluemap.common.plugin.skins.PlayerSkinUpdater;
import de.bluecolored.bluemap.common.rendermanager.MapUpdateTask;
@ -58,7 +59,7 @@ import java.util.*;
import java.util.concurrent.TimeUnit;
@DebugDump
public class Plugin {
public class Plugin implements ServerEventListener {
public static final String PLUGIN_ID = "bluemap";
public static final String PLUGIN_NAME = "BlueMap";
@ -110,7 +111,7 @@ public class Plugin {
unload(); //ensure nothing is left running (from a failed load or something)
blueMap = new BlueMapService(minecraftVersion, serverInterface);
//load configs
coreConfig = blueMap.getCoreConfig();
renderConfig = blueMap.getRenderConfig();
@ -193,7 +194,7 @@ public class Plugin {
//start render-manager
if (pluginState.isRenderThreadsEnabled()) {
renderManager.start(coreConfig.getRenderThreadCount());
checkPausedByPlayerCount(); // <- this also starts the render-manager if it should start
} else {
Logger.global.logInfo("Render-Threads are STOPPED! Use the command 'bluemap start' to start them.");
}
@ -264,6 +265,9 @@ public class Plugin {
this.regionFileWatchServices = new HashMap<>();
initFileWatcherTasks();
//register listener
serverInterface.registerListener(this);
//enable api
this.api = new BlueMapAPIImpl(this);
this.api.register();
@ -378,7 +382,31 @@ public class Plugin {
public boolean flushWorldUpdates(UUID worldUUID) throws IOException {
return serverInterface.persistWorldChanges(worldUUID);
}
@Override
public void onPlayerJoin(UUID playerUuid) {
checkPausedByPlayerCount();
}
@Override
public void onPlayerLeave(UUID playerUuid) {
checkPausedByPlayerCount();
}
public boolean checkPausedByPlayerCount() {
if (
getPluginConfig().getPlayerRenderLimit() > 0 &&
getServerInterface().getOnlinePlayers().size() >= getPluginConfig().getPlayerRenderLimit()
) {
if (renderManager.isRunning()) renderManager.stop();
return true;
} else {
if (!renderManager.isRunning() && getPluginState().isRenderThreadsEnabled())
renderManager.start(getCoreConfig().getRenderThreadCount());
return false;
}
}
public ServerInterface getServerInterface() {
return serverInterface;
}

View File

@ -35,12 +35,13 @@ import java.util.concurrent.TimeUnit;
@DebugDump
public class PluginConfig {
private boolean liveUpdatesEnabled = false;
private boolean skinDownloadEnabled = false;
private Collection<String> hiddenGameModes = Collections.emptyList();
private boolean hideInvisible = false;
private boolean hideSneaking = false;
private long fullUpdateIntervalMinutes = TimeUnit.HOURS.toMinutes(24);
private boolean liveUpdatesEnabled;
private boolean skinDownloadEnabled;
private Collection<String> hiddenGameModes;
private boolean hideInvisible;
private boolean hideSneaking;
private int playerRenderLimit;
private long fullUpdateIntervalMinutes;
public PluginConfig(ConfigurationNode node) {
@ -63,6 +64,9 @@ public class PluginConfig {
//hideSneaking
hideSneaking = node.node("hideSneaking").getBoolean(false);
//playerRenderLimit
playerRenderLimit = node.node("playerRenderLimit").getInt(-1);
//periodic map updates
fullUpdateIntervalMinutes = node.node("fullUpdateInterval").getLong(TimeUnit.HOURS.toMinutes(24));
@ -88,6 +92,10 @@ public class PluginConfig {
return this.hideSneaking;
}
public int getPlayerRenderLimit() {
return playerRenderLimit;
}
public long getFullUpdateIntervalMinutes() {
return fullUpdateIntervalMinutes;
}

View File

@ -27,6 +27,7 @@ package de.bluecolored.bluemap.common.plugin.commands;
import de.bluecolored.bluemap.common.plugin.Plugin;
import de.bluecolored.bluemap.common.plugin.text.Text;
import de.bluecolored.bluemap.common.plugin.text.TextColor;
import de.bluecolored.bluemap.common.plugin.text.TextFormat;
import de.bluecolored.bluemap.common.rendermanager.RenderManager;
import de.bluecolored.bluemap.common.rendermanager.RenderTask;
import de.bluecolored.bluemap.core.map.BmMap;
@ -90,11 +91,17 @@ public class CommandHelper {
}
}
} else {
lines.add(Text.of(TextColor.WHITE, " Render-Threads are ",
Text.of(TextColor.RED, "stopped")
.setHoverText(Text.of("click to start rendering"))
.setClickAction(Text.ClickAction.RUN_COMMAND, "/bluemap start"),
TextColor.GRAY, "!"));
if (plugin.checkPausedByPlayerCount()) {
lines.add(Text.of(TextColor.WHITE, " Render-Threads are ",
Text.of(TextColor.GOLD, "paused")));
lines.add(Text.of(TextColor.GRAY, TextFormat.ITALIC, " (there are " + plugin.getPluginConfig().getPlayerRenderLimit() + " or more players online)"));
} else {
lines.add(Text.of(TextColor.WHITE, " Render-Threads are ",
Text.of(TextColor.RED, "stopped")
.setHoverText(Text.of("click to start rendering"))
.setClickAction(Text.ClickAction.RUN_COMMAND, "/bluemap start"),
TextColor.GRAY, "!"));
}
if (!tasks.isEmpty()) {
lines.add(Text.of(TextColor.WHITE, " Queued Tasks (" + tasks.size() + "):"));

View File

@ -25,6 +25,7 @@
package de.bluecolored.bluemap.core.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
@ -51,8 +52,11 @@ public class AtomicFileHelper {
try {
Files.move(partFile, file, StandardCopyOption.ATOMIC_MOVE);
} catch (FileNotFoundException ignore) {
} catch (IOException ex) {
Files.move(partFile, file);
try {
Files.move(partFile, file);
} catch (FileNotFoundException ignore) {}
}
});
}

View File

@ -3,4 +3,5 @@ skinDownload: true
hiddenGameModes: []
hideInvisible: true
hideSneaking: false
playerRenderLimit: -1
fullUpdateInterval: 1440

View File

@ -26,6 +26,13 @@ hideInvisible: true
# Default is false
hideSneaking: false
# The amount of players that is needed to pause BlueMap's render-threads.
# -> If this amount of players or more is online, bluemap will stop rendering map-updates until enough players
# have logged off again
# Setting this to 0 or -1 will disable this feature -> bluemap will not pause rendering
# Default is -1
playerRenderLimit: -1
# The interval in minutes in which a full map-update will be triggered.
# This is additionally!! to the normal map-update process (in case that fails to detect any file-changes).
# Default is 1440 (24 hours)

View File

@ -3,4 +3,5 @@ skinDownload: true
hiddenGameModes: []
hideInvisible: true
hideSneaking: false
playerRenderLimit: -1
fullUpdateInterval: 1440

View File

@ -26,6 +26,13 @@ hideInvisible: true
# Default is false
hideSneaking: false
# The amount of players that is needed to pause BlueMap's render-threads.
# -> If this amount of players or more is online, bluemap will stop rendering map-updates until enough players
# have logged off again
# Setting this to 0 or -1 will disable this feature -> bluemap will not pause rendering
# Default is -1
playerRenderLimit: -1
# The interval in minutes in which a full map-update will be triggered.
# This is additionally!! to the normal map-update process (in case that fails to detect any file-changes).
# Default is 1440 (24 hours)

View File

@ -26,6 +26,13 @@ hideInvisible: true
# Default is false
hideSneaking: false
# The amount of players that is needed to pause BlueMap's render-threads.
# -> If this amount of players or more is online, bluemap will stop rendering map-updates until enough players
# have logged off again
# Setting this to 0 or -1 will disable this feature -> bluemap will not pause rendering
# Default is -1
playerRenderLimit: -1
# The interval in minutes in which a full map-update will be triggered.
# This is additionally!! to the normal map-update process (in case that fails to detect any file-changes).
# Default is 1440 (24 hours)

View File

@ -3,4 +3,5 @@ skinDownload: true
hiddenGameModes: []
hideInvisible: true
hideSneaking: false
playerRenderLimit: -1
fullUpdateInterval: 1440

View File

@ -26,6 +26,13 @@ hideInvisible: true
# Default is false
hideSneaking: false
# The amount of players that is needed to pause BlueMap's render-threads.
# -> If this amount of players or more is online, bluemap will stop rendering map-updates until enough players
# have logged off again
# Setting this to 0 or -1 will disable this feature -> bluemap will not pause rendering
# Default is -1
playerRenderLimit: -1
# The interval in minutes in which a full map-update will be triggered.
# This is additionally!! to the normal map-update process (in case that fails to detect any file-changes).
# Default is 1440 (24 hours)

View File

@ -3,4 +3,5 @@ skinDownload: true
hiddenGameModes: []
hideInvisible: true
hideSneaking: false
playerRenderLimit: -1
fullUpdateInterval: 1440

View File

@ -26,6 +26,13 @@ hideInvisible: true
# Default is false
hideSneaking: false
# The amount of players that is needed to pause BlueMap's render-threads.
# -> If this amount of players or more is online, bluemap will stop rendering map-updates until enough players
# have logged off again
# Setting this to 0 or -1 will disable this feature -> bluemap will not pause rendering
# Default is -1
playerRenderLimit: -1
# The interval in minutes in which a full map-update will be triggered.
# This is additionally!! to the normal map-update process (in case that fails to detect any file-changes).
# Default is 1440 (24 hours)

View File

@ -3,4 +3,5 @@ skinDownload: true
hiddenGameModes: []
hideInvisible: true
hideSneaking: false
playerRenderLimit: -1
fullUpdateInterval: 1440

View File

@ -26,6 +26,13 @@ hideInvisible: true
# Default is false
hideSneaking: false
# The amount of players that is needed to pause BlueMap's render-threads.
# -> If this amount of players or more is online, bluemap will stop rendering map-updates until enough players
# have logged off again
# Setting this to 0 or -1 will disable this feature -> bluemap will not pause rendering
# Default is -1
playerRenderLimit: -1
# The interval in minutes in which a full map-update will be triggered.
# This is additionally!! to the normal map-update process (in case that fails to detect any file-changes).
# Default is 1440 (24 hours)

View File

@ -3,4 +3,5 @@ skinDownload: true
hiddenGameModes: []
hideInvisible: true
hideSneaking: false
playerRenderLimit: -1
fullUpdateInterval: 1440

View File

@ -26,6 +26,13 @@ hideInvisible: true
# Default is false
hideSneaking: false
# The amount of players that is needed to pause BlueMap's render-threads.
# -> If this amount of players or more is online, bluemap will stop rendering map-updates until enough players
# have logged off again
# Setting this to 0 or -1 will disable this feature -> bluemap will not pause rendering
# Default is -1
playerRenderLimit: -1
# The interval in minutes in which a full map-update will be triggered.
# This is additionally!! to the normal map-update process (in case that fails to detect any file-changes).
# Default is 1440 (24 hours)

View File

@ -3,4 +3,5 @@ skinDownload: true
hiddenGameModes: []
hideInvisible: true
hideSneaking: false
playerRenderLimit: -1
fullUpdateInterval: 1440

View File

@ -26,6 +26,13 @@ hideInvisible: true
# Default is false
hideSneaking: false
# The amount of players that is needed to pause BlueMap's render-threads.
# -> If this amount of players or more is online, bluemap will stop rendering map-updates until enough players
# have logged off again
# Setting this to 0 or -1 will disable this feature -> bluemap will not pause rendering
# Default is -1
playerRenderLimit: -1
# The interval in minutes in which a full map-update will be triggered.
# This is additionally!! to the normal map-update process (in case that fails to detect any file-changes).
# Default is 1440 (24 hours)

View File

@ -45,6 +45,7 @@ import org.spongepowered.api.Server;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.Command;
import org.spongepowered.api.config.ConfigDir;
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.lifecycle.RefreshGameEvent;
import org.spongepowered.api.event.lifecycle.RegisterCommandEvent;
@ -161,6 +162,17 @@ public class SpongePlugin implements ServerInterface {
pluginInstance.unload();
}
});
// update player list
onlinePlayerMap.clear();
synchronized (onlinePlayerList) {
onlinePlayerList.clear();
for (ServerPlayer spongePlayer : Sponge.server().onlinePlayers()) {
SpongePlayer player = new SpongePlayer(spongePlayer.uniqueId());
onlinePlayerMap.put(spongePlayer.uniqueId(), player);
onlinePlayerList.add(player);
}
}
}
@Listener
@ -276,18 +288,20 @@ public class SpongePlugin implements ServerInterface {
* Only call this method on the server-thread.
*/
private void updateSomePlayers() {
int onlinePlayerCount = onlinePlayerList.size();
if (onlinePlayerCount == 0) return;
int playersToBeUpdated = onlinePlayerCount / 20; //with 20 tps, each player is updated once a second
if (playersToBeUpdated == 0) playersToBeUpdated = 1;
for (int i = 0; i < playersToBeUpdated; i++) {
playerUpdateIndex++;
if (playerUpdateIndex >= 20 && playerUpdateIndex >= onlinePlayerCount) playerUpdateIndex = 0;
if (playerUpdateIndex < onlinePlayerCount) {
onlinePlayerList.get(playerUpdateIndex).update();
synchronized (onlinePlayerList) {
int onlinePlayerCount = onlinePlayerList.size();
if (onlinePlayerCount == 0) return;
int playersToBeUpdated = onlinePlayerCount / 20; //with 20 tps, each player is updated once a second
if (playersToBeUpdated == 0) playersToBeUpdated = 1;
for (int i = 0; i < playersToBeUpdated; i++) {
playerUpdateIndex++;
if (playerUpdateIndex >= 20 && playerUpdateIndex >= onlinePlayerCount) playerUpdateIndex = 0;
if (playerUpdateIndex < onlinePlayerCount) {
onlinePlayerList.get(playerUpdateIndex).update();
}
}
}
}

View File

@ -3,4 +3,5 @@ skinDownload: false
hiddenGameModes: []
hideInvisible: true
hideSneaking: false
playerRenderLimit: -1
fullUpdateInterval: 1440

View File

@ -26,6 +26,13 @@ hideInvisible: true
# Default is false
hideSneaking: false
# The amount of players that is needed to pause BlueMap's render-threads.
# -> If this amount of players or more is online, bluemap will stop rendering map-updates until enough players
# have logged off again
# Setting this to 0 or -1 will disable this feature -> bluemap will not pause rendering
# Default is -1
playerRenderLimit: -1
# The interval in minutes in which a full map-update will be triggered.
# This is additionally!! to the normal map-update process (in case that fails to detect any file-changes).
# Default is 1440 (24 hours)