Merge branch 'master' of git://github.com/FrozenCow/dynmap
Conflicts: colorschemes/ovocean.txt src/main/java/org/dynmap/MapManager.java
175
colorschemes/ovocean.txt
Normal file
@ -0,0 +1,175 @@
|
||||
Stone
|
||||
1 119 104 84 255 104 95 80 255 96 87 72 255 77 68 53 255
|
||||
Grass
|
||||
2 75 156 43 255 56 117 32 255 35 104 10 255 32 82 0 255
|
||||
Dirt
|
||||
3 134 96 67 255 107 76 53 255 67 48 33 255 68 49 33 255
|
||||
Cobblestone
|
||||
4 115 115 115 255 92 92 92 255 57 57 57 255 46 46 46 255
|
||||
Wooden Plank
|
||||
5 157 128 79 255 125 102 63 255 78 64 39 255 62 51 31 255
|
||||
Sappling
|
||||
6 120 120 120 0 96 96 96 0 60 60 60 0 48 48 48 0
|
||||
Bedrock
|
||||
7 84 84 84 255 67 67 67 255 42 42 42 255 33 33 33 255
|
||||
Water
|
||||
8 21 88 125 80 7 70 117 80 6 68 115 80 5 53 90 80
|
||||
Stationary Water
|
||||
9 21 88 125 80 7 70 117 80 6 68 115 80 5 53 90 80
|
||||
Lava
|
||||
10 255 90 0 255 204 72 0 255 127 45 0 255 102 36 0 255
|
||||
Stationary Lava
|
||||
11 255 90 0 255 204 72 0 255 127 45 0 255 102 36 0 255
|
||||
Sand
|
||||
12 214 182 111 255 203 171 100 255 186 154 83 255 173 141 70 255
|
||||
Gravel
|
||||
13 136 126 126 255 108 100 100 255 68 63 63 255 54 50 50 255
|
||||
Gold Ore
|
||||
14 143 140 125 255 114 112 100 255 71 70 62 255 57 56 50 255
|
||||
Iron Ore
|
||||
15 136 130 127 255 108 104 101 255 68 65 63 255 54 52 50 255
|
||||
Coal Ore
|
||||
16 115 115 115 255 92 92 92 255 57 57 57 255 46 46 46 255
|
||||
Wood
|
||||
17 102 81 51 255 81 64 40 255 51 40 25 255 40 32 20 255
|
||||
Leaves
|
||||
18 23 68 6 100 12 56 0 100 6 52 0 100 0 42 0 100
|
||||
Sponge
|
||||
19 193 193 65 255 174 174 47 255 97 97 5 255 76 76 20 255
|
||||
Glass
|
||||
20 255 255 255 64 204 204 204 64 127 127 127 64 102 102 102 64
|
||||
Lapis Lazuli Ore
|
||||
21 23 68 196 255 18 56 158 255 14 43 122 255 14 43 78 255
|
||||
Lapis Lazuli Block
|
||||
22 23 68 196 255 18 56 158 255 14 43 122 255 14 43 78 255
|
||||
Dispenser
|
||||
23 96 96 96 255 76 76 76 255 48 48 48 255 38 38 38 255
|
||||
Sandstone
|
||||
24 214 182 111 255 203 171 100 255 186 154 83 255 173 141 70 255
|
||||
Note Block
|
||||
25 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
|
||||
Aqua Green Cloth
|
||||
26 43 192 117 255 38 168 101 255 34 150 90 255 29 130 78 255
|
||||
Cyan Cloth
|
||||
27 43 192 192 255 36 185 185 255 29 130 130 255 22 99 99 255
|
||||
Blue Cloth
|
||||
28 0 0 255 255 0 0 204 255 0 0 127 255 0 0 102 255
|
||||
Purple Cloth
|
||||
29 101 101 188 255 95 95 175 255 86 86 160 255 78 78 145 255
|
||||
Indigo Cloth
|
||||
30 113 41 186 255 99 38 165 255 85 32 142 255 72 27 119 255
|
||||
Violet Cloth
|
||||
31 156 65 198 255 132 55 168 255 112 47 142 255 84 35 107 255
|
||||
Magenta Cloth
|
||||
32 187 42 187 255 160 36 160 255 135 31 135 255 112 25 112 255
|
||||
Pink Cloth
|
||||
33 192 43 117 255 168 38 103 255 142 32 87 255 127 29 78 255
|
||||
Black Cloth
|
||||
34 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255
|
||||
Wool
|
||||
35 222 222 222 255 177 177 177 255 111 111 111 255 88 88 88 255
|
||||
Gray Cloth
|
||||
36 125 125 125 255 114 114 114 255 104 104 104 255 86 86 86 255
|
||||
Yellow Flower
|
||||
37 255 255 0 255 204 204 0 255 127 127 0 255 102 102 0 255
|
||||
Red Rose
|
||||
38 255 0 0 255 204 0 0 255 127 0 0 255 102 0 0 255
|
||||
Brown Mushroom
|
||||
39 204 153 120 32 145 109 85 32 114 86 67 32 73 64 58 32
|
||||
Red Mushroom
|
||||
40 255 43 43 32 196 29 38 32 186 105 109 32 124 64 64 32
|
||||
Gold Block
|
||||
41 232 245 46 255 185 196 36 255 116 122 23 255 92 98 18 255
|
||||
Iron Block
|
||||
42 191 191 191 255 152 152 152 255 95 95 95 255 76 76 76 255
|
||||
Double Stone Slab
|
||||
43 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
|
||||
Stone Slab
|
||||
44 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
|
||||
Brick
|
||||
45 170 86 62 255 136 68 49 255 85 43 31 255 68 34 24 255
|
||||
TNT
|
||||
46 160 83 65 255 128 66 52 255 80 41 32 255 64 33 26 255
|
||||
Bookshelf
|
||||
54 125 91 38 192 100 72 30 192 62 45 19 192 50 36 15 192
|
||||
Moss Stone
|
||||
48 115 115 115 255 92 92 92 255 57 57 57 255 46 46 46 255
|
||||
Obsidian
|
||||
49 26 11 43 255 20 8 34 255 13 5 21 255 10 4 17 255
|
||||
Torch
|
||||
50 159 127 80 255 98 88 20 0 245 220 50 255 196 176 40 0
|
||||
Fire
|
||||
51 255 170 30 200 204 136 24 200 127 85 15 200 102 68 12 200
|
||||
Monster Spawner
|
||||
52 0 150 110 196 0 150 130 196 0 150 110 196 0 150 130 196
|
||||
Wooden Stair
|
||||
53 157 128 79 255 125 102 63 255 78 64 39 255 62 51 31 255
|
||||
Chest
|
||||
54 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
|
||||
|
||||
Diamond Ore
|
||||
56 129 140 143 255 103 112 114 255 64 70 71 255 51 56 57 255
|
||||
Diamond Block
|
||||
57 45 166 152 255 36 132 121 255 22 83 76 255 18 66 60 255
|
||||
Workbench
|
||||
58 114 88 56 255 91 70 44 255 57 44 28 255 45 35 22 255
|
||||
Crops
|
||||
59 146 192 0 255 116 153 0 255 73 96 0 255 58 76 0 255
|
||||
Farmland
|
||||
60 95 58 30 255 76 46 24 255 47 29 15 255 38 23 12 255
|
||||
Furnace
|
||||
61 96 96 96 255 76 76 76 255 48 48 48 255 38 38 38 255
|
||||
Burning Furnace
|
||||
62 96 96 96 255 76 76 76 255 48 48 48 255 38 38 38 255
|
||||
Sign Post
|
||||
63 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255
|
||||
Wooden Door
|
||||
64 136 109 67 255 108 87 53 255 68 54 33 255 54 43 26 255
|
||||
Ladder
|
||||
65 181 140 64 32 144 112 51 32 90 70 32 32 72 56 25 32
|
||||
Minecart Tracks
|
||||
66 150 134 102 180 120 107 81 180 75 67 51 180 60 53 40 180
|
||||
Cobblestone Stairs
|
||||
67 115 115 115 255 92 92 92 255 57 57 57 255 46 46 46 255
|
||||
|
||||
Iron Door
|
||||
71 191 191 191 255 152 152 152 255 95 95 95 255 76 76 76 255
|
||||
|
||||
Redstone Ore
|
||||
73 131 107 107 255 104 85 85 255 65 53 53 255 52 42 42 255
|
||||
Glowing Redstone Ore
|
||||
74 131 107 107 255 104 85 85 255 65 53 53 255 52 42 42 255
|
||||
Redstone Torch off
|
||||
75 159 127 80 255 72 56 25 0 181 140 64 255 144 112 51 0
|
||||
Redstone Torch on
|
||||
76 159 127 80 255 102 0 0 0 255 0 0 255 204 0 0 0
|
||||
Snow
|
||||
78 255 255 255 255 204 204 204 255 127 127 127 255 102 102 102 255
|
||||
Ice
|
||||
79 83 113 163 51 66 90 130 51 41 56 81 51 33 45 65 51
|
||||
Snow Block
|
||||
80 250 250 250 255 200 200 200 255 125 125 125 255 100 100 100 255
|
||||
Cactus
|
||||
81 25 120 25 255 20 96 20 255 12 60 12 255 10 48 10 255
|
||||
Clay
|
||||
82 151 157 169 255 120 125 135 255 75 78 84 255 60 62 67 255
|
||||
Sugar Cane
|
||||
83 193 234 150 255 154 187 120 255 96 117 75 255 77 93 60 255
|
||||
Jukebox
|
||||
84 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
|
||||
Fence
|
||||
85 127 98 49 96 95 72 33 96 48 34 9 96 32 21 21 96
|
||||
Pumpkin
|
||||
86 255 115 0 200 204 92 0 200 126 57 0 200 102 46 0 200
|
||||
Netherrack
|
||||
87 166 89 89 255 141 80 62 255 135 15 15 255 96 6 6 255
|
||||
Soulsand
|
||||
88 133 109 94 255 121 97 82 255 90 70 57 255 79 59 46 255
|
||||
Glowstone
|
||||
89 249 212 156 255 255 188 94 255 192 143 70 255 122 91 44 255
|
||||
Portal
|
||||
90 140 0 196 128 120 0 196 128 140 0 196 128 120 0 196 128
|
||||
Jack-o-lantern
|
||||
91 255 115 0 255 204 92 0 255 126 57 0 255 102 46 0 255
|
||||
Cake Block
|
||||
92 234 234 234 255 210 210 210 255 203 203 203 255 190 190 190 255
|
@ -3,6 +3,14 @@
|
||||
# How often a tile gets rendered (in seconds).
|
||||
renderinterval: 1
|
||||
|
||||
render-triggers:
|
||||
# - playermove
|
||||
# - playerjoin
|
||||
- blockplaced
|
||||
- blockbreak
|
||||
# - chunkgenerated
|
||||
# - chunkloaded
|
||||
|
||||
# The path where the tile-files are placed.
|
||||
tilespath: web/tiles
|
||||
|
||||
@ -28,21 +36,29 @@ jsonfile-interval: 1
|
||||
worlds:
|
||||
- name: world
|
||||
maps:
|
||||
- class: org.dynmap.flat.FlatMap
|
||||
prefix: flat
|
||||
colorscheme: default
|
||||
- class: org.dynmap.kzedmap.KzedMap
|
||||
renderers:
|
||||
- class: org.dynmap.kzedmap.DefaultTileRenderer
|
||||
prefix: t
|
||||
maximumheight: 127
|
||||
colorscheme: default
|
||||
- class: org.dynmap.kzedmap.CaveTileRenderer
|
||||
prefix: ct
|
||||
maximumheight: 127
|
||||
- name: nether
|
||||
maps:
|
||||
- class: org.dynmap.flat.FlatMap
|
||||
prefix: flat
|
||||
colorscheme: default
|
||||
- class: org.dynmap.kzedmap.KzedMap
|
||||
renderers:
|
||||
- class: org.dynmap.kzedmap.DefaultTileRenderer
|
||||
prefix: nt
|
||||
maximumheight: 64
|
||||
colorscheme: default
|
||||
|
||||
web:
|
||||
# Handles the clientside updates differently only enable if using jsonfile
|
||||
@ -61,15 +77,15 @@ web:
|
||||
joinmessage: "%playername% joined"
|
||||
quitmessage: "%playername% quit"
|
||||
|
||||
# The clock that is shown alongside the map.
|
||||
clock: timeofday
|
||||
#clock: digital
|
||||
|
||||
defaultworld: world
|
||||
worlds:
|
||||
- title: World
|
||||
name: world
|
||||
maps:
|
||||
- type: FlatMapType
|
||||
title: Flat
|
||||
name: flat
|
||||
prefix: flat
|
||||
- type: KzedMapType
|
||||
title: Surface
|
||||
name: surface
|
||||
@ -81,19 +97,23 @@ web:
|
||||
- title: Nether
|
||||
name: nether
|
||||
maps:
|
||||
- type: FlatMapType
|
||||
title: Flat
|
||||
name: flat
|
||||
prefix: flat
|
||||
- type: KzedMapType
|
||||
title: Surface
|
||||
name: nether
|
||||
prefix: nt
|
||||
# Example:
|
||||
#- title: Other World # Under what name the world is displayed.
|
||||
#- title: Other World # With what name the world is displayed.
|
||||
# name: world_other # The actual name of the world (equal to your directory-name).
|
||||
# maps:
|
||||
# - type: KzedMapType # The type (or perspective) of the map. At the moment, there are no others than KzedMapType.
|
||||
# title: Surface # The name of the map that will be displayed.
|
||||
# name: surface # The actual name of the map (should be unique for this world).
|
||||
# prefix: t # The prefix of the tile-files that are generated.
|
||||
# icon: block_other.png # Sets the icon of the map. (optional)
|
||||
# icon: images/block_other.png # Sets a custom icon for the map. (optional)
|
||||
# - type: KzedMapType
|
||||
# title: Cave
|
||||
# name: cave
|
||||
@ -102,4 +122,3 @@ web:
|
||||
# Enables debugging.
|
||||
#debuggers:
|
||||
# - class: org.dynmap.debug.LogDebugger
|
||||
# - class: org.dynmap.debug.BukkitPlayerDebugger
|
||||
|
6
pom.xml
@ -1,8 +1,8 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<groupId>org.dynmap</groupId>
|
||||
<artifactId>dynmap</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>0.13</version>
|
||||
<name>DynamicMap</name>
|
||||
<url>http://www.bukkit.org</url>
|
||||
<build>
|
||||
@ -20,7 +20,7 @@
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>assembly.xml</descriptor>
|
||||
<descriptor>src/main/assembly/package.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||
<id>build</id>
|
||||
<id>bin</id>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<formats>
|
||||
<format>tar.bz2</format>
|
||||
@ -13,13 +13,17 @@
|
||||
<include>README*</include>
|
||||
<include>LICENSE*</include>
|
||||
<include>NOTICE*</include>
|
||||
<include>LICENSE*</include>
|
||||
<include>CHANGELOG*</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.basedir}/web</directory>
|
||||
<outputDirectory>/dynmap/web</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.basedir}/colorschemes</directory>
|
||||
<outputDirectory>/dynmap/colorschemes</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.basedir}</directory>
|
||||
<outputDirectory>/dynmap/</outputDirectory>
|
85
src/main/java/org/dynmap/ColorScheme.java
Normal file
@ -0,0 +1,85 @@
|
||||
package org.dynmap;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Scanner;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
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;
|
||||
public java.util.Map<Integer, Color[]> colors;
|
||||
|
||||
public ColorScheme(String name, java.util.Map<Integer, Color[]> colors) {
|
||||
this.name = name;
|
||||
this.colors = colors;
|
||||
}
|
||||
|
||||
private static File getColorSchemeDirectory() {
|
||||
return new File(DynmapPlugin.dataDirectory, "colorschemes");
|
||||
}
|
||||
|
||||
public static ColorScheme getScheme(String name) {
|
||||
if (name == null)
|
||||
name = "default";
|
||||
ColorScheme scheme = cache.get(name);
|
||||
if (scheme == null) {
|
||||
scheme = loadScheme(name);
|
||||
cache.put(name, scheme);
|
||||
}
|
||||
return scheme;
|
||||
}
|
||||
|
||||
public static ColorScheme loadScheme(String name) {
|
||||
File colorSchemeFile = new File(getColorSchemeDirectory(), name + ".txt");
|
||||
java.util.Map<Integer, Color[]> colors = new HashMap<Integer, Color[]>();
|
||||
InputStream stream;
|
||||
try {
|
||||
Debug.debug("Loading colors from '" + colorSchemeFile + "'...");
|
||||
stream = new FileInputStream(colorSchemeFile);
|
||||
|
||||
Scanner scanner = new Scanner(stream);
|
||||
int nc = 0;
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
if (line.startsWith("#") || line.equals("")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] split = line.split("\t");
|
||||
if (split.length < 17) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Integer id = new Integer(split[0]);
|
||||
|
||||
Color[] c = new Color[4];
|
||||
|
||||
/* store colors by raycast sequence number */
|
||||
c[0] = new Color(Integer.parseInt(split[1]), Integer.parseInt(split[2]), Integer.parseInt(split[3]), Integer.parseInt(split[4]));
|
||||
c[3] = new Color(Integer.parseInt(split[5]), Integer.parseInt(split[6]), Integer.parseInt(split[7]), Integer.parseInt(split[8]));
|
||||
c[1] = new Color(Integer.parseInt(split[9]), Integer.parseInt(split[10]), Integer.parseInt(split[11]), Integer.parseInt(split[12]));
|
||||
c[2] = new Color(Integer.parseInt(split[13]), Integer.parseInt(split[14]), Integer.parseInt(split[15]), Integer.parseInt(split[16]));
|
||||
|
||||
colors.put(id, c);
|
||||
nc += 1;
|
||||
}
|
||||
scanner.close();
|
||||
} catch (RuntimeException e) {
|
||||
log.log(Level.SEVERE, "Could not load colors '" + name + "' ('" + colorSchemeFile + "').", e);
|
||||
return null;
|
||||
} catch (FileNotFoundException e) {
|
||||
log.log(Level.SEVERE, "Could not load colors '" + name + "' ('" + colorSchemeFile + "'): File not found.", e);
|
||||
}
|
||||
return new ColorScheme(name, colors);
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package org.dynmap;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockDamageLevel;
|
||||
import org.bukkit.event.block.BlockDamageEvent;
|
||||
import org.bukkit.event.block.BlockListener;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
|
||||
public class DynmapBlockListener extends BlockListener {
|
||||
private MapManager mgr;
|
||||
|
||||
public DynmapBlockListener(MapManager mgr) {
|
||||
this.mgr = mgr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
Block blockPlaced = event.getBlockPlaced();
|
||||
mgr.touch(blockPlaced.getLocation());
|
||||
}
|
||||
|
||||
public void onBlockDamage(BlockDamageEvent event) {
|
||||
if (event.getDamageLevel() == BlockDamageLevel.BROKEN) {
|
||||
Block blockBroken = event.getBlock();
|
||||
mgr.touch(blockBroken.getLocation());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +1,50 @@
|
||||
package org.dynmap;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.Timer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.BlockDamageLevel;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.Event.Priority;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockDamageEvent;
|
||||
import org.bukkit.event.block.BlockListener;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.bukkit.event.player.PlayerListener;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.WorldEvent;
|
||||
import org.bukkit.event.world.WorldListener;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
import org.dynmap.Event.Listener;
|
||||
import org.dynmap.debug.Debug;
|
||||
import org.dynmap.debug.Debugger;
|
||||
import org.dynmap.web.HttpServer;
|
||||
import org.dynmap.web.Json;
|
||||
import org.dynmap.web.handlers.ClientConfigurationHandler;
|
||||
import org.dynmap.web.handlers.ClientUpdateHandler;
|
||||
import org.dynmap.web.handlers.FilesystemHandler;
|
||||
import org.dynmap.web.handlers.SendMessageHandler;
|
||||
import org.dynmap.web.handlers.SendMessageHandler.Message;
|
||||
import org.dynmap.web.Json;
|
||||
|
||||
public class DynmapPlugin extends JavaPlugin {
|
||||
|
||||
@ -44,9 +54,11 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
public MapManager mapManager = null;
|
||||
public PlayerList playerList;
|
||||
public Configuration configuration;
|
||||
public HashSet<String> enabledTriggers = new HashSet<String>();
|
||||
|
||||
public Timer timer;
|
||||
|
||||
public static File dataDirectory;
|
||||
public static File tilesDirectory;
|
||||
|
||||
public World getWorld() {
|
||||
@ -62,13 +74,17 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
}
|
||||
|
||||
public void onEnable() {
|
||||
dataDirectory = this.getDataFolder();
|
||||
|
||||
configuration = new Configuration(new File(this.getDataFolder(), "configuration.txt"));
|
||||
configuration.load();
|
||||
|
||||
loadDebuggers();
|
||||
|
||||
tilesDirectory = getFile(configuration.getString("tilespath", "web/tiles"));
|
||||
tilesDirectory.mkdirs();
|
||||
if (!tilesDirectory.isDirectory() && !tilesDirectory.mkdirs()) {
|
||||
log.warning("Could not create directory for tiles ('" + tilesDirectory + "').");
|
||||
}
|
||||
|
||||
playerList = new PlayerList(getServer(), getFile("hiddenplayers.txt"));
|
||||
playerList.load();
|
||||
@ -76,7 +92,9 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
mapManager = new MapManager(this, configuration);
|
||||
mapManager.startRendering();
|
||||
|
||||
if (!configuration.getBoolean("disable-webserver", false)) {
|
||||
loadWebserver();
|
||||
}
|
||||
|
||||
if (configuration.getBoolean("jsonfile", false)) {
|
||||
jsonConfig();
|
||||
@ -85,6 +103,11 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
timer.scheduleAtFixedRate(new JsonTimerTask(this, configuration), jsonInterval, jsonInterval);
|
||||
}
|
||||
|
||||
enabledTriggers.clear();
|
||||
for (Object trigger : configuration.getList("render-triggers")) {
|
||||
enabledTriggers.add((String) trigger);
|
||||
}
|
||||
|
||||
registerEvents();
|
||||
}
|
||||
|
||||
@ -141,25 +164,81 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
Debug.clearDebuggers();
|
||||
}
|
||||
|
||||
public void registerEvents() {
|
||||
BlockListener blockListener = new DynmapBlockListener(mapManager);
|
||||
getServer().getPluginManager().registerEvent(Event.Type.BLOCK_PLACED, blockListener, Priority.Monitor, this);
|
||||
getServer().getPluginManager().registerEvent(Event.Type.BLOCK_DAMAGED, blockListener, Priority.Monitor, this);
|
||||
public boolean isTrigger(String s) {
|
||||
return enabledTriggers.contains(s);
|
||||
}
|
||||
|
||||
public void registerEvents() {
|
||||
final PluginManager pm = getServer().getPluginManager();
|
||||
final MapManager mm = mapManager;
|
||||
|
||||
// To trigger rendering.
|
||||
{
|
||||
BlockListener renderTrigger = new BlockListener() {
|
||||
@Override
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
mm.touch(event.getBlockPlaced().getLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
mm.touch(event.getBlock().getLocation());
|
||||
}
|
||||
};
|
||||
if (isTrigger("blockplaced")) pm.registerEvent(Event.Type.BLOCK_PLACED, renderTrigger, Priority.Monitor, this);
|
||||
if (isTrigger("blockbreak")) pm.registerEvent(Event.Type.BLOCK_BREAK, renderTrigger, Priority.Monitor, this);
|
||||
}
|
||||
{
|
||||
PlayerListener renderTrigger = new PlayerListener() {
|
||||
@Override
|
||||
public void onPlayerJoin(PlayerEvent event) {
|
||||
mm.touch(event.getPlayer().getLocation());
|
||||
}
|
||||
@Override
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
mm.touch(event.getPlayer().getLocation());
|
||||
}
|
||||
};
|
||||
if (isTrigger("playerjoin")) pm.registerEvent(Event.Type.PLAYER_JOIN, renderTrigger, Priority.Monitor, this);
|
||||
if (isTrigger("playermove")) pm.registerEvent(Event.Type.PLAYER_MOVE, renderTrigger, Priority.Monitor, this);
|
||||
}
|
||||
{
|
||||
WorldListener renderTrigger = new WorldListener() {
|
||||
@Override
|
||||
public void onChunkLoaded(ChunkLoadEvent event) {
|
||||
int x = event.getChunk().getX() * 16 + 8;
|
||||
int z = event.getChunk().getZ() * 16 + 8;
|
||||
mm.touch(new Location(event.getWorld(), x, 127, z));
|
||||
}
|
||||
|
||||
/*@Override
|
||||
public void onChunkGenerated(ChunkLoadEvent event) {
|
||||
int x = event.getChunk().getX() * 16 + 8;
|
||||
int z = event.getChunk().getZ() * 16 + 8;
|
||||
mm.touch(new Location(event.getWorld(), x, 127, z));
|
||||
}*/
|
||||
};
|
||||
if (isTrigger("chunkloaded")) pm.registerEvent(Event.Type.CHUNK_LOADED, renderTrigger, Priority.Monitor, this);
|
||||
//if (isTrigger("chunkgenerated")) pm.registerEvent(Event.Type.CHUNK_GENERATED, renderTrigger, Priority.Monitor, this);
|
||||
}
|
||||
|
||||
// To link configuration to real loaded worlds.
|
||||
WorldListener worldListener = new WorldListener() {
|
||||
@Override
|
||||
public void onWorldLoaded(WorldEvent event) {
|
||||
mapManager.activateWorld(event.getWorld());
|
||||
mm.activateWorld(event.getWorld());
|
||||
}
|
||||
};
|
||||
getServer().getPluginManager().registerEvent(Event.Type.WORLD_LOADED, worldListener, Priority.Monitor, this);
|
||||
pm.registerEvent(Event.Type.WORLD_LOADED, worldListener, Priority.Monitor, this);
|
||||
|
||||
// To handle webchat.
|
||||
PlayerListener playerListener = new DynmapPlayerListener(this);
|
||||
//getServer().getPluginManager().registerEvent(Event.Type.PLAYER_COMMAND, playerListener, Priority.Normal, this);
|
||||
getServer().getPluginManager().registerEvent(Event.Type.PLAYER_CHAT, playerListener, Priority.Normal, this);
|
||||
getServer().getPluginManager().registerEvent(Event.Type.PLAYER_LOGIN, playerListener, Priority.Normal, this);
|
||||
getServer().getPluginManager().registerEvent(Event.Type.PLAYER_JOIN, playerListener, Priority.Normal, this);
|
||||
getServer().getPluginManager().registerEvent(Event.Type.PLAYER_QUIT, playerListener, Priority.Normal, this);
|
||||
pm.registerEvent(Event.Type.PLAYER_CHAT, playerListener, Priority.Monitor, this);
|
||||
pm.registerEvent(Event.Type.PLAYER_LOGIN, playerListener, Priority.Monitor, this);
|
||||
pm.registerEvent(Event.Type.PLAYER_JOIN, playerListener, Priority.Monitor, this);
|
||||
pm.registerEvent(Event.Type.PLAYER_QUIT, playerListener, Priority.Monitor, this);
|
||||
|
||||
}
|
||||
|
||||
private static File combinePaths(File parent, String path) {
|
||||
@ -269,9 +348,9 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
fos.write(Json.stringifyJson(clientConfig).getBytes());
|
||||
fos.close();
|
||||
} catch (FileNotFoundException ex) {
|
||||
System.out.println("FileNotFoundException : " + ex);
|
||||
log.log(Level.SEVERE, "Exception while writing JSON-configuration-file.", ex);
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("IOException : " + ioe);
|
||||
log.log(Level.SEVERE, "Exception while writing JSON-configuration-file.", ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.TimerTask;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
@ -14,6 +16,8 @@ import org.bukkit.util.config.Configuration;
|
||||
import org.dynmap.web.Json;
|
||||
|
||||
class JsonTimerTask extends TimerTask {
|
||||
protected static final Logger log = Logger.getLogger("Minecraft");
|
||||
|
||||
private final DynmapPlugin plugin;
|
||||
private Server server;
|
||||
private MapManager mapManager;
|
||||
@ -57,9 +61,9 @@ class JsonTimerTask extends TimerTask {
|
||||
fos.write(Json.stringifyJson(update).getBytes());
|
||||
fos.close();
|
||||
} catch (FileNotFoundException ex) {
|
||||
System.out.println("FileNotFoundException : " + ex);
|
||||
log.log(Level.SEVERE, "Exception while writing JSON-file.", ex);
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("IOException : " + ioe);
|
||||
log.log(Level.SEVERE, "Exception while writing JSON-file.", ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,6 @@ public class MapManager {
|
||||
}
|
||||
}
|
||||
found.remove(tile);
|
||||
System.gc();
|
||||
}
|
||||
|
||||
// Unload remaining chunks to clean-up.
|
||||
@ -202,7 +201,9 @@ public class MapManager {
|
||||
worldTileDirectory = new File(DynmapPlugin.tilesDirectory, tile.getWorld().getName());
|
||||
worldTileDirectories.put(world, worldTileDirectory);
|
||||
}
|
||||
worldTileDirectory.mkdirs();
|
||||
if (!worldTileDirectory.isDirectory() && !worldTileDirectory.mkdirs()) {
|
||||
log.warning("Could not create directory for tiles ('" + worldTileDirectory + "').");
|
||||
}
|
||||
return new File(worldTileDirectory, tile.getFilename());
|
||||
}
|
||||
|
||||
|
@ -25,4 +25,13 @@ public abstract class MapTile {
|
||||
public int hashCode() {
|
||||
return getFilename().hashCode() ^ getWorld().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof MapTile) {
|
||||
MapTile t = (MapTile)obj;
|
||||
return getFilename().equals(t.getFilename()) && getWorld().equals(t.getWorld());
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public class UpdateQueue {
|
||||
return updates;
|
||||
}
|
||||
|
||||
public class Update {
|
||||
public static class Update {
|
||||
public long time;
|
||||
public Object obj;
|
||||
|
||||
|
@ -1,90 +0,0 @@
|
||||
package org.dynmap.debug;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.Event.Priority;
|
||||
import org.bukkit.event.player.PlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.bukkit.event.player.PlayerListener;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class BukkitPlayerDebugger implements Debugger {
|
||||
private JavaPlugin plugin;
|
||||
private HashSet<Player> debugees = new HashSet<Player>();
|
||||
private String debugCommand;
|
||||
private String undebugCommand;
|
||||
private String prepend;
|
||||
|
||||
public BukkitPlayerDebugger(JavaPlugin plugin, Map<String, Object> configuration) {
|
||||
this.plugin = plugin;
|
||||
|
||||
String name = "dynmap";
|
||||
debugCommand = "/debug_" + name;
|
||||
undebugCommand = "/undebug_" + name;
|
||||
prepend = name + ": ";
|
||||
}
|
||||
|
||||
public synchronized void enable() {
|
||||
plugin.getServer().getPluginManager().registerEvent(Event.Type.PLAYER_COMMAND, new CommandListener(), Priority.Normal, plugin);
|
||||
plugin.getServer().getPluginManager().registerEvent(Event.Type.PLAYER_QUIT, new CommandListener(), Priority.Normal, plugin);
|
||||
}
|
||||
|
||||
public synchronized void disable() {
|
||||
clearDebugees();
|
||||
}
|
||||
|
||||
public synchronized void addDebugee(Player p) {
|
||||
debugees.add(p);
|
||||
}
|
||||
|
||||
public synchronized void removeDebugee(Player p) {
|
||||
debugees.remove(p);
|
||||
}
|
||||
|
||||
public synchronized void clearDebugees() {
|
||||
debugees.clear();
|
||||
}
|
||||
|
||||
public synchronized void sendToDebuggees(String message) {
|
||||
for (Player p : debugees) {
|
||||
p.sendMessage(prepend + message);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void debug(String message) {
|
||||
sendToDebuggees(message);
|
||||
}
|
||||
|
||||
public synchronized void error(String message) {
|
||||
sendToDebuggees(prepend + ChatColor.RED + message);
|
||||
}
|
||||
|
||||
public synchronized void error(String message, Throwable thrown) {
|
||||
sendToDebuggees(prepend + ChatColor.RED + message);
|
||||
sendToDebuggees(thrown.toString());
|
||||
}
|
||||
|
||||
protected class CommandListener extends PlayerListener {
|
||||
@Override
|
||||
public void onPlayerCommand(PlayerChatEvent event) {
|
||||
String[] split = event.getMessage().split(" ");
|
||||
Player player = event.getPlayer();
|
||||
if (split[0].equalsIgnoreCase(debugCommand)) {
|
||||
addDebugee(player);
|
||||
event.setCancelled(true);
|
||||
} else if (split[0].equalsIgnoreCase(undebugCommand)) {
|
||||
removeDebugee(player);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerQuit(PlayerEvent event) {
|
||||
removeDebugee(event.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
123
src/main/java/org/dynmap/flat/FlatMap.java
Normal file
@ -0,0 +1,123 @@
|
||||
package org.dynmap.flat;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.dynmap.ColorScheme;
|
||||
import org.dynmap.DynmapChunk;
|
||||
import org.dynmap.MapTile;
|
||||
import org.dynmap.MapType;
|
||||
import org.dynmap.debug.Debug;
|
||||
|
||||
public class FlatMap extends MapType {
|
||||
private String prefix;
|
||||
private ColorScheme colorScheme;
|
||||
|
||||
public FlatMap(Map<String, Object> configuration) {
|
||||
prefix = (String)configuration.get("prefix");
|
||||
colorScheme = ColorScheme.getScheme((String)configuration.get("colorscheme"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapTile[] getTiles(Location l) {
|
||||
return new MapTile[] { new FlatMapTile(l.getWorld(), this, (int) Math.floor(l.getBlockX() / 128.0), (int) Math.floor(l.getBlockZ() / 128.0), 128) };
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapTile[] getAdjecentTiles(MapTile tile) {
|
||||
FlatMapTile t = (FlatMapTile) tile;
|
||||
World w = t.getWorld();
|
||||
int x = t.x;
|
||||
int y = t.y;
|
||||
int s = t.size;
|
||||
return new MapTile[] {
|
||||
new FlatMapTile(w, this, x, y - 1, s),
|
||||
new FlatMapTile(w, this, x + 1, y, s),
|
||||
new FlatMapTile(w, this, x, y + 1, s),
|
||||
new FlatMapTile(w, this, x - 1, y, s) };
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynmapChunk[] getRequiredChunks(MapTile tile) {
|
||||
FlatMapTile t = (FlatMapTile) tile;
|
||||
int chunksPerTile = t.size / 16;
|
||||
int sx = t.x * chunksPerTile;
|
||||
int sz = t.y * chunksPerTile;
|
||||
|
||||
DynmapChunk[] result = new DynmapChunk[chunksPerTile * chunksPerTile];
|
||||
int index = 0;
|
||||
for (int x = 0; x < chunksPerTile; x++)
|
||||
for (int z = 0; z < chunksPerTile; z++) {
|
||||
result[index] = new DynmapChunk(sx + x, sz + z);
|
||||
index++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean render(MapTile tile, File outputFile) {
|
||||
FlatMapTile t = (FlatMapTile) tile;
|
||||
World w = t.getWorld();
|
||||
|
||||
boolean rendered = false;
|
||||
BufferedImage im = new BufferedImage(t.size, t.size, BufferedImage.TYPE_INT_RGB);
|
||||
WritableRaster r = im.getRaster();
|
||||
|
||||
for (int x = 0; x < t.size; x++)
|
||||
for (int y = 0; y < t.size; y++) {
|
||||
int mx = x + t.x * t.size;
|
||||
int mz = y + t.y * t.size;
|
||||
int my = w.getHighestBlockYAt(mx, mz) - 1;
|
||||
int blockType = w.getBlockTypeIdAt(mx, my, mz);
|
||||
Color[] colors = colorScheme.colors.get(blockType);
|
||||
if (colors == null)
|
||||
continue;
|
||||
Color c = colors[0];
|
||||
if (c == null)
|
||||
continue;
|
||||
r.setPixel(x, y, new int[] {
|
||||
c.getRed(),
|
||||
c.getGreen(),
|
||||
c.getBlue() });
|
||||
rendered = true;
|
||||
}
|
||||
|
||||
try {
|
||||
ImageIO.write(im, "png", outputFile);
|
||||
} catch (IOException e) {
|
||||
Debug.error("Failed to save image: " + outputFile.getPath(), e);
|
||||
} catch (java.lang.NullPointerException e) {
|
||||
Debug.error("Failed to save image (NullPointerException): " + outputFile.getPath(), e);
|
||||
}
|
||||
im.flush();
|
||||
return rendered;
|
||||
}
|
||||
|
||||
public static class FlatMapTile extends MapTile {
|
||||
FlatMap map;
|
||||
public int x;
|
||||
public int y;
|
||||
public int size;
|
||||
|
||||
public FlatMapTile(World world, FlatMap map, int x, int y, int size) {
|
||||
super(world, map);
|
||||
this.map = map;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFilename() {
|
||||
return map.prefix + "_" + size + "_" + x + "_" + y + ".png";
|
||||
}
|
||||
}
|
||||
}
|
@ -10,12 +10,14 @@ import java.util.Map;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.dynmap.ColorScheme;
|
||||
import org.dynmap.debug.Debug;
|
||||
|
||||
public class DefaultTileRenderer implements MapTileRenderer {
|
||||
protected static Color translucent = new Color(0, 0, 0, 0);
|
||||
private String name;
|
||||
protected int maximumHeight = 127;
|
||||
private ColorScheme colorScheme;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
@ -30,6 +32,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
if (maximumHeight > 127)
|
||||
maximumHeight = 127;
|
||||
}
|
||||
colorScheme = ColorScheme.getScheme((String)configuration.get("colorscheme"));
|
||||
}
|
||||
|
||||
public boolean render(KzedMapTile tile, File outputFile) {
|
||||
@ -39,9 +42,9 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
WritableRaster r = im.getRaster();
|
||||
boolean isempty = true;
|
||||
|
||||
int ix = KzedMap.anchorx + tile.px / 2 + tile.py / 2;
|
||||
int ix = KzedMap.anchorx + tile.px / 2 + tile.py / 2 - ((127-maximumHeight)/2);
|
||||
int iy = maximumHeight;
|
||||
int iz = KzedMap.anchorz + tile.px / 2 - tile.py / 2;
|
||||
int iz = KzedMap.anchorz + tile.px / 2 - tile.py / 2 + ((127-maximumHeight)/2);
|
||||
|
||||
int jx, jz;
|
||||
|
||||
@ -132,7 +135,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
seq = (seq + 1) & 3;
|
||||
|
||||
if (id != 0) {
|
||||
Color[] colors = KzedMap.colors.get(id);
|
||||
Color[] colors = colorScheme.colors.get(id);
|
||||
if (colors != null) {
|
||||
Color c = colors[seq];
|
||||
if (c.getAlpha() > 0) {
|
||||
|
@ -1,15 +1,10 @@
|
||||
package org.dynmap.kzedmap;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Location;
|
||||
@ -38,15 +33,10 @@ public class KzedMap extends MapType {
|
||||
public static final int anchory = 127;
|
||||
public static final int anchorz = 0;
|
||||
|
||||
public static java.util.Map<Integer, Color[]> colors;
|
||||
MapTileRenderer[] renderers;
|
||||
ZoomedTileRenderer zoomrenderer;
|
||||
|
||||
public KzedMap(Map<String, Object> configuration) {
|
||||
if (colors == null) {
|
||||
colors = loadColorSet("colors.txt");
|
||||
}
|
||||
|
||||
renderers = loadRenderers(configuration);
|
||||
zoomrenderer = new ZoomedTileRenderer(configuration);
|
||||
}
|
||||
@ -223,54 +213,4 @@ public class KzedMap extends MapType {
|
||||
else
|
||||
return y - (y % zTileHeight);
|
||||
}
|
||||
|
||||
public java.util.Map<Integer, Color[]> loadColorSet(String colorsetpath) {
|
||||
java.util.Map<Integer, Color[]> colors = new HashMap<Integer, Color[]>();
|
||||
|
||||
InputStream stream;
|
||||
|
||||
try {
|
||||
/* load colorset */
|
||||
File cfile = new File(colorsetpath);
|
||||
if (cfile.isFile()) {
|
||||
Debug.debug("Loading colors from '" + colorsetpath + "'...");
|
||||
stream = new FileInputStream(cfile);
|
||||
} else {
|
||||
Debug.debug("Loading colors from jar...");
|
||||
stream = KzedMap.class.getResourceAsStream("/colors.txt");
|
||||
}
|
||||
|
||||
Scanner scanner = new Scanner(stream);
|
||||
int nc = 0;
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
if (line.startsWith("#") || line.equals("")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] split = line.split("\t");
|
||||
if (split.length < 17) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Integer id = new Integer(split[0]);
|
||||
|
||||
Color[] c = new Color[4];
|
||||
|
||||
/* store colors by raycast sequence number */
|
||||
c[0] = new Color(Integer.parseInt(split[1]), Integer.parseInt(split[2]), Integer.parseInt(split[3]), Integer.parseInt(split[4]));
|
||||
c[3] = new Color(Integer.parseInt(split[5]), Integer.parseInt(split[6]), Integer.parseInt(split[7]), Integer.parseInt(split[8]));
|
||||
c[1] = new Color(Integer.parseInt(split[9]), Integer.parseInt(split[10]), Integer.parseInt(split[11]), Integer.parseInt(split[12]));
|
||||
c[2] = new Color(Integer.parseInt(split[13]), Integer.parseInt(split[14]), Integer.parseInt(split[15]), Integer.parseInt(split[16]));
|
||||
|
||||
colors.put(id, c);
|
||||
nc += 1;
|
||||
}
|
||||
scanner.close();
|
||||
} catch (Exception e) {
|
||||
Debug.error("Could not load colors", e);
|
||||
return null;
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
package org.dynmap.web;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class HttpErrorHandler {
|
||||
public static void handle(HttpResponse response, int statusCode, String statusMessage) throws IOException {
|
||||
response.statusCode = statusCode;
|
||||
response.statusMessage = statusMessage;
|
||||
response.fields.put("Content-Length", "0");
|
||||
response.getBody();
|
||||
}
|
||||
|
||||
public static void handleNotFound(HttpResponse response) throws IOException {
|
||||
handle(response, 404, "Not found");
|
||||
}
|
||||
|
||||
public static void handleMethodNotAllowed(HttpResponse response) throws IOException {
|
||||
handle(response, 405, "Method not allowed");
|
||||
}
|
||||
}
|
@ -1,6 +1,52 @@
|
||||
package org.dynmap.web;
|
||||
|
||||
public class HttpField {
|
||||
public static final String contentLength = "Content-Length";
|
||||
public static final String contentType = "Content-Type";
|
||||
// Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||
public static final String Accept = "Accept";
|
||||
public static final String AcceptCharset = "Accept-Charset";
|
||||
public static final String AcceptEncoding = "Accept-Encoding";
|
||||
public static final String AcceptLanguage = "Accept-Language";
|
||||
public static final String AcceptRanges = "Accept-Ranges";
|
||||
public static final String Age = "Age";
|
||||
public static final String Allow = "Allow";
|
||||
public static final String Authorization = "Authorization";
|
||||
public static final String CacheControl = "Cache-Control";
|
||||
public static final String Connection = "Connection";
|
||||
public static final String ContentEncoding = "Content-Encoding";
|
||||
public static final String ContentLanguage = "Content-Language";
|
||||
public static final String ContentLength = "Content-Length";
|
||||
public static final String ContentLocation = "Content-Location";
|
||||
public static final String ContentRange = "Content-Range";
|
||||
public static final String ContentType = "Content-Type";
|
||||
public static final String Date = "Date";
|
||||
public static final String ETag = "ETag";
|
||||
public static final String Expect = "Expect";
|
||||
public static final String Expires = "Expires";
|
||||
public static final String From = "From";
|
||||
public static final String Host = "Host";
|
||||
public static final String IfMatch = "If-Match";
|
||||
public static final String IfModifiedSince = "If-Modified-Since";
|
||||
public static final String IfNoneMatch = "If-None-Match";
|
||||
public static final String IfRange = "If-Range";
|
||||
public static final String IfUnmodifiedSince = "If-Unmodified-Since";
|
||||
public static final String LastModified = "Last-Modified";
|
||||
public static final String Location = "Location";
|
||||
public static final String MaxForwards = "Max-Forwards";
|
||||
public static final String Pragma = "Pragma";
|
||||
public static final String ProxyAuthenticate = "Proxy-Authenticate";
|
||||
public static final String ProxyAuthorization = "Proxy-Authorization";
|
||||
public static final String Range = "Range";
|
||||
public static final String Referer = "Referer";
|
||||
public static final String RetryAfter = "Retry-After";
|
||||
public static final String Server = "Server";
|
||||
public static final String TE = "TE";
|
||||
public static final String Trailer = "Trailer";
|
||||
public static final String TransferEncoding = "Transfer-Encoding";
|
||||
public static final String Upgrade = "Upgrade";
|
||||
public static final String UserAgent = "User-Agent";
|
||||
public static final String Vary = "Vary";
|
||||
public static final String Via = "Via";
|
||||
public static final String Warning = "Warning";
|
||||
public static final String WwwAuthenticate = "WWW-Authenticate";
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package org.dynmap.web;
|
||||
|
||||
public class HttpMethods {
|
||||
public final class HttpMethod {
|
||||
public static final String Get = "GET";
|
||||
public static final String Post = "POST";
|
||||
public static final String Put = "PUT";
|
@ -8,8 +8,7 @@ import java.util.Map;
|
||||
public class HttpResponse {
|
||||
private HttpServerConnection connection;
|
||||
public String version = "1.1";
|
||||
public int statusCode = 200;
|
||||
public String statusMessage = "OK";
|
||||
public HttpStatus status = null;
|
||||
public Map<String, String> fields = new HashMap<String, String>();
|
||||
|
||||
private OutputStream body;
|
||||
|
@ -95,9 +95,9 @@ public class HttpServerConnection extends Thread {
|
||||
out.append("HTTP/");
|
||||
out.append(response.version);
|
||||
out.append(" ");
|
||||
out.append(String.valueOf(response.statusCode));
|
||||
out.append(String.valueOf(response.status.getCode()));
|
||||
out.append(" ");
|
||||
out.append(response.statusMessage);
|
||||
out.append(response.status.getText());
|
||||
out.append("\r\n");
|
||||
for (Entry<String, String> field : response.fields.entrySet()) {
|
||||
out.append(field.getKey());
|
||||
@ -115,6 +115,8 @@ public class HttpServerConnection extends Thread {
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
if (socket == null)
|
||||
return;
|
||||
socket.setSoTimeout(5000);
|
||||
InputStream in = socket.getInputStream();
|
||||
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream(), 40960);
|
||||
@ -131,7 +133,7 @@ public class HttpServerConnection extends Thread {
|
||||
long bound = -1;
|
||||
BoundInputStream boundBody = null;
|
||||
{
|
||||
String contentLengthStr = request.fields.get(HttpField.contentLength);
|
||||
String contentLengthStr = request.fields.get(HttpField.ContentLength);
|
||||
if (contentLengthStr != null) {
|
||||
try {
|
||||
bound = Long.parseLong(contentLengthStr);
|
||||
@ -178,8 +180,10 @@ public class HttpServerConnection extends Thread {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bound > 0) {
|
||||
boundBody.skip(bound);
|
||||
if (bound > 0 && boundBody.skip(bound) < bound) {
|
||||
Debug.debug("Incoming stream was only read partially by handler '" + handler + "'.");
|
||||
//socket.close();
|
||||
//return;
|
||||
}
|
||||
|
||||
String connection = response.fields.get("Connection");
|
||||
|
61
src/main/java/org/dynmap/web/HttpStatus.java
Normal file
@ -0,0 +1,61 @@
|
||||
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");
|
||||
public static final HttpStatus OK = new HttpStatus(200, "OK");
|
||||
public static final HttpStatus Created = new HttpStatus(201, "Created");
|
||||
public static final HttpStatus Accepted = new HttpStatus(202, "Accepted");
|
||||
public static final HttpStatus NonAuthoritativeInformation = new HttpStatus(203, "Non-Authoritative Information");
|
||||
public static final HttpStatus NoContent = new HttpStatus(204, "No Content");
|
||||
public static final HttpStatus ResetContent = new HttpStatus(205, "Reset Content");
|
||||
public static final HttpStatus PartialContent = new HttpStatus(206, "Partial Content");
|
||||
public static final HttpStatus MultipleChoices = new HttpStatus(300, "Multiple Choices");
|
||||
public static final HttpStatus MovedPermanently = new HttpStatus(301, "Moved Permanently");
|
||||
public static final HttpStatus Found = new HttpStatus(302, "Found");
|
||||
public static final HttpStatus SeeOther = new HttpStatus(303, "See Other");
|
||||
public static final HttpStatus NotModified = new HttpStatus(304, "Not Modified");
|
||||
public static final HttpStatus UseProxy = new HttpStatus(305, "Use Proxy");
|
||||
public static final HttpStatus TemporaryRedirect = new HttpStatus(307, "Temporary Redirect");
|
||||
public static final HttpStatus BadRequest = new HttpStatus(400, "Bad Request");
|
||||
public static final HttpStatus Unauthorized = new HttpStatus(401, "Unauthorized");
|
||||
public static final HttpStatus PaymentRequired = new HttpStatus(402, "Payment Required");
|
||||
public static final HttpStatus Forbidden = new HttpStatus(403, "Forbidden");
|
||||
public static final HttpStatus NotFound = new HttpStatus(404, "Not Found");
|
||||
public static final HttpStatus MethodNotAllowed = new HttpStatus(405, "Method Not Allowed");
|
||||
public static final HttpStatus NotAcceptable = new HttpStatus(406, "Not Acceptable");
|
||||
public static final HttpStatus ProxyAuthenticationRequired = new HttpStatus(407, "Proxy Authentication Required");
|
||||
public static final HttpStatus RequestTimeout = new HttpStatus(408, "Request Timeout");
|
||||
public static final HttpStatus Conflict = new HttpStatus(409, "Conflict");
|
||||
public static final HttpStatus Gone = new HttpStatus(410, "Gone");
|
||||
public static final HttpStatus LengthRequired = new HttpStatus(411, "Length Required");
|
||||
public static final HttpStatus PreconditionFailed = new HttpStatus(412, "Precondition Failed");
|
||||
public static final HttpStatus RequestEntityTooLarge = new HttpStatus(413, "Request Entity Too Large");
|
||||
public static final HttpStatus RequestURITooLong = new HttpStatus(414, "Request-URI Too Long");
|
||||
public static final HttpStatus UnsupportedMediaType = new HttpStatus(415, "Unsupported Media Type");
|
||||
public static final HttpStatus RequestedRangeNotSatisfiable = new HttpStatus(416, "Requested Range Not Satisfiable");
|
||||
public static final HttpStatus ExpectationFailed = new HttpStatus(417, "Expectation Failed");
|
||||
public static final HttpStatus InternalServerError = new HttpStatus(500, "Internal Server Error");
|
||||
public static final HttpStatus NotImplemented = new HttpStatus(501, "Not Implemented");
|
||||
public static final HttpStatus BadGateway = new HttpStatus(502, "Bad Gateway");
|
||||
public static final HttpStatus ServiceUnavailable = new HttpStatus(503, "Service Unavailable");
|
||||
public static final HttpStatus GatewayTimeout = new HttpStatus(504, "Gateway Timeout");
|
||||
public static final HttpStatus HttpVersionNotSupported = new HttpStatus(505, "HTTP Version Not Supported");
|
||||
}
|
@ -3,61 +3,62 @@ package org.dynmap.web;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.KeyStore.Entry;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Json {
|
||||
public static String stringifyJson(Object o) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendJson(o, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static void appendJson(Object o, StringBuilder s) {
|
||||
if (o == null) {
|
||||
return "null";
|
||||
s.append("null");
|
||||
} else if (o instanceof Boolean) {
|
||||
return ((Boolean) o) ? "true" : "false";
|
||||
s.append(((Boolean) o) ? "true" : "false");
|
||||
} else if (o instanceof String) {
|
||||
return "\"" + ((String)o).replace("\"", "\\\"") + "\"";
|
||||
s.append("\"" + ((String)o).replace("\"", "\\\"") + "\"");
|
||||
} else if (o instanceof Integer || o instanceof Long || o instanceof Float || o instanceof Double) {
|
||||
return o.toString();
|
||||
s.append(o.toString());
|
||||
} else if (o instanceof LinkedHashMap<?, ?>) {
|
||||
LinkedHashMap<?, ?> m = (LinkedHashMap<?, ?>) o;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{");
|
||||
s.append("{");
|
||||
boolean first = true;
|
||||
for (Object key : m.keySet()) {
|
||||
for (Map.Entry<?, ?> entry : m.entrySet()) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
sb.append(",");
|
||||
s.append(",");
|
||||
|
||||
sb.append(stringifyJson(key));
|
||||
sb.append(": ");
|
||||
sb.append(stringifyJson(m.get(key)));
|
||||
appendJson(entry.getKey(), s);
|
||||
s.append(": ");
|
||||
appendJson(entry.getValue(), s);
|
||||
}
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
s.append("}");
|
||||
} else if (o instanceof List<?>) {
|
||||
List<?> l = (List<?>) o;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
s.append("[");
|
||||
int count = 0;
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
if (count++ > 0) sb.append(",");
|
||||
sb.append(stringifyJson(l.get(i)));
|
||||
if (count++ > 0) s.append(",");
|
||||
appendJson(l.get(i), s);
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
s.append("]");
|
||||
} else if (o.getClass().isArray()) {
|
||||
int length = Array.getLength(o);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
s.append("[");
|
||||
int count = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (count++ > 0) sb.append(",");
|
||||
sb.append(stringifyJson(Array.get(o, i)));
|
||||
if (count++ > 0) s.append(",");
|
||||
appendJson(Array.get(o, i), s);
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
s.append("]");
|
||||
} else if (o instanceof Object) /* TODO: Always true, maybe interface? */ {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{");
|
||||
s.append("{");
|
||||
boolean first = true;
|
||||
|
||||
Class<?> c = o.getClass();
|
||||
@ -77,15 +78,14 @@ public class Json {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
sb.append(",");
|
||||
sb.append(stringifyJson(fieldName));
|
||||
sb.append(": ");
|
||||
sb.append(stringifyJson(fieldValue));
|
||||
s.append(",");
|
||||
appendJson(fieldName, s);
|
||||
s.append(": ");
|
||||
appendJson(fieldValue, s);
|
||||
}
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
s.append("}");
|
||||
} else {
|
||||
return "undefined";
|
||||
s.append("undefined");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,27 +7,33 @@ import java.util.Map;
|
||||
import org.dynmap.web.HttpHandler;
|
||||
import org.dynmap.web.HttpRequest;
|
||||
import org.dynmap.web.HttpResponse;
|
||||
import org.dynmap.web.HttpStatus;
|
||||
import org.dynmap.web.Json;
|
||||
|
||||
public class ClientConfigurationHandler implements HttpHandler {
|
||||
private Map<?, ?> configuration;
|
||||
private byte[] cachedConfiguration = null;
|
||||
public ClientConfigurationHandler(Map<?, ?> configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
@Override
|
||||
public void handle(String path, HttpRequest request, HttpResponse response) throws Exception {
|
||||
if (cachedConfiguration == null) {
|
||||
String s = Json.stringifyJson(configuration);
|
||||
|
||||
byte[] bytes = s.getBytes();
|
||||
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(bytes.length));
|
||||
response.fields.put("Content-Length", Integer.toString(cachedConfiguration.length));
|
||||
response.status = HttpStatus.OK;
|
||||
|
||||
BufferedOutputStream out = new BufferedOutputStream(response.getBody());
|
||||
out.write(s.getBytes());
|
||||
out.write(cachedConfiguration);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,11 @@ import org.bukkit.entity.Player;
|
||||
import org.dynmap.Client;
|
||||
import org.dynmap.MapManager;
|
||||
import org.dynmap.PlayerList;
|
||||
import org.dynmap.web.HttpField;
|
||||
import org.dynmap.web.HttpHandler;
|
||||
import org.dynmap.web.HttpRequest;
|
||||
import org.dynmap.web.HttpResponse;
|
||||
import org.dynmap.web.HttpStatus;
|
||||
import org.dynmap.web.Json;
|
||||
|
||||
public class ClientUpdateHandler implements HttpHandler {
|
||||
@ -28,21 +30,26 @@ public class ClientUpdateHandler implements HttpHandler {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
Pattern updatePathPattern = Pattern.compile("world/([a-zA-Z0-9_]+)/([0-9]*)");
|
||||
Pattern updatePathPattern = Pattern.compile("world/([a-zA-Z0-9_\\-\\.]+)/([0-9]*)");
|
||||
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())
|
||||
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)
|
||||
if (world == null) {
|
||||
response.status = WorldNotFound;
|
||||
return;
|
||||
}
|
||||
|
||||
long current = System.currentTimeMillis();
|
||||
long since = 0;
|
||||
@ -73,11 +80,13 @@ public class ClientUpdateHandler implements HttpHandler {
|
||||
byte[] bytes = Json.stringifyJson(update).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(bytes.length));
|
||||
response.fields.put(HttpField.Date, dateStr);
|
||||
response.fields.put(HttpField.ContentType, "text/plain");
|
||||
response.fields.put(HttpField.Expires, "Thu, 01 Dec 1994 16:00:00 GMT");
|
||||
response.fields.put(HttpField.LastModified, dateStr);
|
||||
response.fields.put(HttpField.ContentLength, Integer.toString(bytes.length));
|
||||
response.status = HttpStatus.OK;
|
||||
|
||||
BufferedOutputStream out = new BufferedOutputStream(response.getBody());
|
||||
out.write(bytes);
|
||||
out.flush();
|
||||
|
@ -7,9 +7,11 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.dynmap.web.HttpField;
|
||||
import org.dynmap.web.HttpHandler;
|
||||
import org.dynmap.web.HttpRequest;
|
||||
import org.dynmap.web.HttpResponse;
|
||||
import org.dynmap.web.HttpStatus;
|
||||
|
||||
public abstract class FileHandler implements HttpHandler {
|
||||
protected static final Logger log = Logger.getLogger("Minecraft");
|
||||
@ -64,17 +66,15 @@ public abstract class FileHandler implements HttpHandler {
|
||||
path = formatPath(path);
|
||||
fileInput = getFileInput(path, request, response);
|
||||
if (fileInput == null) {
|
||||
response.statusCode = 404;
|
||||
response.statusMessage = "Not found";
|
||||
response.fields.put("Content-Length", "0");
|
||||
response.getBody();
|
||||
response.status = HttpStatus.NotFound;
|
||||
return;
|
||||
}
|
||||
|
||||
String extension = getExtension(path);
|
||||
String mimeType = getMimeTypeFromExtension(extension);
|
||||
|
||||
response.fields.put("Content-Type", mimeType);
|
||||
response.fields.put(HttpField.ContentType, mimeType);
|
||||
response.status = HttpStatus.OK;
|
||||
OutputStream out = response.getBody();
|
||||
try {
|
||||
int readBytes;
|
||||
|
@ -5,6 +5,7 @@ import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.dynmap.web.HttpField;
|
||||
import org.dynmap.web.HttpRequest;
|
||||
import org.dynmap.web.HttpResponse;
|
||||
|
||||
@ -26,7 +27,7 @@ public class FilesystemHandler extends FileHandler {
|
||||
} catch (FileNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
response.fields.put("Content-Length", Long.toString(file.length()));
|
||||
response.fields.put(HttpField.ContentLength, Long.toString(file.length()));
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
|
@ -4,12 +4,12 @@ import java.io.InputStreamReader;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.dynmap.Event;
|
||||
import org.dynmap.web.HttpErrorHandler;
|
||||
import org.dynmap.web.HttpField;
|
||||
import org.dynmap.web.HttpHandler;
|
||||
import org.dynmap.web.HttpMethods;
|
||||
import org.dynmap.web.HttpMethod;
|
||||
import org.dynmap.web.HttpRequest;
|
||||
import org.dynmap.web.HttpResponse;
|
||||
import org.dynmap.web.HttpStatus;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
|
||||
@ -20,8 +20,9 @@ public class SendMessageHandler implements HttpHandler {
|
||||
public Event<Message> onMessageReceived = new Event<SendMessageHandler.Message>();
|
||||
@Override
|
||||
public void handle(String path, HttpRequest request, HttpResponse response) throws Exception {
|
||||
if (!request.method.equals(HttpMethods.Post)) {
|
||||
HttpErrorHandler.handleMethodNotAllowed(response);
|
||||
if (!request.method.equals(HttpMethod.Post)) {
|
||||
response.status = HttpStatus.MethodNotAllowed;
|
||||
response.fields.put(HttpField.Accept, HttpMethod.Post);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -34,10 +35,11 @@ public class SendMessageHandler implements HttpHandler {
|
||||
|
||||
onMessageReceived.trigger(message);
|
||||
|
||||
response.fields.put(HttpField.contentLength, "0");
|
||||
response.fields.put(HttpField.ContentLength, "0");
|
||||
response.status = HttpStatus.OK;
|
||||
response.getBody();
|
||||
}
|
||||
public class Message {
|
||||
public static class Message {
|
||||
public String name;
|
||||
public String message;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
name: dynmap
|
||||
main: org.dynmap.DynmapPlugin
|
||||
version: 0.1
|
||||
version: 0.13
|
||||
commands:
|
||||
dynmap:
|
||||
description: Controls Dynmap.
|
||||
|
@ -29,7 +29,7 @@
|
||||
color: white;
|
||||
border: 0px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
background: url(chat_cursor.png) rgba(0,0,0,0.6); background-repeat: no-repeat; background-position:left;
|
||||
background: url(images/chat_cursor.png) rgba(0,0,0,0.6); background-repeat: no-repeat; background-position:left;
|
||||
outline: none;
|
||||
}
|
||||
.messagelist {
|
||||
|
@ -182,8 +182,8 @@ body {
|
||||
|
||||
text-align: center;
|
||||
|
||||
background: url(sidebar_hint.png) rgb(0,0,0);
|
||||
background: url(sidebar_hint.png) rgba(0,0,0,0.6);
|
||||
background: url(images/sidebar_hint.png) rgb(0,0,0);
|
||||
background: url(images/sidebar_hint.png) rgba(0,0,0,0.6);
|
||||
background-repeat: no-repeat;
|
||||
background-position:center;
|
||||
|
||||
@ -223,19 +223,19 @@ body {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
background-image: url(window_close.png);
|
||||
background-image: url(images/window_close.png);
|
||||
}
|
||||
|
||||
.dynmap .sidebar .panel > .pin:hover {
|
||||
background-image: url(window_pinned_hover.png);
|
||||
background-image: url(images/window_pinned_hover.png);
|
||||
}
|
||||
|
||||
.dynmap .sidebar.pinned .panel > .pin:hover {
|
||||
background-image: url(window_close_hover.png);
|
||||
background-image: url(images/window_close_hover.png);
|
||||
}
|
||||
|
||||
.dynmap .sidebar.pinned .panel > .pin {
|
||||
background-image: url(window_pinned.png);
|
||||
background-image: url(images/window_pinned.png);
|
||||
}
|
||||
|
||||
|
||||
@ -260,12 +260,12 @@ body {
|
||||
}
|
||||
|
||||
.clock.night {
|
||||
/* background-image: url(clock_night.png); */
|
||||
/* background-image: url(images/clock_night.png); */
|
||||
color: #dff;
|
||||
}
|
||||
|
||||
.clock.day {
|
||||
/* background-image: url(clock_day.png); */
|
||||
/* background-image: url(images/clock_day.png); */
|
||||
color: #fd3;
|
||||
}
|
||||
|
||||
@ -299,11 +299,11 @@ body {
|
||||
}
|
||||
|
||||
.timeofday.sun {
|
||||
background-image: url(sun.png);
|
||||
background-image: url(images/sun.png);
|
||||
}
|
||||
|
||||
.timeofday.moon {
|
||||
background-image: url(moon.png);
|
||||
background-image: url(images/moon.png);
|
||||
}
|
||||
|
||||
/*******************
|
||||
@ -418,11 +418,11 @@ body {
|
||||
}
|
||||
|
||||
.dynmap .playerlist .player:hover .playericon {
|
||||
background: url(player_follow_off.png) no-repeat;
|
||||
background: url(images/player_follow_off.png) no-repeat;
|
||||
}
|
||||
|
||||
.dynmap .playerlist .player.following .playericon {
|
||||
background: url(player_follow_on.gif) no-repeat;
|
||||
background: url(images/player_follow_on.gif) no-repeat;
|
||||
}
|
||||
|
||||
.dynmap .playerlist .player.following .playericon > *,
|
||||
@ -465,7 +465,7 @@ body {
|
||||
width: 83px;
|
||||
|
||||
background-repeat: no-repeat;
|
||||
background-image: url(compass.png);
|
||||
background-image: url(images/compass.png);
|
||||
}
|
||||
|
||||
/*******************
|
||||
@ -499,7 +499,7 @@ body {
|
||||
|
||||
border: 0px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
background: url(chat_cursor.png) rgba(0,0,0,0.6);
|
||||
background: url(images/chat_cursor.png) rgba(0,0,0,0.6);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 1px center;
|
||||
|
||||
|
43
web/flatmap.js
Normal file
@ -0,0 +1,43 @@
|
||||
function FlatProjection() {}
|
||||
FlatProjection.prototype = {
|
||||
fromLatLngToPoint: function(latLng) {
|
||||
return new google.maps.Point(latLng.lat()*128.0, latLng.lng()*128.0);
|
||||
},
|
||||
fromPointToLatLng: function(point) {
|
||||
return new google.maps.LatLng(point.x/128.0, point.y/128.0);
|
||||
},
|
||||
fromWorldToLatLng: function(x, y, z) {
|
||||
return new google.maps.LatLng(x / 128.0, z / 128.0);
|
||||
}
|
||||
};
|
||||
|
||||
function FlatMapType(configuration) {
|
||||
$.extend(this, configuration); }
|
||||
FlatMapType.prototype = $.extend(new DynMapType(), {
|
||||
constructor: FlatMapType,
|
||||
projection: new FlatProjection(),
|
||||
tileSize: new google.maps.Size(128.0, 128.0),
|
||||
minZoom: 0,
|
||||
maxZoom: 0,
|
||||
prefix: null,
|
||||
getTile: function(coord, zoom, doc) {
|
||||
var tileName;
|
||||
var tile = $('<img/>')
|
||||
.attr('src', this.dynmap.getTileUrl(tileName = this.prefix + '_128_' + coord.x + '_' + coord.y + '.png'))
|
||||
.error(function() { tile.hide(); })
|
||||
.bind('load', function() { tile.show(); })
|
||||
.css({
|
||||
width: '128px',
|
||||
height: '128px',
|
||||
borderStyle: 'none'
|
||||
})
|
||||
.hide();
|
||||
this.dynmap.registerTile(this, tileName, tile);
|
||||
//this.dynmap.unregisterTile(this, tileName);
|
||||
return tile.get(0);
|
||||
},
|
||||
updateTileSize: function(zoom) {
|
||||
}
|
||||
});
|
||||
|
||||
maptypes.FlatMapType = function(configuration) { return new FlatMapType(configuration); };
|
Before Width: | Height: | Size: 339 B After Width: | Height: | Size: 339 B |
Before Width: | Height: | Size: 340 B After Width: | Height: | Size: 340 B |
Before Width: | Height: | Size: 330 B After Width: | Height: | Size: 330 B |
Before Width: | Height: | Size: 342 B After Width: | Height: | Size: 342 B |
Before Width: | Height: | Size: 829 B After Width: | Height: | Size: 829 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 868 B After Width: | Height: | Size: 868 B |
Before Width: | Height: | Size: 395 B After Width: | Height: | Size: 395 B |
Before Width: | Height: | Size: 261 B After Width: | Height: | Size: 261 B |
Before Width: | Height: | Size: 357 B After Width: | Height: | Size: 357 B |
Before Width: | Height: | Size: 360 B After Width: | Height: | Size: 360 B |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 802 B After Width: | Height: | Size: 802 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 377 B After Width: | Height: | Size: 377 B |
Before Width: | Height: | Size: 376 B After Width: | Height: | Size: 376 B |
Before Width: | Height: | Size: 428 B After Width: | Height: | Size: 428 B |
Before Width: | Height: | Size: 351 B After Width: | Height: | Size: 351 B |
Before Width: | Height: | Size: 360 B After Width: | Height: | Size: 360 B |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 328 B After Width: | Height: | Size: 328 B |
Before Width: | Height: | Size: 404 B After Width: | Height: | Size: 404 B |
Before Width: | Height: | Size: 459 B After Width: | Height: | Size: 459 B |
Before Width: | Height: | Size: 361 B After Width: | Height: | Size: 361 B |
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 332 B |
Before Width: | Height: | Size: 355 B After Width: | Height: | Size: 355 B |
Before Width: | Height: | Size: 454 B After Width: | Height: | Size: 454 B |
Before Width: | Height: | Size: 368 B After Width: | Height: | Size: 368 B |
Before Width: | Height: | Size: 271 B After Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 681 B After Width: | Height: | Size: 681 B |
Before Width: | Height: | Size: 407 B After Width: | Height: | Size: 407 B |
Before Width: | Height: | Size: 431 B After Width: | Height: | Size: 431 B |
Before Width: | Height: | Size: 431 B After Width: | Height: | Size: 431 B |
Before Width: | Height: | Size: 435 B After Width: | Height: | Size: 435 B |
Before Width: | Height: | Size: 943 B After Width: | Height: | Size: 943 B |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 374 B After Width: | Height: | Size: 374 B |
Before Width: | Height: | Size: 355 B After Width: | Height: | Size: 355 B |
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 299 B After Width: | Height: | Size: 299 B |
Before Width: | Height: | Size: 290 B After Width: | Height: | Size: 290 B |
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 366 B After Width: | Height: | Size: 366 B |
Before Width: | Height: | Size: 336 B After Width: | Height: | Size: 336 B |
@ -8,7 +8,7 @@
|
||||
<meta name="keywords" content="minecraft, map, dynamic" />
|
||||
<meta name="description" content="Minecraft Dynamic Map" />
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
|
||||
<link rel="icon" href="dynmap.ico" type="image/ico" />
|
||||
<link rel="icon" href="images/dynmap.ico" type="image/ico" />
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="dynmap_style.css" media="screen" />
|
||||
<!-- <link rel="stylesheet" type="text/css" href="override.css" media="screen" /> -->
|
||||
@ -20,6 +20,7 @@
|
||||
<script type="text/javascript" src="minecraft.js"></script>
|
||||
<script type="text/javascript" src="map.js"></script>
|
||||
<script type="text/javascript" src="kzedmaps.js"></script>
|
||||
<script type="text/javascript" src="flatmap.js"></script>
|
||||
<script type="text/javascript" src="clock.timeofday.js"></script>
|
||||
<script type="text/javascript" src="clock.digital.js"></script>
|
||||
<script type="text/javascript" src="chat.js"></script>
|
||||
|
@ -39,14 +39,12 @@ KzedMapType.prototype = $.extend(new DynMapType(), {
|
||||
var tileSize = 128;
|
||||
var tileName;
|
||||
var imgSize;
|
||||
var offset = {x: 0, y: 0};
|
||||
|
||||
var debugred;
|
||||
var debugblue;
|
||||
|
||||
if (zoom == 0) {
|
||||
// Most zoomed out tiles.
|
||||
|
||||
tileSize = 128;
|
||||
imgSize = tileSize;
|
||||
tileName = 'z' + this.prefix + '_' + (-coord.x * tileSize*2) + '_' + (coord.y * tileSize*2) + '.png';
|
||||
@ -54,14 +52,8 @@ KzedMapType.prototype = $.extend(new DynMapType(), {
|
||||
// Other zoom levels.
|
||||
tileSize = 128;
|
||||
|
||||
// Helper functions.
|
||||
/*var floor = Math.floor;
|
||||
var div = function(x,y){return floor(x/y);}
|
||||
var mod = function(x,y){return ((x%y)+y)%y;};*/
|
||||
|
||||
imgSize = Math.pow(2, 6+zoom);
|
||||
var mapcoord = {x: coord.x*tileSize, y: coord.y*tileSize};
|
||||
tileName = this.prefix + '_' + (-mapcoord.x) + '_' + mapcoord.y + '.png';
|
||||
tileName = this.prefix + '_' + (-coord.x*tileSize) + '_' + (coord.y*tileSize) + '.png';
|
||||
}
|
||||
var img;
|
||||
var tile = $('<div/>')
|
||||
@ -87,9 +79,7 @@ KzedMapType.prototype = $.extend(new DynMapType(), {
|
||||
.css({
|
||||
width: imgSize + 'px',
|
||||
height: imgSize + 'px',
|
||||
borderStyle: 'none',
|
||||
/*marginLeft: offset.x + 'px',
|
||||
marginTop: offset.y + 'px'*/
|
||||
borderStyle: 'none'
|
||||
})
|
||||
.hide()
|
||||
.appendTo(tile);
|
||||
|
20
web/map.js
@ -44,6 +44,8 @@ function DynMap(options) {
|
||||
$.getJSON(me.options.updateUrl + 'configuration', function(configuration) {
|
||||
me.configure(configuration);
|
||||
me.initialize();
|
||||
}, function(status, statusMessage) {
|
||||
alert('Could not retrieve configuration: ' + statusMessage);
|
||||
});
|
||||
}
|
||||
DynMap.prototype = {
|
||||
@ -156,7 +158,7 @@ DynMap.prototype = {
|
||||
.append($('<a/>')
|
||||
.attr({ title: map.title, href: '#' })
|
||||
.addClass('maptype')
|
||||
.css({ backgroundImage: 'url(' + (map.icon || 'block_' + map.name + '.png') + ')' })
|
||||
.css({ backgroundImage: 'url(' + (map.icon || 'images/block_' + map.name + '.png') + ')' })
|
||||
.text(map.title)
|
||||
)
|
||||
.click(function() {
|
||||
@ -208,7 +210,7 @@ DynMap.prototype = {
|
||||
value: ''
|
||||
})
|
||||
.keydown(function(event) {
|
||||
if (event.keyCode === '13') {
|
||||
if (event.keyCode == '13') {
|
||||
event.preventDefault();
|
||||
sendChat(chatinput.val());
|
||||
chatinput.val('');
|
||||
@ -232,6 +234,7 @@ DynMap.prototype = {
|
||||
|
||||
var alertbox = me.alertbox = $('<div/>')
|
||||
.addClass('alertbox')
|
||||
.hide()
|
||||
.appendTo(container);
|
||||
|
||||
me.selectMap(me.defaultworld.defaultmap);
|
||||
@ -333,9 +336,9 @@ DynMap.prototype = {
|
||||
//divs.filter(function(i){return parseInt(divs[i].attr('rel')) > timestamp+me.options.messagettl;}).remove();
|
||||
});
|
||||
setTimeout(function() { me.update(); }, me.options.updaterate);
|
||||
}, function(request, statusText, ex) {
|
||||
}, function(status, statusText, request) {
|
||||
me.alertbox
|
||||
.text('Could not update map')
|
||||
.text('Could not update map: ' + (statusText || 'Could not connect to server'))
|
||||
.show();
|
||||
setTimeout(function() { me.update(); }, me.options.updaterate);
|
||||
}
|
||||
@ -488,7 +491,7 @@ DynMap.prototype = {
|
||||
.addClass('Marker')
|
||||
.addClass('playerMarker')
|
||||
.append(playerImage = $('<img/>')
|
||||
.attr({ src: 'player.png' }))
|
||||
.attr({ src: 'images/player.png' }))
|
||||
.append($('<span/>')
|
||||
.addClass('playerName')
|
||||
.text(player.name));
|
||||
@ -509,7 +512,7 @@ DynMap.prototype = {
|
||||
.addClass('player')
|
||||
.append(playerIconContainer = $('<span/>')
|
||||
.addClass('playerIcon')
|
||||
.append($('<img/>').attr({ src: 'player_face.png' }))
|
||||
.append($('<img/>').attr({ src: 'images/player_face.png' }))
|
||||
.attr({ title: 'Follow ' + player.name })
|
||||
.click(function() {
|
||||
var follow = player !== me.followingPlayer;
|
||||
@ -523,7 +526,10 @@ DynMap.prototype = {
|
||||
})
|
||||
.text(player.name)
|
||||
)
|
||||
.click(function(e) { me.panTo(player.location); })
|
||||
.click(function(e) {
|
||||
me.followPlayer(null);
|
||||
me.panTo(player.location);
|
||||
})
|
||||
.appendTo(me.playerlist);
|
||||
if (me.options.showplayerfacesinmenu) {
|
||||
getMinecraftHead(player.name, 16, function(head) {
|
||||
|
@ -34,7 +34,7 @@ function createMinecraftHead(player,completed,failed) {
|
||||
skinImage.src = 'http://www.minecraft.net/img/char.png';
|
||||
}
|
||||
};
|
||||
skinImage.src = 'http://www.minecraft.net/skin/' + player + '.png';
|
||||
skinImage.src = 'http://s3.amazonaws.com/MinecraftSkins/' + player + '.png';
|
||||
}
|
||||
|
||||
function resizeImage(img,size) {
|
||||
|
@ -1,17 +1,19 @@
|
||||
/*******************
|
||||
* This is the over-ride CSS file.
|
||||
*
|
||||
* if you know any CSS you can easily add any custom rules to change how
|
||||
* Dynmap looks for your particular install.
|
||||
* if you know any CSS you can easily add custom rules to change how DynMap
|
||||
* looks and behaves under your DynMap installation.
|
||||
*
|
||||
* Simply uncomment the override.css in the index.html and rename this file
|
||||
* to override.css to use these custom rules.
|
||||
* 1. Uncomment the override.css in the index.html.
|
||||
* 2. Rename this file or create a new override.css.
|
||||
* 3. Add your own rules (or steal these) to personalize how DynMap looks.
|
||||
*
|
||||
* By adding these rules here you can easily save your changes between updates.
|
||||
* By adding your own rules here, you can then save your changes
|
||||
* between DynMap updates and they won't get over-written.
|
||||
*/
|
||||
|
||||
|
||||
/* IE : Use the alternate compass image */
|
||||
/* Use the alternate compass image */
|
||||
|
||||
.compass {
|
||||
top: 20px;
|
||||
@ -20,5 +22,18 @@
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
|
||||
background-image: url(compass_alt.png);
|
||||
background-image: url(images/compass_alt.png);
|
||||
}
|
||||
|
||||
/* These next two keep the DynMap sidebar open... */
|
||||
|
||||
.dynmap .sidebar {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
/* ...and hide the hitbar along with the sidebar controls */
|
||||
|
||||
.dynmap .sidebar .hitbar,
|
||||
.dynmap .sidebar .panel > .pin {
|
||||
display: none;
|
||||
}
|