mirror of
https://github.com/encounter/dynmap.git
synced 2026-03-30 11:08:39 -07:00
Compare commits
67 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 13e829cda0 | |||
| 455b5d3b3e | |||
| 8abf596ba6 | |||
| 1beb4fa466 | |||
| e47b4dc49f | |||
| 3ff0b85ef7 | |||
| 99ae8a8f3b | |||
| 18b36f96fe | |||
| 36d1a7676e | |||
| f14e097c54 | |||
| 4de18ac700 | |||
| 98f03c588e | |||
| 5ee5fee232 | |||
| c2047fe7c4 | |||
| 34093874bc | |||
| 676f6c5a3e | |||
| 9ea9e347ea | |||
| 75efba1425 | |||
| 6419469be3 | |||
| 68412ae27d | |||
| bcb25468db | |||
| 78b243371d | |||
| 867f069822 | |||
| 7dec76aadc | |||
| b27fcdbd4b | |||
| 9b8a90bf9f | |||
| 3aa48f2215 | |||
| ce60452a35 | |||
| 08ba9de51c | |||
| 9f1c8f548a | |||
| 18a1f484d8 | |||
| 53e7ab73a0 | |||
| 6205aee3b6 | |||
| 32567b8569 | |||
| b501f1d8cb | |||
| b22a48d5cb | |||
| b5deec79be | |||
| d594df93ee | |||
| 686b09bc9d | |||
| dfc051743d | |||
| dfe33efdc3 | |||
| 77b0bc1664 | |||
| 2e1a9d0a0e | |||
| ff5f96aa78 | |||
| 342a72f39f | |||
| 4f0e89b1d8 | |||
| c4cce7182a | |||
| d634aede92 | |||
| 27fb8a20f1 | |||
| 8263918b8d | |||
| 4b5e6e6f80 | |||
| c8a08b5af7 | |||
| ce7bfdb46e | |||
| a08edc3fa9 | |||
| 2b2891bd0a | |||
| e1a3ac60e2 | |||
| 8860eb8c04 | |||
| 90afd9ef82 | |||
| 6a7559f3ad | |||
| b4fca31cd5 | |||
| 8162817041 | |||
| c5d5a85a17 | |||
| 225d28e177 | |||
| 4261f30dcd | |||
| eafc8a858c | |||
| f0ec375834 | |||
| 80f9435a1a |
+25
@@ -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
|
||||
@@ -1,46 +1,41 @@
|
||||
<project name="dynmap" default="dist" basedir=".">
|
||||
<!-- Change the following two properties to the correct jar files -->
|
||||
<property name="minecraftserver.jar" location="../../minecraft_server.jar"/>
|
||||
<property name="hmod.jar" location="../../Minecraft_Mod.jar"/>
|
||||
<property name="bukkit.jar" location="C:\Users\Bob\Desktop\minecraft_server\bukkit-0.0.1-SNAPSHOT.jar"/>
|
||||
<property name="minecraft" location="C:\Users\Bob\Desktop\minecraft_server"/>
|
||||
<property name="plugins" location="${minecraft}/plugins/"/>
|
||||
<property name="http_root" location="/srv/http/dynmap/"/>
|
||||
<property name="pluginname" value="dynmap"/>
|
||||
|
||||
<property name="minecraft" location="../../"/>
|
||||
<property name="plugins" location="${minecraft}/plugins/"/>
|
||||
<property name="http_root" location="/srv/http/dynmap/"/>
|
||||
|
||||
<property name="src" location="src"/>
|
||||
<property name="bin" location="bin"/>
|
||||
<property name="dist" location="dist"/>
|
||||
<property name="web" location="web"/>
|
||||
|
||||
<target name="init">
|
||||
<mkdir dir="${bin}"/>
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="init">
|
||||
<javac srcdir="${src}" destdir="${bin}" includeantruntime="false">
|
||||
<classpath>
|
||||
<pathelement location="${hmod.jar}"/>
|
||||
<pathelement location="${minecraftserver.jar}"/>
|
||||
</classpath>
|
||||
</javac>
|
||||
<javac srcdir="${src}/main/java" destdir="${bin}" classpath="${bukkit.jar}" debug="on" includeantruntime="false" />
|
||||
</target>
|
||||
|
||||
<target name="dist" depends="compile">
|
||||
<mkdir dir="${dist}"/>
|
||||
<jar jarfile="${dist}/map.jar" basedir="${bin}"/>
|
||||
<jar jarfile="${dist}/${pluginname}.jar">
|
||||
<fileset dir="${bin}"/>
|
||||
<fileset file="${src}/main/resources/plugin.yml"/>
|
||||
<zipfileset file="${src}/main/resources/colors.txt"/>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="deploy" depends="dist">
|
||||
<copy file="${dist}/map.jar" todir="${plugins}"/>
|
||||
<copy file="colors.txt" todir="${minecraft}"/>
|
||||
<copy file="${dist}/${pluginname}.jar" todir="${plugins}"/>
|
||||
<copy todir="${http_root}">
|
||||
<fileset dir="web"/>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="release" depends="dist">
|
||||
<delete file="dynmap.zip"/>
|
||||
<zip destfile="dynmap.zip">
|
||||
<delete file="${pluginname}.zip"/>
|
||||
<zip destfile="${pluginname}.zip">
|
||||
<zipfileset dir="." includes="README.md" fullpath="readme.txt"/>
|
||||
<zipfileset dir="." includes="build.xml"/>
|
||||
<zipfileset dir="${dist}" includes="*.jar"/>
|
||||
@@ -53,4 +48,4 @@
|
||||
<delete dir="${bin}"/>
|
||||
<delete dir="${dist}"/>
|
||||
</target>
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<project name="dynmap_parameters" basedir=".">
|
||||
<property name="bukkit.jar" location="../../bukkit.jar"/>
|
||||
<property name="minecraft" location="../../"/>
|
||||
<property name="plugins" location="${minecraft}/plugins/"/>
|
||||
<property name="http_root" location="/srv/http/dynmap/"/>
|
||||
</project>
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
# All paths in this configuration file are relative to Dynmap's data-folder: minecraft_server/plugins/dynmap/
|
||||
|
||||
# How often a tile gets rendered (in seconds).
|
||||
renderinterval: 1
|
||||
|
||||
# The path where the tile-files are placed.
|
||||
tilepath: web/tiles
|
||||
|
||||
# The path where the web-files are located.
|
||||
webpath: web
|
||||
|
||||
# The network-interface the webserver will bind to (0.0.0.0 for all interfaces, 127.0.0.1 for only local access).
|
||||
webserver-bindaddress: 0.0.0.0
|
||||
|
||||
# The TCP-port the webserver will listen on.
|
||||
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
|
||||
@@ -0,0 +1,30 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>dynamic-map</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>DynamicMap</name>
|
||||
<url>http://www.bukkit.org</url>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.0.2</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
Commands
|
||||
--------------------------------------------------
|
||||
/map_wait [wait] - set wait between tile renders (ms)
|
||||
/map_stat - query number of tiles in render queue
|
||||
/map_regen - regenerate entire map (currently buggy)
|
||||
/map_debug - send map debugging messages
|
||||
/map_nodebug - disable map debugging messages
|
||||
/map_regenzoom - regenerates zoom-out tiles
|
||||
|
||||
/addsign [name] - adds a named sign to the map
|
||||
/removesign [name] - removes a named sign to the map
|
||||
/listsigns - list all named signs
|
||||
/tpsign [name] - teleport to a named sign
|
||||
|
||||
server.properties
|
||||
--------------------------------------------------
|
||||
map-colorsetpath - point to colors.txt
|
||||
map-tilepath - point to web/tiles folder
|
||||
map-signspath - point to signs.txt file (do not need to create the file, one will be created when you create a sign)
|
||||
map-serverport - the port the web server runs on (default is 8123)
|
||||
map-showmarkers - a list of which markers to show on the map, comma separated if multiple (spawn, homes, warps, signs, players, all, none)
|
||||
map-generateportraits - whether player-portraits are generated by the server (0, 1, default: 0)
|
||||
@@ -1,13 +0,0 @@
|
||||
/* FlatFileSource class wrapper to expose protected properties */
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DMFlatFileSource extends FlatFileSource {
|
||||
public List<Warp> getAllWarps() {
|
||||
return this.warps;
|
||||
}
|
||||
|
||||
public List<Warp> getAllHomes() {
|
||||
return this.homes;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
/* MySQLSource class wrapper to expose protected properties */
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DMMySQLSource extends MySQLSource {
|
||||
public List<Warp> getAllWarps() {
|
||||
return this.warps;
|
||||
}
|
||||
|
||||
public List<Warp> getAllHomes() {
|
||||
return this.homes;
|
||||
}
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class MapListener extends PluginListener {
|
||||
private static final Logger log = Logger.getLogger("Minecraft");
|
||||
private MapManager mgr;
|
||||
|
||||
public MapListener(MapManager mgr)
|
||||
{
|
||||
this.mgr = mgr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockCreate(Player player, Block blockPlaced, Block blockClicked, int itemInHand)
|
||||
{
|
||||
if(mgr.touch(blockPlaced.getX(), blockPlaced.getY(), blockPlaced.getZ()))
|
||||
mgr.debug(player.getName() + " touch " + blockPlaced.getX() + "," + blockPlaced.getY() + "," + blockPlaced.getZ() + " from onBlockCreate");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockDestroy(Player player, Block block)
|
||||
{
|
||||
int x = block.getX();
|
||||
int y = block.getY();
|
||||
int z = block.getZ();
|
||||
if(x == 0 && y == 0 && z == 0)
|
||||
return false;
|
||||
|
||||
if(mgr.touch(x, y, z))
|
||||
mgr.debug(player.getName() + " touch " + x + "," + y + "," + z + " from onBlockBreak");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLogin(Player player)
|
||||
{
|
||||
mgr.getPlayerImage(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(Player player, String[] split)
|
||||
{
|
||||
if(!player.canUseCommand(split[0]))
|
||||
return false;
|
||||
|
||||
if(split[0].equals("/map_wait")) {
|
||||
if(split.length < 2) {
|
||||
mgr.renderWait = 1000;
|
||||
} else {
|
||||
try {
|
||||
mgr.renderWait = Integer.parseInt(split[1]);
|
||||
} catch(NumberFormatException e) {
|
||||
player.sendMessage(Colors.Rose + "Invalid number");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if(split[0].equals("/map_regen")) {
|
||||
mgr.regenerate((int) player.getX(), (int) player.getY(), (int) player.getZ());
|
||||
player.sendMessage(Colors.Rose + "Map regeneration in progress");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(split[0].equals("/map_stat")) {
|
||||
player.sendMessage(Colors.Rose + "Stale tiles: " + mgr.getStaleCount() + " Recent updates: " + mgr.getRecentUpdateCount());
|
||||
return true;
|
||||
}
|
||||
|
||||
if(split[0].equals("/map_debug")) {
|
||||
mgr.debugPlayer = player.getName();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(split[0].equals("/map_nodebug")) {
|
||||
mgr.debugPlayer = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(split[0].equals("/addsign")) {
|
||||
if(split.length < 2)
|
||||
{
|
||||
player.sendMessage("Map> " + Colors.Red + "Usage: /addsign [name]");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mgr.addSign(player, split[1], player.getX(), player.getY(), player.getZ()))
|
||||
{
|
||||
player.sendMessage("Map> " + Colors.White + "Sign \"" + split[1] + "\" added successfully");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if(split[0].equals("/removesign")) {
|
||||
if(split.length < 2)
|
||||
{
|
||||
player.sendMessage("Map> " + Colors.Red + "Usage: /removesign [name]");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mgr.removeSign(player, split[1]))
|
||||
{
|
||||
player.sendMessage("Map> " + Colors.White + "Sign \"" + split[1] + "\" removed successfully");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if(split[0].equals("/listsigns")) {
|
||||
String msg = "";
|
||||
Collection<Warp> values = mgr.signs.values();
|
||||
Iterator<Warp> it = values.iterator();
|
||||
while(it.hasNext())
|
||||
{
|
||||
Warp sign = it.next();
|
||||
String line = " - " + sign.Name + "\t";
|
||||
msg += line;
|
||||
}
|
||||
player.sendMessage("" + Colors.White + msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(split[0].equals("/tpsign")) {
|
||||
if(split.length < 2)
|
||||
{
|
||||
player.sendMessage("Map> " + Colors.Red + "Usage: /tpsign [name]");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mgr.teleportToSign(player, split[1]))
|
||||
{
|
||||
//player.sendMessage("Map> " + Colors.White + "");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if(split[0].equals("/map_regenzoom")) {
|
||||
mgr.regenerateZoom((int) player.getX(), (int) player.getY(), (int) player.getZ());
|
||||
player.sendMessage(Colors.Rose + "regenerateZoom done");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,53 +0,0 @@
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class WebServer extends Thread {
|
||||
|
||||
public static final String VERSION = "Huncraft";
|
||||
protected static final Logger log = Logger.getLogger("Minecraft");
|
||||
|
||||
private ServerSocket sock = null;
|
||||
private boolean running = false;
|
||||
|
||||
private MapManager mgr;
|
||||
|
||||
public WebServer(int port, MapManager mgr) throws IOException
|
||||
{
|
||||
this.mgr = mgr;
|
||||
sock = new ServerSocket(port, 5, InetAddress.getByName("127.0.0.1"));
|
||||
running = true;
|
||||
start();
|
||||
log.info("map WebServer started on port " + port);
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
while (running) {
|
||||
try {
|
||||
Socket socket = sock.accept();
|
||||
WebServerRequest requestThread = new WebServerRequest(socket, mgr);
|
||||
requestThread.start();
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.info("map WebServer.run() stops with IOException");
|
||||
break;
|
||||
}
|
||||
}
|
||||
log.info("map WebServer run() exiting");
|
||||
}
|
||||
|
||||
public void shutdown()
|
||||
{
|
||||
try {
|
||||
if(sock != null) {
|
||||
sock.close();
|
||||
}
|
||||
} catch(IOException e) {
|
||||
log.info("map stop() got IOException while closing socket");
|
||||
}
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.Socket;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class WebServerRequest extends Thread {
|
||||
protected static final Logger log = Logger.getLogger("Minecraft");
|
||||
|
||||
private Socket sock;
|
||||
private MapManager mgr;
|
||||
|
||||
public WebServerRequest(Socket socket, MapManager mgr)
|
||||
{
|
||||
sock = socket;
|
||||
this.mgr = mgr;
|
||||
}
|
||||
|
||||
private static void sendHeader(BufferedOutputStream out, int code, String contentType, long contentLength, long lastModified) throws IOException
|
||||
{
|
||||
out.write(("HTTP/1.0 " + code + " OK\r\n" +
|
||||
"Date: " + new Date().toString() + "\r\n" +
|
||||
"Server: JibbleWebServer/1.0\r\n" +
|
||||
"Content-Type: " + contentType + "\r\n" +
|
||||
"Expires: Thu, 01 Dec 1994 16:00:00 GMT\r\n" +
|
||||
((contentLength != -1) ? "Content-Length: " + contentLength + "\r\n" : "") +
|
||||
"Last-modified: " + new Date(lastModified).toString() + "\r\n" +
|
||||
"\r\n").getBytes());
|
||||
}
|
||||
|
||||
private static void sendError(BufferedOutputStream out, int code, String message) throws IOException
|
||||
{
|
||||
message = message + "<hr>" + WebServer.VERSION;
|
||||
sendHeader(out, code, "text/html", message.length(), System.currentTimeMillis());
|
||||
out.write(message.getBytes());
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
InputStream reader = null;
|
||||
try {
|
||||
sock.setSoTimeout(30000);
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
|
||||
BufferedOutputStream out = new BufferedOutputStream(sock.getOutputStream());
|
||||
|
||||
String request = in.readLine();
|
||||
if (request == null || !request.startsWith("GET ") || !(request.endsWith(" HTTP/1.0") || request.endsWith("HTTP/1.1"))) {
|
||||
// Invalid request type (no "GET")
|
||||
sendError(out, 500, "Invalid Method.");
|
||||
return;
|
||||
}
|
||||
|
||||
String path = request.substring(4, request.length() - 9);
|
||||
|
||||
int current = (int) (System.currentTimeMillis() / 1000);
|
||||
long cutoff = 0;
|
||||
|
||||
if(path.charAt(0) == '/') {
|
||||
try {
|
||||
cutoff = ((long) Integer.parseInt(path.substring(1))) * 1000;
|
||||
} catch(NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
sendHeader(out, 200, "text/plain", -1, System.currentTimeMillis());
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(current + " " + etc.getServer().getRelativeTime() + "\n");
|
||||
|
||||
if (mgr.showPlayers) {
|
||||
for(Player player : etc.getServer().getPlayerList()) {
|
||||
sb.append(player.getName() + " player " + player.getX() + " " + player.getY() + " " + player.getZ() + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (mgr.showSigns) {
|
||||
for(Warp sign : mgr.signs.values())
|
||||
{
|
||||
sb.append(sign.Name + " sign " + sign.Location.x + " " + sign.Location.y + " " + sign.Location.z + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (mgr.showWarps) {
|
||||
List<Warp> warps = mgr.loadWarps();
|
||||
|
||||
if (warps != null) {
|
||||
for(Warp warp : warps) {
|
||||
sb.append(warp.Name + " warp " + warp.Location.x + " " + warp.Location.y + " " + warp.Location.z + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mgr.showHomes) {
|
||||
List<Warp> homes = mgr.loadHomes();
|
||||
|
||||
if (homes != null) {
|
||||
for(Warp warp : homes) {
|
||||
sb.append(warp.Name + " home " + warp.Location.x + " " + warp.Location.y + " " + warp.Location.z + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mgr.showSpawn) {
|
||||
Location spawnLocation = etc.getServer().getSpawnLocation();
|
||||
|
||||
sb.append("Spawn spawn " + spawnLocation.x + " " + spawnLocation.y + " " + spawnLocation.z + "\n");
|
||||
}
|
||||
|
||||
synchronized(mgr.lock) {
|
||||
for(TileUpdate tu : mgr.tileUpdates) {
|
||||
if(tu.at >= cutoff) {
|
||||
sb.append(tu.tile.px + "_" + tu.tile.py + " " + tu.tile.zpx + "_" + tu.tile.zpy + " t\n");
|
||||
}
|
||||
}
|
||||
|
||||
for(TileUpdate tu : mgr.caveTileUpdates) {
|
||||
if(tu.at >= cutoff) {
|
||||
sb.append(tu.tile.px + "_" + tu.tile.py + " " + tu.tile.zpx + "_" + tu.tile.zpy + " c\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.write(sb.toString().getBytes());
|
||||
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
}
|
||||
catch (Exception anye) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
package org.dynmap;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Cache<K, V>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.dynmap;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockDamageLevel;
|
||||
import org.bukkit.event.block.BlockDamageEvent;
|
||||
import org.bukkit.event.block.BlockListener;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
|
||||
public class DynmapBlockListener extends BlockListener {
|
||||
private MapManager mgr;
|
||||
|
||||
public DynmapBlockListener(MapManager mgr) {
|
||||
this.mgr = mgr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
Block blockPlaced = event.getBlockPlaced();
|
||||
mgr.touch(blockPlaced.getX(), blockPlaced.getY(), blockPlaced.getZ());
|
||||
}
|
||||
|
||||
public void onBlockDamage(BlockDamageEvent event) {
|
||||
if (event.getDamageLevel() == BlockDamageLevel.BROKEN) {
|
||||
Block blockBroken = event.getBlock();
|
||||
mgr.touch(blockBroken.getX(), blockBroken.getY(), blockBroken.getZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.dynmap;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerListener;
|
||||
|
||||
public class DynmapPlayerListener extends PlayerListener {
|
||||
private MapManager mgr;
|
||||
private PlayerList playerList;
|
||||
|
||||
public DynmapPlayerListener(MapManager mgr, PlayerList playerList) {
|
||||
this.mgr = mgr;
|
||||
this.playerList = playerList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerCommand(PlayerChatEvent event) {
|
||||
String[] split = event.getMessage().split(" ");
|
||||
if (split[0].equalsIgnoreCase("/dynmap")) {
|
||||
if (split.length > 1) {
|
||||
if (split[1].equals("render")) {
|
||||
Player player = event.getPlayer();
|
||||
mgr.touch(player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ());
|
||||
event.setCancelled(true);
|
||||
} else if (split[1].equals("hide")) {
|
||||
if (split.length == 2) {
|
||||
playerList.hide(event.getPlayer().getName());
|
||||
} else for (int i=2;i<split.length;i++)
|
||||
playerList.hide(split[i]);
|
||||
event.setCancelled(true);
|
||||
} else if (split[1].equals("show")) {
|
||||
if (split.length == 2) {
|
||||
playerList.show(event.getPlayer().getName());
|
||||
} else for (int i=2;i<split.length;i++)
|
||||
playerList.show(split[i]);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player sends a chat message
|
||||
*
|
||||
* @param event Relevant event details
|
||||
*/
|
||||
public void onPlayerChat(PlayerChatEvent event)
|
||||
{
|
||||
mgr.addChatEvent(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package org.dynmap;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.io.File;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.event.*;
|
||||
import org.bukkit.event.Event.Priority;
|
||||
import org.bukkit.event.block.BlockListener;
|
||||
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 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;
|
||||
}
|
||||
|
||||
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"));
|
||||
configuration.load();
|
||||
|
||||
debugger.enable();
|
||||
playerList = new PlayerList(getServer());
|
||||
playerList.load();
|
||||
|
||||
mapManager = new MapManager(getWorld(), debugger, configuration);
|
||||
mapManager.startManager();
|
||||
|
||||
try {
|
||||
webServer = new WebServer(mapManager, getWorld(), playerList, debugger, configuration);
|
||||
} catch(IOException e) {
|
||||
log.info("position failed to start WebServer (IOException)");
|
||||
}
|
||||
|
||||
registerEvents();
|
||||
}
|
||||
|
||||
public void onDisable() {
|
||||
mapManager.stopManager();
|
||||
|
||||
if(webServer != null) {
|
||||
webServer.shutdown();
|
||||
webServer = null;
|
||||
}
|
||||
debugger.disable();
|
||||
}
|
||||
|
||||
public void registerEvents() {
|
||||
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(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);
|
||||
etc.getLoader().addListener(PluginLoader.Hook.BLOCK_DESTROYED, listener, this, PluginListener.Priority.MEDIUM);
|
||||
etc.getLoader().addListener(PluginLoader.Hook.LOGIN, listener, this, PluginListener.Priority.MEDIUM);
|
||||
|
||||
etc.getInstance().addCommand("/map_wait", " [wait] - set wait between tile renders (ms)");
|
||||
etc.getInstance().addCommand("/map_stat", " - query number of tiles in render queue");
|
||||
etc.getInstance().addCommand("/map_regen", " - regenerate entire map");
|
||||
etc.getInstance().addCommand("/map_debug", " - send map debugging messages");
|
||||
etc.getInstance().addCommand("/map_nodebug", " - disable map debugging messages");
|
||||
etc.getInstance().addCommand("/addsign", " [name] - adds a named sign to the map");
|
||||
etc.getInstance().addCommand("/removesign", " [name] - removes a named sign to the map");
|
||||
etc.getInstance().addCommand("/listsigns", " - list all named signs");
|
||||
etc.getInstance().addCommand("/tpsign", " [name] - teleport to a named sign");
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.dynmap;
|
||||
|
||||
public class MapLocation {
|
||||
public float x;
|
||||
public float y;
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
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;
|
||||
|
||||
public class MapManager extends Thread {
|
||||
protected static final Logger log = Logger.getLogger("Minecraft");
|
||||
|
||||
private World world;
|
||||
private Debugger debugger;
|
||||
private MapType[] maps;
|
||||
public StaleQueue staleQueue;
|
||||
public ChatQueue chatQueue;
|
||||
public PlayerList playerList;
|
||||
|
||||
/* lock for our data structures */
|
||||
public static final Object lock = new Object();
|
||||
|
||||
/* whether the worker thread should be running now */
|
||||
private boolean running = false;
|
||||
|
||||
/* path to image tile directory */
|
||||
public File tileDirectory;
|
||||
|
||||
/* web files location */
|
||||
public File webDirectory;
|
||||
|
||||
/* bind web server to ip-address */
|
||||
public String bindaddress = "0.0.0.0";
|
||||
|
||||
/* port to run web server on */
|
||||
public int serverport = 8123;
|
||||
|
||||
/* time to pause between rendering tiles (ms) */
|
||||
public int renderWait = 500;
|
||||
|
||||
public void debug(String msg)
|
||||
{
|
||||
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 = 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();
|
||||
|
||||
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 */
|
||||
public void startManager()
|
||||
{
|
||||
synchronized(lock) {
|
||||
running = true;
|
||||
this.start();
|
||||
try {
|
||||
this.setPriority(MIN_PRIORITY);
|
||||
log.info("Set minimum priority for worker thread");
|
||||
} catch(SecurityException e) {
|
||||
log.info("Failed to set minimum priority for worker thread!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* stop map manager */
|
||||
public void stopManager()
|
||||
{
|
||||
synchronized(lock) {
|
||||
if(!running)
|
||||
return;
|
||||
|
||||
log.info("Stopping map renderer...");
|
||||
running = false;
|
||||
|
||||
try {
|
||||
this.join();
|
||||
} catch(InterruptedException e) {
|
||||
log.info("Waiting for map renderer to stop is interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* the worker/renderer thread */
|
||||
public void run()
|
||||
{
|
||||
try {
|
||||
log.info("Map renderer has started.");
|
||||
|
||||
while(running) {
|
||||
boolean found = false;
|
||||
|
||||
MapTile t = staleQueue.popStaleTile();
|
||||
if(t != null) {
|
||||
debugger.debug("rendering tile " + t + "...");
|
||||
t.getMap().render(t);
|
||||
|
||||
staleQueue.onTileUpdated(t);
|
||||
|
||||
try {
|
||||
Thread.sleep(renderWait);
|
||||
} catch(InterruptedException e) {
|
||||
}
|
||||
|
||||
found = true;
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch(InterruptedException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.info("Map renderer has stopped.");
|
||||
} catch(Exception ex) {
|
||||
debugger.error("Exception on rendering-thread: " + ex.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void touch(int x, int y, int 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);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user