mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-11-13 22:05:12 +01:00
Merge pull request #143 from mikeprimm/master
Remerged - nether render updates, and rest of HeroChat
This commit is contained in:
commit
cbfa26a5b3
@ -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:
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()) {
|
||||||
|
@ -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;
|
||||||
|
@ -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:
|
||||||
|
@ -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();
|
||||||
|
@ -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];
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user