forked from mirror/BlueMap
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 org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.common.plugin.Plugin;
|
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.ServerEventListener;
|
||||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
||||||
import de.bluecolored.bluemap.core.logger.Logger;
|
import de.bluecolored.bluemap.core.logger.Logger;
|
||||||
@ -184,13 +184,13 @@ public static BukkitPlugin getInstance() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<PlayerState> getOnlinePlayers() {
|
public Collection<Player> getOnlinePlayers() {
|
||||||
// TODO Implement
|
// TODO Implement
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<PlayerState> getPlayer(UUID uuid) {
|
public Optional<Player> getPlayer(UUID uuid) {
|
||||||
// TODO Implement
|
// TODO Implement
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.common.plugin.serverinterface.Gamemode;
|
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.common.plugin.serverinterface.ServerInterface;
|
||||||
import de.bluecolored.bluemap.core.webserver.HttpRequest;
|
import de.bluecolored.bluemap.core.webserver.HttpRequest;
|
||||||
import de.bluecolored.bluemap.core.webserver.HttpRequestHandler;
|
import de.bluecolored.bluemap.core.webserver.HttpRequestHandler;
|
||||||
@ -50,7 +50,8 @@ public LiveAPIRequestHandler(ServerInterface server, HttpRequestHandler notFound
|
|||||||
this.notFoundHandler = notFoundHandler;
|
this.notFoundHandler = notFoundHandler;
|
||||||
|
|
||||||
this.liveAPIRequests = new HashMap<>();
|
this.liveAPIRequests = new HashMap<>();
|
||||||
|
|
||||||
|
this.liveAPIRequests.put("live", this::handleLivePingRequest);
|
||||||
this.liveAPIRequests.put("live/players", this::handlePlayersRequest);
|
this.liveAPIRequests.put("live/players", this::handlePlayersRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,6 +63,12 @@ public HttpResponse handle(HttpRequest request) {
|
|||||||
return this.notFoundHandler.handle(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) {
|
public HttpResponse handlePlayersRequest(HttpRequest request) {
|
||||||
if (!request.getMethod().equalsIgnoreCase("GET")) return new HttpResponse(HttpStatusCode.BAD_REQUEST);
|
if (!request.getMethod().equalsIgnoreCase("GET")) return new HttpResponse(HttpStatusCode.BAD_REQUEST);
|
||||||
|
|
||||||
@ -72,7 +79,7 @@ public HttpResponse handlePlayersRequest(HttpRequest request) {
|
|||||||
|
|
||||||
json.beginObject();
|
json.beginObject();
|
||||||
json.name("players").beginArray();
|
json.name("players").beginArray();
|
||||||
for (PlayerState player : server.getOnlinePlayers()) {
|
for (Player player : server.getOnlinePlayers()) {
|
||||||
|
|
||||||
if (player.isInvisible()) continue;
|
if (player.isInvisible()) continue;
|
||||||
if (player.isSneaking()) continue;
|
if (player.isSneaking()) continue;
|
||||||
|
@ -27,85 +27,38 @@
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import com.flowpowered.math.vector.Vector3d;
|
import com.flowpowered.math.vector.Vector3d;
|
||||||
import com.google.common.base.MoreObjects;
|
|
||||||
|
|
||||||
import de.bluecolored.bluemap.common.plugin.text.Text;
|
import de.bluecolored.bluemap.common.plugin.text.Text;
|
||||||
|
|
||||||
public class PlayerState {
|
public interface Player {
|
||||||
|
|
||||||
private final UUID uuid;
|
public UUID getUuid();
|
||||||
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 PlayerState(UUID uuid, Text name, UUID world, Vector3d position) {
|
public Text getName();
|
||||||
this.uuid = uuid;
|
|
||||||
this.name = name;
|
|
||||||
this.world = world;
|
|
||||||
this.position = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UUID getUuid() {
|
public UUID getWorld();
|
||||||
return uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Text getName() {
|
public Vector3d getPosition();
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UUID getWorld() {
|
|
||||||
return world;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector3d getPosition() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isOnline() {
|
public boolean isOnline();
|
||||||
return online;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return <code>true</code> if the player is sneaking.
|
* 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>
|
* <p><i>If the player is offline the value of this method is undetermined.</i></p>
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean isSneaking() {
|
public boolean isSneaking();
|
||||||
return sneaking;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns <code>true</code> if the player has an invisibillity effect
|
* 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>
|
* <p><i>If the player is offline the value of this method is undetermined.</i></p>
|
||||||
*/
|
*/
|
||||||
public boolean isInvisible() {
|
public boolean isInvisible();
|
||||||
return invisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link Gamemode} this player is in
|
* Returns the {@link Gamemode} this player is in
|
||||||
* <p><i>If the player is offline the value of this method is undetermined.</i></p>
|
* <p><i>If the player is offline the value of this method is undetermined.</i></p>
|
||||||
*/
|
*/
|
||||||
public Gamemode getGamemode() {
|
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -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>
|
* Returns the state of the player with that UUID if present<br>
|
||||||
* this method is only guaranteed to return a player if the player is currently online.
|
* 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) {
|
public void setFrom(World world, String mapId) {
|
||||||
set(world.getSpawnPoint().getX(), "maps", mapId, "startPos", "x");
|
set(world.getSpawnPoint().getX(), "maps", mapId, "startPos", "x");
|
||||||
set(world.getSpawnPoint().getZ(), "maps", mapId, "startPos", "z");
|
set(world.getSpawnPoint().getZ(), "maps", mapId, "startPos", "z");
|
||||||
|
set(world.getUUID().toString(), "maps", mapId, "world");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFrom(MapConfig mapConfig, String mapId) {
|
public void setFrom(MapConfig mapConfig, String mapId) {
|
||||||
|
@ -26,7 +26,10 @@
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
@ -39,6 +42,7 @@
|
|||||||
|
|
||||||
import de.bluecolored.bluemap.common.plugin.Plugin;
|
import de.bluecolored.bluemap.common.plugin.Plugin;
|
||||||
import de.bluecolored.bluemap.common.plugin.commands.Commands;
|
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.ServerEventListener;
|
||||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
||||||
import de.bluecolored.bluemap.core.logger.Logger;
|
import de.bluecolored.bluemap.core.logger.Logger;
|
||||||
@ -146,5 +150,17 @@ private UUID loadUUIDForWorld(ServerWorld world) throws IOException {
|
|||||||
public File getConfigFolder() {
|
public File getConfigFolder() {
|
||||||
return new File("config/bluemap");
|
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.Plugin;
|
||||||
import de.bluecolored.bluemap.common.plugin.commands.Commands;
|
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.ServerEventListener;
|
||||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
||||||
import de.bluecolored.bluemap.core.logger.Logger;
|
import de.bluecolored.bluemap.core.logger.Logger;
|
||||||
@ -237,13 +237,13 @@ public Commands<CommandSource> getCommands() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<PlayerState> getOnlinePlayers() {
|
public Collection<Player> getOnlinePlayers() {
|
||||||
// TODO Implement
|
// TODO Implement
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<PlayerState> getPlayer(UUID uuid) {
|
public Optional<Player> getPlayer(UUID uuid) {
|
||||||
// TODO Implement
|
// TODO Implement
|
||||||
return Optional.empty();
|
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.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@ -48,12 +47,13 @@
|
|||||||
import org.spongepowered.api.event.network.ClientConnectionEvent;
|
import org.spongepowered.api.event.network.ClientConnectionEvent;
|
||||||
import org.spongepowered.api.plugin.PluginContainer;
|
import org.spongepowered.api.plugin.PluginContainer;
|
||||||
import org.spongepowered.api.scheduler.SpongeExecutorService;
|
import org.spongepowered.api.scheduler.SpongeExecutorService;
|
||||||
|
import org.spongepowered.api.scheduler.Task;
|
||||||
import org.spongepowered.api.util.Tristate;
|
import org.spongepowered.api.util.Tristate;
|
||||||
import org.spongepowered.api.world.World;
|
import org.spongepowered.api.world.World;
|
||||||
import org.spongepowered.api.world.storage.WorldProperties;
|
import org.spongepowered.api.world.storage.WorldProperties;
|
||||||
|
|
||||||
import de.bluecolored.bluemap.common.plugin.Plugin;
|
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.ServerEventListener;
|
||||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
||||||
import de.bluecolored.bluemap.core.logger.Logger;
|
import de.bluecolored.bluemap.core.logger.Logger;
|
||||||
@ -61,7 +61,7 @@
|
|||||||
import net.querz.nbt.CompoundTag;
|
import net.querz.nbt.CompoundTag;
|
||||||
import net.querz.nbt.NBTUtil;
|
import net.querz.nbt.NBTUtil;
|
||||||
|
|
||||||
@org.spongepowered.api.plugin.Plugin(
|
@org.spongepowered.api.plugin.Plugin (
|
||||||
id = Plugin.PLUGIN_ID,
|
id = Plugin.PLUGIN_ID,
|
||||||
name = Plugin.PLUGIN_NAME,
|
name = Plugin.PLUGIN_NAME,
|
||||||
authors = { "Blue (Lukas Rieger)" },
|
authors = { "Blue (Lukas Rieger)" },
|
||||||
@ -80,17 +80,18 @@ public class SpongePlugin implements ServerInterface {
|
|||||||
private Plugin bluemap;
|
private Plugin bluemap;
|
||||||
private SpongeCommands commands;
|
private SpongeCommands commands;
|
||||||
|
|
||||||
private SpongeExecutorService syncExecutor;
|
|
||||||
private SpongeExecutorService asyncExecutor;
|
private SpongeExecutorService asyncExecutor;
|
||||||
|
|
||||||
private long lastPlayerUpdate = -1;
|
private int playerUpdateIndex = 0;
|
||||||
private Map<UUID, PlayerState> onlinePlayers;
|
private Map<UUID, Player> onlinePlayerMap;
|
||||||
|
private List<SpongePlayer> onlinePlayerList;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public SpongePlugin(org.slf4j.Logger logger) {
|
public SpongePlugin(org.slf4j.Logger logger) {
|
||||||
Logger.global = new Slf4jLogger(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.bluemap = new Plugin("sponge", this);
|
||||||
this.commands = new SpongeCommands(bluemap);
|
this.commands = new SpongeCommands(bluemap);
|
||||||
@ -99,7 +100,6 @@ public SpongePlugin(org.slf4j.Logger logger) {
|
|||||||
@Listener
|
@Listener
|
||||||
public void onServerStart(GameStartingServerEvent evt) {
|
public void onServerStart(GameStartingServerEvent evt) {
|
||||||
asyncExecutor = Sponge.getScheduler().createAsyncExecutor(this);
|
asyncExecutor = Sponge.getScheduler().createAsyncExecutor(this);
|
||||||
syncExecutor = Sponge.getScheduler().createSyncExecutor(this);
|
|
||||||
|
|
||||||
//save all world properties to generate level_sponge.dat files
|
//save all world properties to generate level_sponge.dat files
|
||||||
for (WorldProperties properties : Sponge.getServer().getAllWorldProperties()) {
|
for (WorldProperties properties : Sponge.getServer().getAllWorldProperties()) {
|
||||||
@ -111,6 +111,12 @@ public void onServerStart(GameStartingServerEvent evt) {
|
|||||||
Sponge.getCommandManager().register(this, command, command.getLabel());
|
Sponge.getCommandManager().register(this, command, command.getLabel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//start updating players
|
||||||
|
Task.builder()
|
||||||
|
.intervalTicks(1)
|
||||||
|
.execute(this::updateSomePlayers)
|
||||||
|
.submit(this);
|
||||||
|
|
||||||
asyncExecutor.execute(() -> {
|
asyncExecutor.execute(() -> {
|
||||||
try {
|
try {
|
||||||
Logger.global.logInfo("Loading...");
|
Logger.global.logInfo("Loading...");
|
||||||
@ -145,12 +151,16 @@ public void onServerReload(GameReloadEvent evt) {
|
|||||||
|
|
||||||
@Listener
|
@Listener
|
||||||
public void onPlayerJoin(ClientConnectionEvent.Join evt) {
|
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
|
@Listener
|
||||||
public void onPlayerLeave(ClientConnectionEvent.Disconnect evt) {
|
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
|
@Override
|
||||||
@ -191,38 +201,13 @@ public File getConfigFolder() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<PlayerState> getOnlinePlayers() {
|
public Collection<Player> getOnlinePlayers() {
|
||||||
updatePlayers();
|
return onlinePlayerMap.values();
|
||||||
return onlinePlayers.values();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<PlayerState> getPlayer(UUID uuid) {
|
public Optional<Player> getPlayer(UUID uuid) {
|
||||||
updatePlayers();
|
return Optional.ofNullable(onlinePlayerMap.get(uuid));
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -238,4 +223,25 @@ public boolean isMetricsEnabled(boolean configValue) {
|
|||||||
return Sponge.getMetricsConfigManager().getGlobalCollectionState().asBoolean();
|
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