Compare commits

...

106 Commits

Author SHA1 Message Date
FrozenCow 39db895b9d Fixed disable-webserver not being used (thanks for checking that Kilandor). 2011-02-24 00:58:40 +01:00
FrozenCow e6d2c4932a Reverted back to "== '13'" like flames suggested before. This seemed to raise incompatiblities for Firefox and Safari on Mac, not on Linux. 2011-02-24 00:38:46 +01:00
FrozenCow 00f55758c1 Changed version to 0.13. :D 2011-02-24 00:29:57 +01:00
FrozenCow ea64a55c04 Some dumb description changes in configuration. 2011-02-24 00:21:35 +01:00
FrozenCow fcbd76c591 Removed clock configuration. 2011-02-24 00:16:30 +01:00
FrozenCow 9a32485ca9 Small cleanup. 2011-02-24 00:16:10 +01:00
FrozenCow 20e954b905 Change for the inner nerd in me. 2011-02-24 00:06:36 +01:00
FrozenCow da4c456254 Merge remote-tracking branch 'flames/master' 2011-02-24 00:03:52 +01:00
FrozenCow 95bf263f11 Merge remote-tracking branch 'kilandor/master' 2011-02-24 00:02:15 +01:00
Jason Booth 774e013558 Fix jsonfile-interval should be 1 not 1000 2011-02-23 16:31:57 -06:00
Arthur Mayer b6ec0a2955 lechd updated override example 2011-02-23 23:28:28 +01:00
Arthur Mayer cdd30d95c5 lechd's new override style to let the sidebar always open and hides
also the icon
2011-02-23 23:03:26 +01:00
Arthur Mayer cc0bb3b509 fixed chat sending messages from web.
event.keyCode === '13', where the strict equal operator seem to break
safari, firefox and chrome (different value types? keydown event seem
not to provide either a string nor an integer)
2011-02-23 21:26:51 +01:00
FrozenCow 1d2cce6caa Simplified tile-mechanism again (a bit like hMod's version). 2011-02-23 14:06:13 +01:00
FrozenCow b7f6a5a39d Applied style-change of lechd. 2011-02-23 12:40:05 +01:00
FrozenCow 1cc43637ee Merge remote-tracking branch 'kilandor/master' into nowebserver
Conflicts:
	configuration.txt
	src/main/java/org/dynmap/DynmapPlayerListener.java
	src/main/java/org/dynmap/DynmapPlugin.java
	web/map.js
2011-02-22 17:58:39 +01:00
FrozenCow da7da17235 Applied some suggestions by JSLint. 2011-02-22 15:38:49 +01:00
FrozenCow b99f487567 Replaced onPlayerCommand by onCommand (server-consoles can now also be used to execute commands). 2011-02-22 14:51:40 +01:00
FrozenCow ccf6f2ac49 Player per world support @ client. 2011-02-22 14:49:03 +01:00
FrozenCow ca76b29fb9 Made Dynmap package not include subdirectory. 2011-02-22 14:09:14 +01:00
FrozenCow 40c7c9fa66 It's official, ima retard. 2011-02-22 09:17:38 +01:00
FrozenCow fae5014b4e Added commands to plugin.yml, removed disabledcommands and added fullrender <worldname>. 2011-02-22 00:42:37 +01:00
FrozenCow 0fbd0c0a44 Added commands to plugin.yml. 2011-02-21 22:39:21 +01:00
FrozenCow 8d0f509bfe Made MapTypes per World (instead of having MapTypes for all worlds). 2011-02-21 22:17:38 +01:00
FrozenCow 65f3ea4fe3 Used new Bukkit constructor format. 2011-02-21 16:22:16 +01:00
FrozenCow b097fb8321 Added entry for css overrides and cleaned up styles by lechd. 2011-02-20 23:55:16 +01:00
FrozenCow feb6d65d82 Merge remote-tracking branch 'flames/master' 2011-02-20 22:13:41 +01:00
FrozenCow cd4027495c New buttons and example override css by lechd. 2011-02-20 22:11:28 +01:00
Arthur Mayer 298c0f3391 corrected (hopefully) the chat response for show/hide commands 2011-02-20 20:06:07 +01:00
Arthur Mayer e15514291b only OPs can use fullrender. added response to chat for
hide/show/fillrender commands.
2011-02-20 19:49:05 +01:00
FrozenCow f80385e1af Added lechd's new images. 2011-02-20 18:47:18 +01:00
FrozenCow 618d1b05c9 Merge branch 'master' of https://github.com/flames/dynmap 2011-02-20 17:46:27 +01:00
alron aaa06bfc38 Automagic packages built. Love me for this. :) 2011-02-19 21:49:24 -08:00
Arthur Mayer ad07d68d7e added configuration option messagettl, TimeToLive for chatmessages, in
Milliseconds! 15seconds: messagettl: 15000
2011-02-20 02:11:44 +01:00
Arthur Mayer 02fb226350 removed forgotten comma 2011-02-20 02:02:45 +01:00
Arthur Mayer d7fe6072a5 a lot of changes. chat and ui related. thanks FrozenCow & lechd 2011-02-20 01:58:53 +01:00
Jason Booth 6ab82174a5 Added timestamp support to Update Tiles and Chat.
New web config to handle for jsonfile method
Modified webclient to handle timestamps to prevent duplication.
Removed duplicate code in JsonTimerTask.java
2011-02-19 18:55:01 -06:00
FrozenCow 83f334445b Made chatinput reset after send. 2011-02-19 21:16:14 +01:00
FrozenCow d5bd6ff038 Made sendmessage url relative. 2011-02-19 21:08:14 +01:00
Arthur Mayer 22cc46f4b8 many ui iprovements by lechd 2011-02-19 20:51:21 +01:00
FrozenCow 77539522f0 Merge branch 'master' of https://github.com/flames/dynmap 2011-02-19 16:31:36 +01:00
FrozenCow 2bd0052aa9 Added WebChat back to web. 2011-02-19 16:31:13 +01:00
FrozenCow c53e6058be Added debugging to configuration. Disabled by default. 2011-02-19 15:25:31 +01:00
Arthur Mayer 9b604d4e75 Merge remote branch 'choose_remote_name/master' into HEAD 2011-02-19 08:28:03 +01:00
Arthur Mayer 9d490cbcc8 removed my custom url, made it relative 2011-02-19 08:26:40 +01:00
FrozenCow 791341f210 Fixed httpserver thereby also more optimized. 2011-02-19 00:01:42 +01:00
FrozenCow 42d07d6ca2 Added quotes to login/out messages for yaml. 2011-02-19 00:01:21 +01:00
Arthur Mayer 61c6f4a086 corrected the json string in sendChat() 2011-02-18 20:15:18 +01:00
FrozenCow 723e7da8d3 Added stacktrace for errors. 2011-02-18 19:43:45 +01:00
FrozenCow d3cf795ebb Fixed stupid mistake with body of http requests. 2011-02-18 19:42:32 +01:00
Arthur Mayer 67baf5100c forgotten config change for chat 2011-02-18 18:46:48 +01:00
Arthur Mayer 56f126d5f2 uups. removed debug alert, added function call 2011-02-18 11:15:05 +01:00
Arthur Mayer 10f93c02c1 added chatSend() function 2011-02-18 10:21:55 +01:00
Arthur Mayer 5ddaf940ed chat interface added, config option changed from showchatballoons:
ture/false to showchat: balloons/modal
2011-02-18 07:08:29 +01:00
Arthur Mayer 7c917b729e added join and quit messages to chat 2011-02-18 05:30:49 +01:00
Arthur Mayer 00485ddcc2 fixed small bug/typo where players were not removed from player list
at quit game.
2011-02-18 01:28:58 +01:00
Arthur Mayer 55aeb3c583 added custom configuration to nether rendering, changed pom.xml, so
maven compiles dynmap.jar instead of dynamic-map.jar
2011-02-18 01:23:14 +01:00
FrozenCow 1388fa11e5 Some desperate attempts to make IE8 work. 2011-02-18 00:07:59 +01:00
FrozenCow b860c7dd0e Added pinning. 2011-02-18 00:07:51 +01:00
FrozenCow c67b2e5cc2 Added example to configuration. 2011-02-17 21:17:54 +01:00
FrozenCow 44748d7f07 Changed gui by lechd + map per world client-configuration. 2011-02-17 20:08:50 +01:00
Jason Booth 13099587e0 Fixed mistake with map updates only pulling interval+10 instead of interval+10000 2011-02-17 11:14:37 -06:00
Jason Booth 3916c363ae Fixed jsontimer-interval config not being used.
Change JsonTimerTask.java to use jsontimer-interval+10 to allow a buffer for late/delayed client requests(to prevent updated tiles info to be missing)
2011-02-17 10:05:07 -06:00
Jason Booth 77d9a88868 Fixed timer to be stopped onDisabled if it was started 2011-02-17 09:45:32 -06:00
Jason Booth e1f2ca26d6 Changed disable-webserver and jsonfile to default false 2011-02-17 09:38:08 -06:00
Jason Booth 3c1bde1092 Updated JsonTimerTask.java to be Multi-World Compatible 2011-02-17 09:33:27 -06:00
Jason Booth f7dbc89ab4 Merge branch 'master' of git://github.com/FrozenCow/dynmap
Conflicts:
	configuration.txt
	src/main/java/org/dynmap/DynmapPlugin.java
