mirror of https://github.com/webbukkit/dynmap.git
311 lines
13 KiB
Java
311 lines
13 KiB
Java
package org.dynmap;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
import org.dynmap.common.DynmapListenerManager.EventType;
|
|
import org.dynmap.common.DynmapListenerManager.WorldEventListener;
|
|
import org.dynmap.common.DynmapListenerManager.PlayerEventListener;
|
|
import org.dynmap.common.DynmapPlayer;
|
|
import org.dynmap.markers.AreaMarker;
|
|
import org.dynmap.markers.Marker;
|
|
import org.dynmap.markers.MarkerAPI;
|
|
import org.dynmap.markers.MarkerIcon;
|
|
import org.dynmap.markers.MarkerSet;
|
|
import org.dynmap.markers.impl.MarkerSignManager;
|
|
import org.dynmap.utils.Polygon;
|
|
|
|
/**
|
|
* Markers component - ties in the component system, both on the server and client
|
|
*/
|
|
public class MarkersComponent extends ClientComponent {
|
|
private MarkerAPI api;
|
|
private MarkerSignManager signmgr;
|
|
private MarkerIcon spawnicon;
|
|
private String spawnlbl;
|
|
private String worldborderlbl;
|
|
private MarkerSet offlineset;
|
|
private MarkerIcon offlineicon;
|
|
private MarkerSet spawnbedset;
|
|
private MarkerIcon spawnbedicon;
|
|
private String spawnbedformat;
|
|
private long maxofflineage;
|
|
private boolean showSpawn;
|
|
private boolean showBorder;
|
|
private HashMap<String, Long> offline_times = new HashMap<String, Long>();
|
|
private static final String OFFLINE_PLAYERS_SETID = "offline_players";
|
|
private static final String PLAYER_SPAWN_BED_SETID = "spawn_beds";
|
|
|
|
public MarkersComponent(final DynmapCore core, ConfigurationNode configuration) {
|
|
super(core, configuration);
|
|
|
|
api = core.getMarkerAPI();
|
|
|
|
/* If configuration has enabled sign support, prime it too */
|
|
if(configuration.getBoolean("enablesigns", false)) {
|
|
signmgr = MarkerSignManager.initializeSignManager(core, configuration.getString("default-sign-set", MarkerSet.DEFAULT));
|
|
}
|
|
showBorder = configuration.getBoolean("showworldborder", false);
|
|
showSpawn = configuration.getBoolean("showspawn", false);
|
|
/* If we're posting spawn point markers, initialize and add world listener */
|
|
if(showSpawn) {
|
|
String ico = configuration.getString("spawnicon", MarkerIcon.WORLD);
|
|
spawnlbl = configuration.getString("spawnlabel", "Spawn");
|
|
spawnicon = api.getMarkerIcon(ico); /* Load it */
|
|
if(spawnicon == null) {
|
|
spawnicon = api.getMarkerIcon(MarkerIcon.WORLD);
|
|
}
|
|
}
|
|
if (showBorder) {
|
|
worldborderlbl = configuration.getString("worldborderlabel", "Border");
|
|
}
|
|
if (showSpawn || showBorder) {
|
|
/* Add listener for world loads */
|
|
WorldEventListener wel = new WorldEventListener() {
|
|
@Override
|
|
public void worldEvent(DynmapWorld w) {
|
|
DynmapLocation loc = w.getSpawnLocation(); /* Get location of spawn */
|
|
if(loc != null)
|
|
addUpdateWorld(w, loc);
|
|
}
|
|
};
|
|
core.listenerManager.addListener(EventType.WORLD_LOAD, wel);
|
|
/* Add listener for spawn changes */
|
|
core.listenerManager.addListener(EventType.WORLD_SPAWN_CHANGE, wel);
|
|
|
|
/* Initialize already loaded worlds */
|
|
for(DynmapWorld w : core.getMapManager().getWorlds()) {
|
|
DynmapLocation loc = w.getSpawnLocation();
|
|
if(loc != null)
|
|
addUpdateWorld(w, loc);
|
|
}
|
|
}
|
|
/* If showing offline players as markers */
|
|
if(configuration.getBoolean("showofflineplayers", false)) {
|
|
/* Make set, if needed */
|
|
offlineset = api.getMarkerSet(OFFLINE_PLAYERS_SETID);
|
|
if(offlineset == null) {
|
|
offlineset = api.createMarkerSet(OFFLINE_PLAYERS_SETID, configuration.getString("offlinelabel", "Offline"), null, true);
|
|
}
|
|
offlineset.setHideByDefault(configuration.getBoolean("offlinehidebydefault", true));
|
|
offlineset.setMinZoom(configuration.getInteger("offlineminzoom", 0));
|
|
maxofflineage = 60000L * configuration.getInteger("maxofflinetime", 30); /* 30 minutes */
|
|
/* Now, see if existing offline markers - check for last login on their users */
|
|
if(maxofflineage > 0) {
|
|
Set<Marker> prev_m = offlineset.getMarkers();
|
|
for(Marker m : prev_m) {
|
|
DynmapPlayer p = core.getServer().getOfflinePlayer(m.getMarkerID());
|
|
if(p != null) {
|
|
long ageout = p.getLastLoginTime() + maxofflineage;
|
|
if(ageout < System.currentTimeMillis()) {
|
|
m.deleteMarker();
|
|
}
|
|
else {
|
|
offline_times.put(p.getName(), ageout);
|
|
}
|
|
}
|
|
else {
|
|
m.deleteMarker();
|
|
}
|
|
}
|
|
}
|
|
offlineicon = api.getMarkerIcon(configuration.getString("offlineicon", "offlineuser"));
|
|
if(maxofflineage > 0) {
|
|
core.getServer().scheduleServerTask(new Runnable() {
|
|
public void run() {
|
|
long ts = System.currentTimeMillis();
|
|
ArrayList<String> deleted = new ArrayList<String>();
|
|
for(Map.Entry<String,Long> me : offline_times.entrySet()) {
|
|
if(ts > me.getValue()) {
|
|
deleted.add(me.getKey());
|
|
}
|
|
}
|
|
for(String id : deleted) {
|
|
Marker m = offlineset.findMarker(id);
|
|
if(m != null)
|
|
m.deleteMarker();
|
|
}
|
|
core.getServer().scheduleServerTask(this, 30 * 20);
|
|
}
|
|
}, 30 * 20); /* Check every 30 seconds */
|
|
}
|
|
/* Add listener for players coming and going */
|
|
core.listenerManager.addListener(EventType.PLAYER_JOIN, new PlayerEventListener() {
|
|
@Override
|
|
public void playerEvent(DynmapPlayer p) {
|
|
Marker m = offlineset.findMarker(p.getName());
|
|
if(m != null) {
|
|
m.deleteMarker();
|
|
offline_times.remove(p.getName());
|
|
}
|
|
}
|
|
});
|
|
core.listenerManager.addListener(EventType.PLAYER_QUIT, new PlayerEventListener() {
|
|
@Override
|
|
public void playerEvent(DynmapPlayer p) {
|
|
String pname = p.getName();
|
|
Marker m = offlineset.findMarker(pname);
|
|
if(m != null) {
|
|
m.deleteMarker();
|
|
offline_times.remove(p.getName());
|
|
}
|
|
if(core.playerList.isVisiblePlayer(pname)) {
|
|
DynmapLocation loc = p.getLocation();
|
|
m = offlineset.createMarker(p.getName(), core.getServer().stripChatColor(p.getDisplayName()), false,
|
|
loc.world, loc.x, loc.y, loc.z, offlineicon, true);
|
|
if(maxofflineage > 0)
|
|
offline_times.put(p.getName(), System.currentTimeMillis() + maxofflineage);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
/* Make set, if needed */
|
|
offlineset = api.getMarkerSet(OFFLINE_PLAYERS_SETID);
|
|
if(offlineset != null) {
|
|
offlineset.deleteMarkerSet();
|
|
}
|
|
}
|
|
/* If showing player spawn bed locations as markers */
|
|
if(configuration.getBoolean("showspawnbeds", false)) {
|
|
/* Make set, if needed */
|
|
spawnbedset = api.getMarkerSet(PLAYER_SPAWN_BED_SETID);
|
|
if(spawnbedset == null) {
|
|
spawnbedset = api.createMarkerSet(PLAYER_SPAWN_BED_SETID, configuration.getString("spawnbedlabel", "Spawn Beds"), null, true);
|
|
}
|
|
spawnbedset.setHideByDefault(configuration.getBoolean("spawnbedhidebydefault", true));
|
|
spawnbedset.setMinZoom(configuration.getInteger("spawnbedminzoom", 0));
|
|
|
|
spawnbedicon = api.getMarkerIcon(configuration.getString("spawnbedicon", "bed"));
|
|
spawnbedformat = configuration.getString("spawnbedformat", "%name%'s bed");
|
|
|
|
/* Add listener for players coming and going */
|
|
core.listenerManager.addListener(EventType.PLAYER_JOIN, new PlayerEventListener() {
|
|
@Override
|
|
public void playerEvent(DynmapPlayer p) {
|
|
updatePlayer(p);
|
|
}
|
|
});
|
|
core.listenerManager.addListener(EventType.PLAYER_QUIT, new PlayerEventListener() {
|
|
@Override
|
|
public void playerEvent(DynmapPlayer p) {
|
|
Marker m = spawnbedset.findMarker(p.getName()+"_bed");
|
|
if(m != null) {
|
|
m.deleteMarker();
|
|
}
|
|
}
|
|
});
|
|
core.listenerManager.addListener(EventType.PLAYER_BED_LEAVE, new PlayerEventListener() {
|
|
@Override
|
|
public void playerEvent(final DynmapPlayer p) {
|
|
core.getServer().scheduleServerTask(new Runnable() {
|
|
public void run() {
|
|
updatePlayer(p);
|
|
}
|
|
}, 0);
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
/* Make set, if needed */
|
|
spawnbedset = api.getMarkerSet(PLAYER_SPAWN_BED_SETID);
|
|
if(spawnbedset != null) {
|
|
spawnbedset.deleteMarkerSet();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updatePlayer(DynmapPlayer p) {
|
|
DynmapLocation bl = p.getBedSpawnLocation();
|
|
Marker m = spawnbedset.findMarker(p.getName()+"_bed");
|
|
if(bl == null) { /* No bed location */
|
|
if(m != null) {
|
|
m.deleteMarker();
|
|
}
|
|
}
|
|
else {
|
|
if(m != null)
|
|
m.setLocation(bl.world, bl.x, bl.y, bl.z);
|
|
else
|
|
m = spawnbedset.createMarker(p.getName()+"_bed", spawnbedformat.replace("%name%", core.getServer().stripChatColor(p.getDisplayName())), false,
|
|
bl.world, bl.x, bl.y, bl.z,
|
|
spawnbedicon, true);
|
|
}
|
|
}
|
|
|
|
|
|
private void addUpdateWorld(DynmapWorld w, DynmapLocation loc) {
|
|
MarkerSet ms = api.getMarkerSet(MarkerSet.DEFAULT);
|
|
if(ms != null) {
|
|
String spawnid = "_spawn_" + w.getName();
|
|
Marker m = ms.findMarker(spawnid); /* See if defined */
|
|
if (showSpawn) {
|
|
if(m == null) { /* Not defined yet, add it */
|
|
ms.createMarker(spawnid, spawnlbl, w.getName(), loc.x, loc.y, loc.z,
|
|
spawnicon, false);
|
|
}
|
|
else {
|
|
m.setLocation(w.getName(), loc.x, loc.y, loc.z);
|
|
}
|
|
}
|
|
else {
|
|
if (m != null) {
|
|
m.deleteMarker();
|
|
}
|
|
}
|
|
String borderid = "_worldborder_" + w.getName();
|
|
AreaMarker am = ms.findAreaMarker(borderid);
|
|
Polygon p = null;
|
|
if (showBorder && w.showborder) {
|
|
p = w.getWorldBorder();
|
|
}
|
|
if ((p != null) && (p.size() > 1)) {
|
|
double[] x;
|
|
double[] z;
|
|
if (p.size() == 2) {
|
|
x = new double[4];
|
|
z = new double[4];
|
|
Polygon.Point2D p0 = p.getVertex(0);
|
|
Polygon.Point2D p1 = p.getVertex(1);
|
|
x[0] = p0.x; z[0] = p0.y;
|
|
x[1] = p0.x; z[1] = p1.y;
|
|
x[2] = p1.x; z[2] = p1.y;
|
|
x[3] = p1.x; z[3] = p0.y;
|
|
}
|
|
else {
|
|
int sz = p.size();
|
|
x = new double[sz];
|
|
z = new double[sz];
|
|
for (int i = 0; i < sz; i++) {
|
|
Polygon.Point2D pi = p.getVertex(i);
|
|
x[i] = pi.x; z[i] = pi.y;
|
|
}
|
|
}
|
|
if (am == null) {
|
|
am = ms.createAreaMarker(borderid, worldborderlbl, false, w.getName(), x, z, false);
|
|
}
|
|
else {
|
|
am.setCornerLocations(x, z);
|
|
}
|
|
am.setFillStyle(0.0, 0);
|
|
}
|
|
else {
|
|
if (am != null) {
|
|
am.deleteMarker();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void dispose() {
|
|
if(signmgr != null) {
|
|
MarkerSignManager.terminateSignManager(this.core);
|
|
signmgr = null;
|
|
}
|
|
/* Don't unregister API - other plugins might be using it, and we want to keep non-persistent markers */
|
|
}
|
|
}
|