mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-11-28 05:05:16 +01:00
Tabs and spaces.
This commit is contained in:
parent
5e107cccb9
commit
17f5f43772
@ -30,7 +30,7 @@ public class Client {
|
||||
public static class Stamped {
|
||||
public long timestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
public static class ChatMessage extends Stamped {
|
||||
public String type = "chat";
|
||||
public String source;
|
||||
@ -43,7 +43,7 @@ public class Client {
|
||||
this.message = ChatColor.stripColor(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class PlayerJoinMessage extends Stamped {
|
||||
public String type = "playerjoin";
|
||||
public String playerName;
|
||||
@ -51,7 +51,7 @@ public class Client {
|
||||
this.playerName = ChatColor.stripColor(playerName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class PlayerQuitMessage extends Stamped {
|
||||
public String type = "playerquit";
|
||||
public String playerName;
|
||||
|
@ -7,9 +7,9 @@ package org.dynmap;
|
||||
public class Color {
|
||||
/* RGBA value */
|
||||
private int val;
|
||||
|
||||
|
||||
public static final int TRANSPARENT = 0;
|
||||
|
||||
|
||||
public Color(int red, int green, int blue, int alpha) {
|
||||
setRGBA(red, green, blue, alpha);
|
||||
}
|
||||
|
@ -15,9 +15,9 @@ import org.dynmap.debug.Debug;
|
||||
public class ColorScheme {
|
||||
protected static final Logger log = Logger.getLogger("Minecraft");
|
||||
private static final HashMap<String, ColorScheme> cache = new HashMap<String, ColorScheme>();
|
||||
|
||||
|
||||
public String name;
|
||||
/* Switch to arrays - faster than map */
|
||||
/* Switch to arrays - faster than map */
|
||||
public Color[][] colors; /* [blk-type][step] */
|
||||
public Color[][][] datacolors; /* [bkt-type][blk-dat][step] */
|
||||
|
||||
@ -26,11 +26,11 @@ public class ColorScheme {
|
||||
this.colors = colors;
|
||||
this.datacolors = datacolors;
|
||||
}
|
||||
|
||||
|
||||
private static File getColorSchemeDirectory() {
|
||||
return new File(DynmapPlugin.dataDirectory, "colorschemes");
|
||||
}
|
||||
|
||||
|
||||
public static ColorScheme getScheme(String name) {
|
||||
if (name == null)
|
||||
name = "default";
|
||||
@ -41,7 +41,7 @@ public class ColorScheme {
|
||||
}
|
||||
return scheme;
|
||||
}
|
||||
|
||||
|
||||
public static ColorScheme loadScheme(String name) {
|
||||
File colorSchemeFile = new File(getColorSchemeDirectory(), name + ".txt");
|
||||
Color[][] colors = new Color[256][];
|
||||
|
@ -28,4 +28,4 @@ public class DynmapPlayerChatListener extends PlayerListener {
|
||||
plugin.mapManager.pushUpdate(new Client.PlayerQuitMessage(event.getPlayer().getDisplayName()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
public HttpServer getWebServer() {
|
||||
return webServer;
|
||||
}
|
||||
|
||||
|
||||
public void onEnable() {
|
||||
permissions = NijikokunPermissions.create(getServer(), "dynmap");
|
||||
if (permissions == null)
|
||||
@ -108,14 +108,14 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
}
|
||||
|
||||
hchand = new HeroChatHandler(configuration, this, getServer());
|
||||
|
||||
|
||||
enabledTriggers.clear();
|
||||
for (Object trigger : configuration.getList("render-triggers")) {
|
||||
enabledTriggers.add((String) trigger);
|
||||
}
|
||||
|
||||
registerEvents();
|
||||
|
||||
|
||||
/* Print version info */
|
||||
PluginDescriptionFile pdfFile = this.getDescription();
|
||||
log.info("[dynmap] version " + pdfFile.getVersion() + " is enabled" );
|
||||
@ -152,7 +152,7 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
}
|
||||
});
|
||||
}};
|
||||
|
||||
|
||||
webServer.handlers.put("/up/sendmessage", messageHandler);
|
||||
}
|
||||
|
||||
@ -408,7 +408,7 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
mapManager.pushUpdate(new Client.ChatMessage("web", name, message));
|
||||
log.info("[WEB]" + name + ": " + message);
|
||||
/* Let HeroChat take a look - only broadcast to players if it doesn't handle it */
|
||||
if(hchand.sendWebMessageToHeroChat(name, message) == false)
|
||||
if(hchand.sendWebMessageToHeroChat(name, message) == false)
|
||||
getServer().broadcastMessage("[WEB]" + name + ": " + message);
|
||||
}
|
||||
}
|
||||
|
@ -5,21 +5,21 @@ 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);
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ public class HeroChatHandler {
|
||||
.forName("com.herocraftonline.dthielke.herochat.channels.Channel");
|
||||
getname = channel.getMethod("getName");
|
||||
getnick = channel.getMethod("getNick", new Class[0]);
|
||||
sendmessage = channel.getMethod("sendMessage", new Class[] {
|
||||
sendmessage = channel.getMethod("sendMessage", new Class[] {
|
||||
String.class, String.class, String.class, boolean.class } );
|
||||
isgood = true;
|
||||
} catch (ClassNotFoundException cnfx) {
|
||||
@ -256,7 +256,7 @@ public class HeroChatHandler {
|
||||
log.severe("[dynmap] Cannot load HeroChat channel event class!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Register event handler */
|
||||
plugin.getServer().getPluginManager().registerEvent(Event.Type.CUSTOM_EVENT,
|
||||
new OurEventListener(), Event.Priority.Monitor, plugin);
|
||||
|
@ -33,7 +33,7 @@ public class MapManager {
|
||||
|
||||
public AsynchronousQueue<MapTile> tileQueue;
|
||||
public AsynchronousQueue<ImageWriter> writeQueue;
|
||||
|
||||
|
||||
public Map<String, DynmapWorld> worlds = new HashMap<String, DynmapWorld>();
|
||||
public Map<String, DynmapWorld> inactiveworlds = new HashMap<String, DynmapWorld>();
|
||||
private BukkitScheduler scheduler;
|
||||
@ -48,7 +48,7 @@ public class MapManager {
|
||||
public static final Object lock = new Object();
|
||||
|
||||
public static MapManager mapman; /* Our singleton */
|
||||
|
||||
|
||||
private static class ImageWriter {
|
||||
Runnable run;
|
||||
}
|
||||
@ -62,7 +62,7 @@ public class MapManager {
|
||||
HashSet<MapTile> rendered = null;
|
||||
LinkedList<MapTile> renderQueue = null;
|
||||
MapTile tile0 = null;
|
||||
|
||||
|
||||
/* Full world, all maps render */
|
||||
FullWorldRenderState(DynmapWorld dworld, Location l) {
|
||||
world = dworld;
|
||||
@ -71,16 +71,16 @@ public class MapManager {
|
||||
rendered = new HashSet<MapTile>();
|
||||
renderQueue = new LinkedList<MapTile>();
|
||||
}
|
||||
|
||||
|
||||
/* Single tile render - used for incremental renders */
|
||||
FullWorldRenderState(MapTile t) {
|
||||
world = worlds.get(t.getWorld().getName());
|
||||
tile0 = t;
|
||||
}
|
||||
|
||||
|
||||
public void run() {
|
||||
MapTile tile;
|
||||
|
||||
|
||||
if(tile0 == null) { /* Not single tile render */
|
||||
/* If render queue is empty, start next map */
|
||||
if(renderQueue.isEmpty()) {
|
||||
@ -144,12 +144,12 @@ public class MapManager {
|
||||
for(Entity e: cc.getEntities())
|
||||
e.remove();
|
||||
}
|
||||
/* Since we only remember ones we loaded, and we're synchronous, no player has
|
||||
/* Since we only remember ones we loaded, and we're synchronous, no player has
|
||||
* moved, so it must be safe (also prevent chunk leak, which appears to happen
|
||||
* because isChunkInUse defined "in use" as being within 256 blocks of a player,
|
||||
* while the actual in-use chunk area for a player where the chunks are managed
|
||||
* by the MC base server is 21x21 (or about a 160 block radius) */
|
||||
w.unloadChunk(c.x, c.z, false, false);
|
||||
w.unloadChunk(c.x, c.z, false, false);
|
||||
}
|
||||
if(tile0 == null) { /* fullrender */
|
||||
/* Schedule the next tile to be worked */
|
||||
@ -159,20 +159,20 @@ public class MapManager {
|
||||
}
|
||||
|
||||
public MapManager(DynmapPlugin plugin, ConfigurationNode configuration) {
|
||||
|
||||
|
||||
mapman = this;
|
||||
|
||||
|
||||
this.tileQueue = new AsynchronousQueue<MapTile>(new Handler<MapTile>() {
|
||||
@Override
|
||||
public void handle(MapTile t) {
|
||||
if(do_sync_render)
|
||||
scheduler.scheduleSyncDelayedTask(plug_in,
|
||||
scheduler.scheduleSyncDelayedTask(plug_in,
|
||||
new FullWorldRenderState(t), 1);
|
||||
else
|
||||
render(t);
|
||||
}
|
||||
}, (int) (configuration.getDouble("renderinterval", 0.5) * 1000));
|
||||
|
||||
|
||||
this.writeQueue = new AsynchronousQueue<ImageWriter>(
|
||||
new Handler<ImageWriter>() {
|
||||
@Override
|
||||
@ -184,7 +184,7 @@ public class MapManager {
|
||||
do_timesliced_render = configuration.getBoolean("timeslicerender", true);
|
||||
timeslice_interval = configuration.getDouble("timesliceinterval", 0.5);
|
||||
do_sync_render = configuration.getBoolean("renderonsync", true);
|
||||
|
||||
|
||||
for(Object worldConfigurationObj : (List<?>)configuration.getProperty("worlds")) {
|
||||
Map<?, ?> worldConfiguration = (Map<?, ?>)worldConfigurationObj;
|
||||
String worldName = (String)worldConfiguration.get("name");
|
||||
@ -195,21 +195,21 @@ public class MapManager {
|
||||
}
|
||||
}
|
||||
inactiveworlds.put(worldName, world);
|
||||
|
||||
|
||||
World bukkitWorld = plugin.getServer().getWorld(worldName);
|
||||
if (bukkitWorld != null)
|
||||
activateWorld(bukkitWorld);
|
||||
}
|
||||
|
||||
|
||||
scheduler = plugin.getServer().getScheduler();
|
||||
plug_in = plugin;
|
||||
|
||||
|
||||
tileQueue.start();
|
||||
writeQueue.start();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void renderFullWorld(Location l) {
|
||||
DynmapWorld world = worlds.get(l.getWorld().getName());
|
||||
if (world == null) {
|
||||
@ -232,7 +232,7 @@ public class MapManager {
|
||||
return;
|
||||
}
|
||||
World w = world.world;
|
||||
|
||||
|
||||
log.info("Full render starting on world '" + w.getName() + "'...");
|
||||
for (MapType map : world.maps) {
|
||||
int requiredChunkCount = 200;
|
||||
@ -303,7 +303,7 @@ public class MapManager {
|
||||
log.info("Activated world '" + w.getName() + "' in Dynmap.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private MapType[] loadMapTypes(List<?> mapConfigurations) {
|
||||
Event.Listener<MapTile> invalitateListener = new Event.Listener<MapTile>() {
|
||||
@Override
|
||||
@ -332,7 +332,7 @@ public class MapManager {
|
||||
mapTypes.toArray(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public int touch(Location l) {
|
||||
DynmapWorld world = worlds.get(l.getWorld().getName());
|
||||
if (world == null)
|
||||
@ -352,24 +352,24 @@ public class MapManager {
|
||||
Debug.debug("Invalidating tile " + tile.getFilename());
|
||||
tileQueue.push(tile);
|
||||
}
|
||||
|
||||
|
||||
public void startRendering() {
|
||||
tileQueue.start();
|
||||
writeQueue.start();
|
||||
}
|
||||
|
||||
|
||||
public void stopRendering() {
|
||||
tileQueue.stop();
|
||||
writeQueue.stop();
|
||||
}
|
||||
|
||||
|
||||
public boolean render(MapTile tile) {
|
||||
boolean result = tile.getMap().render(tile, getTileFile(tile));
|
||||
//Do update after async file write
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private HashMap<World, File> worldTileDirectories = new HashMap<World, File>();
|
||||
public File getTileFile(MapTile tile) {
|
||||
World world = tile.getWorld();
|
||||
@ -381,7 +381,7 @@ public class MapManager {
|
||||
if (!worldTileDirectory.isDirectory() && !worldTileDirectory.mkdirs()) {
|
||||
log.warning("Could not create directory for tiles ('" + worldTileDirectory + "').");
|
||||
}
|
||||
return new File(worldTileDirectory, tile.getFilename());
|
||||
return new File(worldTileDirectory, tile.getFilename());
|
||||
}
|
||||
|
||||
public void pushUpdate(Object update) {
|
||||
@ -389,29 +389,29 @@ public class MapManager {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
public void enqueueImageWrite(Runnable run) {
|
||||
ImageWriter handler = new ImageWriter();
|
||||
handler.run = run;
|
||||
writeQueue.push(handler);
|
||||
}
|
||||
|
||||
|
||||
public boolean doSyncRender() {
|
||||
return do_sync_render;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ public abstract class MapTile {
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
|
||||
public MapType getMap() {
|
||||
return map;
|
||||
}
|
||||
@ -20,12 +20,12 @@ public abstract class MapTile {
|
||||
this.world = world;
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getFilename().hashCode() ^ getWorld().hashCode();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof MapTile) {
|
||||
|
@ -6,7 +6,7 @@ import org.bukkit.Location;
|
||||
|
||||
public abstract class MapType {
|
||||
public Event<MapTile> onTileInvalidated = new Event<MapTile>();
|
||||
|
||||
|
||||
public abstract MapTile[] getTiles(Location l);
|
||||
|
||||
public abstract MapTile[] getAdjecentTiles(MapTile tile);
|
||||
|
@ -87,7 +87,7 @@ public class PlayerList {
|
||||
visiblePlayers.toArray(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public Player[] getVisiblePlayers() {
|
||||
ArrayList<Player> visiblePlayers = new ArrayList<Player>();
|
||||
Player[] onlinePlayers = server.getOnlinePlayers();
|
||||
|
@ -13,7 +13,7 @@ public class UpdateQueue {
|
||||
|
||||
public void pushUpdate(Object obj) {
|
||||
synchronized (lock) {
|
||||
/* Do inside lock - prevent delay between time and actual work */
|
||||
/* Do inside lock - prevent delay between time and actual work */
|
||||
long now = System.currentTimeMillis();
|
||||
long deadline = now - maxUpdateAge;
|
||||
ListIterator<Update> i = updateQueue.listIterator(0);
|
||||
@ -49,7 +49,7 @@ public class UpdateQueue {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Reverse output.
|
||||
updates = new Object[tmpupdates.size()];
|
||||
for (int i = 0; i < updates.length; i++) {
|
||||
|
@ -8,15 +8,15 @@ public class Debug {
|
||||
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);
|
||||
}
|
||||
|
@ -9,10 +9,10 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||
public class LogDebugger implements Debugger {
|
||||
protected static final Logger log = Logger.getLogger("Minecraft");
|
||||
private static String prepend = "dynmap: ";
|
||||
|
||||
|
||||
public LogDebugger(JavaPlugin plugin, Map<String, Object> configuration) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void debug(String message) {
|
||||
log.info(prepend + message);
|
||||
|
@ -9,7 +9,7 @@ public class NullDebugger implements Debugger {
|
||||
|
||||
public NullDebugger(JavaPlugin plugin, Map<String, Object> configuration) {
|
||||
}
|
||||
|
||||
|
||||
public void debug(String message) {
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ public class FlatMap extends MapType {
|
||||
private String prefix;
|
||||
private ColorScheme colorScheme;
|
||||
private int maximumHeight = 127;
|
||||
|
||||
|
||||
public FlatMap(Map<String, Object> configuration) {
|
||||
prefix = (String) configuration.get("prefix");
|
||||
colorScheme = ColorScheme.getScheme((String) configuration.get("colorscheme"));
|
||||
@ -91,36 +91,36 @@ public class FlatMap extends MapType {
|
||||
int my;
|
||||
int blockType;
|
||||
if(isnether) {
|
||||
/* Scan until we hit air */
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Scan until we hit air */
|
||||
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);
|
||||
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];
|
||||
data = w.getBlockAt(mx, my, mz).getData();
|
||||
colors = colorScheme.datacolors[blockType][data];
|
||||
}
|
||||
if (colors == null)
|
||||
continue;
|
||||
@ -129,26 +129,26 @@ public class FlatMap extends MapType {
|
||||
continue;
|
||||
|
||||
boolean below = my < 64;
|
||||
|
||||
|
||||
// Make height range from 0 - 1 (1 - 0 for below and 0 - 1 above)
|
||||
float height = (below ? 64 - my : my - 64) / 64.0f;
|
||||
|
||||
|
||||
// Defines the 'step' in coloring.
|
||||
float step = 10 / 128.0f;
|
||||
|
||||
|
||||
// The step applied to height.
|
||||
float scale = ((int)(height/step))*step;
|
||||
|
||||
// Make the smaller values change the color (slightly) more than the higher values.
|
||||
scale = (float)Math.pow(scale, 1.1f);
|
||||
|
||||
|
||||
// Don't let the color go fully white or fully black.
|
||||
scale *= 0.8f;
|
||||
|
||||
|
||||
pixel[0] = c.getRed();
|
||||
pixel[1] = c.getGreen();
|
||||
pixel[2] = c.getBlue();
|
||||
|
||||
|
||||
if (below) {
|
||||
pixel[0] -= pixel[0] * scale;
|
||||
pixel[1] -= pixel[1] * scale;
|
||||
@ -158,7 +158,7 @@ public class FlatMap extends MapType {
|
||||
pixel[1] += (255-pixel[1]) * scale;
|
||||
pixel[2] += (255-pixel[2]) * scale;
|
||||
}
|
||||
|
||||
|
||||
raster.setPixel(t.size-y-1, x, pixel);
|
||||
rendered = true;
|
||||
}
|
||||
@ -167,19 +167,19 @@ public class FlatMap extends MapType {
|
||||
final MapTile mtile = tile;
|
||||
final BufferedImage img = im;
|
||||
MapManager.mapman.enqueueImageWrite(new Runnable() {
|
||||
public void run() {
|
||||
Debug.debug("saving image " + fname.getPath());
|
||||
try {
|
||||
ImageIO.write(img, "png", fname);
|
||||
} catch (IOException e) {
|
||||
Debug.error("Failed to save image: " + fname.getPath(), e);
|
||||
} catch (java.lang.NullPointerException e) {
|
||||
Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e);
|
||||
}
|
||||
img.flush();
|
||||
MapManager.mapman.pushUpdate(mtile.getWorld(),
|
||||
new Client.Tile(mtile.getFilename()));
|
||||
}
|
||||
public void run() {
|
||||
Debug.debug("saving image " + fname.getPath());
|
||||
try {
|
||||
ImageIO.write(img, "png", fname);
|
||||
} catch (IOException e) {
|
||||
Debug.error("Failed to save image: " + fname.getPath(), e);
|
||||
} catch (java.lang.NullPointerException e) {
|
||||
Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e);
|
||||
}
|
||||
img.flush();
|
||||
MapManager.mapman.pushUpdate(mtile.getWorld(),
|
||||
new Client.Tile(mtile.getFilename()));
|
||||
}
|
||||
});
|
||||
|
||||
return rendered;
|
||||
|
@ -20,11 +20,11 @@ public class CaveTileRenderer extends DefaultTileRenderer {
|
||||
return;
|
||||
|
||||
int id = world.getBlockTypeIdAt(x, y, z);
|
||||
if(isnether) { /* Make ceiling into air in nether */
|
||||
if(id != 0)
|
||||
id = 0;
|
||||
else
|
||||
isnether = false;
|
||||
if(isnether) { /* Make ceiling into air in nether */
|
||||
if(id != 0)
|
||||
id = 0;
|
||||
else
|
||||
isnether = false;
|
||||
}
|
||||
|
||||
switch (seq) {
|
||||
|
@ -26,10 +26,10 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
protected String name;
|
||||
protected int maximumHeight = 127;
|
||||
protected ColorScheme colorScheme;
|
||||
|
||||
|
||||
protected HashSet<Integer> highlightBlocks = new HashSet<Integer>();
|
||||
protected Color highlightColor = new Color(255, 0, 0);
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
@ -60,10 +60,10 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
|
||||
/* Don't mess with existing height-clipped renders */
|
||||
if(maximumHeight < 127)
|
||||
isnether = false;
|
||||
|
||||
isnether = false;
|
||||
|
||||
int jx, jz;
|
||||
|
||||
|
||||
int x, y;
|
||||
|
||||
Color c1 = new Color();
|
||||
@ -87,7 +87,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
r.setPixel(x - 1, y, rgb);
|
||||
isempty = false;
|
||||
}
|
||||
|
||||
|
||||
jx++;
|
||||
jz++;
|
||||
|
||||
@ -126,90 +126,90 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
final File fname = outputFile;
|
||||
final KzedMapTile mtile = tile;
|
||||
final BufferedImage img = im;
|
||||
final KzedZoomedMapTile zmtile = new KzedZoomedMapTile(mtile.getWorld(),
|
||||
(KzedMap) mtile.getMap(), mtile);
|
||||
final File zoomFile = MapManager.mapman.getTileFile(zmtile);
|
||||
|
||||
MapManager.mapman.enqueueImageWrite(new Runnable() {
|
||||
public void run() {
|
||||
doFileWrites(fname, mtile, img, zmtile, zoomFile);
|
||||
}
|
||||
});
|
||||
final KzedZoomedMapTile zmtile = new KzedZoomedMapTile(mtile.getWorld(),
|
||||
(KzedMap) mtile.getMap(), mtile);
|
||||
final File zoomFile = MapManager.mapman.getTileFile(zmtile);
|
||||
|
||||
MapManager.mapman.enqueueImageWrite(new Runnable() {
|
||||
public void run() {
|
||||
doFileWrites(fname, mtile, img, zmtile, zoomFile);
|
||||
}
|
||||
});
|
||||
|
||||
return !isempty;
|
||||
}
|
||||
|
||||
|
||||
private void doFileWrites(final File fname, final KzedMapTile mtile,
|
||||
final BufferedImage img, final KzedZoomedMapTile zmtile, final File zoomFile) {
|
||||
Debug.debug("saving image " + fname.getPath());
|
||||
try {
|
||||
ImageIO.write(img, "png", fname);
|
||||
} catch (IOException e) {
|
||||
Debug.error("Failed to save image: " + fname.getPath(), e);
|
||||
} catch (java.lang.NullPointerException e) {
|
||||
Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e);
|
||||
}
|
||||
mtile.file = fname;
|
||||
// Since we've already got the new tile, and we're on an async thread, just
|
||||
// make the zoomed tile here
|
||||
int px = mtile.px;
|
||||
int py = mtile.py;
|
||||
int zpx = zmtile.getTileX();
|
||||
int zpy = zmtile.getTileY();
|
||||
final BufferedImage img, final KzedZoomedMapTile zmtile, final File zoomFile) {
|
||||
Debug.debug("saving image " + fname.getPath());
|
||||
try {
|
||||
ImageIO.write(img, "png", fname);
|
||||
} catch (IOException e) {
|
||||
Debug.error("Failed to save image: " + fname.getPath(), e);
|
||||
} catch (java.lang.NullPointerException e) {
|
||||
Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e);
|
||||
}
|
||||
mtile.file = fname;
|
||||
// Since we've already got the new tile, and we're on an async thread, just
|
||||
// make the zoomed tile here
|
||||
int px = mtile.px;
|
||||
int py = mtile.py;
|
||||
int zpx = zmtile.getTileX();
|
||||
int zpy = zmtile.getTileY();
|
||||
|
||||
/* scaled size */
|
||||
int scw = KzedMap.tileWidth / 2;
|
||||
int sch = KzedMap.tileHeight / 2;
|
||||
/* scaled size */
|
||||
int scw = KzedMap.tileWidth / 2;
|
||||
int sch = KzedMap.tileHeight / 2;
|
||||
|
||||
/* origin in zoomed-out tile */
|
||||
int ox = 0;
|
||||
int oy = 0;
|
||||
/* origin in zoomed-out tile */
|
||||
int ox = 0;
|
||||
int oy = 0;
|
||||
|
||||
if (zpx != px)
|
||||
ox = scw;
|
||||
if (zpy != py)
|
||||
oy = sch;
|
||||
if (zpx != px)
|
||||
ox = scw;
|
||||
if (zpy != py)
|
||||
oy = sch;
|
||||
|
||||
BufferedImage zIm = null;
|
||||
try {
|
||||
zIm = ImageIO.read(zoomFile);
|
||||
} catch (IOException e) {
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
}
|
||||
BufferedImage zIm = null;
|
||||
try {
|
||||
zIm = ImageIO.read(zoomFile);
|
||||
} catch (IOException e) {
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
}
|
||||
|
||||
if (zIm == null) {
|
||||
/* create new one */
|
||||
zIm = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB);
|
||||
Debug.debug("New zoom-out tile created " + zmtile.getFilename());
|
||||
} else {
|
||||
Debug.debug("Loaded zoom-out tile from " + zmtile.getFilename());
|
||||
}
|
||||
|
||||
/* blit scaled rendered tile onto zoom-out tile */
|
||||
Graphics2D g2 = zIm.createGraphics();
|
||||
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
g2.drawImage(img, ox, oy, scw, sch, null);
|
||||
if (zIm == null) {
|
||||
/* create new one */
|
||||
zIm = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB);
|
||||
Debug.debug("New zoom-out tile created " + zmtile.getFilename());
|
||||
} else {
|
||||
Debug.debug("Loaded zoom-out tile from " + zmtile.getFilename());
|
||||
}
|
||||
|
||||
img.flush();
|
||||
/* blit scaled rendered tile onto zoom-out tile */
|
||||
Graphics2D g2 = zIm.createGraphics();
|
||||
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
g2.drawImage(img, ox, oy, scw, sch, null);
|
||||
|
||||
/* save zoom-out tile */
|
||||
|
||||
try {
|
||||
ImageIO.write(zIm, "png", zoomFile);
|
||||
Debug.debug("Saved zoom-out tile at " + zoomFile.getName());
|
||||
} catch (IOException e) {
|
||||
Debug.error("Failed to save zoom-out tile: " + zoomFile.getName(), e);
|
||||
} catch (java.lang.NullPointerException e) {
|
||||
Debug.error("Failed to save zoom-out tile (NullPointerException): " + zoomFile.getName(), e);
|
||||
}
|
||||
zIm.flush();
|
||||
/* Push updates for both files.*/
|
||||
MapManager.mapman.pushUpdate(mtile.getWorld(),
|
||||
new Client.Tile(mtile.getFilename()));
|
||||
MapManager.mapman.pushUpdate(zmtile.getWorld(),
|
||||
new Client.Tile(zmtile.getFilename()));
|
||||
img.flush();
|
||||
|
||||
/* save zoom-out tile */
|
||||
|
||||
try {
|
||||
ImageIO.write(zIm, "png", zoomFile);
|
||||
Debug.debug("Saved zoom-out tile at " + zoomFile.getName());
|
||||
} catch (IOException e) {
|
||||
Debug.error("Failed to save zoom-out tile: " + zoomFile.getName(), e);
|
||||
} catch (java.lang.NullPointerException e) {
|
||||
Debug.error("Failed to save zoom-out tile (NullPointerException): " + zoomFile.getName(), e);
|
||||
}
|
||||
zIm.flush();
|
||||
/* Push updates for both files.*/
|
||||
MapManager.mapman.pushUpdate(mtile.getWorld(),
|
||||
new Client.Tile(mtile.getFilename()));
|
||||
MapManager.mapman.pushUpdate(zmtile.getWorld(),
|
||||
new Client.Tile(zmtile.getFilename()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void scan(World world, int x, int y, int z, int seq, boolean isnether, final Color result) {
|
||||
result.setTransparent();
|
||||
@ -219,19 +219,19 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
}
|
||||
int id = world.getBlockTypeIdAt(x, y, z);
|
||||
byte data = 0;
|
||||
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.isTransparent())
|
||||
if(colorScheme.colors[id] != null)
|
||||
result.setColor(colorScheme.colors[id][seq]);
|
||||
id = 0;
|
||||
}
|
||||
else
|
||||
isnether = false;
|
||||
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.isTransparent())
|
||||
if(colorScheme.colors[id] != null)
|
||||
result.setColor(colorScheme.colors[id][seq]);
|
||||
id = 0;
|
||||
}
|
||||
else
|
||||
isnether = false;
|
||||
}
|
||||
if(colorScheme.datacolors[id] != null) { /* If data colored */
|
||||
data = world.getBlockAt(x, y, z).getData();
|
||||
if(colorScheme.datacolors[id] != null) { /* If data colored */
|
||||
data = world.getBlockAt(x, y, z).getData();
|
||||
}
|
||||
switch (seq) {
|
||||
case 0:
|
||||
@ -257,9 +257,9 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
}
|
||||
Color[] colors;
|
||||
if(data != 0)
|
||||
colors = colorScheme.datacolors[id][data];
|
||||
colors = colorScheme.datacolors[id][data];
|
||||
else
|
||||
colors = colorScheme.colors[id];
|
||||
colors = colorScheme.colors[id];
|
||||
if (colors != null) {
|
||||
Color c = colors[seq];
|
||||
if (c.getAlpha() > 0) {
|
||||
|
@ -21,7 +21,7 @@ public class HighlightTileRenderer extends DefaultTileRenderer {
|
||||
highlightBlocks.add((Integer)highlightObj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void scan(World world, int x, int y, int z, int seq, boolean isnether, final Color result) {
|
||||
result.setTransparent();
|
||||
@ -31,20 +31,20 @@ public class HighlightTileRenderer extends DefaultTileRenderer {
|
||||
}
|
||||
|
||||
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.isTransparent())
|
||||
if(colorScheme.colors[id] != null)
|
||||
result.setColor(colorScheme.colors[id][seq]);
|
||||
id = 0;
|
||||
}
|
||||
else
|
||||
isnether = false;
|
||||
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.isTransparent())
|
||||
if(colorScheme.colors[id] != null)
|
||||
result.setColor(colorScheme.colors[id][seq]);
|
||||
id = 0;
|
||||
}
|
||||
else
|
||||
isnether = false;
|
||||
}
|
||||
byte data = 0;
|
||||
if(colorScheme.datacolors[id] != null) { /* If data colored */
|
||||
data = world.getBlockAt(x, y, z).getData();
|
||||
if(colorScheme.datacolors[id] != null) { /* If data colored */
|
||||
data = world.getBlockAt(x, y, z).getData();
|
||||
}
|
||||
|
||||
switch (seq) {
|
||||
@ -67,9 +67,9 @@ public class HighlightTileRenderer extends DefaultTileRenderer {
|
||||
if (id != 0) {
|
||||
Color[] colors;
|
||||
if(data != 0)
|
||||
colors = colorScheme.datacolors[id][data];
|
||||
colors = colorScheme.datacolors[id][data];
|
||||
else
|
||||
colors = colorScheme.colors[id];
|
||||
colors = colorScheme.colors[id];
|
||||
if (colors != null) {
|
||||
Color c = colors[seq];
|
||||
|
||||
@ -85,9 +85,9 @@ public class HighlightTileRenderer extends DefaultTileRenderer {
|
||||
* if (c.getAlpha() == 255) { return c; }
|
||||
*/
|
||||
/* this block is transparent, so recurse */
|
||||
|
||||
|
||||
// No need to blend if result is opaque.
|
||||
if (result.getAlpha() < 255) {
|
||||
if (result.getAlpha() < 255) {
|
||||
int cr = result.getRed();
|
||||
int cg = result.getGreen();
|
||||
int cb = result.getBlue();
|
||||
@ -96,7 +96,7 @@ public class HighlightTileRenderer extends DefaultTileRenderer {
|
||||
cg *= ca;
|
||||
cb *= ca;
|
||||
int na = 255 - ca;
|
||||
|
||||
|
||||
result.setRGBA((c.getRed() * na + cr) >> 8, (c.getGreen() * na + cg) >> 8, (c.getBlue() * na + cb) >> 8,
|
||||
Math.min(255, c.getAlpha()+ca) // Not really correct, but gets the job done without recursion while still looking ok.
|
||||
);
|
||||
|
@ -67,7 +67,7 @@ public class KzedMap extends MapType {
|
||||
@Override
|
||||
public MapTile[] getTiles(Location l) {
|
||||
World world = l.getWorld();
|
||||
|
||||
|
||||
int x = l.getBlockX();
|
||||
int y = l.getBlockY();
|
||||
int z = l.getBlockZ();
|
||||
@ -141,7 +141,7 @@ public class KzedMap extends MapType {
|
||||
/**
|
||||
* Test if point x,z is inside rectangle with corner at r0x,r0z and with
|
||||
* size vectors s1x,s1z and s2x,s2z
|
||||
*
|
||||
*
|
||||
*/
|
||||
private boolean testPointInRectangle(int x, int z, int r0x, int r0z, int s1x, int s1z,
|
||||
int s2x, int s2z) {
|
||||
@ -150,7 +150,7 @@ public class KzedMap extends MapType {
|
||||
int dots1 = xr*s1x + zr*s1z;
|
||||
int dots2 = xr*s2x + zr*s2z;
|
||||
/* If dot product of relative point and each side is between zero and dot product
|
||||
* of each side and itself, we're inside
|
||||
* of each side and itself, we're inside
|
||||
*/
|
||||
if((dots1 >= 0) && (dots1 <= (s1x*s1x+s1z*s1z)) &&
|
||||
(dots2 >= 0) && (dots2 <= (s2x*s2x+s2z*s2z))) {
|
||||
@ -162,11 +162,11 @@ public class KzedMap extends MapType {
|
||||
public DynmapChunk[] getRequiredChunks(MapTile tile) {
|
||||
if (tile instanceof KzedMapTile) {
|
||||
KzedMapTile t = (KzedMapTile) tile;
|
||||
|
||||
|
||||
int ix = KzedMap.anchorx + t.px / 2 + t.py / 2;
|
||||
//int iy = 127;
|
||||
int iz = KzedMap.anchorz + t.px / 2 - t.py / 2;
|
||||
|
||||
|
||||
int x1 = ix - KzedMap.tileHeight / 2;
|
||||
int x2 = ix + KzedMap.tileWidth / 2 + KzedMap.tileHeight / 2;
|
||||
|
||||
@ -183,10 +183,10 @@ public class KzedMap extends MapType {
|
||||
* render path to y=0), correspond to ix-64, iz+64 to
|
||||
* ix,iz+128 to ix+64,iz+64 to ix,iz. Projection of
|
||||
* the prism on to the x,z plane (which is all that matters for
|
||||
* chunks) yields a diagonal rectangular area from ix-64(x1),iz+64
|
||||
* to ix,iz+128(z2) to ix+128(x2),iz to ix+64,iz-64(z1).
|
||||
* chunks) yields a diagonal rectangular area from ix-64(x1),iz+64
|
||||
* to ix,iz+128(z2) to ix+128(x2),iz to ix+64,iz-64(z1).
|
||||
* Chunks outside this are not needed - we scan a simple rectangle
|
||||
* (chunk grid aligned) and skip adding the ones that are outside.
|
||||
* (chunk grid aligned) and skip adding the ones that are outside.
|
||||
* This results in 42% less chunks being loaded.
|
||||
*/
|
||||
ArrayList<DynmapChunk> chunks = new ArrayList<DynmapChunk>();
|
||||
@ -211,7 +211,7 @@ public class KzedMap extends MapType {
|
||||
chunks.add(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DynmapChunk[] result = new DynmapChunk[chunks.size()];
|
||||
chunks.toArray(result);
|
||||
return result;
|
||||
|
@ -9,7 +9,7 @@ public class KzedMapTile extends MapTile {
|
||||
public KzedMap map;
|
||||
public MapTileRenderer renderer;
|
||||
public int px, py;
|
||||
|
||||
|
||||
// Hack.
|
||||
public File file = null;
|
||||
|
||||
|
@ -8,12 +8,12 @@ public class BoundInputStream extends InputStream {
|
||||
protected static final Logger log = Logger.getLogger("Minecraft");
|
||||
private InputStream base;
|
||||
private long bound;
|
||||
|
||||
|
||||
public BoundInputStream(InputStream base, long bound) {
|
||||
this.base = base;
|
||||
this.bound = bound;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (bound <= 0) return -1;
|
||||
@ -22,17 +22,17 @@ public class BoundInputStream extends InputStream {
|
||||
bound--;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return (int)Math.min(base.available(), bound);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (bound <= 0) return -1;
|
||||
@ -41,19 +41,19 @@ public class BoundInputStream extends InputStream {
|
||||
bound -= r;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
return read(b, 0, b.length);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
long r = base.skip(Math.min(bound, n));
|
||||
bound -= r;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
base.close();
|
||||
|
@ -9,5 +9,5 @@ public class HttpRequest {
|
||||
public String path;
|
||||
public String version;
|
||||
public Map<String, String> fields = new HashMap<String, String>();
|
||||
public InputStream body;
|
||||
public InputStream body;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ public class HttpResponse {
|
||||
public String version = "1.1";
|
||||
public HttpStatus status = null;
|
||||
public Map<String, String> fields = new HashMap<String, String>();
|
||||
|
||||
|
||||
private OutputStream body;
|
||||
public OutputStream getBody() throws IOException {
|
||||
if (body != null) {
|
||||
@ -21,7 +21,7 @@ public class HttpResponse {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public HttpResponse(HttpServerConnection connection, OutputStream body) {
|
||||
this.connection = connection;
|
||||
this.body = body;
|
||||
|
@ -21,10 +21,10 @@ public class HttpServerConnection extends Thread {
|
||||
|
||||
private static Pattern requestHeaderLine = Pattern.compile("^(\\S+)\\s+(\\S+)\\s+HTTP/(.+)$");
|
||||
private static Pattern requestHeaderField = Pattern.compile("^([^:]+):\\s*(.+)$");
|
||||
|
||||
|
||||
private Socket socket;
|
||||
private HttpServer server;
|
||||
|
||||
|
||||
private PrintStream printOut;
|
||||
private StringWriter sw = new StringWriter();
|
||||
private Matcher requestHeaderLineMatcher;
|
||||
@ -45,7 +45,7 @@ public class HttpServerConnection extends Thread {
|
||||
sw.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final String readLine(InputStream in) throws IOException {
|
||||
readLine(in, sw);
|
||||
String r = sw.toString();
|
||||
@ -55,16 +55,16 @@ public class HttpServerConnection extends Thread {
|
||||
|
||||
private final boolean readRequestHeader(InputStream in, HttpRequest request) throws IOException {
|
||||
String statusLine = readLine(in);
|
||||
|
||||
|
||||
if (statusLine == null)
|
||||
return false;
|
||||
|
||||
|
||||
if (requestHeaderLineMatcher == null) {
|
||||
requestHeaderLineMatcher = requestHeaderLine.matcher(statusLine);
|
||||
} else {
|
||||
requestHeaderLineMatcher.reset(statusLine);
|
||||
}
|
||||
|
||||
|
||||
Matcher m = requestHeaderLineMatcher;
|
||||
if (!m.matches())
|
||||
return false;
|
||||
@ -79,7 +79,7 @@ public class HttpServerConnection extends Thread {
|
||||
} else {
|
||||
requestHeaderFieldMatcher.reset(line);
|
||||
}
|
||||
|
||||
|
||||
m = requestHeaderFieldMatcher;
|
||||
// Warning: unknown lines are ignored.
|
||||
if (m.matches()) {
|
||||
@ -109,7 +109,7 @@ public class HttpServerConnection extends Thread {
|
||||
out.append("\r\n");
|
||||
out.flush();
|
||||
}
|
||||
|
||||
|
||||
public final void writeResponseHeader(HttpResponse response) throws IOException {
|
||||
writeResponseHeader(printOut, response);
|
||||
}
|
||||
@ -121,16 +121,16 @@ public class HttpServerConnection extends Thread {
|
||||
socket.setSoTimeout(5000);
|
||||
InputStream in = socket.getInputStream();
|
||||
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream(), 40960);
|
||||
|
||||
|
||||
printOut = new PrintStream(out, false);
|
||||
while (true) {
|
||||
HttpRequest request = new HttpRequest();
|
||||
|
||||
|
||||
if (!readRequestHeader(in, request)) {
|
||||
socket.close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
long bound = -1;
|
||||
BoundInputStream boundBody = null;
|
||||
{
|
||||
@ -166,9 +166,9 @@ public class HttpServerConnection extends Thread {
|
||||
socket.close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
HttpResponse response = new HttpResponse(this, out);
|
||||
|
||||
|
||||
try {
|
||||
handler.handle(relativePath, request, response);
|
||||
} catch (IOException e) {
|
||||
@ -187,9 +187,9 @@ public class HttpServerConnection extends Thread {
|
||||
//socket.close();
|
||||
//return;
|
||||
}
|
||||
|
||||
|
||||
boolean isKeepalive = !"close".equals(request.fields.get(HttpField.Connection)) && !"close".equals(response.fields.get(HttpField.Connection));
|
||||
|
||||
|
||||
String contentLength = response.fields.get("Content-Length");
|
||||
if (isKeepalive && contentLength == null) {
|
||||
// A handler has been a bad boy, but we're here to fix it.
|
||||
|
@ -3,20 +3,20 @@ package org.dynmap.web;
|
||||
public final class HttpStatus {
|
||||
private int code;
|
||||
private String text;
|
||||
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
public HttpStatus(int code, String text) {
|
||||
this.code = code;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
|
||||
// Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
||||
public static final HttpStatus Continue = new HttpStatus(100, "Continue");
|
||||
public static final HttpStatus SwitchingProtocols = new HttpStatus(101, "Switching Protocols");
|
||||
|
@ -13,7 +13,7 @@ public class Json {
|
||||
appendJson(o, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
public static void appendJson(Object o, StringBuilder s) {
|
||||
if (o == null) {
|
||||
s.append("null");
|
||||
@ -59,7 +59,7 @@ public class Json {
|
||||
} else if (o instanceof Object) /* TODO: Always true, maybe interface? */ {
|
||||
s.append("{");
|
||||
boolean first = true;
|
||||
|
||||
|
||||
Class<?> c = o.getClass();
|
||||
for(Field field : c.getFields()) {
|
||||
if (!Modifier.isPublic(field.getModifiers()))
|
||||
@ -73,7 +73,7 @@ public class Json {
|
||||
} catch (IllegalAccessException e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
|
@ -20,18 +20,18 @@ public class ClientConfigurationHandler implements HttpHandler {
|
||||
public void handle(String path, HttpRequest request, HttpResponse response) throws Exception {
|
||||
if (cachedConfiguration == null) {
|
||||
String s = Json.stringifyJson(configuration);
|
||||
|
||||
|
||||
cachedConfiguration = s.getBytes();
|
||||
}
|
||||
String dateStr = new Date().toString();
|
||||
|
||||
|
||||
response.fields.put("Date", dateStr);
|
||||
response.fields.put("Content-Type", "text/plain");
|
||||
response.fields.put("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
|
||||
response.fields.put("Last-modified", dateStr);
|
||||
response.fields.put("Content-Length", Integer.toString(cachedConfiguration.length));
|
||||
response.status = HttpStatus.OK;
|
||||
|
||||
|
||||
BufferedOutputStream out = null;
|
||||
out = new BufferedOutputStream(response.getBody());
|
||||
out.write(cachedConfiguration);
|
||||
|
@ -31,26 +31,26 @@ public class ClientUpdateHandler implements HttpHandler {
|
||||
}
|
||||
|
||||
Pattern updatePathPattern = Pattern.compile("world/([^/]+)/([0-9]*)");
|
||||
private static final HttpStatus WorldNotFound = new HttpStatus(HttpStatus.NotFound.getCode(), "World Not Found");
|
||||
private static final HttpStatus WorldNotFound = new HttpStatus(HttpStatus.NotFound.getCode(), "World Not Found");
|
||||
@Override
|
||||
public void handle(String path, HttpRequest request, HttpResponse response) throws Exception {
|
||||
|
||||
|
||||
Matcher match = updatePathPattern.matcher(path);
|
||||
|
||||
|
||||
if (!match.matches()) {
|
||||
response.status = HttpStatus.Forbidden;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String worldName = match.group(1);
|
||||
String timeKey = match.group(2);
|
||||
|
||||
|
||||
World world = server.getWorld(worldName);
|
||||
if (world == null) {
|
||||
response.status = WorldNotFound;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
long current = System.currentTimeMillis();
|
||||
long since = 0;
|
||||
|
||||
@ -60,14 +60,14 @@ public class ClientUpdateHandler implements HttpHandler {
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Client.Update update = new Client.Update();
|
||||
update.timestamp = current;
|
||||
update.servertime = world.getTime() % 24000;
|
||||
update.hasStorm = world.hasStorm();
|
||||
update.isThundering = world.isThundering();
|
||||
|
||||
|
||||
|
||||
|
||||
Player[] players = playerList.getVisiblePlayers();
|
||||
update.players = new Client.Player[players.length];
|
||||
for(int i=0;i<players.length;i++) {
|
||||
@ -75,10 +75,10 @@ public class ClientUpdateHandler implements HttpHandler {
|
||||
Location pl = p.getLocation();
|
||||
update.players[i] = new Client.Player(p.getDisplayName(), pl.getWorld().getName(), pl.getX(), pl.getY(), pl.getZ());
|
||||
}
|
||||
|
||||
|
||||
update.updates = mapManager.getWorldUpdates(worldName, since);
|
||||
|
||||
|
||||
|
||||
|
||||
byte[] bytes = Json.stringifyJson(update).getBytes();
|
||||
|
||||
String dateStr = new Date().toString();
|
||||
@ -88,10 +88,10 @@ public class ClientUpdateHandler implements HttpHandler {
|
||||
response.fields.put(HttpField.LastModified, dateStr);
|
||||
response.fields.put(HttpField.ContentLength, Integer.toString(bytes.length));
|
||||
response.status = HttpStatus.OK;
|
||||
|
||||
|
||||
BufferedOutputStream out = null;
|
||||
out = new BufferedOutputStream(response.getBody());
|
||||
out.write(bytes);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,16 +33,16 @@ public abstract class FileHandler implements HttpHandler {
|
||||
return m;
|
||||
return "application/octet-steam";
|
||||
}
|
||||
|
||||
|
||||
protected abstract InputStream getFileInput(String path, HttpRequest request, HttpResponse response);
|
||||
|
||||
|
||||
protected String getExtension(String path) {
|
||||
int dotindex = path.lastIndexOf('.');
|
||||
if (dotindex > 0)
|
||||
return path.substring(dotindex);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected final String formatPath(String path) {
|
||||
int qmark = path.indexOf('?');
|
||||
if (qmark >= 0)
|
||||
@ -54,11 +54,11 @@ public abstract class FileHandler implements HttpHandler {
|
||||
path = getDefaultFilename(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
protected String getDefaultFilename(String path) {
|
||||
return path + "index.html";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(String path, HttpRequest request, HttpResponse response) throws Exception {
|
||||
InputStream fileInput = null;
|
||||
@ -69,10 +69,10 @@ public abstract class FileHandler implements HttpHandler {
|
||||
response.status = HttpStatus.NotFound;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String extension = getExtension(path);
|
||||
String mimeType = getMimeTypeFromExtension(extension);
|
||||
|
||||
|
||||
response.fields.put(HttpField.ContentType, mimeType);
|
||||
response.status = HttpStatus.OK;
|
||||
OutputStream out = response.getBody();
|
||||
|
@ -32,4 +32,4 @@ public class FilesystemHandler extends FileHandler {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,4 +16,4 @@ public class JarFileHandler extends FileHandler {
|
||||
protected InputStream getFileInput(String path, HttpRequest request, HttpResponse response) {
|
||||
return this.getClass().getResourceAsStream(root + "/" + path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,16 +17,16 @@ import org.json.simple.parser.JSONParser;
|
||||
|
||||
public class SendMessageHandler implements HttpHandler {
|
||||
protected static final Logger log = Logger.getLogger("Minecraft");
|
||||
|
||||
|
||||
private static final JSONParser parser = new JSONParser();
|
||||
public Event<Message> onMessageReceived = new Event<SendMessageHandler.Message>();
|
||||
|
||||
|
||||
public int maximumMessageInterval = 1000;
|
||||
public String spamMessage = "\"You may only chat once every %interval% seconds.\"";
|
||||
private HashMap<String, WebUser> disallowedUsers = new HashMap<String, WebUser>();
|
||||
private LinkedList<WebUser> disallowedUserQueue = new LinkedList<WebUser>();
|
||||
private Object disallowedUsersLock = new Object();
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(String path, HttpRequest request, HttpResponse response) throws Exception {
|
||||
if (!request.method.equals(HttpMethod.Post)) {
|
||||
@ -36,14 +36,14 @@ public class SendMessageHandler implements HttpHandler {
|
||||
}
|
||||
|
||||
InputStreamReader reader = new InputStreamReader(request.body);
|
||||
|
||||
|
||||
JSONObject o = (JSONObject)parser.parse(reader);
|
||||
final Message message = new Message();
|
||||
message.name = String.valueOf(o.get("name"));
|
||||
message.message = String.valueOf(o.get("message"));
|
||||
|
||||
final long now = System.currentTimeMillis();
|
||||
|
||||
|
||||
synchronized(disallowedUsersLock) {
|
||||
// Allow users that user that are now allowed to send messages.
|
||||
while (!disallowedUserQueue.isEmpty()) {
|
||||
@ -55,7 +55,7 @@ public class SendMessageHandler implements HttpHandler {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WebUser user = disallowedUsers.get(message.name);
|
||||
if (user == null) {
|
||||
user = new WebUser() {{
|
||||
@ -71,14 +71,14 @@ public class SendMessageHandler implements HttpHandler {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMessageReceived.trigger(message);
|
||||
|
||||
|
||||
response.fields.put(HttpField.ContentLength, "0");
|
||||
response.status = HttpStatus.OK;
|
||||
response.getBody();
|
||||
}
|
||||
|
||||
|
||||
public static class Message {
|
||||
public String name;
|
||||
public String message;
|
||||
|
Loading…
Reference in New Issue
Block a user