Compare commits

...

18 Commits

Author SHA1 Message Date
FrozenCow 13e829cda0 Updated Server.getTime to World.getTime (to reflect Bukkit's changes) 2011-02-02 11:40:49 +01:00
FrozenCow 455b5d3b3e Added showchatballoons, showplayerfacesonmap and showplayerfacesinmenu to configuration. 2011-02-01 15:16:54 +01:00
FrozenCow 8abf596ba6 Organized imports. 2011-02-01 14:23:13 +01:00
FrozenCow 1beb4fa466 Added server-to-client configuration and maptype-configuration: enables serverside configuration of maps and updaterate. 2011-02-01 14:17:08 +01:00
FrozenCow e47b4dc49f Small fixes to chat-balloons. 2011-01-26 01:05:00 +01:00
FrozenCow 3ff0b85ef7 Merge branch 'master' of https://github.com/NathanWolf/dynmap 2011-01-26 00:39:48 +01:00
FrozenCow 99ae8a8f3b Moved Web* to webpackage and added server-to-client configuration (server-side). 2011-01-26 00:38:36 +01:00
Nathan Wolf 18b36f96fe Finish the client-side chat bubble interface:
- Bubbles disappear automatically after some time
 - Each bubble shows the last 5 messages for each player
 - Some formatting to the bubble done, could be better (add high-res
player pic?)
2011-01-25 15:10:42 -08:00
FrozenCow 36d1a7676e Merge branch 'master' of https://github.com/NathanWolf/dynmap 2011-01-25 23:06:48 +01:00
Nathan Wolf f14e097c54 Adding chat message pop-ups! 2011-01-25 14:03:27 -08:00
FrozenCow 4de18ac700 Changed startup message (shows webserver-info, hides debug) 2011-01-25 22:59:22 +01:00
FrozenCow 98f03c588e Added ignores. 2011-01-25 22:56:35 +01:00
FrozenCow 5ee5fee232 Added getters/setters. 2011-01-25 18:43:11 +01:00
FrozenCow c2047fe7c4 Fixed webpath and tilepath accepting absolute paths. 2011-01-23 19:56:59 +01:00
FrozenCow 34093874bc Changed /map to /dynmap. 2011-01-23 12:07:23 +01:00
FrozenCow 676f6c5a3e Made it possible to change background color in style.css 2011-01-23 12:00:15 +01:00
FrozenCow 9ea9e347ea Changed proxy-url to /up/ as ktr suggested. 2011-01-22 14:55:50 -08:00
FrozenCow 75efba1425 Fixed comment in config.js. 2011-01-20 23:29:38 +01:00
19 changed files with 562 additions and 128 deletions
+25
View File
@@ -0,0 +1,25 @@
# Eclipse stuff
/.classpath
/.project
/.settings
# netbeans
/nbproject
# we use maven!
/build.xml
# maven
/target
# vim
.*.sw[a-p]
# various other potential build files
/build
/bin
/dist
/manifest.mf
# Mac filesystem dust
/.DS_Store
Regular → Executable
+30 -1
View File
@@ -13,4 +13,33 @@ webpath: web
webserver-bindaddress: 0.0.0.0
# The TCP-port the webserver will listen on.
webserver-port: 8123
webserver-port: 8123
# The maptypes Dynmap will use to render.
maps:
- class: org.dynmap.kzedmap.KzedMap
renderers:
- class: org.dynmap.kzedmap.DefaultTileRenderer
prefix: t
- class: org.dynmap.kzedmap.CaveTileRenderer
prefix: ct
web:
# Interval the browser should poll for updates.
updaterate: 2000
showchatballoons: true
showplayerfacesonmap: true
showplayerfacesinmenu: true
# The name of the map shown when opening Dynmap's page (must be in menu).
defaultmap: defaultmap
# The maps shown in the menu.
shownmaps:
- type: KzedMapType
name: defaultmap
prefix: t
- type: KzedMapType
name: cavemap
prefix: ct
+70
View File
@@ -0,0 +1,70 @@
package org.dynmap;
import java.util.ArrayList;
import java.util.LinkedList;
import org.bukkit.event.player.PlayerChatEvent;
public class ChatQueue {
public class ChatMessage
{
public long time;
public String playerName;
public String message;
public ChatMessage(PlayerChatEvent event)
{
time = System.currentTimeMillis();
playerName = event.getPlayer().getName();
message = event.getMessage();
}
}
/* a list of recent chat message */
private LinkedList<ChatMessage> messageQueue;
/* remember up to this old chat messages (ms) */
private static final int maxChatAge = 120000;
public ChatQueue() {
messageQueue = new LinkedList<ChatMessage>();
}
/* put a chat message in the queue */
public void pushChatMessage(PlayerChatEvent event)
{
synchronized(MapManager.lock) {
messageQueue.add(new ChatMessage(event));
}
}
public ChatMessage[] getChatMessages(long cutoff) {
ArrayList<ChatMessage> queue = new ArrayList<ChatMessage>();
ArrayList<ChatMessage> updateList = new ArrayList<ChatMessage>();
queue.addAll(messageQueue);
long now = System.currentTimeMillis();
long deadline = now - maxChatAge;
synchronized(MapManager.lock) {
for (ChatMessage message : queue)
{
if (message.time < deadline)
{
messageQueue.remove(message);
}
else if (message.time >= cutoff)
{
updateList.add(message);
}
}
}
ChatMessage[] messages = new ChatMessage[updateList.size()];
updateList.toArray(messages);
return messages;
}
}
@@ -16,7 +16,7 @@ public class DynmapPlayerListener extends PlayerListener {
@Override
public void onPlayerCommand(PlayerChatEvent event) {
String[] split = event.getMessage().split(" ");
if (split[0].equalsIgnoreCase("/map")) {
if (split[0].equalsIgnoreCase("/dynmap")) {
if (split.length > 1) {
if (split[1].equals("render")) {
Player player = event.getPlayer();
@@ -38,4 +38,14 @@ public class DynmapPlayerListener extends PlayerListener {
}
}
}
/**
* Called when a player sends a chat message
*
* @param event Relevant event details
*/
public void onPlayerChat(PlayerChatEvent event)
{
mgr.addChatEvent(event);
}
}
+22 -12
View File
@@ -12,19 +12,20 @@ import org.bukkit.plugin.*;
import org.bukkit.plugin.java.*;
import org.bukkit.util.config.Configuration;
import org.dynmap.debug.BukkitPlayerDebugger;
import org.dynmap.web.WebServer;
public class DynmapPlugin extends JavaPlugin {
protected static final Logger log = Logger.getLogger("Minecraft");
private WebServer webserver = null;
private MapManager mgr = null;
private WebServer webServer = null;
private MapManager mapManager = null;
private PlayerList playerList;
private BukkitPlayerDebugger debugger = new BukkitPlayerDebugger(this);
public static File dataRoot;
public DynmapPlugin(PluginLoader pluginLoader, Server instance, PluginDescriptionFile desc, File folder, File plugin, ClassLoader cLoader) {
super(pluginLoader, instance, desc, folder, plugin, cLoader);
dataRoot = folder;
@@ -33,6 +34,14 @@ public class DynmapPlugin extends JavaPlugin {
public World getWorld() {
return getServer().getWorlds()[0];
}
public MapManager getMapManager() {
return mapManager;
}
public WebServer getWebServer() {
return webServer;
}
public void onEnable() {
Configuration configuration = new Configuration(new File(this.getDataFolder(), "configuration.txt"));
@@ -42,11 +51,11 @@ public class DynmapPlugin extends JavaPlugin {
playerList = new PlayerList(getServer());
playerList.load();
mgr = new MapManager(getWorld(), debugger, configuration);
mgr.startManager();
mapManager = new MapManager(getWorld(), debugger, configuration);
mapManager.startManager();
try {
webserver = new WebServer(mgr, getServer(), playerList, debugger, configuration);
webServer = new WebServer(mapManager, getWorld(), playerList, debugger, configuration);
} catch(IOException e) {
log.info("position failed to start WebServer (IOException)");
}
@@ -55,21 +64,22 @@ public class DynmapPlugin extends JavaPlugin {
}
public void onDisable() {
mgr.stopManager();
mapManager.stopManager();
if(webserver != null) {
webserver.shutdown();
webserver = null;
if(webServer != null) {
webServer.shutdown();
webServer = null;
}
debugger.disable();
}
public void registerEvents() {
BlockListener blockListener = new DynmapBlockListener(mgr);
BlockListener blockListener = new DynmapBlockListener(mapManager);
getServer().getPluginManager().registerEvent(Event.Type.BLOCK_PLACED, blockListener, Priority.Normal, this);
getServer().getPluginManager().registerEvent(Event.Type.BLOCK_DAMAGED, blockListener, Priority.Normal, this);
getServer().getPluginManager().registerEvent(Event.Type.PLAYER_COMMAND, new DynmapPlayerListener(mgr, playerList), Priority.Normal, this);
getServer().getPluginManager().registerEvent(Event.Type.PLAYER_COMMAND, new DynmapPlayerListener(mapManager, playerList), Priority.Normal, this);
getServer().getPluginManager().registerEvent(Event.Type.PLAYER_CHAT, new DynmapPlayerListener(mapManager, playerList), Priority.Normal, this);
//getServer().getPluginManager().registerEvent(Event.Type.BLOCK_DESTROYED, listener, Priority.Normal, this);
/* etc.getLoader().addListener(PluginLoader.Hook.COMMAND, listener, this, PluginListener.Priority.MEDIUM);
etc.getLoader().addListener(PluginLoader.Hook.BLOCK_CREATED, listener, this, PluginListener.Priority.MEDIUM);
+48 -6
View File
@@ -1,21 +1,26 @@
package org.dynmap;
import java.io.File;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.util.config.ConfigurationNode;
import org.dynmap.debug.Debugger;
import org.dynmap.kzedmap.KzedMap;
public class MapManager extends Thread {
protected static final Logger log = Logger.getLogger("Minecraft");
private World world;
private Debugger debugger;
private MapType map;
private MapType[] maps;
public StaleQueue staleQueue;
public ChatQueue chatQueue;
public PlayerList playerList;
/* lock for our data structures */
@@ -44,20 +49,50 @@ public class MapManager extends Thread {
debugger.debug(msg);
}
private static File combinePaths(File parent, String path) { return combinePaths(parent, new File(path)); }
private static File combinePaths(File parent, File path) {
if (path.isAbsolute()) return path;
return new File(parent, path.getPath());
}
public MapManager(World world, Debugger debugger, ConfigurationNode configuration)
{
this.world = world;
this.debugger = debugger;
this.staleQueue = new StaleQueue();
this.chatQueue = new ChatQueue();
tileDirectory = new File(DynmapPlugin.dataRoot, configuration.getString("tilespath", "web/tiles"));
webDirectory = new File(DynmapPlugin.dataRoot, configuration.getString("webpath", "web"));
tileDirectory = combinePaths(DynmapPlugin.dataRoot, configuration.getString("tilespath", "web/tiles"));
webDirectory = combinePaths(DynmapPlugin.dataRoot, configuration.getString("webpath", "web"));
renderWait = (int)(configuration.getDouble("renderinterval", 0.5) * 1000);
if (!tileDirectory.isDirectory())
tileDirectory.mkdirs();
map = new KzedMap(this, world, debugger, configuration);
maps = loadMapTypes(configuration);
}
private MapType[] loadMapTypes(ConfigurationNode configuration) {
List<?> configuredMaps = (List<?>)configuration.getProperty("maps");
ArrayList<MapType> mapTypes = new ArrayList<MapType>();
for(Object configuredMapObj : configuredMaps) {
try {
@SuppressWarnings("unchecked")
Map<String, Object> configuredMap = (Map<String, Object>)configuredMapObj;
String typeName = (String)configuredMap.get("class");
log.info("Loading map '" + typeName.toString() + "'...");
Class<?> mapTypeClass = Class.forName(typeName);
Constructor<?> constructor = mapTypeClass.getConstructor(MapManager.class, World.class, Debugger.class, Map.class);
MapType mapType = (MapType)constructor.newInstance(this, world, debugger, configuredMap);
mapTypes.add(mapType);
} catch (Exception e) {
debugger.error("Error loading map", e);
}
}
MapType[] result = new MapType[mapTypes.size()];
mapTypes.toArray(result);
return result;
}
/* initialize and start map manager */
@@ -132,11 +167,18 @@ public class MapManager extends Thread {
}
public void touch(int x, int y, int z) {
map.touch(new Location(world, x, y, z));
for (int i = 0; i < maps.length; i++) {
maps[i].touch(new Location(world, x, y, z));
}
}
public void invalidateTile(MapTile tile) {
debugger.debug("invalidating tile " + tile.getName());
staleQueue.pushStaleTile(tile);
}
public void addChatEvent(PlayerChatEvent event)
{
chatQueue.pushChatMessage(event);
}
}
@@ -37,7 +37,6 @@ public class BukkitPlayerDebugger implements Debugger {
public synchronized void enable() {
plugin.getServer().getPluginManager().registerEvent(Event.Type.PLAYER_COMMAND, new CommandListener(), Priority.Normal, plugin);
plugin.getServer().getPluginManager().registerEvent(Event.Type.PLAYER_QUIT, new CommandListener(), Priority.Normal, plugin);
log.info("Debugger enabled, use: " + debugCommand);
}
public synchronized void disable() {
@@ -1,15 +1,14 @@
package org.dynmap.kzedmap;
import java.awt.Color;
import java.util.Map;
import org.bukkit.World;
import org.bukkit.util.config.ConfigurationNode;
import org.dynmap.debug.Debugger;
public class CaveTileRenderer extends DefaultTileRenderer {
public CaveTileRenderer(String name, Debugger debugger, ConfigurationNode configuration) {
super(name, debugger, configuration);
public CaveTileRenderer(Debugger debugger, Map<String, Object> configuration) {
super(debugger, configuration);
}
@Override
@@ -5,11 +5,11 @@ import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import javax.imageio.ImageIO;
import org.bukkit.World;
import org.bukkit.util.config.ConfigurationNode;
import org.dynmap.debug.Debugger;
public class DefaultTileRenderer implements MapTileRenderer {
@@ -20,9 +20,9 @@ public class DefaultTileRenderer implements MapTileRenderer {
return name;
}
public DefaultTileRenderer(String name, Debugger debugger, ConfigurationNode configuration) {
this.name = name;
public DefaultTileRenderer(Debugger debugger, Map<String, Object> configuration) {
this.debugger = debugger;
name = (String)configuration.get("prefix");
}
public void render(KzedMapTile tile, String path) {
+33 -7
View File
@@ -4,18 +4,24 @@ import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.logging.Logger;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.util.config.ConfigurationNode;
import org.dynmap.MapType;
import org.dynmap.MapManager;
import org.dynmap.MapTile;
import org.dynmap.MapType;
import org.dynmap.debug.Debugger;
public class KzedMap extends MapType {
protected static final Logger log = Logger.getLogger("Minecraft");
/* dimensions of a map tile */
public static final int tileWidth = 128;
public static final int tileHeight = 128;
@@ -34,18 +40,38 @@ public class KzedMap extends MapType {
MapTileRenderer[] renderers;
ZoomedTileRenderer zoomrenderer;
public KzedMap(MapManager manager, World world, Debugger debugger, ConfigurationNode configuration) {
public KzedMap(MapManager manager, World world, Debugger debugger, Map<String, Object> configuration) {
super(manager, world, debugger);
if (colors == null) {
colors = loadColorSet("colors.txt");
}
renderers = new MapTileRenderer[] {
new DefaultTileRenderer("t", debugger, configuration),
new CaveTileRenderer("ct", debugger, configuration),
};
renderers = loadRenderers(configuration);
zoomrenderer = new ZoomedTileRenderer(debugger, configuration);
}
private MapTileRenderer[] loadRenderers(Map<String, Object> configuration) {
List<?> configuredRenderers = (List<?>)configuration.get("renderers");
ArrayList<MapTileRenderer> renderers = new ArrayList<MapTileRenderer>();
for(Object configuredRendererObj : configuredRenderers) {
try {
@SuppressWarnings("unchecked")
Map<String, Object> configuredRenderer = (Map<String, Object>)configuredRendererObj;
String typeName = (String)configuredRenderer.get("class");
log.info("Loading renderer '" + typeName.toString() + "'...");
Class<?> mapTypeClass = Class.forName(typeName);
Constructor<?> constructor = mapTypeClass.getConstructor(Debugger.class, Map.class);
MapTileRenderer mapTileRenderer = (MapTileRenderer)constructor.newInstance(getDebugger(), configuredRenderer);
renderers.add(mapTileRenderer);
} catch (Exception e) {
getDebugger().error("Error loading renderer", e);
}
}
MapTileRenderer[] result = new MapTileRenderer[renderers.size()];
renderers.toArray(result);
return result;
}
@Override
public void touch(Location l) {
int x = l.getBlockX();
@@ -5,16 +5,14 @@ import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import javax.imageio.ImageIO;
import org.bukkit.util.config.ConfigurationNode;
import org.dynmap.debug.Debugger;
public class ZoomedTileRenderer {
protected Debugger debugger;
public ZoomedTileRenderer(Debugger debugger, ConfigurationNode configuration) {
public ZoomedTileRenderer(Debugger debugger, Map<String, Object> configuration) {
this.debugger = debugger;
}
@@ -1,4 +1,4 @@
package org.dynmap;
package org.dynmap.web;
import java.io.IOException;
import java.net.InetAddress;
@@ -6,8 +6,10 @@ import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Logger;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.util.config.ConfigurationNode;
import org.dynmap.MapManager;
import org.dynmap.PlayerList;
import org.dynmap.debug.Debugger;
public class WebServer extends Thread {
@@ -21,14 +23,16 @@ public class WebServer extends Thread {
private boolean running = false;
private MapManager mgr;
private Server server;
private World world;
private PlayerList playerList;
private ConfigurationNode configuration;
public WebServer(MapManager mgr, Server server, PlayerList playerList, Debugger debugger, ConfigurationNode configuration) throws IOException
public WebServer(MapManager mgr, World world, PlayerList playerList, Debugger debugger, ConfigurationNode configuration) throws IOException
{
this.mgr = mgr;
this.server = server;
this.world = world;
this.playerList = playerList;
this.configuration = configuration;
this.debugger = debugger;
String bindAddress = configuration.getString("webserver-bindaddress", "0.0.0.0");
@@ -37,7 +41,7 @@ public class WebServer extends Thread {
sock = new ServerSocket(port, 5, bindAddress.equals("0.0.0.0") ? null : InetAddress.getByName(bindAddress));
running = true;
start();
debugger.debug("WebServer started on " + bindAddress + ":" + port);
log.info("Dynmap WebServer started on " + bindAddress + ":" + port);
}
public void run()
@@ -46,7 +50,7 @@ public class WebServer extends Thread {
while (running) {
try {
Socket socket = sock.accept();
WebServerRequest requestThread = new WebServerRequest(socket, mgr, server, playerList, debugger);
WebServerRequest requestThread = new WebServerRequest(socket, mgr, world, playerList, configuration, debugger);
requestThread.start();
}
catch (IOException e) {
@@ -1,4 +1,4 @@
package org.dynmap;
package org.dynmap.web;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
@@ -8,13 +8,20 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Logger;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.util.config.ConfigurationNode;
import org.dynmap.ChatQueue;
import org.dynmap.MapManager;
import org.dynmap.PlayerList;
import org.dynmap.TileUpdate;
import org.dynmap.debug.Debugger;
public class WebServerRequest extends Thread {
@@ -23,16 +30,18 @@ public class WebServerRequest extends Thread {
private Debugger debugger;
private Socket socket;
private MapManager mgr;
private Server server;
private World world;
private PlayerList playerList;
private ConfigurationNode configuration;
public WebServerRequest(Socket socket, MapManager mgr, Server server, PlayerList playerList, Debugger debugger)
public WebServerRequest(Socket socket, MapManager mgr, World world, PlayerList playerList, ConfigurationNode configuration, Debugger debugger)
{
this.debugger = debugger;
this.socket = socket;
this.mgr = mgr;
this.server = server;
this.world = world;
this.playerList = playerList;
this.configuration = configuration;
}
private static void writeHttpHeader(BufferedOutputStream out, int statusCode, String statusText) throws IOException {
@@ -57,11 +66,12 @@ public class WebServerRequest extends Thread {
public void run()
{
InputStream reader = null;
BufferedReader in = null;
BufferedOutputStream out = null;
try {
socket.setSoTimeout(30000);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new BufferedOutputStream(socket.getOutputStream());
String request = in.readLine();
if (request == null || !request.startsWith("GET ") || !(request.endsWith(" HTTP/1.0") || request.endsWith("HTTP/1.1"))) {
@@ -73,7 +83,9 @@ public class WebServerRequest extends Thread {
String path = request.substring(4, request.length() - 9);
debugger.debug("request: " + path);
if (path.startsWith("/up/")) {
if (path.equals("/up/configuration")) {
handleConfiguration(out);
} else if (path.startsWith("/up/")) {
handleUp(out, path.substring(3));
} else if (path.startsWith("/tiles/")) {
handleMapToDirectory(out, path.substring(6), mgr.tileDirectory);
@@ -84,20 +96,73 @@ public class WebServerRequest extends Thread {
out.close();
}
catch (IOException e) {
if (reader != null) {
try {
reader.close();
}
catch (Exception anye) {
// Do nothing.
}
}
if (out != null) { try { out.close(); } catch (Exception anye) { } }
if (in != null) { try { in.close(); } catch (Exception anye) { } }
}
catch(Exception ex) {
if (out != null) { try { out.close(); } catch (Exception anye) { } }
if (in != null) { try { in.close(); } catch (Exception anye) { } }
debugger.error("Exception on WebRequest-thread: " + ex.toString());
}
}
public String stringifyJson(Object o) {
if (o == null) {
return "null";
} else if (o instanceof Boolean) {
return ((Boolean)o) ? "true" : "false";
} else if (o instanceof String) {
return "\"" + o + "\"";
} else if (o instanceof Integer || o instanceof Long || o instanceof Float || o instanceof Double) {
return o.toString();
} else if (o instanceof LinkedHashMap<?, ?>) {
@SuppressWarnings("unchecked")
LinkedHashMap<String, Object> m = (LinkedHashMap<String, Object>)o;
StringBuilder sb = new StringBuilder();
sb.append("{");
boolean first = true;
for (String key : m.keySet()) {
if (first) first = false;
else sb.append(",");
sb.append(stringifyJson(key));
sb.append(": ");
sb.append(stringifyJson(m.get(key)));
}
sb.append("}");
return sb.toString();
} else if (o instanceof ArrayList<?>) {
@SuppressWarnings("unchecked")
ArrayList<Object> l = (ArrayList<Object>)o;
StringBuilder sb = new StringBuilder();
int count = 0;
for(int i=0;i<l.size();i++) {
sb.append(count++ == 0 ? "[" : ",");
sb.append(stringifyJson(l.get(i)));
}
sb.append("]");
return sb.toString();
} else {
return "undefined";
}
}
public void handleConfiguration(BufferedOutputStream out) throws IOException {
String s = stringifyJson(configuration.getProperty("web"));
byte[] bytes = s.getBytes();
String dateStr = new Date().toString();
writeHttpHeader(out, 200, "OK");
writeHeaderField(out, "Date", dateStr);
writeHeaderField(out, "Content-Type", "text/plain");
writeHeaderField(out, "Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
writeHeaderField(out, "Last-modified", dateStr);
writeHeaderField(out, "Content-Length", Integer.toString(bytes.length));
writeEndOfHeaders(out);
out.write(bytes);
}
public void handleUp(BufferedOutputStream out, String path) throws IOException {
int current = (int) (System.currentTimeMillis() / 1000);
long cutoff = 0;
@@ -110,8 +175,7 @@ public class WebServerRequest extends Thread {
}
StringBuilder sb = new StringBuilder();
long relativeTime = server.getTime() % 24000;
long relativeTime = world.getTime() % 24000;
sb.append(current + " " + relativeTime + "\n");
Player[] players = playerList.getVisiblePlayers();
@@ -123,8 +187,13 @@ public class WebServerRequest extends Thread {
for(TileUpdate tu : tileUpdates) {
sb.append("tile " + tu.tile.getName() + "\n");
}
ChatQueue.ChatMessage[] messages = mgr.chatQueue.getChatMessages(cutoff);
for(ChatQueue.ChatMessage cu : messages) {
sb.append("chat " + cu.playerName + " " + cu.message + "\n");
}
debugger.debug("Sending " + players.length + " players and " + tileUpdates.length + " tile-updates. " + path + ";" + cutoff);
debugger.debug("Sending " + players.length + " players, " + tileUpdates.length + " tile-updates, and " + messages.length + " chats. "+ path + ";" + cutoff);
byte[] bytes = sb.toString().getBytes();
+1 -10
View File
@@ -1,16 +1,7 @@
var config = {
tileUrl: 'tiles/',
updateUrl: 'up/', // For Apache and lighttpd
// updateUrl: 'up/default.aspx?lasttimestamp=', // For IIS
updateRate: 2000, // Seconds the map should poll for updates. (Seconds) * 1000. The default is 2000 (every 2 seconds).
showPortraitsOnMap: true,
showPortraitsInPlayerList: true,
showPlayerNameOnMap: false,
defaultMap: 'defaultmap',
maps: {
'defaultmap': new DefaultMapType(),
'cavemap': new CaveMapType()
},
// updateUrl: 'up.aspx?path=', // For IIS
tileWidth: 128,
tileHeight: 128
};
File diff suppressed because one or more lines are too long
+2 -16
View File
@@ -26,7 +26,7 @@ KzedProjection.prototype = {
}
};
function KzedMapType() {}
function KzedMapType(configuration) { $.extend(this, configuration); }
KzedMapType.prototype = $.extend(new DynMapType(), {
constructor: KzedMapType,
projection: new KzedProjection(),
@@ -113,18 +113,4 @@ KzedMapType.prototype = $.extend(new DynMapType(), {
}
return tile.get(0);
}
});
function DefaultMapType(){}
DefaultMapType.prototype = $.extend(new KzedMapType(), {
prefix: 't'
});
function CaveMapType(){}
CaveMapType.prototype = $.extend(new KzedMapType(), {
prefix: 'ct'
});
});
+112 -21
View File
@@ -68,15 +68,29 @@ MinecraftClock.prototype = {
};
function DynMap(options) {
this.options = options;
this.initialize();
var me = this;
me.options = options;
$.getJSON(me.options.updateUrl + 'configuration', function(configuration) {
me.configure(configuration);
me.initialize();
})
}
DynMap.prototype = {
registeredTiles: new Array(),
clock: null,
markers: new Array(),
chatPopups: new Array(),
lasttimestamp: '0',
followingPlayer: '',
configure: function(configuration) {
var me = this;
$.extend(me.options, configuration);
if (!me.options.maps) me.options.maps = {};
$.each(me.options.shownmaps, function(index, mapentry) {
var mapconstructor = eval(mapentry.type);
me.options.maps[mapentry.name] = new mapconstructor(mapentry);
});
},
initialize: function() {
var me = this;
@@ -97,7 +111,7 @@ DynMap.prototype = {
scaleControl: false,
mapTypeControl: false,
streetViewControl: false,
backgroundColor: '#000'
backgroundColor: 'none'
});
google.maps.event.addListener(map, 'dragstart', function(mEvent) {
@@ -135,7 +149,7 @@ DynMap.prototype = {
name: 'map',
id: 'maptypebutton_' + name
})
.attr('checked', me.options.defaultMap == name ? 'checked' : null)
.attr('checked', me.options.defaultmap == name ? 'checked' : null)
)
.append($('<label/>')
.attr('for', 'maptypebutton_' + name)
@@ -149,7 +163,7 @@ DynMap.prototype = {
.data('maptype', mapType)
.appendTo(maplist);
});
map.setMapTypeId(me.options.defaultMap);
map.setMapTypeId(me.options.defaultmap);
// The Player List
var playerlist = me.playerlist = $('<div/>')
@@ -176,10 +190,14 @@ DynMap.prototype = {
.addClass('alertbox')
.appendTo(container);
setTimeout(function() { me.update(); }, me.options.updateRate);
setTimeout(function() { me.update(); }, me.options.updaterate);
},
update: function() {
var me = this;
// TODO: is there a better place for this?
this.cleanPopups();
$.ajax({
url: me.options.updateUrl + me.lasttimestamp,
success: function(res) {
@@ -210,7 +228,23 @@ DynMap.prototype = {
tile: function() {
me.onTileUpdated(row.name);
}
}, function() {
, chat: function() {
if (!me.options.showchatballoons)
return;
var chats = line.split(' ');
var message = '';
for (var chatIndex = 2; chatIndex < chats.length; chatIndex++)
{
if (chatIndex > 2) message = message + " ";
message = message + chats[chatIndex];
}
if (message.length > 0)
{
me.onPlayerChat(row.name, message);
}
}
},
function() {
var mi = {
id: row.type + '_' + row.name,
text: row.name,
@@ -234,16 +268,70 @@ DynMap.prototype = {
delete me.markers[m];
}
}
setTimeout(function() { me.update(); }, me.options.updateRate);
setTimeout(function() { me.update(); }, me.options.updaterate);
},
error: function(request, statusText, ex) {
me.alertbox
.text('Could not update map')
.show();
setTimeout(function() { me.update(); }, me.options.updateRate);
setTimeout(function() { me.update(); }, me.options.updaterate);
}
});
},
cleanPopups: function() {
var POPUP_LIFE = 8000;
var d = new Date();
var now = d.getTime();
for (var popupIndex in this.chatPopups)
{
var popup = this.chatPopups[popupIndex];
if (now - popup.popupTime > POPUP_LIFE)
{
popup.infoWindow.close();
popup.infoWindow = null;
delete this.chatPopups[popupIndex];
}
}
},
onPlayerChat: function(playerName, message) {
var me = this;
var markers = me.markers;
var chatPopups = this.chatPopups;
var map = me.map;
var mid = "player_" + playerName;
var playerMarker = markers[mid];
if (playerMarker)
{
var popup = chatPopups[playerName];
if (!popup)
popup = { lines: [ message ] };
else
popup.lines[popup.lines.length] = message;
var MAX_LINES = 5;
if (popup.lines.length > MAX_LINES)
{
popup.lines = popup.lines.slice(1);
}
htmlMessage = '<div id="content"><b>' + playerName + "</b><br/><br/>"
for (var line in popup.lines)
{
htmlMessage = htmlMessage + popup.lines[line] + "<br/>";
}
htmlMessage = htmlMessage + "</div>"
var now = new Date();
popup.popupTime = now.getTime();
if (!popup.infoWindow) {
popup.infoWindow = new google.maps.InfoWindow({
content: htmlMessage
});
} else {
popup.infoWindow.setContent(htmlMessage);
}
popup.infoWindow.open(map, playerMarker);
this.chatPopups[playerName] = popup;
}
},
onTileUpdated: function(tileName) {
var me = this;
var tile = this.registeredTiles[tileName];
@@ -281,13 +369,14 @@ DynMap.prototype = {
.append($('<span/>')
.addClass('playerName')
.text(mi.text))
getMinecraftHead(mi.text, 32, function(head) {
$(head)
.addClass('playerIcon')
.prependTo(div);
playerImage.remove();
});
if (me.options.showplayerfacesonmap) {
getMinecraftHead(mi.text, 32, function(head) {
$(head)
.addClass('playerIcon')
.prependTo(div);
playerImage.remove();
});
}
};
}
var marker = new CustomMarker(mi.position, map, contentfun, mi);
@@ -316,11 +405,13 @@ DynMap.prototype = {
.click(function(e) { map.panTo(markers[mi.id].getPosition()); })
);
getMinecraftHead(mi.text, 16, function(head) {
marker.playerRow.icon = $(head)
.addClass('playerIcon')
.appendTo(marker.playerIconContainer);
});
if (me.options.showplayerfacesinmenu) {
getMinecraftHead(mi.text, 16, function(head) {
marker.playerRow.icon = $(head)
.addClass('playerIcon')
.appendTo(marker.playerIconContainer);
});
}
me.playerlist.append(marker.playerRow);
}
+1
View File
@@ -4,6 +4,7 @@ body { height: 100%; margin: 0px; padding: 0px ; background-color: #000; }
.map {
width: 100%; height: 100%;
background-color: black;
}
.sidebar {
+15 -15
View File
@@ -1,16 +1,16 @@
<%@ Page Language="C#" %>
<script runat="server" language="C#">
public void Page_Load(object sender, EventArgs e)
{
string path = Request.Params["path"];
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create("http://localhost:8123/" + path);
System.Net.WebResponse response = request.GetResponse();
System.IO.Stream responseStream = response.GetResponseStream();
System.IO.StreamReader reader = new System.IO.StreamReader(responseStream);
Response.ContentType = response.ContentType;
Response.Write(reader.ReadToEnd());
reader.Close();
responseStream.Close();
response.Close();
}
<%@ Page Language="C#" %>
<script runat="server" language="C#">
public void Page_Load(object sender, EventArgs e)
{
string path = Request.Params["path"];
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create("http://localhost:8123/up/" + path);
System.Net.WebResponse response = request.GetResponse();
System.IO.Stream responseStream = response.GetResponseStream();
System.IO.StreamReader reader = new System.IO.StreamReader(responseStream);
Response.ContentType = response.ContentType;
Response.Write(reader.ReadToEnd());
reader.Close();
responseStream.Close();
response.Close();
}
</script>