Merge pull request #143 from mikeprimm/master

Remerged - nether render updates, and rest of HeroChat
This commit is contained in:
mikeprimm 2011-05-15 19:20:52 -07:00
commit cbfa26a5b3
10 changed files with 319 additions and 195 deletions

View File

@ -75,7 +75,7 @@ worlds:
renderers: renderers:
- class: org.dynmap.kzedmap.DefaultTileRenderer - class: org.dynmap.kzedmap.DefaultTileRenderer
prefix: nt prefix: nt
maximumheight: 64 maximumheight: 127
colorscheme: default colorscheme: default
web: web:

View File

@ -115,6 +115,10 @@ public class DynmapPlugin extends JavaPlugin {
} }
registerEvents(); registerEvents();
/* Print version info */
PluginDescriptionFile pdfFile = this.getDescription();
log.info("[dynmap] version " + pdfFile.getVersion() + " is enabled" );
} }
public void loadWebserver() { public void loadWebserver() {
@ -157,9 +161,7 @@ public class DynmapPlugin extends JavaPlugin {
} catch (IOException e) { } catch (IOException e) {
log.severe("Failed to start WebServer on " + bindAddress + ":" + port + "!"); log.severe("Failed to start WebServer on " + bindAddress + ":" + port + "!");
} }
/* Print version info */
PluginDescriptionFile pdfFile = this.getDescription();
log.info("[dynmap] version " + pdfFile.getVersion() + " is enabled" );
} }
public void onDisable() { public void onDisable() {
@ -405,6 +407,8 @@ public class DynmapPlugin extends JavaPlugin {
public void webChat(String name, String message) { public void webChat(String name, String message) {
mapManager.pushUpdate(new Client.ChatMessage("web", name, message)); mapManager.pushUpdate(new Client.ChatMessage("web", name, message));
log.info("[WEB]" + name + ": " + message); log.info("[WEB]" + name + ": " + message);
getServer().broadcastMessage("[WEB]" + name + ": " + message); /* Let HeroChat take a look - only broadcast to players if it doesn't handle it */
if(hchand.sendWebMessageToHeroChat(name, message) == false)
getServer().broadcastMessage("[WEB]" + name + ": " + message);
} }
} }

View File

@ -22,6 +22,7 @@ public class HeroChatHandler {
private List<String> hcchannels; private List<String> hcchannels;
private String hcwebinputchannel; private String hcwebinputchannel;
private HeroChatChannel hcwebinputchan;
private DynmapPlugin plugin; private DynmapPlugin plugin;
private class OurPluginListener extends ServerListener { private class OurPluginListener extends ServerListener {
@ -39,10 +40,8 @@ public class HeroChatHandler {
/* Reflection-based access wrapper for ChannelChatEvent from HeroChat */ /* Reflection-based access wrapper for ChannelChatEvent from HeroChat */
private static class HeroChatChannelChatEvent { private static class HeroChatChannelChatEvent {
private static Class channelchatevent; private static Class channelchatevent;
private static Method getchannel;
private static Method getsource; private static Method getsource;
private static Method getmessage; private static Method getmessage;
private static Method iscancelled;
private static boolean isgood = false; private static boolean isgood = false;
private Event evt; private Event evt;
@ -51,14 +50,8 @@ public class HeroChatHandler {
try { try {
channelchatevent = Class channelchatevent = Class
.forName("com.herocraftonline.dthielke.herochat.event.ChannelChatEvent"); .forName("com.herocraftonline.dthielke.herochat.event.ChannelChatEvent");
getchannel = channelchatevent.getMethod("getChannel", getsource = channelchatevent.getMethod("getSource", new Class[0]);
new Class[0]); getmessage = channelchatevent.getMethod("getMessage", new Class[0]);
getsource = channelchatevent.getMethod("getSource",
new Class[0]);
getmessage = channelchatevent.getMethod("getMessage",
new Class[0]);
iscancelled = channelchatevent.getMethod("isCancelled",
new Class[0]);
isgood = true; isgood = true;
} catch (ClassNotFoundException cnfx) { } catch (ClassNotFoundException cnfx) {
} catch (NoSuchMethodException nsmx) { } catch (NoSuchMethodException nsmx) {
@ -74,18 +67,6 @@ public class HeroChatHandler {
return channelchatevent.isInstance(evt); return channelchatevent.isInstance(evt);
} }
public HeroChatChannel getChannel() {
try {
Object o;
o = getchannel.invoke(evt);
if (o != null) {
return new HeroChatChannel(o);
}
} catch (Exception x) {
}
return null;
}
public String getSource() { public String getSource() {
try { try {
return (String) getsource.invoke(evt); return (String) getsource.invoke(evt);
@ -101,6 +82,49 @@ public class HeroChatHandler {
return null; return null;
} }
} }
}
/* Reflection-based access wrapper for ChannelEvent from HeroChat */
private static class HeroChatChannelEvent {
private static Class channelevent;
private static Method getchannel;
private static Method iscancelled;
private static boolean isgood = false;
private Event evt;
@SuppressWarnings("unchecked")
public static boolean initialize() {
try {
channelevent = Class
.forName("com.herocraftonline.dthielke.herochat.event.ChannelEvent");
getchannel = channelevent.getMethod("getChannel", new Class[0]);
iscancelled = channelevent.getMethod("isCancelled", new Class[0]);
isgood = true;
} catch (ClassNotFoundException cnfx) {
} catch (NoSuchMethodException nsmx) {
}
return isgood;
}
public HeroChatChannelEvent(Event evt) {
this.evt = evt;
}
public static boolean isInstance(Event evt) {
return channelevent.isInstance(evt);
}
public HeroChatChannel getChannel() {
try {
Object o;
o = getchannel.invoke(evt);
if (o != null) {
return new HeroChatChannel(o);
}
} catch (Exception x) {
}
return null;
}
public boolean isCancelled() { public boolean isCancelled() {
try { try {
@ -115,6 +139,8 @@ public class HeroChatHandler {
private static class HeroChatChannel { private static class HeroChatChannel {
private static Class channel; private static Class channel;
private static Method getname; private static Method getname;
private static Method getnick;
private static Method sendmessage;
private static boolean isgood = false; private static boolean isgood = false;
private Object chan; private Object chan;
@ -123,10 +149,14 @@ public class HeroChatHandler {
try { try {
channel = Class channel = Class
.forName("com.herocraftonline.dthielke.herochat.channels.Channel"); .forName("com.herocraftonline.dthielke.herochat.channels.Channel");
getname = channel.getMethod("getName", new Class[0]); getname = channel.getMethod("getName");
getnick = channel.getMethod("getNick", new Class[0]);
sendmessage = channel.getMethod("sendMessage", new Class[] {
String.class, String.class, String.class, boolean.class } );
isgood = true; isgood = true;
} catch (ClassNotFoundException cnfx) { } catch (ClassNotFoundException cnfx) {
} catch (NoSuchMethodException nsmx) { } catch (NoSuchMethodException nsmx) {
System.out.println(nsmx);
} }
return isgood; return isgood;
} }
@ -135,10 +165,6 @@ public class HeroChatHandler {
this.chan = chan; this.chan = chan;
} }
public static boolean isInstance(Object obj) {
return channel.isInstance(obj);
}
public String getName() { public String getName() {
try { try {
return (String) getname.invoke(chan); return (String) getname.invoke(chan);
@ -146,6 +172,21 @@ public class HeroChatHandler {
return null; return null;
} }
} }
public String getNick() {
try {
return (String) getnick.invoke(chan);
} catch (Exception x) {
return null;
}
}
public void sendMessage(String source, String msg, String format, boolean sentByPlayer) {
try {
sendmessage.invoke(chan, source, msg, format, sentByPlayer);
} catch (Exception x) {
}
}
} }
private class OurEventListener extends CustomEventListener { private class OurEventListener extends CustomEventListener {
@ -154,16 +195,32 @@ public class HeroChatHandler {
*/ */
@Override @Override
public void onCustomEvent(Event event) { public void onCustomEvent(Event event) {
if (HeroChatChannelChatEvent.isInstance(event)) { if (HeroChatChannelEvent.isInstance(event)) {
HeroChatChannelChatEvent cce = new HeroChatChannelChatEvent( HeroChatChannelEvent ce = new HeroChatChannelEvent(event);
event); /* Snoop for our web channel - we'll need it, and we'll see it before it matters,
if (cce.isCancelled()) * since anyone that joins the channel will give us an event (and reflection on
* the plugin class to get the manager didn't work, due to a dependency on the IRC
* plugin that may not be present....)
*/
HeroChatChannel c = ce.getChannel();
/* If channel name or nickname matches out web channel, remember it */
if((c != null) && (hcwebinputchannel != null) &&
((c.getName().equals(hcwebinputchannel)) ||
c.getNick().equals(hcwebinputchannel))) {
hcwebinputchan = c;
}
if (ce.isCancelled())
return; return;
HeroChatChannel c = cce.getChannel(); if (HeroChatChannelChatEvent.isInstance(event)) {
if (hcchannels.contains(c.getName())) { HeroChatChannelChatEvent cce = new HeroChatChannelChatEvent(
plugin.mapManager.pushUpdate(new Client.ChatMessage( event);
"player", "[" + c.getName() + "] " /* Match on name or nickname of channel */
if (hcchannels.contains(c.getName()) ||
hcchannels.contains(c.getNick())) {
plugin.mapManager.pushUpdate(new Client.ChatMessage(
"player", "[" + c.getNick() + "] "
+ cce.getSource(), cce.getMessage())); + cce.getSource(), cce.getMessage()));
}
} }
} }
} }
@ -188,16 +245,38 @@ public class HeroChatHandler {
private void activateHeroChat(Plugin herochat) { private void activateHeroChat(Plugin herochat) {
if (HeroChatChannelChatEvent.initialize() == false) { if (HeroChatChannelChatEvent.initialize() == false) {
log.severe("[dynmap] Cannot load HeroChat event class!"); log.severe("[dynmap] Cannot load HeroChat chat event class!");
return; return;
} }
if (HeroChatChannel.initialize() == false) { if (HeroChatChannel.initialize() == false) {
log.severe("[dynmap] Cannot load HeroChat channel class!"); log.severe("[dynmap] Cannot load HeroChat channel class!");
return; return;
} }
if (HeroChatChannelEvent.initialize() == false) {
log.severe("[dynmap] Cannot load HeroChat channel event class!");
return;
}
/* Register event handler */ /* Register event handler */
plugin.getServer().getPluginManager().registerEvent(Event.Type.CUSTOM_EVENT, plugin.getServer().getPluginManager().registerEvent(Event.Type.CUSTOM_EVENT,
new OurEventListener(), Event.Priority.Monitor, plugin); new OurEventListener(), Event.Priority.Monitor, plugin);
log.info("[dynmap] HeroChat integration active"); log.info("[dynmap] HeroChat integration active");
} }
/**
* Send message from web to appropriate HeroChat channel
* @param sender - sender ID
* @param message - message
* @return true if herochat is handling this, false if not
*/
public boolean sendWebMessageToHeroChat(String sender, String message) {
if(hcwebinputchannel != null) { /* Are we handling them? */
if(hcwebinputchan != null) { /* Have we seen it yet? Maybe no if nobody has logged on or
* joined it, but then who would see it anyway?
*/
hcwebinputchan.sendMessage(sender, message, "{default}", false);
}
return true;
}
return false;
}
} }

View File

@ -11,10 +11,11 @@ public class UpdateQueue {
private static final int maxUpdateAge = 120000; private static final int maxUpdateAge = 120000;
public synchronized void pushUpdate(Object obj) { public void pushUpdate(Object obj) {
long now = System.currentTimeMillis();
long deadline = now - maxUpdateAge;
synchronized (lock) { synchronized (lock) {
/* Do inside lock - prevent delay between time and actual work */
long now = System.currentTimeMillis();
long deadline = now - maxUpdateAge;
ListIterator<Update> i = updateQueue.listIterator(0); ListIterator<Update> i = updateQueue.listIterator(0);
while (i.hasNext()) { while (i.hasNext()) {
Update u = i.next(); Update u = i.next();
@ -27,11 +28,11 @@ public class UpdateQueue {
private ArrayList<Object> tmpupdates = new ArrayList<Object>(); private ArrayList<Object> tmpupdates = new ArrayList<Object>();
public synchronized Object[] getUpdatedObjects(long since) { public Object[] getUpdatedObjects(long since) {
long now = System.currentTimeMillis();
long deadline = now - maxUpdateAge;
Object[] updates; Object[] updates;
synchronized (lock) { synchronized (lock) {
long now = System.currentTimeMillis();
long deadline = now - maxUpdateAge;
tmpupdates.clear(); tmpupdates.clear();
Iterator<Update> it = updateQueue.descendingIterator(); Iterator<Update> it = updateQueue.descendingIterator();
while (it.hasNext()) { while (it.hasNext()) {

View File

@ -11,6 +11,7 @@ import javax.imageio.ImageIO;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.World.Environment;
import org.dynmap.Client; import org.dynmap.Client;
import org.dynmap.ColorScheme; import org.dynmap.ColorScheme;
import org.dynmap.DynmapChunk; import org.dynmap.DynmapChunk;
@ -22,10 +23,17 @@ import org.dynmap.debug.Debug;
public class FlatMap extends MapType { public class FlatMap extends MapType {
private String prefix; private String prefix;
private ColorScheme colorScheme; private ColorScheme colorScheme;
private int maximumHeight = 127;
public FlatMap(Map<String, Object> configuration) { public FlatMap(Map<String, Object> configuration) {
prefix = (String) configuration.get("prefix"); prefix = (String) configuration.get("prefix");
colorScheme = ColorScheme.getScheme((String) configuration.get("colorscheme")); colorScheme = ColorScheme.getScheme((String) configuration.get("colorscheme"));
Object o = configuration.get("maximumheight");
if (o != null) {
maximumHeight = Integer.parseInt(String.valueOf(o));
if (maximumHeight > 127)
maximumHeight = 127;
}
} }
@Override @Override
@ -68,6 +76,7 @@ public class FlatMap extends MapType {
public boolean render(MapTile tile, File outputFile) { public boolean render(MapTile tile, File outputFile) {
FlatMapTile t = (FlatMapTile) tile; FlatMapTile t = (FlatMapTile) tile;
World w = t.getWorld(); World w = t.getWorld();
boolean isnether = (w.getEnvironment() == Environment.NETHER) && (maximumHeight == 127);
boolean rendered = false; boolean rendered = false;
BufferedImage im = new BufferedImage(t.size, t.size, BufferedImage.TYPE_INT_RGB); BufferedImage im = new BufferedImage(t.size, t.size, BufferedImage.TYPE_INT_RGB);
@ -79,17 +88,40 @@ public class FlatMap extends MapType {
for (int y = 0; y < t.size; y++) { for (int y = 0; y < t.size; y++) {
int mx = x + t.x * t.size; int mx = x + t.x * t.size;
int mz = y + t.y * t.size; int mz = y + t.y * t.size;
int my = w.getHighestBlockYAt(mx, mz) - 1; int my;
int blockType = w.getBlockTypeIdAt(mx, my, mz); int blockType;
byte data = 0; if(isnether) {
if(colorScheme.datacolors[blockType] != null) { /* If data colored */ /* Scan until we hit air */
data = w.getBlockAt(mx, my, mz).getData(); my = 127;
while((blockType = w.getBlockTypeIdAt(mx, my, mz)) != 0) {
my--;
if(my < 0) { /* Solid - use top */
my = 127;
blockType = w.getBlockTypeIdAt(mx, my, mz);
break;
}
}
if(blockType == 0) { /* Hit air - now find non-air */
while((blockType = w.getBlockTypeIdAt(mx, my, mz)) == 0) {
my--;
if(my < 0) {
my = 0;
break;
}
}
}
}
else {
my = w.getHighestBlockYAt(mx, mz) - 1;
if(my > maximumHeight) my = maximumHeight;
blockType = w.getBlockTypeIdAt(mx, my, mz);
}
byte data = 0;
Color[] colors = colorScheme.colors[blockType];
if(colorScheme.datacolors[blockType] != null) {
data = w.getBlockAt(mx, my, mz).getData();
colors = colorScheme.datacolors[blockType][data];
} }
Color[] colors;
if(data != 0)
colors = colorScheme.datacolors[blockType][data];
else
colors = colorScheme.colors[blockType];
if (colors == null) if (colors == null)
continue; continue;
Color c = colors[0]; Color c = colors[0];
@ -103,7 +135,7 @@ public class FlatMap extends MapType {
// Defines the 'step' in coloring. // Defines the 'step' in coloring.
float step = 10 / 128.0f; float step = 10 / 128.0f;
// The step applied to height. // The step applied to height.
float scale = ((int)(height/step))*step; float scale = ((int)(height/step))*step;
@ -135,19 +167,19 @@ public class FlatMap extends MapType {
final MapTile mtile = tile; final MapTile mtile = tile;
final BufferedImage img = im; final BufferedImage img = im;
MapManager.mapman.enqueueImageWrite(new Runnable() { MapManager.mapman.enqueueImageWrite(new Runnable() {
public void run() { public void run() {
Debug.debug("saving image " + fname.getPath()); Debug.debug("saving image " + fname.getPath());
try { try {
ImageIO.write(img, "png", fname); ImageIO.write(img, "png", fname);
} catch (IOException e) { } catch (IOException e) {
Debug.error("Failed to save image: " + fname.getPath(), e); Debug.error("Failed to save image: " + fname.getPath(), e);
} catch (java.lang.NullPointerException e) { } catch (java.lang.NullPointerException e) {
Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e); Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e);
} }
img.flush(); img.flush();
MapManager.mapman.pushUpdate(mtile.getWorld(), MapManager.mapman.pushUpdate(mtile.getWorld(),
new Client.Tile(mtile.getFilename())); new Client.Tile(mtile.getFilename()));
} }
}); });
return rendered; return rendered;

View File

@ -12,14 +12,20 @@ public class CaveTileRenderer extends DefaultTileRenderer {
} }
@Override @Override
protected Color scan(World world, int x, int y, int z, int seq) { protected Color scan(World world, int x, int y, int z, int seq, boolean isnether) {
boolean air = true; boolean air = true;
for (;;) { for (;;) {
if (y < 0) if (y < 0)
return translucent; return translucent;
int id = world.getBlockTypeIdAt(x, y, z); int id = world.getBlockTypeIdAt(x, y, z);
if(isnether) { /* Make ceiling into air in nether */
if(id != 0)
id = 0;
else
isnether = false;
}
switch (seq) { switch (seq) {
case 0: case 0:

View File

@ -12,7 +12,9 @@ import java.util.Map;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.World.Environment;
import org.dynmap.Client; import org.dynmap.Client;
import org.dynmap.ColorScheme; import org.dynmap.ColorScheme;
import org.dynmap.MapManager; import org.dynmap.MapManager;
@ -28,25 +30,6 @@ public class DefaultTileRenderer implements MapTileRenderer {
protected HashSet<Integer> highlightBlocks = new HashSet<Integer>(); protected HashSet<Integer> highlightBlocks = new HashSet<Integer>();
protected Color highlightColor = new Color(255, 0, 0); protected Color highlightColor = new Color(255, 0, 0);
private static final Color[] woolshades = {
Color.WHITE,
Color.ORANGE,
Color.MAGENTA,
new Color(51,204,255),
Color.YELLOW,
new Color(102,255,102),
Color.PINK,
Color.GRAY,
Color.LIGHT_GRAY,
Color.CYAN,
new Color(255,0,255),
Color.BLUE,
new Color(102,51,51),
Color.GREEN,
Color.RED,
Color.BLACK
};
@Override @Override
public String getName() { public String getName() {
return name; return name;
@ -65,6 +48,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
public boolean render(KzedMapTile tile, File outputFile) { public boolean render(KzedMapTile tile, File outputFile) {
World world = tile.getWorld(); World world = tile.getWorld();
boolean isnether = (world.getEnvironment() == Environment.NETHER);
BufferedImage im = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB); BufferedImage im = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB);
WritableRaster r = im.getRaster(); WritableRaster r = im.getRaster();
@ -74,8 +58,12 @@ public class DefaultTileRenderer implements MapTileRenderer {
int iy = maximumHeight; int iy = maximumHeight;
int iz = KzedMap.anchorz + tile.px / 2 - tile.py / 2 + ((127-maximumHeight)/2); int iz = KzedMap.anchorz + tile.px / 2 - tile.py / 2 + ((127-maximumHeight)/2);
/* Don't mess with existing height-clipped renders */
if(maximumHeight < 127)
isnether = false;
int jx, jz; int jx, jz;
int x, y; int x, y;
/* draw the map */ /* draw the map */
@ -84,8 +72,8 @@ public class DefaultTileRenderer implements MapTileRenderer {
jz = iz; jz = iz;
for (x = KzedMap.tileWidth - 1; x >= 0; x -= 2) { for (x = KzedMap.tileWidth - 1; x >= 0; x -= 2) {
Color c1 = scan(world, jx, iy, jz, 0); Color c1 = scan(world, jx, iy, jz, 0, isnether);
Color c2 = scan(world, jx, iy, jz, 2); Color c2 = scan(world, jx, iy, jz, 2, isnether);
isempty = isempty && c1 == translucent && c2 == translucent; isempty = isempty && c1 == translucent && c2 == translucent;
r.setPixel(x, y, new int[] { r.setPixel(x, y, new int[] {
c1.getRed(), c1.getRed(),
@ -107,10 +95,10 @@ public class DefaultTileRenderer implements MapTileRenderer {
jz = iz - 1; jz = iz - 1;
for (x = KzedMap.tileWidth - 1; x >= 0; x -= 2) { for (x = KzedMap.tileWidth - 1; x >= 0; x -= 2) {
Color c1 = scan(world, jx, iy, jz, 2); Color c1 = scan(world, jx, iy, jz, 2, isnether);
jx++; jx++;
jz++; jz++;
Color c2 = scan(world, jx, iy, jz, 0); Color c2 = scan(world, jx, iy, jz, 0, isnether);
isempty = isempty && c1 == translucent && c2 == translucent; isempty = isempty && c1 == translucent && c2 == translucent;
r.setPixel(x, y, new int[] { r.setPixel(x, y, new int[] {
c1.getRed(), c1.getRed(),
@ -132,100 +120,112 @@ public class DefaultTileRenderer implements MapTileRenderer {
final File fname = outputFile; final File fname = outputFile;
final KzedMapTile mtile = tile; final KzedMapTile mtile = tile;
final BufferedImage img = im; final BufferedImage img = im;
final KzedZoomedMapTile zmtile = new KzedZoomedMapTile(mtile.getWorld(), final KzedZoomedMapTile zmtile = new KzedZoomedMapTile(mtile.getWorld(),
(KzedMap) mtile.getMap(), mtile); (KzedMap) mtile.getMap(), mtile);
final File zoomFile = MapManager.mapman.getTileFile(zmtile); final File zoomFile = MapManager.mapman.getTileFile(zmtile);
MapManager.mapman.enqueueImageWrite(new Runnable() { MapManager.mapman.enqueueImageWrite(new Runnable() {
public void run() { public void run() {
doFileWrites(fname, mtile, img, zmtile, zoomFile); doFileWrites(fname, mtile, img, zmtile, zoomFile);
} }
}); });
return !isempty; return !isempty;
} }
private void doFileWrites(final File fname, final KzedMapTile mtile, private void doFileWrites(final File fname, final KzedMapTile mtile,
final BufferedImage img, final KzedZoomedMapTile zmtile, final File zoomFile) { final BufferedImage img, final KzedZoomedMapTile zmtile, final File zoomFile) {
Debug.debug("saving image " + fname.getPath()); Debug.debug("saving image " + fname.getPath());
try { try {
ImageIO.write(img, "png", fname); ImageIO.write(img, "png", fname);
} catch (IOException e) { } catch (IOException e) {
Debug.error("Failed to save image: " + fname.getPath(), e); Debug.error("Failed to save image: " + fname.getPath(), e);
} catch (java.lang.NullPointerException e) { } catch (java.lang.NullPointerException e) {
Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e); Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e);
} }
mtile.file = fname; mtile.file = fname;
// Since we've already got the new tile, and we're on an async thread, just // Since we've already got the new tile, and we're on an async thread, just
// make the zoomed tile here // make the zoomed tile here
int px = mtile.px; int px = mtile.px;
int py = mtile.py; int py = mtile.py;
int zpx = zmtile.getTileX(); int zpx = zmtile.getTileX();
int zpy = zmtile.getTileY(); int zpy = zmtile.getTileY();
/* scaled size */ /* scaled size */
int scw = KzedMap.tileWidth / 2; int scw = KzedMap.tileWidth / 2;
int sch = KzedMap.tileHeight / 2; int sch = KzedMap.tileHeight / 2;
/* origin in zoomed-out tile */ /* origin in zoomed-out tile */
int ox = 0; int ox = 0;
int oy = 0; int oy = 0;
if (zpx != px) if (zpx != px)
ox = scw; ox = scw;
if (zpy != py) if (zpy != py)
oy = sch; oy = sch;
BufferedImage zIm = null; BufferedImage zIm = null;
try { try {
zIm = ImageIO.read(zoomFile); zIm = ImageIO.read(zoomFile);
} catch (IOException e) { } catch (IOException e) {
} catch (IndexOutOfBoundsException e) { } catch (IndexOutOfBoundsException e) {
} }
if (zIm == null) { if (zIm == null) {
/* create new one */ /* create new one */
zIm = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB); zIm = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB);
Debug.debug("New zoom-out tile created " + zmtile.getFilename()); Debug.debug("New zoom-out tile created " + zmtile.getFilename());
} else { } else {
Debug.debug("Loaded zoom-out tile from " + zmtile.getFilename()); Debug.debug("Loaded zoom-out tile from " + zmtile.getFilename());
} }
/* blit scaled rendered tile onto zoom-out tile */ /* blit scaled rendered tile onto zoom-out tile */
Graphics2D g2 = zIm.createGraphics(); Graphics2D g2 = zIm.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(img, ox, oy, scw, sch, null); g2.drawImage(img, ox, oy, scw, sch, null);
img.flush(); img.flush();
/* save zoom-out tile */ /* save zoom-out tile */
try { try {
ImageIO.write(zIm, "png", zoomFile); ImageIO.write(zIm, "png", zoomFile);
Debug.debug("Saved zoom-out tile at " + zoomFile.getName()); Debug.debug("Saved zoom-out tile at " + zoomFile.getName());
} catch (IOException e) { } catch (IOException e) {
Debug.error("Failed to save zoom-out tile: " + zoomFile.getName(), e); Debug.error("Failed to save zoom-out tile: " + zoomFile.getName(), e);
} catch (java.lang.NullPointerException e) { } catch (java.lang.NullPointerException e) {
Debug.error("Failed to save zoom-out tile (NullPointerException): " + zoomFile.getName(), e); Debug.error("Failed to save zoom-out tile (NullPointerException): " + zoomFile.getName(), e);
} }
zIm.flush(); zIm.flush();
/* Push updates for both files.*/ /* Push updates for both files.*/
MapManager.mapman.pushUpdate(mtile.getWorld(), MapManager.mapman.pushUpdate(mtile.getWorld(),
new Client.Tile(mtile.getFilename())); new Client.Tile(mtile.getFilename()));
MapManager.mapman.pushUpdate(zmtile.getWorld(), MapManager.mapman.pushUpdate(zmtile.getWorld(),
new Client.Tile(zmtile.getFilename())); new Client.Tile(zmtile.getFilename()));
} }
protected Color scan(World world, int x, int y, int z, int seq) { protected Color scan(World world, int x, int y, int z, int seq, boolean isnether) {
Color result = translucent;
for (;;) { for (;;) {
if (y < 0) if (y < 0) {
return translucent; return result;
}
int id = world.getBlockTypeIdAt(x, y, z); int id = world.getBlockTypeIdAt(x, y, z);
byte data = 0; byte data = 0;
if(colorScheme.datacolors[id] != null) { /* If data colored */ if(isnether) { /* Make bedrock ceiling into air in nether */
data = world.getBlockAt(x, y, z).getData(); if(id != 0) {
/* Remember first color we see, in case we wind up solid */
if(result == translucent)
if(colorScheme.colors[id] != null)
result = colorScheme.colors[id][seq];
id = 0;
}
else
isnether = false;
}
if(colorScheme.datacolors[id] != null) { /* If data colored */
data = world.getBlockAt(x, y, z).getData();
} }
switch (seq) { switch (seq) {
case 0: case 0:
@ -250,9 +250,9 @@ public class DefaultTileRenderer implements MapTileRenderer {
} }
Color[] colors; Color[] colors;
if(data != 0) if(data != 0)
colors = colorScheme.datacolors[id][data]; colors = colorScheme.datacolors[id][data];
else else
colors = colorScheme.colors[id]; colors = colorScheme.colors[id];
if (colors != null) { if (colors != null) {
Color c = colors[seq]; Color c = colors[seq];
if (c.getAlpha() > 0) { if (c.getAlpha() > 0) {
@ -263,7 +263,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
} }
/* this block is transparent, so recurse */ /* this block is transparent, so recurse */
Color bg = scan(world, x, y, z, seq); Color bg = scan(world, x, y, z, seq, isnether);
int cr = c.getRed(); int cr = c.getRed();
int cg = c.getGreen(); int cg = c.getGreen();

View File

@ -21,19 +21,31 @@ public class HighlightTileRenderer extends DefaultTileRenderer {
highlightBlocks.add((Integer)highlightObj); highlightBlocks.add((Integer)highlightObj);
} }
} }
@Override @Override
protected Color scan(World world, int x, int y, int z, int seq) { protected Color scan(World world, int x, int y, int z, int seq, boolean isnether) {
Color result = translucent; Color result = translucent;
int top_nether_id = 0;
for (;;) { for (;;) {
if (y < 0) { if (y < 0) {
break; break;
} }
int id = world.getBlockTypeIdAt(x, y, z); int id = world.getBlockTypeIdAt(x, y, z);
if(isnether) { /* Make bedrock ceiling into air in nether */
if(id != 0) {
/* Remember first color we see, in case we wind up solid */
if(result == translucent)
if(colorScheme.colors[id] != null)
result = colorScheme.colors[id][seq];
id = 0;
}
else
isnether = false;
}
byte data = 0; byte data = 0;
if(colorScheme.datacolors[id] != null) { /* If data colored */ if(colorScheme.datacolors[id] != null) { /* If data colored */
data = world.getBlockAt(x, y, z).getData(); data = world.getBlockAt(x, y, z).getData();
} }
switch (seq) { switch (seq) {
@ -56,9 +68,9 @@ public class HighlightTileRenderer extends DefaultTileRenderer {
if (id != 0) { if (id != 0) {
Color[] colors; Color[] colors;
if(data != 0) if(data != 0)
colors = colorScheme.datacolors[id][data]; colors = colorScheme.datacolors[id][data];
else else
colors = colorScheme.colors[id]; colors = colorScheme.colors[id];
if (colors != null) { if (colors != null) {
Color c = colors[seq]; Color c = colors[seq];

View File

@ -1,18 +1,8 @@
package org.dynmap.kzedmap; package org.dynmap.kzedmap;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.Map; import java.util.Map;
import javax.imageio.ImageIO;
import org.dynmap.Client;
import org.dynmap.MapManager;
import org.dynmap.debug.Debug;
public class ZoomedTileRenderer { public class ZoomedTileRenderer {
public ZoomedTileRenderer(Map<String, Object> configuration) { public ZoomedTileRenderer(Map<String, Object> configuration) {
} }

View File

@ -386,7 +386,7 @@ DynMap.prototype = {
swtch(update.type, { swtch(update.type, {
tile: function() { tile: function() {
me.onTileUpdated(update.name); me.onTileUpdated(update.name,update.timestamp);
}, },
playerjoin: function() { playerjoin: function() {
$(me).trigger('playerjoin', [ update.playerName ]); $(me).trigger('playerjoin', [ update.playerName ]);
@ -436,12 +436,12 @@ DynMap.prototype = {
unregisterTile: function(mapType, tileName) { unregisterTile: function(mapType, tileName) {
delete this.registeredTiles[tileName]; delete this.registeredTiles[tileName];
}, },
onTileUpdated: function(tileName) { onTileUpdated: function(tileName,timestamp) {
var me = this; var me = this;
var tile = this.registeredTiles[tileName]; var tile = this.registeredTiles[tileName];
if (tile) { if (tile) {
tile.lastseen = this.lasttimestamp; tile.lastseen = timestamp;
tile.mapType.onTileUpdated(tile.tileElement, tileName); tile.mapType.onTileUpdated(tile.tileElement, tileName);
} }
}, },