mirror of
https://github.com/BlueMap-Minecraft/BlueMap.git
synced 2024-11-25 20:16:00 +01:00
Finish implementing the first live-api for sponge
This commit is contained in:
parent
b64941783f
commit
b286670953
@ -43,7 +43,7 @@
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import de.bluecolored.bluemap.common.plugin.Plugin;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.PlayerState;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.Player;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
@ -184,13 +184,13 @@ public static BukkitPlugin getInstance() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<PlayerState> getOnlinePlayers() {
|
||||
public Collection<Player> getOnlinePlayers() {
|
||||
// TODO Implement
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<PlayerState> getPlayer(UUID uuid) {
|
||||
public Optional<Player> getPlayer(UUID uuid) {
|
||||
// TODO Implement
|
||||
return Optional.empty();
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.Gamemode;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.PlayerState;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.Player;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
||||
import de.bluecolored.bluemap.core.webserver.HttpRequest;
|
||||
import de.bluecolored.bluemap.core.webserver.HttpRequestHandler;
|
||||
@ -50,7 +50,8 @@ public LiveAPIRequestHandler(ServerInterface server, HttpRequestHandler notFound
|
||||
this.notFoundHandler = notFoundHandler;
|
||||
|
||||
this.liveAPIRequests = new HashMap<>();
|
||||
|
||||
|
||||
this.liveAPIRequests.put("live", this::handleLivePingRequest);
|
||||
this.liveAPIRequests.put("live/players", this::handlePlayersRequest);
|
||||
}
|
||||
|
||||
@ -62,6 +63,12 @@ public HttpResponse handle(HttpRequest request) {
|
||||
return this.notFoundHandler.handle(request);
|
||||
}
|
||||
|
||||
public HttpResponse handleLivePingRequest(HttpRequest request) {
|
||||
HttpResponse response = new HttpResponse(HttpStatusCode.OK);
|
||||
response.setData("{\"status\":\"OK\"}");
|
||||
return response;
|
||||
}
|
||||
|
||||
public HttpResponse handlePlayersRequest(HttpRequest request) {
|
||||
if (!request.getMethod().equalsIgnoreCase("GET")) return new HttpResponse(HttpStatusCode.BAD_REQUEST);
|
||||
|
||||
@ -72,7 +79,7 @@ public HttpResponse handlePlayersRequest(HttpRequest request) {
|
||||
|
||||
json.beginObject();
|
||||
json.name("players").beginArray();
|
||||
for (PlayerState player : server.getOnlinePlayers()) {
|
||||
for (Player player : server.getOnlinePlayers()) {
|
||||
|
||||
if (player.isInvisible()) continue;
|
||||
if (player.isSneaking()) continue;
|
||||
|
@ -27,85 +27,38 @@
|
||||
import java.util.UUID;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3d;
|
||||
import com.google.common.base.MoreObjects;
|
||||
|
||||
import de.bluecolored.bluemap.common.plugin.text.Text;
|
||||
|
||||
public class PlayerState {
|
||||
public interface Player {
|
||||
|
||||
private final UUID uuid;
|
||||
protected Text name;
|
||||
protected UUID world;
|
||||
protected Vector3d position = Vector3d.ZERO;
|
||||
protected boolean online = false;
|
||||
protected boolean sneaking = false;
|
||||
protected boolean invisible = false;
|
||||
protected Gamemode gamemode = Gamemode.SURVIVAL;
|
||||
public UUID getUuid();
|
||||
|
||||
public PlayerState(UUID uuid, Text name, UUID world, Vector3d position) {
|
||||
this.uuid = uuid;
|
||||
this.name = name;
|
||||
this.world = world;
|
||||
this.position = position;
|
||||
}
|
||||
public Text getName();
|
||||
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
public UUID getWorld();
|
||||
|
||||
public Text getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public UUID getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public Vector3d getPosition() {
|
||||
return position;
|
||||
}
|
||||
public Vector3d getPosition();
|
||||
|
||||
public boolean isOnline() {
|
||||
return online;
|
||||
}
|
||||
public boolean isOnline();
|
||||
|
||||
/**
|
||||
* Return <code>true</code> if the player is sneaking.
|
||||
* <p><i>If the player is offline the value of this method is undetermined.</i></p>
|
||||
* @return
|
||||
*/
|
||||
public boolean isSneaking() {
|
||||
return sneaking;
|
||||
}
|
||||
public boolean isSneaking();
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the player has an invisibillity effect
|
||||
* <p><i>If the player is offline the value of this method is undetermined.</i></p>
|
||||
*/
|
||||
public boolean isInvisible() {
|
||||
return invisible;
|
||||
}
|
||||
public boolean isInvisible();
|
||||
|
||||
/**
|
||||
* Returns the {@link Gamemode} this player is in
|
||||
* <p><i>If the player is offline the value of this method is undetermined.</i></p>
|
||||
*/
|
||||
public Gamemode getGamemode() {
|
||||
return gamemode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MoreObjects.toStringHelper(this)
|
||||
.add("uuid", uuid)
|
||||
//.add("name", name)
|
||||
//.add("world", world)
|
||||
//.add("position", position)
|
||||
//.add("online", online)
|
||||
//.add("sneaking", sneaking)
|
||||
//.add("invisible", invisible)
|
||||
//.add("gamemode", gamemode)
|
||||
.toString();
|
||||
}
|
||||
public Gamemode getGamemode();
|
||||
|
||||
}
|
@ -76,15 +76,15 @@ default boolean isMetricsEnabled(boolean configValue) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a collection of players that are currently online
|
||||
* Returns a collection of the states of players that are currently online
|
||||
*/
|
||||
Collection<PlayerState> getOnlinePlayers();
|
||||
Collection<Player> getOnlinePlayers();
|
||||
|
||||
/**
|
||||
* Returns the player with that UUID if present<br>
|
||||
* this method is only guaranteed to return a player if the player is currently online.
|
||||
* Returns the state of the player with that UUID if present<br>
|
||||
* this method is only guaranteed to return a {@link PlayerState} if the player is currently online.
|
||||
*/
|
||||
Optional<PlayerState> getPlayer(UUID uuid);
|
||||
Optional<Player> getPlayer(UUID uuid);
|
||||
|
||||
|
||||
}
|
||||
|
@ -136,6 +136,7 @@ public void setFrom(TileRenderer tileRenderer, String mapId) {
|
||||
public void setFrom(World world, String mapId) {
|
||||
set(world.getSpawnPoint().getX(), "maps", mapId, "startPos", "x");
|
||||
set(world.getSpawnPoint().getZ(), "maps", mapId, "startPos", "z");
|
||||
set(world.getUUID().toString(), "maps", mapId, "world");
|
||||
}
|
||||
|
||||
public void setFrom(MapConfig mapConfig, String mapId) {
|
||||
|
@ -26,7 +26,10 @@
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@ -39,6 +42,7 @@
|
||||
|
||||
import de.bluecolored.bluemap.common.plugin.Plugin;
|
||||
import de.bluecolored.bluemap.common.plugin.commands.Commands;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.Player;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
@ -146,5 +150,17 @@ private UUID loadUUIDForWorld(ServerWorld world) throws IOException {
|
||||
public File getConfigFolder() {
|
||||
return new File("config/bluemap");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Player> getOnlinePlayers() {
|
||||
// TODO Implement
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Player> getPlayer(UUID uuid) {
|
||||
// TODO Implement
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,7 +44,7 @@
|
||||
|
||||
import de.bluecolored.bluemap.common.plugin.Plugin;
|
||||
import de.bluecolored.bluemap.common.plugin.commands.Commands;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.PlayerState;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.Player;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
@ -237,13 +237,13 @@ public Commands<CommandSource> getCommands() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<PlayerState> getOnlinePlayers() {
|
||||
public Collection<Player> getOnlinePlayers() {
|
||||
// TODO Implement
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<PlayerState> getPlayer(UUID uuid) {
|
||||
public Optional<Player> getPlayer(UUID uuid) {
|
||||
// TODO Implement
|
||||
return Optional.empty();
|
||||
}
|
||||
|
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.data.key.Keys;
|
||||
import org.spongepowered.api.effect.potion.PotionEffect;
|
||||
import org.spongepowered.api.effect.potion.PotionEffectTypes;
|
||||
import org.spongepowered.api.entity.living.player.gamemode.GameMode;
|
||||
import org.spongepowered.api.entity.living.player.gamemode.GameModes;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3d;
|
||||
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.Gamemode;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.Player;
|
||||
import de.bluecolored.bluemap.common.plugin.text.Text;
|
||||
|
||||
public class SpongePlayer implements Player {
|
||||
|
||||
private static final Map<GameMode, Gamemode> GAMEMODE_MAP = new HashMap<>(5);
|
||||
static {
|
||||
GAMEMODE_MAP.put(GameModes.ADVENTURE, Gamemode.ADVENTURE);
|
||||
GAMEMODE_MAP.put(GameModes.SURVIVAL, Gamemode.SURVIVAL);
|
||||
GAMEMODE_MAP.put(GameModes.CREATIVE, Gamemode.CREATIVE);
|
||||
GAMEMODE_MAP.put(GameModes.SPECTATOR, Gamemode.SPECTATOR);
|
||||
GAMEMODE_MAP.put(GameModes.NOT_SET, Gamemode.SURVIVAL);
|
||||
}
|
||||
|
||||
private UUID uuid;
|
||||
private Text name;
|
||||
private UUID world;
|
||||
private Vector3d position;
|
||||
private boolean online;
|
||||
private boolean sneaking;
|
||||
private boolean invisible;
|
||||
private Gamemode gamemode;
|
||||
|
||||
private WeakReference<org.spongepowered.api.entity.living.player.Player> delegate;
|
||||
|
||||
public SpongePlayer(org.spongepowered.api.entity.living.player.Player delegate) {
|
||||
this.uuid = delegate.getUniqueId();
|
||||
this.delegate = new WeakReference<>(delegate);
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUuid() {
|
||||
return this.uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getWorld() {
|
||||
return this.world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3d getPosition() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnline() {
|
||||
return this.online;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSneaking() {
|
||||
return this.sneaking;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInvisible() {
|
||||
return this.invisible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Gamemode getGamemode() {
|
||||
return this.gamemode;
|
||||
}
|
||||
|
||||
/**
|
||||
* API access, only call on server thread!
|
||||
*/
|
||||
public void update() {
|
||||
org.spongepowered.api.entity.living.player.Player player = delegate.get();
|
||||
if (player == null) {
|
||||
player = Sponge.getServer().getPlayer(uuid).orElse(null);
|
||||
if (player == null) {
|
||||
this.online = false;
|
||||
return;
|
||||
}
|
||||
|
||||
delegate = new WeakReference<>(player);
|
||||
}
|
||||
|
||||
this.gamemode = GAMEMODE_MAP.get(player.get(Keys.GAME_MODE).orElse(GameModes.NOT_SET));
|
||||
|
||||
boolean invis = player.get(Keys.VANISH).orElse(false);
|
||||
if (!invis && player.get(Keys.INVISIBLE).orElse(false)) invis = true;
|
||||
if (!invis) {
|
||||
Optional<List<PotionEffect>> effects = player.get(Keys.POTION_EFFECTS);
|
||||
if (effects.isPresent()) {
|
||||
for (PotionEffect effect : effects.get()) {
|
||||
if (effect.getType().equals(PotionEffectTypes.INVISIBILITY) && effect.getDuration() > 0) invis = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.invisible = invis;
|
||||
|
||||
this.name = Text.of(player.getName());
|
||||
this.online = player.isOnline();
|
||||
this.position = player.getPosition();
|
||||
this.sneaking = player.get(Keys.IS_SNEAKING).orElse(false);
|
||||
this.world = player.getWorld().getUniqueId();
|
||||
}
|
||||
|
||||
}
|
@ -1,76 +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.sponge;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import org.spongepowered.api.data.key.Keys;
|
||||
import org.spongepowered.api.entity.living.player.Player;
|
||||
import org.spongepowered.api.entity.living.player.gamemode.GameMode;
|
||||
import org.spongepowered.api.entity.living.player.gamemode.GameModes;
|
||||
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.Gamemode;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.PlayerState;
|
||||
import de.bluecolored.bluemap.common.plugin.text.Text;
|
||||
|
||||
public class SpongePlayerState extends PlayerState {
|
||||
|
||||
private WeakReference<Player> playerRef;
|
||||
|
||||
public SpongePlayerState(Player player) {
|
||||
super(player.getUniqueId(), Text.of(player.getName()), player.getWorld().getUniqueId(), player.getPosition());
|
||||
this.playerRef = new WeakReference<Player>(player);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void update() {
|
||||
Player player = playerRef.get();
|
||||
if (player == null) {
|
||||
this.online = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.online = player.isOnline();
|
||||
|
||||
if (this.online) {
|
||||
this.name = Text.of(player.getName());
|
||||
|
||||
this.world = player.getWorld().getUniqueId();
|
||||
this.position = player.getPosition();
|
||||
|
||||
GameMode gm = player.get(Keys.GAME_MODE).orElse(GameModes.NOT_SET);
|
||||
if (gm == GameModes.SURVIVAL) this.gamemode = Gamemode.SURVIVAL;
|
||||
else if (gm == GameModes.CREATIVE) this.gamemode = Gamemode.CREATIVE;
|
||||
else if (gm == GameModes.SPECTATOR) this.gamemode = Gamemode.SPECTATOR;
|
||||
else if (gm == GameModes.ADVENTURE) this.gamemode = Gamemode.ADVENTURE;
|
||||
else this.gamemode = Gamemode.SURVIVAL;
|
||||
|
||||
this.invisible = player.get(Keys.INVISIBLE).orElse(false);
|
||||
this.sneaking = player.get(Keys.IS_SNEAKING).orElse(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -27,14 +27,13 @@
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ -48,12 +47,13 @@
|
||||
import org.spongepowered.api.event.network.ClientConnectionEvent;
|
||||
import org.spongepowered.api.plugin.PluginContainer;
|
||||
import org.spongepowered.api.scheduler.SpongeExecutorService;
|
||||
import org.spongepowered.api.scheduler.Task;
|
||||
import org.spongepowered.api.util.Tristate;
|
||||
import org.spongepowered.api.world.World;
|
||||
import org.spongepowered.api.world.storage.WorldProperties;
|
||||
|
||||
import de.bluecolored.bluemap.common.plugin.Plugin;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.PlayerState;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.Player;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
@ -61,7 +61,7 @@
|
||||
import net.querz.nbt.CompoundTag;
|
||||
import net.querz.nbt.NBTUtil;
|
||||
|
||||
@org.spongepowered.api.plugin.Plugin(
|
||||
@org.spongepowered.api.plugin.Plugin (
|
||||
id = Plugin.PLUGIN_ID,
|
||||
name = Plugin.PLUGIN_NAME,
|
||||
authors = { "Blue (Lukas Rieger)" },
|
||||
@ -80,17 +80,18 @@ public class SpongePlugin implements ServerInterface {
|
||||
private Plugin bluemap;
|
||||
private SpongeCommands commands;
|
||||
|
||||
private SpongeExecutorService syncExecutor;
|
||||
private SpongeExecutorService asyncExecutor;
|
||||
|
||||
private long lastPlayerUpdate = -1;
|
||||
private Map<UUID, PlayerState> onlinePlayers;
|
||||
private int playerUpdateIndex = 0;
|
||||
private Map<UUID, Player> onlinePlayerMap;
|
||||
private List<SpongePlayer> onlinePlayerList;
|
||||
|
||||
@Inject
|
||||
public SpongePlugin(org.slf4j.Logger logger) {
|
||||
Logger.global = new Slf4jLogger(logger);
|
||||
|
||||
this.onlinePlayers = new ConcurrentHashMap<>();
|
||||
this.onlinePlayerMap = new ConcurrentHashMap<>();
|
||||
this.onlinePlayerList = new ArrayList<>();
|
||||
|
||||
this.bluemap = new Plugin("sponge", this);
|
||||
this.commands = new SpongeCommands(bluemap);
|
||||
@ -99,7 +100,6 @@ public SpongePlugin(org.slf4j.Logger logger) {
|
||||
@Listener
|
||||
public void onServerStart(GameStartingServerEvent evt) {
|
||||
asyncExecutor = Sponge.getScheduler().createAsyncExecutor(this);
|
||||
syncExecutor = Sponge.getScheduler().createSyncExecutor(this);
|
||||
|
||||
//save all world properties to generate level_sponge.dat files
|
||||
for (WorldProperties properties : Sponge.getServer().getAllWorldProperties()) {
|
||||
@ -111,6 +111,12 @@ public void onServerStart(GameStartingServerEvent evt) {
|
||||
Sponge.getCommandManager().register(this, command, command.getLabel());
|
||||
}
|
||||
|
||||
//start updating players
|
||||
Task.builder()
|
||||
.intervalTicks(1)
|
||||
.execute(this::updateSomePlayers)
|
||||
.submit(this);
|
||||
|
||||
asyncExecutor.execute(() -> {
|
||||
try {
|
||||
Logger.global.logInfo("Loading...");
|
||||
@ -145,12 +151,16 @@ public void onServerReload(GameReloadEvent evt) {
|
||||
|
||||
@Listener
|
||||
public void onPlayerJoin(ClientConnectionEvent.Join evt) {
|
||||
onlinePlayers.put(evt.getTargetEntity().getUniqueId(), new SpongePlayerState(evt.getTargetEntity()));
|
||||
SpongePlayer player = new SpongePlayer(evt.getTargetEntity());
|
||||
onlinePlayerMap.put(evt.getTargetEntity().getUniqueId(), player);
|
||||
onlinePlayerList.add(player);
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void onPlayerLeave(ClientConnectionEvent.Disconnect evt) {
|
||||
onlinePlayers.remove(evt.getTargetEntity().getUniqueId());
|
||||
UUID playerUUID = evt.getTargetEntity().getUniqueId();
|
||||
onlinePlayerMap.remove(playerUUID);
|
||||
onlinePlayerList.removeIf(p -> p.getUuid().equals(playerUUID));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -191,38 +201,13 @@ public File getConfigFolder() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<PlayerState> getOnlinePlayers() {
|
||||
updatePlayers();
|
||||
return onlinePlayers.values();
|
||||
public Collection<Player> getOnlinePlayers() {
|
||||
return onlinePlayerMap.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<PlayerState> getPlayer(UUID uuid) {
|
||||
updatePlayers();
|
||||
return Optional.ofNullable(onlinePlayers.get(uuid));
|
||||
}
|
||||
|
||||
private synchronized void updatePlayers() {
|
||||
if (lastPlayerUpdate + 1000 > System.currentTimeMillis()) return; //only update once a second
|
||||
|
||||
if (Sponge.getServer().isMainThread()) {
|
||||
updatePlayersSync();
|
||||
} else {
|
||||
try {
|
||||
syncExecutor.submit(this::updatePlayersSync).get(3, TimeUnit.SECONDS);
|
||||
} catch (TimeoutException | InterruptedException ignore) {
|
||||
} catch (ExecutionException e) {
|
||||
Logger.global.logError("Unexpected exception trying to update player-states!", e);
|
||||
}
|
||||
}
|
||||
|
||||
lastPlayerUpdate = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private void updatePlayersSync() {
|
||||
for (PlayerState player : onlinePlayers.values()) {
|
||||
if (player instanceof SpongePlayerState) ((SpongePlayerState) player).update();
|
||||
}
|
||||
public Optional<Player> getPlayer(UUID uuid) {
|
||||
return Optional.ofNullable(onlinePlayerMap.get(uuid));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -238,4 +223,25 @@ public boolean isMetricsEnabled(boolean configValue) {
|
||||
return Sponge.getMetricsConfigManager().getGlobalCollectionState().asBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Only update some of the online players each tick to minimize performance impact on the server-thread.
|
||||
* 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(i).update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user