2011-02-17 08:54:23 -06:00
FrozenCow 909207ac26 Organized imports. 2011-02-15 21:44:08 +01:00
FrozenCow 99605ba433 Make sure request-body is skipped if not read. 2011-02-15 21:06:14 +01:00
FrozenCow ada9637d72 Added sendmessage handler (for chatting back). 2011-02-15 21:00:36 +01:00
FrozenCow 2d693b1ebf Improved HTTP performance and POST/PUT compatbility. 2011-02-15 21:00:04 +01:00
FrozenCow e900aca2e0 Added helper classes for HTTP. 2011-02-15 14:19:43 +01:00
FrozenCow 060d1092f9 Made clock configurable and split clocks from map. 2011-02-15 13:50:04 +01:00
FrozenCow 38df91bafe Report world for players in updates. 2011-02-15 13:38:46 +01:00
FrozenCow 18ad2e1d79 Removed copyrights through flames' css. 2011-02-15 13:33:40 +01:00
FrozenCow 5fb098259a focuschatballoons now defaults to false. 2011-02-15 13:08:33 +01:00
Daniel Chesters 24c9dfed41 if focuschatballoons is at false, disableAutoPan should be at true 2011-02-14 21:53:07 +01:00
FrozenCow a1c86bfabb Removed depricated time-images. 2011-02-14 00:02:52 +01:00
FrozenCow 49d45c653d Made clock and timeofday interchangable. 2011-02-14 00:01:20 +01:00
FrozenCow 42391cc4d5 Readded getMinecraftTime. 2011-02-13 23:30:19 +01:00
FrozenCow 3980ebefa1 Revert "Removed Clock"
This reverts commit 9ca8f8dc64e9a28da81a538a3578c2b2a8b34c88.
2011-02-13 23:27:37 +01:00
lishid 058ab0eea7 Transparent compass now 2011-02-13 23:27:37 +01:00
lishid 6e8160e576 Removed Clock 2011-02-13 23:27:37 +01:00
lishid 51e7420bdb Dynamic Time of the day Added 2011-02-13 23:27:37 +01:00
lishid 60ea503053 Added/Modified images 2011-02-13 23:27:37 +01:00
lishid f894c4945b Added/Modified images 2011-02-13 23:27:37 +01:00
lishid 7241b2be81 Added compass and TimeOfDay 2011-02-13 23:27:37 +01:00
unknown b729f28df4 initial commit 2011-02-13 23:27:37 +01:00
FrozenCow 1fc2cdb636 Force making directories on tile-rendering (needs cleaner fix). 2011-02-13 23:23:15 +01:00
FrozenCow b63369675d Re-added flushing again (oops). 2011-02-13 23:22:57 +01:00
FrozenCow a81665d38d Fixed time being reported of the correct world. 2011-02-13 22:46:45 +01:00
FrozenCow db9ced3394 Fixed tiles not updating. 2011-02-13 22:42:08 +01:00
FrozenCow d5d737d385 Fixed 'unknown command' being shown after fullrender. 2011-02-13 22:34:38 +01:00
FrozenCow f3a1d53277 Added maximumheight to configuration for somewhat better nether rendering. 2011-02-13 22:33:33 +01:00
FrozenCow 9a2b9ccac0 Fixed HttpServer some more. 2011-02-13 22:30:24 +01:00
FrozenCow 835e566151 Some improvements to HttpServer. 2011-02-13 02:56:00 +01:00
FrozenCow 2380325975 Added automatically creating tiles directory. 2011-02-13 01:33:05 +01:00
FrozenCow 100f3e0590 Added multiworld update support along with client-side support. 2011-02-13 01:19:47 +01:00
FrozenCow 5b0171c459 Server-side multiworld support with several improvements overal. 2011-02-12 23:47:00 +01:00
FrozenCow 2fd91ef94b Changed tilepath to tilespath in configuration. 2011-02-11 06:28:17 -08:00
FrozenCow 403a2acc53 Added default player-faces. 2011-02-10 01:20:50 +01:00
Jason Booth 959040e5f4 Merge branch 'master' of git://github.com/FrozenCow/dynmap 2011-02-09 14:24:13 -06:00
Jason Booth 2f6930bc17 Removed System debug messages.
Added missing JsonTimerTask.java
2011-02-09 11:57:46 -06:00
Jason Booth fb01f6ecf7 New config to Disable Webserver
New feature and config to output JSON to file
2011-02-09 11:35:09 -06:00
FrozenCow 29517e9a24 Fixed handling invalid http requests. 2011-02-09 17:22:16 +01:00
FrozenCow d566fccb1e Fixed rendering zoomedout tiles. 2011-02-09 13:25:06 +01:00
87 changed files with 2563 additions and 1082 deletions
+34
View File
@@ -0,0 +1,34 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>build</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>tar.bz2</format>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>README*</include>
<include>LICENSE*</include>
<include>NOTICE*</include>
<include>LICENSE*</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.basedir}/web</directory>
<outputDirectory>/dynmap/web</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/dynmap/</outputDirectory>
<includes>
<include>configuration.txt</include></includes></fileSet>
</fileSets>
<files>
<file>
<source>${project.build.directory}/${artifactId}-${version}.jar</source>
<outputDirectory>/</outputDirectory>
<destName>dynmap.jar</destName></file></files>
</assembly>
+101 -49
View File
@@ -1,49 +1,101 @@
# 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
disabledcommands:
- fullrender
# 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
focuschatballoons: false
# 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
# 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.
tilespath: 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
# Disables Webserver portion of Dynmap (Advanced users only)
disable-webserver: false
# Writes JSON to file in the webpath
jsonfile: false
# How often the json file gets written to(in seconds)
jsonfile-interval: 1
# The maptypes Dynmap will use to render.
worlds:
- name: world
maps:
- class: org.dynmap.kzedmap.KzedMap
renderers:
- class: org.dynmap.kzedmap.DefaultTileRenderer
prefix: t
maximumheight: 127
- class: org.dynmap.kzedmap.CaveTileRenderer
prefix: ct
maximumheight: 127
- name: nether
maps:
- class: org.dynmap.kzedmap.KzedMap
renderers:
- class: org.dynmap.kzedmap.DefaultTileRenderer
prefix: nt
maximumheight: 64
web:
# Handles the clientside updates differently only enable if using jsonfile
jsonfile: false
# Interval the browser should poll for updates.
updaterate: 2000
# showchat: modal/balloons
showchat: modal
messagettl: 15000
showplayerfacesonmap: true
showplayerfacesinmenu: true
focuschatballoons: false
joinmessage: "%playername% joined"
quitmessage: "%playername% quit"
defaultworld: world
worlds:
- title: World
name: world
maps:
- type: KzedMapType
title: Surface
name: surface
prefix: t
- type: KzedMapType
title: Cave
name: cave
prefix: ct
- title: Nether
name: nether
maps:
- type: KzedMapType
title: Surface
name: nether
prefix: nt
# Example:
#- title: Other World # With what name the world is displayed.
# name: world_other # The actual name of the world (equal to your directory-name).
# maps:
# - type: KzedMapType # The type (or perspective) of the map. At the moment, there are no others than KzedMapType.
# title: Surface # The name of the map that will be displayed.
# name: surface # The actual name of the map (should be unique for this world).
# prefix: t # The prefix of the tile-files that are generated.
# icon: block_other.png # Sets a custom icon for the map. (optional)
# - type: KzedMapType
# title: Cave
# name: cave
# prefix: ct
# Enables debugging.
#debuggers:
# - class: org.dynmap.debug.LogDebugger
# - class: org.dynmap.debug.BukkitPlayerDebugger
+20 -3
View File
@@ -1,8 +1,8 @@
<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>
<artifactId>dynmap</artifactId>
<version>0.13</version>
<name>DynamicMap</name>
<url>http://www.bukkit.org</url>
<build>
@@ -16,7 +16,24 @@
<target>1.6</target>
</configuration>
</plugin>
</plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>build</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
@@ -0,0 +1,108 @@
package org.dynmap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AsynchronousQueue<T> {
protected static final Logger log = Logger.getLogger("Minecraft");
private Object lock = new Object();
private Thread thread;
private LinkedList<T> queue = new LinkedList<T>();
private Set<T> set = new HashSet<T>();
private Handler<T> handler;
private int dequeueTime;
public AsynchronousQueue(Handler<T> handler, int dequeueTime) {
this.handler = handler;
this.dequeueTime = dequeueTime;
}
public boolean push(T t) {
synchronized (lock) {
if (set.add(t)) {
queue.addLast(t);
return true;
}
return false;
}
}
private T pop() {
synchronized (lock) {
try {
T t = queue.removeFirst();
if (!set.remove(t)) {
// This should never happen.
}
return t;
} catch (NoSuchElementException e) {
return null;
}
}
}
public int size() {
return set.size();
}
public void start() {
synchronized (lock) {
thread = new Thread(new Runnable() {
@Override
public void run() {
running();
}
});
thread.start();
try {
thread.setPriority(Thread.MIN_PRIORITY);
} catch (SecurityException e) {
log.info("Failed to set minimum priority for worker thread!");
}
}
}
public void stop() {
synchronized (lock) {
if (thread == null)
return;
Thread oldThread = thread;
thread = null;
log.info("Stopping map renderer...");
try {
oldThread.join();
} catch (InterruptedException e) {
log.info("Waiting for map renderer to stop is interrupted");
}
}
}
private void running() {
try {
while (Thread.currentThread() == thread) {
T t = pop();
if (t != null) {
handler.handle(t);
}
sleep(dequeueTime);
}
} catch (Exception ex) {
log.log(Level.SEVERE, "Exception on rendering-thread", ex);
}
}
private void sleep(int time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
}
}
}
+20 -3
View File
@@ -11,17 +11,23 @@ public class Client {
public static class Player {
public String type = "player";
public String name;
public String world;
public double x, y, z;
public Player(String name, double x, double y, double z) {
public Player(String name, String world, double x, double y, double z) {
this.name = name;
this.world = world;
this.x = x;
this.y = y;
this.z = z;
}
}
public static class ChatMessage {
public static class Stamped {
public long timestamp = System.currentTimeMillis();
}
public static class ChatMessage extends Stamped {
public String type = "chat";
public String playerName;
public String message;
@@ -31,8 +37,19 @@ public class Client {
this.message = message;
}
}
public static class WebChatMessage extends Stamped {
public String type = "webchat";
public String playerName;
public String message;
public static class Tile {
public WebChatMessage(String playerName, String message) {
this.playerName = playerName;
this.message = message;
}
}
public static class Tile extends Stamped {
public String type = "tile";
public String name;
@@ -16,13 +16,13 @@ public class DynmapBlockListener extends BlockListener {
@Override
public void onBlockPlace(BlockPlaceEvent event) {
Block blockPlaced = event.getBlockPlaced();
mgr.touch(blockPlaced.getX(), blockPlaced.getY(), blockPlaced.getZ());
mgr.touch(blockPlaced.getLocation());
}
public void onBlockDamage(BlockDamageEvent event) {
if (event.getDamageLevel() == BlockDamageLevel.BROKEN) {
Block blockBroken = event.getBlock();
mgr.touch(blockBroken.getX(), blockBroken.getY(), blockBroken.getZ());
mgr.touch(blockBroken.getLocation());
}
}
}
@@ -1,71 +1,33 @@
package org.dynmap;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerListener;
import org.bukkit.util.config.ConfigurationNode;
public class DynmapPlayerListener extends PlayerListener {
private MapManager mgr;
private PlayerList playerList;
private ConfigurationNode configuration;
DynmapPlugin plugin;
public DynmapPlayerListener(MapManager mgr, PlayerList playerList, ConfigurationNode configuration) {
this.mgr = mgr;
this.playerList = playerList;
this.configuration = configuration;
public DynmapPlayerListener(DynmapPlugin plugin) {
this.plugin = plugin;
}
@Override
public void onPlayerCommand(PlayerChatEvent event) {
String[] split = event.getMessage().split(" ");
if (split[0].equalsIgnoreCase("/dynmap")) {
if (split.length > 1) {
if (configuration.getProperty("disabledcommands") instanceof Iterable<?>) {
for(String s : (Iterable<String>)configuration.getProperty("disabledcommands")) {
if (split[1].equals(s)) {
return;
}
}
}
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);
} else if (split[1].equals("fullrender")) {
Player player = event.getPlayer();
mgr.renderFullWorld(player.getLocation());
}
}
}
public void onPlayerChat(PlayerChatEvent event) {
plugin.mapManager.pushUpdate(new Client.ChatMessage(event.getPlayer().getName(), event.getMessage()));
}
/**
* Called when a player sends a chat message
*
* @param event
* Relevant event details
*/
public void onPlayerChat(PlayerChatEvent event) {
mgr.updateQueue.pushUpdate(new Client.ChatMessage(event.getPlayer().getName(), event.getMessage()));
@Override
public void onPlayerJoin(PlayerEvent event) {
String joinMessage = plugin.configuration.getString("joinmessage", "%playername% joined");
joinMessage = joinMessage.replaceAll("%playername%", event.getPlayer().getName());
plugin.mapManager.pushUpdate(new Client.ChatMessage("Server", joinMessage));
}
@Override
public void onPlayerQuit(PlayerEvent event) {
String quitMessage = plugin.configuration.getString("quitmessage", "%playername% quit");
quitMessage = quitMessage.replaceAll("%playername%", event.getPlayer().getName());
plugin.mapManager.pushUpdate(new Client.ChatMessage("Server", quitMessage));
}
}
+195 -30
View File
@@ -1,45 +1,53 @@
package org.dynmap;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import java.util.Timer;
import org.bukkit.Server;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.block.BlockListener;
import org.bukkit.event.player.PlayerListener;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginLoader;
import org.bukkit.event.world.WorldEvent;
import org.bukkit.event.world.WorldListener;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.config.Configuration;
import org.dynmap.debug.BukkitPlayerDebugger;
import org.dynmap.Event.Listener;
import org.dynmap.debug.Debug;
import org.dynmap.debug.Debugger;
import org.dynmap.web.HttpServer;
import org.dynmap.web.handlers.ClientConfigurationHandler;
import org.dynmap.web.handlers.ClientUpdateHandler;
import org.dynmap.web.handlers.FilesystemHandler;
import org.dynmap.web.handlers.SendMessageHandler;
import org.dynmap.web.handlers.SendMessageHandler.Message;
import org.dynmap.web.Json;
public class DynmapPlugin extends JavaPlugin {
protected static final Logger log = Logger.getLogger("Minecraft");
private HttpServer webServer = null;
private MapManager mapManager = null;
private PlayerList playerList;
private Configuration configuration;
public HttpServer webServer = null;
public MapManager mapManager = null;
public PlayerList playerList;
public Configuration configuration;
private BukkitPlayerDebugger debugger = new BukkitPlayerDebugger(this);
public Timer timer;
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 static File tilesDirectory;
public World getWorld() {
return getServer().getWorlds().get(0);
@@ -57,13 +65,32 @@ public class DynmapPlugin extends JavaPlugin {
configuration = new Configuration(new File(this.getDataFolder(), "configuration.txt"));
configuration.load();
debugger.enable();
playerList = new PlayerList(getServer());
loadDebuggers();
tilesDirectory = getFile(configuration.getString("tilespath", "web/tiles"));
tilesDirectory.mkdirs();
playerList = new PlayerList(getServer(), getFile("hiddenplayers.txt"));
playerList.load();
mapManager = new MapManager(getWorld(), debugger, configuration);
mapManager.startManager();
mapManager = new MapManager(this, configuration);
mapManager.startRendering();
if (!configuration.getBoolean("disable-webserver", false)) {
loadWebserver();
}
if (configuration.getBoolean("jsonfile", false)) {
jsonConfig();
int jsonInterval = configuration.getInt("jsonfile-interval", 1) * 1000;
timer = new Timer();
timer.scheduleAtFixedRate(new JsonTimerTask(this, configuration), jsonInterval, jsonInterval);
}
registerEvents();
}
public void loadWebserver() {
InetAddress bindAddress;
{
String address = configuration.getString("webserver-bindaddress", "0.0.0.0");
@@ -78,37 +105,175 @@ public class DynmapPlugin extends JavaPlugin {
int port = configuration.getInt("webserver-port", 8123);
webServer = new HttpServer(bindAddress, port);
webServer.handlers.put("/", new FilesystemHandler(mapManager.webDirectory));
webServer.handlers.put("/tiles/", new FilesystemHandler(mapManager.tileDirectory));
webServer.handlers.put("/up/", new ClientUpdateHandler(mapManager, playerList, getWorld()));
webServer.handlers.put("/", new FilesystemHandler(getFile(configuration.getString("webpath", "web"))));
webServer.handlers.put("/tiles/", new FilesystemHandler(tilesDirectory));
webServer.handlers.put("/up/", new ClientUpdateHandler(mapManager, playerList, getServer()));
webServer.handlers.put("/up/configuration", new ClientConfigurationHandler((Map<?, ?>) configuration.getProperty("web")));
SendMessageHandler messageHandler = new SendMessageHandler();
messageHandler.onMessageReceived.addListener(new Listener<SendMessageHandler.Message>() {
@Override
public void triggered(Message t) {
mapManager.pushUpdate(new Client.WebChatMessage(t.name, t.message));
log.info("[WEB]" + t.name + ": " + t.message);
getServer().broadcastMessage("[WEB]" + t.name + ": " + t.message);
}
});
webServer.handlers.put("/up/sendmessage", messageHandler);
try {
webServer.startServer();
} catch (IOException e) {
log.severe("Failed to start WebServer on " + bindAddress + ":" + port + "!");
}
registerEvents();
}
public void onDisable() {
mapManager.stopManager();
mapManager.stopRendering();
if (webServer != null) {
webServer.shutdown();
webServer = null;
}
debugger.disable();
if (timer != null) {
timer.cancel();
}
Debug.clearDebuggers();
}
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.BLOCK_PLACED, blockListener, Priority.Monitor, this);
getServer().getPluginManager().registerEvent(Event.Type.BLOCK_DAMAGED, blockListener, Priority.Monitor, this);
PlayerListener playerListener = new DynmapPlayerListener(mapManager, playerList, configuration);
getServer().getPluginManager().registerEvent(Event.Type.PLAYER_COMMAND, playerListener, Priority.Normal, this);
WorldListener worldListener = new WorldListener() {
@Override
public void onWorldLoaded(WorldEvent event) {
mapManager.activateWorld(event.getWorld());
}
};
getServer().getPluginManager().registerEvent(Event.Type.WORLD_LOADED, worldListener, Priority.Monitor, this);
PlayerListener playerListener = new DynmapPlayerListener(this);
//getServer().getPluginManager().registerEvent(Event.Type.PLAYER_COMMAND, playerListener, Priority.Normal, this);
getServer().getPluginManager().registerEvent(Event.Type.PLAYER_CHAT, playerListener, Priority.Normal, this);
getServer().getPluginManager().registerEvent(Event.Type.PLAYER_LOGIN, playerListener, Priority.Normal, this);
getServer().getPluginManager().registerEvent(Event.Type.PLAYER_JOIN, playerListener, Priority.Normal, this);
getServer().getPluginManager().registerEvent(Event.Type.PLAYER_QUIT, playerListener, Priority.Normal, this);
}
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 File getFile(String path) {
return combinePaths(getDataFolder(), path);
}
protected void loadDebuggers() {
Object debuggersConfiguration = configuration.getProperty("debuggers");
Debug.clearDebuggers();
if (debuggersConfiguration != null) {
for (Object debuggerConfiguration : (List<?>) debuggersConfiguration) {
Map<?, ?> debuggerConfigurationMap = (Map<?, ?>) debuggerConfiguration;
try {
Class<?> debuggerClass = Class.forName((String) debuggerConfigurationMap.get("class"));
Constructor<?> constructor = debuggerClass.getConstructor(JavaPlugin.class, Map.class);
Debugger debugger = (Debugger) constructor.newInstance(this, debuggerConfigurationMap);
Debug.addDebugger(debugger);
} catch (Exception e) {
log.severe("Error loading debugger: " + e);
e.printStackTrace();
continue;
}
}
}
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
if (!cmd.getName().equalsIgnoreCase("dynmap"))
return false;
Player player = null;
if (sender instanceof Player)
player = (Player) sender;
if (args.length > 0) {
if (args[0].equals("render")) {
if (sender instanceof Player) {
mapManager.touch(((Player) sender).getLocation());
return true;
}
} else if (args[0].equals("hide")) {
if (args.length == 1 && player != null) {
playerList.hide(player.getName());
sender.sendMessage("You are now hidden on Dynmap.");
return true;
} else {
for (int i = 1; i < args.length; i++) {
playerList.hide(args[i]);
sender.sendMessage(args[i] + " is now hidden on Dynmap.");
}
return true;
}
} else if (args[0].equals("show")) {
if (args.length == 1 && player != null) {
playerList.show(player.getName());
sender.sendMessage("You are now visible on Dynmap.");
return true;
} else {
for (int i = 1; i < args.length; i++) {
playerList.show(args[i]);
sender.sendMessage(args[i] + " is now visible on Dynmap.");
}
return true;
}
} else if (args[0].equals("fullrender")) {
if (player == null || player.isOp()) {
if (args.length > 2) {
for (int i = 1; i < args.length; i++) {
World w = getServer().getWorld(args[i]);
mapManager.renderFullWorld(new Location(w, 0, 0, 0));
}
return true;
} else if (player != null) {
mapManager.renderFullWorld(player.getLocation());
return true;
}
} else if (player != null) {
player.sendMessage("Only OPs are allowed to use this command!");
return true;
}
}
}
return false;
}
private void jsonConfig() {
File outputFile;
Map<?, ?> clientConfig = (Map<?, ?>) configuration.getProperty("web");
File webpath = new File(configuration.getString("webpath", "web"), "dynmap_config.json");
if (webpath.isAbsolute())
outputFile = webpath;
else
outputFile = new File(getDataFolder(), webpath.toString());
try {
FileOutputStream fos = new FileOutputStream(outputFile);
fos.write(Json.stringifyJson(clientConfig).getBytes());
fos.close();
} catch (FileNotFoundException ex) {
System.out.println("FileNotFoundException : " + ex);
} catch (IOException ioe) {
System.out.println("IOException : " + ioe);
}
}
}
+12
View File
@@ -0,0 +1,12 @@
package org.dynmap;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.World;
public class DynmapWorld {
public World world;
public List<MapType> maps = new ArrayList<MapType>();
public UpdateQueue updates = new UpdateQueue();
}
+26
View File
@@ -0,0 +1,26 @@
package org.dynmap;
import java.util.LinkedList;
import java.util.List;
public class Event<T> {
private List<Listener<T>> listeners = new LinkedList<Listener<T>>();
public synchronized void addListener(Listener<T> l) {
listeners.add(l);
}
public synchronized void removeListener(Listener<T> l) {
listeners.remove(l);
}
public synchronized void trigger(T t) {
for (Listener<T> l : listeners) {
l.triggered(t);
}
}
public interface Listener<T> {
void triggered(T t);
}
}
+5
View File
@@ -0,0 +1,5 @@
package org.dynmap;
public interface Handler<T> {
void handle(T t);
}
@@ -0,0 +1,66 @@
package org.dynmap;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.TimerTask;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.util.config.Configuration;
import org.dynmap.web.Json;
class JsonTimerTask extends TimerTask {
private final DynmapPlugin plugin;
private Server server;
private MapManager mapManager;
private Configuration configuration;
public JsonTimerTask(DynmapPlugin instance, Configuration config) {
this.plugin = instance;
this.server = this.plugin.getServer();
this.mapManager = this.plugin.getMapManager();
this.configuration = config;
}
public void run() {
for (World world : this.server.getWorlds()) {
long current = System.currentTimeMillis();
Client.Update update = new Client.Update();
update.timestamp = current;
update.servertime = world.getTime() % 24000;
Player[] players = mapManager.playerList.getVisiblePlayers();
update.players = new Client.Player[players.length];
for (int i = 0; i < players.length; i++) {
Player p = players[i];
Location pl = p.getLocation();
update.players[i] = new Client.Player(p.getName(), pl.getWorld().getName(), pl.getX(), pl.getY(), pl.getZ());
}
update.updates = mapManager.getWorldUpdates(world.getName(), current - (configuration.getInt("jsonfile-interval", 1) + 10000));
File webpath = new File(this.configuration.getString("webpath", "web"), "dynmap_" + world.getName() + ".json");
File outputFile;
if (webpath.isAbsolute())
outputFile = webpath;
else {
outputFile = new File(plugin.getDataFolder(), webpath.toString());
}
try {
FileOutputStream fos = new FileOutputStream(outputFile);
fos.write(Json.stringifyJson(update).getBytes());
fos.close();
} catch (FileNotFoundException ex) {
System.out.println("FileNotFoundException : " + ex);
} catch (IOException ioe) {
System.out.println("IOException : " + ioe);
}
}
}
}
@@ -1,6 +0,0 @@
package org.dynmap;
public class MapLocation {
public float x;
public float y;
}
+133 -139
View File
@@ -3,84 +3,68 @@ package org.dynmap;
import java.io.File;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.util.config.ConfigurationNode;
import org.dynmap.debug.Debugger;
import org.dynmap.debug.Debug;
public class MapManager extends Thread {
public class MapManager {
protected static final Logger log = Logger.getLogger("Minecraft");
private World world;
private Debugger debugger;
private MapType[] maps;
public StaleQueue staleQueue;
public UpdateQueue updateQueue;
public AsynchronousQueue<MapTile> tileQueue;
public Map<String, DynmapWorld> worlds = new HashMap<String, DynmapWorld>();
public Map<String, DynmapWorld> inactiveworlds = new HashMap<String, DynmapWorld>();
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 boolean loadChunks = true;
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.updateQueue = new UpdateQueue();
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);
loadChunks = configuration.getBoolean("loadchunks", true);
if (!tileDirectory.isDirectory())
tileDirectory.mkdirs();
maps = loadMapTypes(configuration);
public MapManager(DynmapPlugin plugin, ConfigurationNode configuration) {
this.tileQueue = new AsynchronousQueue<MapTile>(new Handler<MapTile>() {
@Override
public void handle(MapTile t) {
render(t);
}
}, (int) (configuration.getDouble("renderinterval", 0.5) * 1000));
for(Object worldConfigurationObj : (List<?>)configuration.getProperty("worlds")) {
Map<?, ?> worldConfiguration = (Map<?, ?>)worldConfigurationObj;
String worldName = (String)worldConfiguration.get("name");
DynmapWorld world = new DynmapWorld();
if (worldConfiguration.get("maps") != null) {
for(MapType map : loadMapTypes((List<?>)worldConfiguration.get("maps"))) {
world.maps.add(map);
}
}
inactiveworlds.put(worldName, world);
World bukkitWorld = plugin.getServer().getWorld(worldName);
if (bukkitWorld != null)
activateWorld(bukkitWorld);
}
tileQueue.start();
}
void renderFullWorld(Location l) {
debugger.debug("Full render starting...");
for (MapType map : maps) {
DynmapWorld world = worlds.get(l.getWorld().getName());
if (world == null) {
log.severe("Could not render: world '" + l.getWorld().getName() + "' not defined in configuration.");
return;
}
World w = world.world;
log.info("Full render starting on world '" + w.getName() + "'...");
for (MapType map : world.maps) {
int requiredChunkCount = 200;
HashSet<MapTile> found = new HashSet<MapTile>();
HashSet<MapTile> rendered = new HashSet<MapTile>();
@@ -103,21 +87,20 @@ public class MapManager extends Thread {
// Unload old chunks.
while (loadedChunks.size() >= requiredChunkCount - requiredChunks.length) {
DynmapChunk c = loadedChunks.pollFirst();
world.unloadChunk(c.x, c.z, false, true);
w.unloadChunk(c.x, c.z, false, true);
}
// Load the required chunks.
for (DynmapChunk chunk : requiredChunks) {
boolean wasLoaded = world.isChunkLoaded(chunk.x, chunk.z);
world.loadChunk(chunk.x, chunk.z, false);
boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z);
w.loadChunk(chunk.x, chunk.z, false);
if (!wasLoaded)
loadedChunks.add(chunk);
}
if (map.render(tile)) {
if (render(tile)) {
found.remove(tile);
rendered.add(tile);
updateQueue.pushUpdate(new Client.Tile(tile.getName()));
for (MapTile adjTile : map.getAdjecentTiles(tile)) {
if (!found.contains(adjTile) && !rendered.contains(adjTile)) {
found.add(adjTile);
@@ -132,99 +115,61 @@ public class MapManager extends Thread {
// Unload remaining chunks to clean-up.
while (!loadedChunks.isEmpty()) {
DynmapChunk c = loadedChunks.pollFirst();
world.unloadChunk(c.x, c.z, false, true);
w.unloadChunk(c.x, c.z, false, true);
}
}
debugger.debug("Full render finished.");
log.info("Full render finished.");
}
private MapType[] loadMapTypes(ConfigurationNode configuration) {
List<?> configuredMaps = (List<?>) configuration.getProperty("maps");
public void activateWorld(World w) {
DynmapWorld world = inactiveworlds.get(w.getName());
if (world == null) {
world = worlds.get(w.getName());
} else {
inactiveworlds.remove(w.getName());
}
if (world != null) {
world.world = w;
worlds.put(w.getName(), world);
log.info("Activated world '" + w.getName() + "' in Dynmap.");
}
}
private MapType[] loadMapTypes(List<?> mapConfigurations) {
Event.Listener<MapTile> invalitateListener = new Event.Listener<MapTile>() {
@Override
public void triggered(MapTile t) {
invalidateTile(t);
}
};
ArrayList<MapType> mapTypes = new ArrayList<MapType>();
for (Object configuredMapObj : configuredMaps) {
for (Object configuredMapObj : mapConfigurations) {
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);
Constructor<?> constructor = mapTypeClass.getConstructor(Map.class);
MapType mapType = (MapType) constructor.newInstance(configuredMap);
mapType.onTileInvalidated.addListener(invalitateListener);
mapTypes.add(mapType);
} catch (Exception e) {
debugger.error("Error loading map", e);
log.log(Level.SEVERE, "Error loading maptype", e);
e.printStackTrace();
}
}
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) {
MapTile t = staleQueue.popStaleTile();
if (t != null) {
debugger.debug("Rendering tile " + t + "...");
boolean isNonEmptyTile = t.getMap().render(t);
updateQueue.pushUpdate(new Client.Tile(t.getName()));
try {
Thread.sleep(renderWait);
} catch (InterruptedException e) {
}
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
log.info("Map renderer has stopped.");
} catch (Exception ex) {
debugger.error("Exception on rendering-thread: " + ex.toString());
ex.printStackTrace();
}
}
public void touch(int x, int y, int z) {
for (int i = 0; i < maps.length; i++) {
MapTile[] tiles = maps[i].getTiles(new Location(world, x, y, z));
public void touch(Location l) {
DynmapWorld world = worlds.get(l.getWorld().getName());
if (world == null)
return;
for (int i = 0; i < world.maps.size(); i++) {
MapTile[] tiles = world.maps.get(i).getTiles(l);
for (int j = 0; j < tiles.length; j++) {
invalidateTile(tiles[j]);
}
@@ -232,7 +177,56 @@ public class MapManager extends Thread {
}
public void invalidateTile(MapTile tile) {
debugger.debug("Invalidating tile " + tile.getName());
staleQueue.pushStaleTile(tile);
Debug.debug("Invalidating tile " + tile.getFilename());
tileQueue.push(tile);
}
public void startRendering() {
tileQueue.start();
}
public void stopRendering() {
tileQueue.stop();
}
public boolean render(MapTile tile) {
boolean result = tile.getMap().render(tile, getTileFile(tile));
pushUpdate(tile.getWorld(), new Client.Tile(tile.getFilename()));
return result;
}
private HashMap<World, File> worldTileDirectories = new HashMap<World, File>();
private File getTileFile(MapTile tile) {
World world = tile.getWorld();
File worldTileDirectory = worldTileDirectories.get(world);
if (worldTileDirectory == null) {
worldTileDirectory = new File(DynmapPlugin.tilesDirectory, tile.getWorld().getName());
worldTileDirectories.put(world, worldTileDirectory);
}
worldTileDirectory.mkdirs();
return new File(worldTileDirectory, tile.getFilename());
}
public void pushUpdate(Object update) {
for(DynmapWorld world : worlds.values()) {
world.updates.pushUpdate(update);
}
}
public void pushUpdate(World world, Object update) {
pushUpdate(world.getName(), update);
}
public void pushUpdate(String worldName, Object update) {
DynmapWorld world = worlds.get(worldName);
world.updates.pushUpdate(update);
}
public Object[] getWorldUpdates(String worldName, long since) {
DynmapWorld world = worlds.get(worldName);
if (world == null)
return new Object[0];
return world.updates.getUpdatedObjects(since);
}
}
+15 -2
View File
@@ -1,15 +1,28 @@
package org.dynmap;
import org.bukkit.World;
public abstract class MapTile {
private World world;
private MapType map;
public World getWorld() {
return world;
}
public MapType getMap() {
return map;
}
public abstract String getName();
public abstract String getFilename();
public MapTile(MapType map) {
public MapTile(World world, MapType map) {
this.world = world;
this.map = map;
}
@Override
public int hashCode() {
return getFilename().hashCode() ^ getWorld().hashCode();
}
}
+5 -29
View File
@@ -1,41 +1,17 @@
package org.dynmap;
import java.io.File;
import org.bukkit.Location;
import org.bukkit.World;
import org.dynmap.debug.Debugger;
public abstract class MapType {
private MapManager manager;
public MapManager getMapManager() {
return manager;
}
private World world;
public World getWorld() {
return world;
}
private Debugger debugger;
public Debugger getDebugger() {
return debugger;
}
public MapType(MapManager manager, World world, Debugger debugger) {
this.manager = manager;
this.world = world;
this.debugger = debugger;
}
public Event<MapTile> onTileInvalidated = new Event<MapTile>();
public abstract MapTile[] getTiles(Location l);
public abstract MapTile[] getAdjecentTiles(MapTile tile);
public abstract DynmapChunk[] getRequiredChunks(MapTile tile);
public abstract boolean render(MapTile tile);
public abstract boolean isRendered(MapTile tile);
public abstract boolean render(MapTile tile, File outputFile);
}
+18 -2
View File
@@ -16,10 +16,11 @@ import org.bukkit.entity.Player;
public class PlayerList {
private Server server;
private HashSet<String> hiddenPlayerNames = new HashSet<String>();
private File hiddenPlayersFile = new File(DynmapPlugin.dataRoot, "hiddenplayers.txt");
private File hiddenPlayersFile;
public PlayerList(Server server) {
public PlayerList(Server server, File hiddenPlayersFile) {
this.server = server;
this.hiddenPlayersFile = hiddenPlayersFile;
}
public void save() {
@@ -68,6 +69,21 @@ public class PlayerList {
hide(playerName);
}
// TODO: Clean this up... one day
public Player[] getVisiblePlayers(String worldName) {
ArrayList<Player> visiblePlayers = new ArrayList<Player>();
Player[] onlinePlayers = server.getOnlinePlayers();
for (int i = 0; i < onlinePlayers.length; i++) {
Player p = onlinePlayers[i];
if (p.getWorld().getName().equals(worldName) && !hiddenPlayerNames.contains(p.getName())) {
visiblePlayers.add(p);
}
}
Player[] result = new Player[visiblePlayers.size()];
visiblePlayers.toArray(result);
return result;
}
public Player[] getVisiblePlayers() {
ArrayList<Player> visiblePlayers = new ArrayList<Player>();
Player[] onlinePlayers = server.getOnlinePlayers();
+2 -2
View File
@@ -11,7 +11,7 @@ public class UpdateQueue {
private static final int maxUpdateAge = 120000;
public void pushUpdate(Object obj) {
public synchronized void pushUpdate(Object obj) {
long now = System.currentTimeMillis();
long deadline = now - maxUpdateAge;
synchronized (lock) {
@@ -27,7 +27,7 @@ public class UpdateQueue {
private ArrayList<Object> tmpupdates = new ArrayList<Object>();
public Object[] getUpdatedObjects(long since) {
public synchronized Object[] getUpdatedObjects(long since) {
long now = System.currentTimeMillis();
long deadline = now - maxUpdateAge;
Object[] updates;
@@ -1,8 +1,7 @@
package org.dynmap.debug;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Map;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
@@ -11,27 +10,22 @@ import org.bukkit.event.Event.Priority;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerListener;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
public class BukkitPlayerDebugger implements Debugger {
protected static final Logger log = Logger.getLogger("Minecraft");
private boolean isLogging = false;
private JavaPlugin plugin;
private HashSet<Player> debugees = new HashSet<Player>();
private String debugCommand;
private String undebugCommand;
private String prepend;
public BukkitPlayerDebugger(JavaPlugin plugin) {
public BukkitPlayerDebugger(JavaPlugin plugin, Map<String, Object> configuration) {
this.plugin = plugin;
PluginDescriptionFile pdfFile = plugin.getDescription();
debugCommand = "/debug_" + pdfFile.getName();
undebugCommand = "/undebug_" + pdfFile.getName();
prepend = pdfFile.getName() + ": ";
String name = "dynmap";
debugCommand = "/debug_" + name;
undebugCommand = "/undebug_" + name;
prepend = name + ": ";
}
public synchronized void enable() {
@@ -63,19 +57,15 @@ public class BukkitPlayerDebugger implements Debugger {
public synchronized void debug(String message) {
sendToDebuggees(message);
if (isLogging)
log.info(prepend + message);
}
public synchronized void error(String message) {
sendToDebuggees(prepend + ChatColor.RED + message);
log.log(Level.SEVERE, prepend + message);
}
public synchronized void error(String message, Throwable thrown) {
sendToDebuggees(prepend + ChatColor.RED + message);
sendToDebuggees(thrown.toString());
log.log(Level.SEVERE, prepend + message);
}
protected class CommandListener extends PlayerListener {
+31
View File
@@ -0,0 +1,31 @@
package org.dynmap.debug;
import java.util.ArrayList;
public class Debug {
private static ArrayList<Debugger> debuggers = new ArrayList<Debugger>();
public synchronized static void addDebugger(Debugger d) {
debuggers.add(d);
}
public synchronized static void removeDebugger(Debugger d) {
debuggers.remove(d);
}
public synchronized static void clearDebuggers() {
debuggers.clear();
}
public synchronized static void debug(String message) {
for(int i = 0; i < debuggers.size(); i++) debuggers.get(i).debug(message);
}
public synchronized static void error(String message) {
for(int i = 0; i < debuggers.size(); i++) debuggers.get(i).error(message);
}
public synchronized static void error(String message, Throwable thrown) {
for(int i = 0; i < debuggers.size(); i++) debuggers.get(i).error(message, thrown);
}
}

Some files were not shown because too many files have changed in this diff Show More