Finish split of dynmap and DynmapCore

This commit is contained in:
Mike Primm 2012-01-17 23:58:11 -06:00
parent aa5d73ea09
commit fc319a2d32
363 changed files with 77 additions and 31180 deletions

View File

@ -1,60 +0,0 @@
<project name="dynmap" default="dist" basedir=".">
<property name="bukkit.jar" location="C:\Users\Bob\Desktop\minecraft_server\bukkit-0.0.1-SNAPSHOT.jar"/>
<property name="minecraft" location="C:\Users\Bob\Desktop\minecraft_server"/>
<property name="plugins" location="${minecraft}/plugins/"/>
<property name="http_root" location="/srv/http/dynmap/"/>
<property name="pluginname" value="dynmap"/>
<property name="src" location="src"/>
<property name="bin" location="bin"/>
<property name="dist" location="dist"/>
<target name="init">
<mkdir dir="${bin}"/>
</target>
<target name="compile" depends="init">
<javac srcdir="${src}/main/java" destdir="${bin}" classpath="${bukkit.jar}" debug="on" includeantruntime="false" />
</target>
<target name="dist" depends="compile">
<mkdir dir="${dist}"/>
<jar jarfile="${dist}/${pluginname}.jar">
<fileset dir="${bin}"/>
<fileset file="${src}/main/resources/plugin.yml"/>
<fileset file="${src}/main/resources/configuration.txt"/>
<fileset file="${src}/main/resources/custom-lightings.txt"/>
<fileset file="${src}/main/resources/custom-perspectives.txt"/>
<fileset file="${src}/main/resources/custom-shaders.txt"/>
<fileset file="${src}/main/resources/lightings.txt"/>
<fileset file="${src}/main/resources/models.txt"/>
<fileset file="${src}/main/resources/perspectives.txt"/>
<fileset file="${src}/main/resources/texture.txt"/>
<fileset file="${src}/main/resources/worlds.txt"/>
<zipfileset file="${src}/main/resources/colors.txt"/>
</jar>
</target>
<target name="deploy" depends="dist">
<copy file="${dist}/${pluginname}.jar" todir="${plugins}"/>
<copy todir="${http_root}">
<fileset dir="web"/>
</copy>
</target>
<target name="release" depends="dist">
<delete file="${pluginname}.zip"/>
<zip destfile="${pluginname}.zip">
<zipfileset dir="." includes="README.md" fullpath="readme.txt"/>
<zipfileset dir="." includes="build.xml"/>
<zipfileset dir="${dist}" includes="*.jar"/>
<zipfileset dir="${src}" includes="*.java" prefix="src/"/>
<zipfileset dir="${web}" includes="**" prefix="web/"/>
</zip>
</target>
<target name="clean">
<delete dir="${bin}"/>
<delete dir="${dist}"/>
</target>
</project>

View File

@ -1,6 +0,0 @@
<project name="dynmap_parameters" basedir=".">
<property name="bukkit.jar" location="../../bukkit.jar"/>
<property name="minecraft" location="../../"/>
<property name="plugins" location="${minecraft}/plugins/"/>
<property name="http_root" location="/srv/http/dynmap/"/>
</project>

View File

@ -1,340 +0,0 @@
Stone
1 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Grass
2 117 176 73 255 93 140 58 255 58 88 36 255 46 70 29 255
Dirt
3 134 96 67 255 107 76 53 255 67 48 33 255 53 38 26 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
Sapling
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 38 92 255 51 30 73 204 51 19 46 127 51 15 36 102 51
Stationary Water
9 38 92 255 51 30 73 204 51 19 46 127 51 15 36 102 51
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 218 210 158 255 174 168 126 255 109 105 79 255 87 84 63 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 - Normal
17 102 81 51 255 125 102 63 255 78 64 39 255 40 32 20 255
17:0 102 81 51 255 125 102 63 255 78 64 39 255 40 32 20 255
Wood - Spruce (Red/dark wood)
17:1 75 44 24 255 125 102 63 255 78 64 39 255 30 18 10 255
Wood - Birch (light wood)
17:2 191 191 191 255 125 102 63 255 78 64 39 255 76 76 76 255
Leaves
18 60 192 41 100 48 153 32 100 30 96 20 100 24 76 16 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 218 210 158 255 174 168 126 255 109 105 79 255 87 84 63 255
Note Block
25 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
Bed
26 200 20 20 255 160 16 16 255 100 10 10 255 80 8 8 255
Powered Rail
27 150 134 102 180 120 107 81 180 75 67 51 180 60 53 40 180
Detector Rail
28 150 134 102 180 120 107 81 180 75 67 51 180 60 53 40 180
Sticky Piston
29 157 128 79 255 96 96 96 255 78 64 39 255 48 48 48 255
Cobweb
30 138 145 145 255 110 115 115 255 69 72 72 255 55 57 57 255
Tall Grass
31 97 156 53 255 73 120 38 255 38 68 16 255 26 50 9 255
Dead Shrubs
32 75 44 24 255 60 35 19 255 37 22 12 255 30 18 10 255
Piston
33 157 128 79 255 96 96 96 255 78 64 39 255 48 48 48 255
Piston Head
34 157 128 79 255 96 96 96 255 78 64 39 255 48 48 48 255
Wool
35 222 222 222 255 177 177 177 255 111 111 111 255 88 88 88 255
35:0 222 222 222 255 177 177 177 255 111 111 111 255 88 88 88 255
Wool - Orange
35:1 204 111 48 255 162 89 38 255 102 56 24 255 81 44 19 255
Wool - Magenta
35:2 166 66 175 255 133 53 140 255 83 33 87 255 66 26 69 255
Wool - Light Blue
35:3 91 121 185 255 73 96 147 255 46 61 92 255 36 48 73 255
Wool - Yellow
35:4 170 158 24 255 135 126 19 255 85 79 12 255 67 62 10 255
Wool - Light Green
35:5 51 165 42 255 41 131 33 255 26 82 21 255 20 65 17 255
Wool - Pink
35:6 190 115 135 255 151 92 108 255 95 57 67 255 75 46 53 255
Wool - Gray
35:7 58 58 58 255 47 47 47 255 29 29 29 255 23 23 23 255
Wool - Light Gray
35:8 138 145 145 255 110 115 115 255 69 72 72 255 55 57 57 255
Wool - Cyan
35:9 34 102 131 255 27 81 104 255 17 51 65 255 13 40 52 255
Wool - Purple
35:10 113 47 171 255 90 37 136 255 57 24 85 255 45 19 68 255
Wool - Blue
35:11 34 44 134 255 27 35 107 255 17 22 67 255 13 18 53 255
Wool - Brown
35:12 75 44 24 255 60 35 19 255 37 22 12 255 30 18 10 255
Wool - Dark Green
35:13 49 67 21 255 39 53 17 255 24 34 10 255 19 27 8 255
Wool - Red
35:14 143 39 36 255 114 31 28 255 71 20 18 255 57 16 14 255
Wool - Black
35:15 24 20 20 255 19 16 16 255 12 10 10 255 9 8 8 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
43:0 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
43:6 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
Double Stone Slab - Sandstone
43:1 218 210 158 255 174 168 126 255 109 105 79 255 87 84 63 255
Double Stone Slab - Wood
43:2 157 128 79 255 125 102 63 255 78 64 39 255 62 51 31 255
Double Stone Slab - Cobblestone
43:3 115 115 115 255 92 92 92 255 57 57 57 255 46 46 46 255
Double Stone Slab - Brick
43:4 170 86 62 255 136 68 49 255 85 43 31 255 68 34 24 255
Double Stone Slab - Stone Brick
43:5 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
44:0 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
44:6 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
Stone Slab - Sandstone
44:1 218 210 158 255 174 168 126 255 109 105 79 255 87 84 63 255
Stone Slab - Wood
44:2 157 128 79 255 125 102 63 255 78 64 39 255 62 51 31 255
Stone Slab - Cobblestone
44:3 115 115 115 255 92 92 92 255 57 57 57 255 46 46 46 255
Stone Slab - Brick
44:4 170 86 62 255 136 68 49 255 85 43 31 255 68 34 24 255
Stone Slab - Stone Brick
44:5 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
47 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
53:4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Chest
54 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
Redstone Wire
55 240 30 30 64 160 20 20 64 120 15 15 64 100 12 12 64
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
Wall Sign
68 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255
Lever
69 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255
Stone Pressure Plate
70 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Iron Door
71 191 191 191 255 152 152 152 255 95 95 95 255 76 76 76 255
Wooden Pressure Plate
72 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 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
Stone Button
77 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
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
Redstone Repeater off
93 159 127 80 255 72 56 25 0 181 140 64 255 144 112 51 0
Redstone Repeater on
94 159 127 80 255 102 0 0 0 255 0 0 255 204 0 0 0
Locked Chest
95 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
Trap Door
96 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255
Stone - Sliverfish
97 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Stone Brick
98 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Huge Brown Mushroom
99 204 153 120 255 145 109 85 255 114 86 67 255 73 64 58 255
Huge Red Mushroom
100 255 43 43 255 196 29 38 255 186 105 109 255 124 64 64 255
Iron Bars
101 191 191 191 96 152 152 152 96 95 95 95 96 76 76 76 96
Glass Pane
102 255 255 255 64 204 204 204 64 127 127 127 64 102 102 102 64
Melon
103 193 193 65 255 174 174 47 255 97 97 5 255 76 76 20 255
Pumpkin Stem
104 146 192 0 255 116 153 0 255 73 96 0 255 58 76 0 255
Melon Stem
105 146 192 0 255 116 153 0 255 73 96 0 255 58 76 0 255
Vines
106 60 192 41 100 48 153 32 100 30 96 20 100 24 76 16 100
Fence Gate
107 127 98 49 96 95 72 33 96 48 34 9 96 32 21 21 96
Brick Stairs
108 170 86 62 255 136 68 49 255 85 43 31 255 68 34 24 255
Stone Stairs
109 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Mycelium
110 110 98 104 255 88 78 83 255 55 49 52 255 44 39 42 255
Lilly pad
111 117 176 73 255 93 140 58 255 58 88 36 255 46 70 29 255
Nether brick
112 166 89 89 255 141 80 62 255 135 15 15 255 96 6 6 255
Nether brick fence
113 166 89 89 96 141 80 62 96 135 15 15 96 96 6 6 96
Nether brick stairs
114 166 89 89 255 141 80 62 255 135 15 15 255 96 6 6 255
Nether Wart
115 142 19 21 96 113 15 17 96 71 10 10 96 57 7 8 96
Enchantment table
116 88 23 22 255 29 10 16 255 17 7 10 255 15 5 8 255
Brewing stand
117 114 114 114 96 91 91 91 96 67 67 67 96 46 46 46 96
Cauldron
118 74 74 74 255 59 59 59 255 37 37 37 255 30 30 30 255
Air portal
119 26 11 43 255 20 8 34 255 13 5 21 255 10 4 17 255
Air portal frame
120 113 133 104 255 90 106 83 255 56 66 52 255 45 54 42 255
White stone
121 224 226 169 255 179 180 135 255 112 113 85 255 90 90 66 255
Dragon Egg
122 26 11 43 255 20 8 34 255 13 5 21 255 10 4 17 255
Biome Mapping
[RAINFOREST] 49 67 21 255 39 54 17 255 25 34 11 255 20 27 8 255
[SWAMPLAND] 64 128 0 255 51 102 0 255 32 64 0 255 26 51 0 255
[SEASONAL_FOREST] 51 165 42 255 41 132 34 255 26 83 21 255 20 66 17 255
[FOREST] 0 128 64 255 0 102 51 255 0 64 32 255 0 51 26 255
[SAVANNA] 58 58 58 255 46 46 46 255 29 29 29 255 23 23 23 255
[SHRUBLAND] 170 158 24 255 136 126 19 255 85 79 12 255 68 63 10 255
[TAIGA] 204 255 102 255 163 204 82 255 102 128 51 255 82 102 41 255
[DESERT] 255 255 102 255 204 204 82 255 128 128 51 255 102 102 41 255
[PLAINS] 255 204 102 255 204 163 82 255 128 102 51 255 102 82 41 255
[ICE_DESERT] 26 33 103 255 21 26 82 255 13 17 52 255 10 13 41 255
[TUNDRA] 222 222 222 255 178 178 178 255 111 111 111 255 89 89 89 255
[HELL] 255 0 0 255 204 0 0 255 128 0 0 255 102 0 0 255
[SKY] 102 204 255 255 82 163 204 255 51 102 128 255 41 82 102 255
[OCEAN] 0 0 255 255 0 0 204 255 0 0 128 255 0 0 102 255
[RIVER] 0 128 255 255 0 102 204 255 0 64 128 255 0 51 102 255
[EXTREME_HILLS] 128 64 0 255 102 51 0 255 64 32 0 255 51 26 0 255
[FROZEN_OCEAN] 102 255 204 255 82 204 163 255 51 128 102 255 41 102 82 255
[FROZEN_RIVER] 102 102 255 255 82 82 204 255 51 51 128 255 41 41 102 255
[ICE_PLAINS] 102 255 255 255 82 204 204 255 51 128 128 255 41 102 102 255
[ICE_MOUNTAINS] 255 255 255 255 204 204 204 255 128 128 128 255 102 102 102 255
[MUSHROOM_ISLAND] 255 111 207 255 204 89 166 255 128 56 104 255 102 44 83 255
[MUSHROOM_SHORE] 255 0 128 255 204 0 102 255 128 0 64 255 102 0 51 255
[BEACH] 255 206 75 255 230 185 68 255 255 206 75 255 179 144 53 255
[DESERT_HILLS] 255 146 51 255 230 131 46 255 255 146 51 255 179 102 36 255
[FOREST_HILLS] 0 162 100 255 0 146 90 255 0 162 100 255 0 113 70 255
[TAIGA_HILLS] 178 212 117 255 160 191 105 255 178 212 117 255 125 148 82 255
[SMALL_MOUNTAINS] 184 103 33 255 166 93 30 255 184 103 33 255 129 72 23 255
Rainfall/Temperature Mapping
[RAINFALL-0.0] 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
[RAINFALL-1.0] 38 92 255 255 30 73 204 255 19 46 127 255 15 36 102 255
[TEMPERATURE-0.0] 38 92 255 255 30 73 204 255 19 46 127 255 15 36 102 255
[TEMPERATURE-0.5] 91 121 185 255 73 96 147 255 46 61 92 255 36 48 73 255
[TEMPERATURE-0.8] 51 165 42 255 41 131 33 255 26 82 21 255 20 65 17 255
[TEMPERATURE-0.9] 170 158 24 255 135 126 19 255 85 79 12 255 67 62 10 255
[TEMPERATURE-0.95] 204 111 48 255 162 89 38 255 102 56 24 255 81 44 19 255
[TEMPERATURE-1.0] 143 39 36 255 114 31 28 255 71 20 18 255 57 16 14 255

View File

@ -1,340 +0,0 @@
Stone
1 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Grass
2 60 113 17 255 50 94 14 255 42 79 12 255 50 94 14 255
Dirt
3 134 96 67 255 107 76 53 255 67 48 33 255 53 38 26 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
Sapling
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 38 92 255 51 30 73 204 51 19 46 127 51 15 36 102 51
Stationary Water
9 38 92 255 51 30 73 204 51 19 46 127 51 15 36 102 51
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 218 210 158 255 174 168 126 255 109 105 79 255 87 84 63 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 - Normal
17 102 81 51 255 125 102 63 255 78 64 39 255 40 32 20 255
17:0 102 81 51 255 125 102 63 255 78 64 39 255 40 32 20 255
Wood - Spruce (Red/dark wood)
17:1 75 44 24 255 125 102 63 255 78 64 39 255 30 18 10 255
Wood - Birch (light wood)
17:2 191 191 191 255 125 102 63 255 78 64 39 255 76 76 76 255
Leaves
18 27 69 37 180 22 57 31 180 19 48 25 180 22 57 31 180
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 192 178 110 255 160 148 92 255 134 124 77 255 160 148 92 255
Note Block
25 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
Bed
26 200 20 20 255 160 16 16 255 100 10 10 255 80 8 8 255
Powered Rail
27 150 134 102 180 120 107 81 180 75 67 51 180 60 53 40 180
Detector Rail
28 150 134 102 180 120 107 81 180 75 67 51 180 60 53 40 180
Sticky Piston
29 157 128 79 255 96 96 96 255 78 64 39 255 48 48 48 255
Cobweb
30 138 145 145 255 110 115 115 255 69 72 72 255 55 57 57 255
Tall Grass
31 97 156 53 255 73 120 38 255 38 68 16 255 26 50 9 255
Dead Shrubs
32 75 44 24 255 60 35 19 255 37 22 12 255 30 18 10 255
Piston
33 157 128 79 255 96 96 96 255 78 64 39 255 48 48 48 255
Piston Head
34 157 128 79 255 96 96 96 255 78 64 39 255 48 48 48 255
Wool
35 247 255 239 255 244 251 236 255 204 210 197 255 244 251 236 255
35:0 247 255 239 255 244 251 236 255 204 210 197 255 244 251 236 255
Wool - Orange
35:1 227 128 52 255 224 126 51 255 187 105 42 255 224 126 51 255
Wool - Magenta
35:2 185 76 188 255 183 75 186 255 153 63 155 255 183 75 186 255
Wool - Light Blue
35:3 102 139 199 255 100 137 196 255 84 114 164 255 100 137 196 255
Wool - Yellow
35:4 189 181 26 255 187 178 26 255 156 149 22 255 187 178 26 255
Wool - Light Green
35:5 57 189 45 255 56 186 44 255 47 156 37 255 56 186 44 255
Wool - Pink
35:6 211 132 145 255 209 130 143 255 174 109 120 255 209 130 143 255
Wool - Gray
35:7 65 67 63 255 64 66 62 255 54 55 52 255 64 66 62 255
Wool - Light Gray
35:8 154 166 156 255 152 163 154 255 127 137 128 255 152 163 154 255
Wool - Cyan
35:9 38 117 141 255 37 115 139 255 31 96 116 255 37 115 139 255
Wool - Purple
35:10 126 54 184 255 124 53 181 255 104 44 151 255 124 53 181 255
Wool - Blue
35:11 38 51 144 255 37 50 143 255 31 42 119 255 37 50 143 255
Wool - Brown
35:12 83 51 26 255 82 50 26 255 69 42 22 255 82 50 26 255
Wool - Dark Green
35:13 54 77 22 255 54 76 22 255 45 63 19 255 54 76 22 255
Wool - Red
35:14 159 45 38 255 157 44 38 255 131 37 32 255 157 44 38 255
Wool - Black
35:15 26 23 22 255 26 23 21 255 22 19 18 255 26 23 21 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
43:0 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
43:6 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
Double Stone Slab - Sandstone
43:1 192 178 110 255 160 148 92 255 134 124 77 255 160 148 92 255
Double Stone Slab - Wood
43:2 157 128 79 255 125 102 63 255 78 64 39 255 62 51 31 255
Double Stone Slab - Cobblestone
43:3 115 115 115 255 92 92 92 255 57 57 57 255 46 46 46 255
Double Stone Slab - Brick
43:4 170 86 62 255 136 68 49 255 85 43 31 255 68 34 24 255
Double Stone Slab - Stone Brick
43:5 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
44:0 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
44:6 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
Stone Slab - Sandstone
44:1 192 178 110 255 160 148 92 255 134 124 77 255 160 148 92 255
Stone Slab - Wood
44:2 157 128 79 255 125 102 63 255 78 64 39 255 62 51 31 255
Stone Slab - Cobblestone
44:3 115 115 115 255 92 92 92 255 57 57 57 255 46 46 46 255
Stone Slab - Brick
44:4 170 86 62 255 136 68 49 255 85 43 31 255 68 34 24 255
Stone Slab - Stone Brick
44:5 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
47 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
53:4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Chest
54 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
Redstone Wire
55 240 30 30 64 160 20 20 64 120 15 15 64 100 12 12 64
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
Wall Sign
68 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255
Lever
69 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255
Stone Pressure Plate
70 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Iron Door
71 191 191 191 255 152 152 152 255 95 95 95 255 76 76 76 255
Wooden Pressure Plate
72 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 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
Stone Button
77 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
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
Redstone Repeater off
93 159 127 80 255 72 56 25 0 181 140 64 255 144 112 51 0
Redstone Repeater on
94 159 127 80 255 102 0 0 0 255 0 0 255 204 0 0 0
Locked Chest
95 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
Trap Door
96 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255
Stone - Sliverfish
97 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Stone Brick
98 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Huge Brown Mushroom
99 204 153 120 255 145 109 85 255 114 86 67 255 73 64 58 255
Huge Red Mushroom
100 255 43 43 255 196 29 38 255 186 105 109 255 124 64 64 255
Iron Bars
101 191 191 191 96 152 152 152 96 95 95 95 96 76 76 76 96
Glass Pane
102 255 255 255 64 204 204 204 64 127 127 127 64 102 102 102 64
Melon
103 193 193 65 255 174 174 47 255 97 97 5 255 76 76 20 255
Pumpkin Stem
104 146 192 0 255 116 153 0 255 73 96 0 255 58 76 0 255
Melon Stem
105 146 192 0 255 116 153 0 255 73 96 0 255 58 76 0 255
Vines
106 60 192 41 100 48 153 32 100 30 96 20 100 24 76 16 100
Fence Gate
107 127 98 49 96 95 72 33 96 48 34 9 96 32 21 21 96
Brick Stairs
108 170 86 62 255 136 68 49 255 85 43 31 255 68 34 24 255
Stone Stairs
109 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Mycelium
110 110 98 104 255 88 78 83 255 55 49 52 255 44 39 42 255
Lilly pad
111 117 176 73 255 93 140 58 255 58 88 36 255 46 70 29 255
Nether brick
112 166 89 89 255 141 80 62 255 135 15 15 255 96 6 6 255
Nether brick fence
113 166 89 89 96 141 80 62 96 135 15 15 96 96 6 6 96
Nether brick stairs
114 166 89 89 255 141 80 62 255 135 15 15 255 96 6 6 255
Nether Wart
115 142 19 21 96 113 15 17 96 71 10 10 96 57 7 8 96
Enchantment table
116 88 23 22 255 29 10 16 255 17 7 10 255 15 5 8 255
Brewing stand
117 114 114 114 96 91 91 91 96 67 67 67 96 46 46 46 96
Cauldron
118 74 74 74 255 59 59 59 255 37 37 37 255 30 30 30 255
Air portal
119 26 11 43 255 20 8 34 255 13 5 21 255 10 4 17 255
Air portal frame
120 113 133 104 255 90 106 83 255 56 66 52 255 45 54 42 255
White stone
121 224 226 169 255 179 180 135 255 112 113 85 255 90 90 66 255
Dragon Egg
122 26 11 43 255 20 8 34 255 13 5 21 255 10 4 17 255
Biome Mapping
[RAINFOREST] 49 67 21 255 39 54 17 255 25 34 11 255 20 27 8 255
[SWAMPLAND] 64 128 0 255 51 102 0 255 32 64 0 255 26 51 0 255
[SEASONAL_FOREST] 51 165 42 255 41 132 34 255 26 83 21 255 20 66 17 255
[FOREST] 0 128 64 255 0 102 51 255 0 64 32 255 0 51 26 255
[SAVANNA] 58 58 58 255 46 46 46 255 29 29 29 255 23 23 23 255
[SHRUBLAND] 170 158 24 255 136 126 19 255 85 79 12 255 68 63 10 255
[TAIGA] 204 255 102 255 163 204 82 255 102 128 51 255 82 102 41 255
[DESERT] 255 255 102 255 204 204 82 255 128 128 51 255 102 102 41 255
[PLAINS] 255 204 102 255 204 163 82 255 128 102 51 255 102 82 41 255
[ICE_DESERT] 26 33 103 255 21 26 82 255 13 17 52 255 10 13 41 255
[TUNDRA] 222 222 222 255 178 178 178 255 111 111 111 255 89 89 89 255
[HELL] 255 0 0 255 204 0 0 255 128 0 0 255 102 0 0 255
[SKY] 102 204 255 255 82 163 204 255 51 102 128 255 41 82 102 255
[OCEAN] 0 0 255 255 0 0 204 255 0 0 128 255 0 0 102 255
[RIVER] 0 128 255 255 0 102 204 255 0 64 128 255 0 51 102 255
[EXTREME_HILLS] 128 64 0 255 102 51 0 255 64 32 0 255 51 26 0 255
[FROZEN_OCEAN] 102 255 204 255 82 204 163 255 51 128 102 255 41 102 82 255
[FROZEN_RIVER] 102 102 255 255 82 82 204 255 51 51 128 255 41 41 102 255
[ICE_PLAINS] 102 255 255 255 82 204 204 255 51 128 128 255 41 102 102 255
[ICE_MOUNTAINS] 255 255 255 255 204 204 204 255 128 128 128 255 102 102 102 255
[MUSHROOM_ISLAND] 255 111 207 255 204 89 166 255 128 56 104 255 102 44 83 255
[MUSHROOM_SHORE] 255 0 128 255 204 0 102 255 128 0 64 255 102 0 51 255
[BEACH] 255 206 75 255 230 185 68 255 255 206 75 255 179 144 53 255
[DESERT_HILLS] 255 146 51 255 230 131 46 255 255 146 51 255 179 102 36 255
[FOREST_HILLS] 0 162 100 255 0 146 90 255 0 162 100 255 0 113 70 255
[TAIGA_HILLS] 178 212 117 255 160 191 105 255 178 212 117 255 125 148 82 255
[SMALL_MOUNTAINS] 184 103 33 255 166 93 30 255 184 103 33 255 129 72 23 255
Rainfall/Temperature Mapping
[RAINFALL-0.0] 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
[RAINFALL-1.0] 38 92 255 255 30 73 204 255 19 46 127 255 15 36 102 255
[TEMPERATURE-0.0] 38 92 255 255 30 73 204 255 19 46 127 255 15 36 102 255
[TEMPERATURE-0.5] 91 121 185 255 73 96 147 255 46 61 92 255 36 48 73 255
[TEMPERATURE-0.8] 51 165 42 255 41 131 33 255 26 82 21 255 20 65 17 255
[TEMPERATURE-0.9] 170 158 24 255 135 126 19 255 85 79 12 255 67 62 10 255
[TEMPERATURE-0.95] 204 111 48 255 162 89 38 255 102 56 24 255 81 44 19 255
[TEMPERATURE-1.0] 143 39 36 255 114 31 28 255 71 20 18 255 57 16 14 255

View File

@ -1,340 +0,0 @@
Stone
1 149 145 138 255 125 122 116 255 114 111 105 255 88 85 81 255
Grass
2 111 185 79 255 86 158 53 255 65 131 40 255 57 105 21 255
Dirt
3 174 133 106 255 152 113 82 255 136 102 74 255 93 73 57 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 47 116 160 80 40 100 138 80 33 92 129 80 26 74 103 80
Stationary Water
9 47 116 160 80 40 100 138 80 33 92 129 80 26 74 103 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 251 240 193 255 251 223 157 255 237 202 135 255 200 168 107 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 - Normal
17 102 81 51 255 125 102 63 255 78 64 39 255 40 32 20 255
17:0 102 81 51 255 125 102 63 255 78 64 39 255 40 32 20 255
Wood - Spruce (Red/dark wood)
17:1 75 44 24 255 125 102 63 255 78 64 39 255 30 18 10 255
Wood - Birch (light wood)
17:2 191 191 191 255 125 102 63 255 78 64 39 255 76 76 76 255
Leaves
18 47 99 32 255 34 86 20 255 24 66 14 255 23 57 13 255
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 251 240 193 255 251 223 157 255 237 202 135 255 200 168 107 255
Note Block
25 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
Bed
26 200 20 20 255 160 16 16 255 100 10 10 255 80 8 8 255
Powered Rail
27 150 134 102 180 120 107 81 180 75 67 51 180 60 53 40 180
Detector Rail
28 150 134 102 180 120 107 81 180 75 67 51 180 60 53 40 180
Sticky Piston
29 157 128 79 255 125 122 116 255 78 64 39 255 88 85 81 255
Cobweb
30 138 145 145 255 110 115 115 255 69 72 72 255 55 57 57 255
Tall Grass
31 111 185 79 255 86 158 53 255 65 131 40 255 57 105 21 255
Dead Shrubs
32 75 44 24 255 60 35 19 255 37 22 12 255 30 18 10 255
Piston
33 157 128 79 255 125 122 116 255 78 64 39 255 88 85 81 255
Piston Head
34 157 128 79 255 125 122 116 255 78 64 39 255 88 85 81 255
Wool
35 222 222 222 255 177 177 177 255 111 111 111 255 88 88 88 255
35:0 222 222 222 255 177 177 177 255 111 111 111 255 88 88 88 255
Wool - Orange
35:1 204 111 48 255 162 89 38 255 102 56 24 255 81 44 19 255
Wool - Magenta
35:2 166 66 175 255 133 53 140 255 83 33 87 255 66 26 69 255
Wool - Light Blue
35:3 91 121 185 255 73 96 147 255 46 61 92 255 36 48 73 255
Wool - Yellow
35:4 170 158 24 255 135 126 19 255 85 79 12 255 67 62 10 255
Wool - Light Green
35:5 51 165 42 255 41 131 33 255 26 82 21 255 20 65 17 255
Wool - Pink
35:6 190 115 135 255 151 92 108 255 95 57 67 255 75 46 53 255
Wool - Gray
35:7 58 58 58 255 47 47 47 255 29 29 29 255 23 23 23 255
Wool - Light Gray
35:8 138 145 145 255 110 115 115 255 69 72 72 255 55 57 57 255
Wool - Cyan
35:9 34 102 131 255 27 81 104 255 17 51 65 255 13 40 52 255
Wool - Purple
35:10 113 47 171 255 90 37 136 255 57 24 85 255 45 19 68 255
Wool - Blue
35:11 34 44 134 255 27 35 107 255 17 22 67 255 13 18 53 255
Wool - Brown
35:12 75 44 24 255 60 35 19 255 37 22 12 255 30 18 10 255
Wool - Dark Green
35:13 49 67 21 255 39 53 17 255 24 34 10 255 19 27 8 255
Wool - Red
35:14 143 39 36 255 114 31 28 255 71 20 18 255 57 16 14 255
Wool - Black
35:15 24 20 20 255 19 16 16 255 12 10 10 255 9 8 8 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
43:0 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
43:6 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
Double Stone Slab - Sandstone
43:1 218 210 158 255 174 168 126 255 109 105 79 255 87 84 63 255
Double Stone Slab - Wood
43:2 157 128 79 255 125 102 63 255 78 64 39 255 62 51 31 255
Double Stone Slab - Cobblestone
43:3 115 115 115 255 92 92 92 255 57 57 57 255 46 46 46 255
Double Stone Slab - Brick
43:4 170 86 62 255 136 68 49 255 85 43 31 255 68 34 24 255
Double Stone Slab - Stone Brick
43:5 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
44:0 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
44:6 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
Stone Slab - Sandstone
44:1 218 210 158 255 174 168 126 255 109 105 79 255 87 84 63 255
Stone Slab - Wood
44:2 157 128 79 255 125 102 63 255 78 64 39 255 62 51 31 255
Stone Slab - Cobblestone
44:3 115 115 115 255 92 92 92 255 57 57 57 255 46 46 46 255
Stone Slab - Brick
44:4 170 86 62 255 136 68 49 255 85 43 31 255 68 34 24 255
Stone Slab - Stone Brick
44:5 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
47 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 103 80 45 255 98 88 20 0 255 249 79 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
53:4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Chest
54 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
Redstone Wire
55 240 30 30 64 160 20 20 64 120 15 15 64 100 12 12 64
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
Wall Sign
68 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255
Lever
69 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255
Stone Pressure Plate
70 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Iron Door
71 191 191 191 255 152 152 152 255 95 95 95 255 76 76 76 255
Wooden Pressure Plate
72 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 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
Stone Button
77 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Snow
78 255 255 255 255 252 253 253 255 198 220 225 255 129 179 190 255
Ice
79 182 211 235 150 164 189 211 150 138 177 211 150 128 165 196 150
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
Redstone Repeater off
93 159 127 80 255 72 56 25 0 181 140 64 255 144 112 51 0
Redstone Repeater on
94 159 127 80 255 102 0 0 0 255 0 0 255 204 0 0 0
Locked Chest
95 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
Trap Door
96 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255
Stone - Sliverfish
97 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Stone Brick
98 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Huge Brown Mushroom
99 204 153 120 255 145 109 85 255 114 86 67 255 73 64 58 255
Huge Red Mushroom
100 255 43 43 255 196 29 38 255 186 105 109 255 124 64 64 255
Iron Bars
101 191 191 191 96 152 152 152 96 95 95 95 96 76 76 76 96
Glass Pane
102 255 255 255 64 204 204 204 64 127 127 127 64 102 102 102 64
Melon
103 193 193 65 255 174 174 47 255 97 97 5 255 76 76 20 255
Pumpkin Stem
104 146 192 0 255 116 153 0 255 73 96 0 255 58 76 0 255
Melon Stem
105 146 192 0 255 116 153 0 255 73 96 0 255 58 76 0 255
Vines
106 60 192 41 100 48 153 32 100 30 96 20 100 24 76 16 100
Fence Gate
107 127 98 49 96 95 72 33 96 48 34 9 96 32 21 21 96
Brick Stairs
108 170 86 62 255 136 68 49 255 85 43 31 255 68 34 24 255
Stone Stairs
109 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
Mycelium
110 110 98 104 255 88 78 83 255 55 49 52 255 44 39 42 255
Lilly pad
111 117 176 73 255 93 140 58 255 58 88 36 255 46 70 29 255
Nether brick
112 166 89 89 255 141 80 62 255 135 15 15 255 96 6 6 255
Nether brick fence
113 166 89 89 96 141 80 62 96 135 15 15 96 96 6 6 96
Nether brick stairs
114 166 89 89 255 141 80 62 255 135 15 15 255 96 6 6 255
Nether Wart
115 142 19 21 96 113 15 17 96 71 10 10 96 57 7 8 96
Enchantment table
116 88 23 22 255 29 10 16 255 17 7 10 255 15 5 8 255
Brewing stand
117 114 114 114 96 91 91 91 96 67 67 67 96 46 46 46 96
Cauldron
118 74 74 74 255 59 59 59 255 37 37 37 255 30 30 30 255
Air portal
119 26 11 43 255 20 8 34 255 13 5 21 255 10 4 17 255
Air portal frame
120 113 133 104 255 90 106 83 255 56 66 52 255 45 54 42 255
White stone
121 224 226 169 255 179 180 135 255 112 113 85 255 90 90 66 255
Dragon Egg
122 26 11 43 255 20 8 34 255 13 5 21 255 10 4 17 255
Biome Mapping
[RAINFOREST] 49 67 21 255 39 54 17 255 25 34 11 255 20 27 8 255
[SWAMPLAND] 64 128 0 255 51 102 0 255 32 64 0 255 26 51 0 255
[SEASONAL_FOREST] 51 165 42 255 41 132 34 255 26 83 21 255 20 66 17 255
[FOREST] 0 128 64 255 0 102 51 255 0 64 32 255 0 51 26 255
[SAVANNA] 58 58 58 255 46 46 46 255 29 29 29 255 23 23 23 255
[SHRUBLAND] 170 158 24 255 136 126 19 255 85 79 12 255 68 63 10 255
[TAIGA] 204 255 102 255 163 204 82 255 102 128 51 255 82 102 41 255
[DESERT] 255 255 102 255 204 204 82 255 128 128 51 255 102 102 41 255
[PLAINS] 255 204 102 255 204 163 82 255 128 102 51 255 102 82 41 255
[ICE_DESERT] 26 33 103 255 21 26 82 255 13 17 52 255 10 13 41 255
[TUNDRA] 222 222 222 255 178 178 178 255 111 111 111 255 89 89 89 255
[HELL] 255 0 0 255 204 0 0 255 128 0 0 255 102 0 0 255
[SKY] 102 204 255 255 82 163 204 255 51 102 128 255 41 82 102 255
[OCEAN] 0 0 255 255 0 0 204 255 0 0 128 255 0 0 102 255
[RIVER] 0 128 255 255 0 102 204 255 0 64 128 255 0 51 102 255
[EXTREME_HILLS] 128 64 0 255 102 51 0 255 64 32 0 255 51 26 0 255
[FROZEN_OCEAN] 102 255 204 255 82 204 163 255 51 128 102 255 41 102 82 255
[FROZEN_RIVER] 102 102 255 255 82 82 204 255 51 51 128 255 41 41 102 255
[ICE_PLAINS] 102 255 255 255 82 204 204 255 51 128 128 255 41 102 102 255
[ICE_MOUNTAINS] 255 255 255 255 204 204 204 255 128 128 128 255 102 102 102 255
[MUSHROOM_ISLAND] 255 111 207 255 204 89 166 255 128 56 104 255 102 44 83 255
[MUSHROOM_SHORE] 255 0 128 255 204 0 102 255 128 0 64 255 102 0 51 255
[BEACH] 255 206 75 255 230 185 68 255 255 206 75 255 179 144 53 255
[DESERT_HILLS] 255 146 51 255 230 131 46 255 255 146 51 255 179 102 36 255
[FOREST_HILLS] 0 162 100 255 0 146 90 255 0 162 100 255 0 113 70 255
[TAIGA_HILLS] 178 212 117 255 160 191 105 255 178 212 117 255 125 148 82 255
[SMALL_MOUNTAINS] 184 103 33 255 166 93 30 255 184 103 33 255 129 72 23 255
Rainfall/Temperature Mapping
[RAINFALL-0.0] 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
[RAINFALL-1.0] 38 92 255 255 30 73 204 255 19 46 127 255 15 36 102 255
[TEMPERATURE-0.0] 38 92 255 255 30 73 204 255 19 46 127 255 15 36 102 255
[TEMPERATURE-0.5] 91 121 185 255 73 96 147 255 46 61 92 255 36 48 73 255
[TEMPERATURE-0.8] 51 165 42 255 41 131 33 255 26 82 21 255 20 65 17 255
[TEMPERATURE-0.9] 170 158 24 255 135 126 19 255 85 79 12 255 67 62 10 255
[TEMPERATURE-0.95] 204 111 48 255 162 89 38 255 102 56 24 255 81 44 19 255
[TEMPERATURE-1.0] 143 39 36 255 114 31 28 255 71 20 18 255 57 16 14 255

View File

@ -1,191 +0,0 @@
1 133 129 118 255 111 108 98 255 93 90 82 255 111 108 98 255
2 60 113 17 255 50 94 14 255 42 79 12 255 50 94 14 255
3 103 83 51 255 86 69 43 255 72 58 36 255 86 69 43 255
4 118 112 96 255 98 93 80 255 82 78 67 255 98 93 80 255
5 109 80 60 255 91 67 50 255 76 56 41 255 91 67 50 255
7 79 79 82 255 66 66 68 255 55 55 57 255 66 66 68 255
8 94 170 255 51 82 148 223 51 69 124 186 51 82 148 223 51
9 94 170 255 51 82 148 223 51 69 124 186 51 82 148 223 51
10 255 164 41 255 255 164 41 255 212 137 34 255 255 164 41 255
11 255 164 41 255 255 164 41 255 212 137 34 255 255 164 41 255
12 192 178 110 255 160 148 92 255 134 124 77 255 160 148 92 255
13 120 105 79 255 100 87 66 255 84 73 55 255 100 87 66 255
14 255 181 38 255 255 181 38 255 212 151 31 255 255 181 38 255
15 231 174 113 255 193 145 94 255 161 121 79 255 193 145 94 255
16 56 60 70 255 46 50 58 255 39 42 49 255 46 50 58 255
17 119 97 74 255 99 81 62 255 83 68 52 255 99 81 62 255
17:0 119 97 74 255 99 81 62 255 83 68 52 255 99 81 62 255
17:1 75 44 24 255 125 102 63 255 78 64 39 255 30 18 10 255
17:2 191 191 191 255 125 102 63 255 78 64 39 255 76 76 76 255
18 27 69 37 180 22 57 31 180 19 48 25 180 22 57 31 180
19 193 193 65 255 174 174 47 255 97 97 5 255 76 76 20 255
20 178 217 223 90 148 181 186 90 124 151 155 90 148 181 186 90
21 23 68 196 255 18 56 158 255 14 43 122 255 14 43 78 255
22 23 68 196 255 18 56 158 255 14 43 122 255 14 43 78 255
23 96 96 96 255 76 76 76 255 48 48 48 255 38 38 38 255
24 192 178 110 255 160 148 92 255 134 124 77 255 160 148 92 255
25 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
26 200 20 20 255 160 16 16 255 100 10 10 255 80 8 8 255
27 150 134 102 180 120 107 81 180 75 67 51 180 60 53 40 180
28 150 134 102 180 120 107 81 180 75 67 51 180 60 53 40 180
29 109 80 60 255 111 108 98 255 76 56 41 255 111 108 98 255
30 138 145 145 255 110 115 115 255 69 72 72 255 55 57 57 255
31 97 156 53 255 73 120 38 255 38 68 16 255 26 50 9 255
32 75 44 24 255 60 35 19 255 37 22 12 255 30 18 10 255
33 109 80 60 255 111 108 98 255 76 56 41 255 111 108 98 255
34 109 80 60 255 111 108 98 255 76 56 41 255 111 108 98 255
35 247 255 239 255 244 251 236 255 204 210 197 255 244 251 236 255
35:0 247 255 239 255 244 251 236 255 204 210 197 255 244 251 236 255
35:1 227 128 52 255 224 126 51 255 187 105 42 255 224 126 51 255
35:2 185 76 188 255 183 75 186 255 153 63 155 255 183 75 186 255
35:3 102 139 199 255 100 137 196 255 84 114 164 255 100 137 196 255
35:4 189 181 26 255 187 178 26 255 156 149 22 255 187 178 26 255
35:5 57 189 45 255 56 186 44 255 47 156 37 255 56 186 44 255
35:6 211 132 145 255 209 130 143 255 174 109 120 255 209 130 143 255
35:7 65 67 63 255 64 66 62 255 54 55 52 255 64 66 62 255
35:8 154 166 156 255 152 163 154 255 127 137 128 255 152 163 154 255
35:9 38 117 141 255 37 115 139 255 31 96 116 255 37 115 139 255
35:10 126 54 184 255 124 53 181 255 104 44 151 255 124 53 181 255
35:11 38 51 144 255 37 50 143 255 31 42 119 255 37 50 143 255
35:12 83 51 26 255 82 50 26 255 69 42 22 255 82 50 26 255
35:13 54 77 22 255 54 76 22 255 45 63 19 255 54 76 22 255
35:14 159 45 38 255 157 44 38 255 131 37 32 255 157 44 38 255
35:15 26 23 22 255 26 23 21 255 22 19 18 255 26 23 21 255
37 73 108 60 254 61 90 50 254 51 75 42 254 61 90 50 254
38 84 139 187 254 70 116 155 254 59 97 130 254 70 116 155 254
39 184 144 0 254 153 119 0 254 128 100 0 254 153 119 0 254
40 201 17 17 254 168 14 14 254 140 12 12 254 168 14 14 254
41 247 255 239 255 244 251 236 255 204 210 197 255 244 251 236 255
42 249 249 249 255 207 207 207 255 173 173 173 255 207 207 207 255
43 122 112 99 255 101 93 82 255 85 78 69 255 101 93 82 255
43:0 122 112 99 255 101 93 82 255 85 78 69 255 101 93 82 255
43:1 192 178 110 255 160 148 92 255 134 124 77 255 160 148 92 255
43:2 109 80 60 255 91 67 50 255 76 56 41 255 91 67 50 255
43:3 118 112 96 255 98 93 80 255 82 78 67 255 98 93 80 255
43:4 170 86 62 255 136 68 49 255 85 43 31 255 68 34 24 255
43:5 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
43:6 122 112 99 255 101 93 82 255 85 78 69 255 101 93 82 255
44 122 112 99 254 101 93 82 254 85 78 69 254 101 93 82 254
44:0 122 112 99 254 101 93 82 254 85 78 69 254 101 93 82 254
44:1 192 178 110 255 160 148 92 255 134 124 77 255 160 148 92 255
44:2 109 80 60 255 91 67 50 255 76 56 41 255 91 67 50 255
44:3 118 112 96 255 98 93 80 255 82 78 67 255 98 93 80 255
44:4 170 86 62 255 136 68 49 255 85 43 31 255 68 34 24 255
44:5 200 200 200 255 160 160 160 255 100 100 100 255 80 80 80 255
44:6 122 112 99 254 101 93 82 254 85 78 69 254 101 93 82 254
45 230 103 73 255 192 86 61 255 160 71 50 255 192 86 61 255
46 255 79 30 255 231 72 27 255 193 60 22 255 231 72 27 255
47 125 91 38 192 100 72 30 192 62 45 19 192 50 36 15 192
48 96 108 70 255 80 90 58 255 67 75 49 255 80 90 58 255
49 83 67 83 255 69 56 69 255 58 47 58 255 69 56 69 255
50 255 203 58 200 255 203 58 200 212 169 48 200 255 203 58 200
51 255 170 30 200 255 170 30 200 212 141 25 200 255 170 30 200
52 255 228 52 255 255 228 52 255 212 190 43 255 255 228 52 255
53 145 109 80 255 121 91 67 255 101 76 56 255 121 91 67 255
53:4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
54 165 132 100 255 138 110 84 255 115 92 70 255 138 110 84 255
55 116 21 21 255 97 18 18 255 81 15 15 255 97 18 18 255
56 115 230 255 255 105 210 232 255 88 175 194 255 105 210 232 255
57 164 217 237 255 136 181 198 255 114 151 165 255 136 181 198 255
58 171 138 99 255 142 115 82 255 118 96 68 255 142 115 82 255
59 136 152 21 255 114 127 17 255 95 106 14 255 114 127 17 255
60 123 82 51 255 103 68 43 255 86 57 36 255 103 68 43 255
61 158 128 73 255 132 106 61 255 110 89 51 255 132 106 61 255
62 158 128 73 255 132 106 61 255 110 89 51 255 132 106 61 255
63 60 112 17 255 50 93 14 255 42 78 12 255 50 93 14 255
64 129 97 69 255 108 81 57 255 90 68 47 255 108 81 57 255
65 144 128 99 32 120 106 82 32 100 89 69 32 120 106 82 32
66 113 109 102 180 94 91 85 180 79 76 71 180 94 91 85 180
67 115 107 93 255 96 89 78 255 80 75 65 255 96 89 78 255
68 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255
69 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255
70 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
71 255 255 255 255 229 229 229 255 191 191 191 255 229 229 229 255
72 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255
73 174 107 107 255 145 89 89 255 121 75 75 255 145 89 89 255
74 174 107 107 255 145 89 89 255 121 75 75 255 145 89 89 255
75 255 140 61 254 217 119 52 254 181 99 43 254 217 119 52 254
76 255 0 0 254 255 0 0 254 212 0 0 254 255 0 0 254
77 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
78 237 248 255 254 237 248 255 254 198 207 212 254 237 248 255 254
79 166 222 255 55 166 222 255 55 139 185 212 55 166 222 255 55
80 237 248 255 255 237 248 255 255 198 207 212 255 237 248 255 255
81 116 167 80 255 97 139 67 255 81 116 56 255 97 139 67 255
82 234 240 255 255 216 221 235 255 180 185 196 255 216 221 235 255
83 136 167 74 255 114 139 62 255 95 116 52 255 114 139 62 255
84 116 97 80 255 97 81 67 255 81 68 55 255 97 81 67 255
85 115 99 63 255 96 82 52 255 80 69 44 255 96 82 52 255
86 255 115 0 200 204 92 0 200 126 57 0 200 102 46 0 200
87 166 89 89 255 141 80 62 255 135 15 15 255 96 6 6 255
88 133 109 94 255 121 97 82 255 90 70 57 255 79 59 46 255
89 249 212 156 255 255 188 94 255 192 143 70 255 122 91 44 255
90 140 0 196 128 120 0 196 128 140 0 196 128 120 0 196 128
91 255 115 0 255 204 92 0 255 126 57 0 255 102 46 0 255
92 234 234 234 255 210 210 210 255 203 203 203 255 190 190 190 255
93 159 127 80 255 72 56 25 0 181 140 64 255 144 112 51 0
94 159 127 80 255 102 0 0 0 255 0 0 255 204 0 0 0
95 125 91 38 255 100 72 30 255 62 45 19 255 50 36 15 255
96 111 91 54 255 88 72 43 255 55 45 27 255 44 36 21 255
97 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
98 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
99 204 153 120 255 145 109 85 255 114 86 67 255 73 64 58 255
100 255 43 43 255 196 29 38 255 186 105 109 255 124 64 64 255
101 191 191 191 96 152 152 152 96 95 95 95 96 76 76 76 96
102 255 255 255 64 204 204 204 64 127 127 127 64 102 102 102 64
103 193 193 65 255 174 174 47 255 97 97 5 255 76 76 20 255
104 146 192 0 255 116 153 0 255 73 96 0 255 58 76 0 255
105 146 192 0 255 116 153 0 255 73 96 0 255 58 76 0 255
106 60 192 41 100 48 153 32 100 30 96 20 100 24 76 16 100
107 127 98 49 96 95 72 33 96 48 34 9 96 32 21 21 96
108 170 86 62 255 136 68 49 255 85 43 31 255 68 34 24 255
109 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
110 110 98 104 255 88 78 83 255 55 49 52 255 44 39 42 255
111 117 176 73 255 93 140 58 255 58 88 36 255 46 70 29 255
112 166 89 89 255 141 80 62 255 135 15 15 255 96 6 6 255
113 166 89 89 96 141 80 62 96 135 15 15 96 96 6 6 96
114 166 89 89 255 141 80 62 255 135 15 15 255 96 6 6 255
115 142 19 21 96 113 15 17 96 71 10 10 96 57 7 8 96
116 88 23 22 255 29 10 16 255 17 7 10 255 15 5 8 255
117 114 114 114 96 91 91 91 96 67 67 67 96 46 46 46 96
118 74 74 74 255 59 59 59 255 37 37 37 255 30 30 30 255
119 26 11 43 255 20 8 34 255 13 5 21 255 10 4 17 255
120 113 133 104 255 90 106 83 255 56 66 52 255 45 54 42 255
121 224 226 169 255 179 180 135 255 112 113 85 255 90 90 66 255
122 26 11 43 255 20 8 34 255 13 5 21 255 10 4 17 255
Biome Mapping
[RAINFOREST] 49 67 21 255 39 54 17 255 25 34 11 255 20 27 8 255
[SWAMPLAND] 64 128 0 255 51 102 0 255 32 64 0 255 26 51 0 255
[SEASONAL_FOREST] 51 165 42 255 41 132 34 255 26 83 21 255 20 66 17 255
[FOREST] 0 128 64 255 0 102 51 255 0 64 32 255 0 51 26 255
[SAVANNA] 58 58 58 255 46 46 46 255 29 29 29 255 23 23 23 255
[SHRUBLAND] 170 158 24 255 136 126 19 255 85 79 12 255 68 63 10 255
[TAIGA] 204 255 102 255 163 204 82 255 102 128 51 255 82 102 41 255
[DESERT] 255 255 102 255 204 204 82 255 128 128 51 255 102 102 41 255
[PLAINS] 255 204 102 255 204 163 82 255 128 102 51 255 102 82 41 255
[ICE_DESERT] 26 33 103 255 21 26 82 255 13 17 52 255 10 13 41 255
[TUNDRA] 222 222 222 255 178 178 178 255 111 111 111 255 89 89 89 255
[HELL] 255 0 0 255 204 0 0 255 128 0 0 255 102 0 0 255
[SKY] 102 204 255 255 82 163 204 255 51 102 128 255 41 82 102 255
[OCEAN] 0 0 255 255 0 0 204 255 0 0 128 255 0 0 102 255
[RIVER] 0 128 255 255 0 102 204 255 0 64 128 255 0 51 102 255
[EXTREME_HILLS] 128 64 0 255 102 51 0 255 64 32 0 255 51 26 0 255
[FROZEN_OCEAN] 102 255 204 255 82 204 163 255 51 128 102 255 41 102 82 255
[FROZEN_RIVER] 102 102 255 255 82 82 204 255 51 51 128 255 41 41 102 255
[ICE_PLAINS] 102 255 255 255 82 204 204 255 51 128 128 255 41 102 102 255
[ICE_MOUNTAINS] 255 255 255 255 204 204 204 255 128 128 128 255 102 102 102 255
[MUSHROOM_ISLAND] 255 111 207 255 204 89 166 255 128 56 104 255 102 44 83 255
[MUSHROOM_SHORE] 255 0 128 255 204 0 102 255 128 0 64 255 102 0 51 255
[BEACH] 255 206 75 255 230 185 68 255 255 206 75 255 179 144 53 255
[DESERT_HILLS] 255 146 51 255 230 131 46 255 255 146 51 255 179 102 36 255
[FOREST_HILLS] 0 162 100 255 0 146 90 255 0 162 100 255 0 113 70 255
[TAIGA_HILLS] 178 212 117 255 160 191 105 255 178 212 117 255 125 148 82 255
[SMALL_MOUNTAINS] 184 103 33 255 166 93 30 255 184 103 33 255 129 72 23 255
Rainfall/Temperature Mapping
[RAINFALL-0.0] 120 120 120 255 96 96 96 255 60 60 60 255 48 48 48 255
[RAINFALL-1.0] 38 92 255 255 30 73 204 255 19 46 127 255 15 36 102 255
[TEMPERATURE-0.0] 38 92 255 255 30 73 204 255 19 46 127 255 15 36 102 255
[TEMPERATURE-0.5] 91 121 185 255 73 96 147 255 46 61 92 255 36 48 73 255
[TEMPERATURE-0.8] 51 165 42 255 41 131 33 255 26 82 21 255 20 65 17 255
[TEMPERATURE-0.9] 170 158 24 255 135 126 19 255 85 79 12 255 67 62 10 255
[TEMPERATURE-0.95] 204 111 48 255 162 89 38 255 102 56 24 255 81 44 19 255
[TEMPERATURE-1.0] 143 39 36 255 114 31 28 255 71 20 18 255 57 16 14 255

37
pom.xml
View File

@ -43,6 +43,31 @@
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals><goal>unpack</goal></goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.dynmap</groupId>
<artifactId>DynmapCore</artifactId>
<version>${project.version}</version>
<classifier>bin</classifier>
<type>zip</type>
<outputDirectory>${project.build.directory}/core</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
@ -57,8 +82,7 @@
<artifactSet>
<includes>
<include>org.dynmap:dynmap-api:jar:*</include>
<include>org.eclipse.jetty:jetty-*:jar:*</include>
<include>javax.servlet:javax.servlet-api:jar:*</include>
<include>org.dynmap:DynmapCore:jar:*</include>
</includes>
</artifactSet>
</configuration>
@ -106,7 +130,7 @@
<dependency>
<groupId>org.dynmap</groupId>
<artifactId>dynmap-api</artifactId>
<version>[0.25,)</version>
<version>${version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
@ -126,5 +150,12 @@
<version>8.0.1.v20110908</version>
</dependency>
<dependency>
<groupId>org.dynmap</groupId>
<artifactId>DynmapCore</artifactId>
<version>${version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,257 +0,0 @@
# BuildCraft Block mapping
# define buildcraft-support: true in configuration.txt to enable
enabled:buildcraft-support
# Variables - can be altered in configuration.txt
var:bc-autoWorkbench=152,bc-builder=157,bc-dockingStation=168,bc-drill=151
var:bc-engine=161,bc-filler=155,bc-frame=160,bc-marker=154,bc-miningWell=150
var:bc-oilMoving=162,bc-oilStill=163,bc-pipe=166,bc-pump=164,bc-quarry=153,bc-refinery=167
var:bc-tank=165,bc-template=158
# Pipe - set render alg
linkmap:id=bc-pipe,linkalg=5,linkid=bc-pipe
# Frame
linkmap:id=bc-frame,linkalg=5,linkid=bc-frame
# Pipe - (data is faked: 1=north,2=east,4=south,8=west)
# Pipe - no neighbors
# Frame
block:id=bc-pipe,id=bc-frame,data=0,scale=4
layer:1,2
----
-**-
-**-
----
# Pipe - just north neighbor
# Frame
block:id=bc-pipe,id=bc-frame,data=1,scale=4
layer:1,2
-**-
-**-
-**-
----
# Pipe - just east neighbor
# Frame
block:id=bc-pipe,id=bc-frame,data=2,scale=4
rotate:id=bc-pipe,data=1,rot=90
# Pipe - just south neighbor
# Frame
block:id=bc-pipe,id=bc-frame,data=4,scale=4
rotate:id=bc-pipe,data=1,rot=180
# Pipe - just south neighbor
# Frame
block:id=bc-pipe,id=bc-frame,data=8,scale=4
rotate:id=bc-pipe,data=1,rot=270
# Pipe - north and east neighbor
# Frame
block:id=bc-pipe,id=bc-frame,data=3,scale=4
layer:1,2
-**-
-***
-***
----
# Pipe - east and south neighbor
# Frame
block:id=bc-pipe,id=bc-frame,data=6,scale=4
rotate:id=bc-pipe,data=3,rot=90
# Pipe - south and west neighbor
# Frame
block:id=bc-pipe,id=bc-frame,data=12,scale=4
rotate:id=bc-pipe,data=3,rot=180
# Pipe - west and north neighbor
# Frame
block:id=bc-pipe,id=bc-frame,data=9,scale=4
rotate:id=bc-pipe,data=3,rot=270
# Pipe - north and south neighbor
# Frame
block:id=bc-pipe,id=bc-frame,data=5,scale=4
layer:1,2
-**-
-**-
-**-
-**-
# Pipe - east and west neighbor
# Frame
block:id=bc-pipe,id=bc-frame,data=10,scale=4
rotate:id=bc-pipe,data=5,rot=90
# Pipe - north, east and south neighbor
# Frame
block:id=bc-pipe,id=bc-frame,data=7,scale=4
layer:1,2
-**-
-***
-***
-**-
# Pipe - east, south and west neighbor
# Frame
block:id=bc-pipe,id=bc-frame,data=14,scale=4
rotate:id=bc-pipe,data=7,rot=90
# Pipe - south, west and north neighbor
# Frame
block:id=bc-pipe,id=bc-frame,data=13,scale=4
rotate:id=bc-pipe,data=7,rot=180
# Pipe - west, north and east neighbor
# Frame
block:id=bc-pipe,id=bc-frame,data=11,scale=4
rotate:id=bc-pipe,data=7,rot=270
# Pipe - north, south, east, west neightbors
# Frame
block:id=bc-pipe,id=bc-frame,data=15,scale=4
layer:1,2
-**-
****
****
-**-
# Drill - set render alg
linkmap:id=bc-drill,linkalg=5
# Drill - (data is faked: 1=north,2=east,4=south,8=west)
# Drill - no neighbors
block:id=bc-drill,data=0,scale=4
layer:0,1,2,3
----
-**-
-**-
----
# Drill - just north neighbor
block:id=bc-drill,data=1,scale=4
layer:0,3
----
-**-
-**-
----
layer:1,2
-**-
-**-
-**-
----
# Drill - just east neighbor
block:id=bc-drill,data=2,scale=4
rotate:id=bc-drill,data=1,rot=90
# Drill - just south neighbor
block:id=bc-drill,data=4,scale=4
rotate:id=bc-drill,data=1,rot=180
# Drill - just south neighbor
block:id=bc-drill,data=8,scale=4
rotate:id=bc-drill,data=1,rot=270
# Drill - north and east neighbor
block:id=bc-drill,data=3,scale=4
layer:0,3
----
-**-
-**-
----
layer:1,2
-**-
-***
-***
----
# Drill - east and south neighbor
block:id=bc-drill,data=6,scale=4
rotate:id=bc-drill,data=3,rot=90
# Drill - south and west neighbor
block:id=bc-drill,data=12,scale=4
rotate:id=bc-drill,data=3,rot=180
# Drill - west and north neighbor
block:id=bc-drill,data=9,scale=4
rotate:id=bc-drill,data=3,rot=270
# Drill - north and south neighbor
block:id=bc-drill,data=5,scale=4
layer:0,3
----
-**-
-**-
----
layer:1,2
-**-
-**-
-**-
-**-
# Drill - east and west neighbor
block:id=bc-drill,data=10,scale=4
rotate:id=bc-drill,data=5,rot=90
# Drill - north, east and south neighbor
block:id=bc-drill,data=7,scale=4
layer:0,3
----
-**-
-**-
----
layer:1,2
-**-
-***
-***
-**-
# Drill - east, south and west neighbor
block:id=bc-drill,data=14,scale=4
rotate:id=bc-drill,data=7,rot=90
# Drill - south, west and north neighbor
block:id=bc-drill,data=13,scale=4
rotate:id=bc-drill,data=7,rot=180
# Drill - west, north and east neighbor
block:id=bc-drill,data=11,scale=4
rotate:id=bc-drill,data=7,rot=270
# Drill - north, south, east, west neightbors
block:id=bc-drill,data=15,scale=4
layer:0,3
----
-**-
-**-
----
layer:1,2
-**-
****
****
-**-
# Marker
block:id=bc-marker,data=*,scale=8
layer:0,1,2,3,4,5,6,7
--------
--------
---**---
--****--
--****--
---**---
--------
--------
# Engine
block:id=bc-engine,data=*,scale=8
layer:2,3
********
********
********
********
********
********
********
********
layer:4,5,6,7
--------
--------
--****--
--****--
--****--
--****--
--------
--------
# Oil, flowing
block:id=bc-oilMoving,data=*,scale=4
layer:0
****
****
****
****
# Oil
block:id=bc-oilStill,data=*,scale=4
layer:0,1
****
****
****
****
# Tank
block:id=bc-tank,data=*,scale=8
layer:0,1,2,3,4,5,6,7
--------
-******-
-******-
-******-
-******-
-******-
-******-
--------

View File

@ -1,60 +0,0 @@
# BuildCraft Block mapping
# define buildcraft-support: true in configuration.txt to enable
enabled:buildcraft-support
# Variables - can be altered in configuration.txt
var:bc-autoWorkbench=152,bc-builder=157,bc-cobblestonePipe=159,bc-dockingStation=168,bc-drill=151
var:bc-engine=161,bc-filler=155,bc-frame=160,bc-marker=154,bc-miningWell=150
var:bc-oilMoving=162,bc-oilStill=163,bc-pipe=166,bc-pump=164,bc-quarry=153,bc-refinery=167
var:bc-tank=165,bc-template=158
# Files
texturefile:id=blk,filename=buildcraft/block_textures.png,xcount=16,ycount=16
texturefile:id=wood,filename=buildcraft/base_wood.png,xcount=4,ycount=2
texturefile:id=iron,filename=buildcraft/base_iron.png,xcount=4,ycount=2
texturefile:id=stone,filename=buildcraft/base_stone.png,xcount=4,ycount=2
# MINING_WELL_ID = 150
block:id=bc-miningWell,data=2,east=35,top=4036,north=37,south=37,west=38,bottom=38,txtid=blk
block:id=bc-miningWell,data=3,west=35,top=4036,north=37,south=37,east=38,bottom=38,txtid=blk
block:id=bc-miningWell,data=4,north=35,top=4036,east=37,west=37,south=38,bottom=38,txtid=blk
block:id=bc-miningWell,data=5,south=35,top=4036,east=37,west=37,north=38,bottom=38,txtid=blk
# DRILL_ID = 151
block:id=bc-drill,data=*,allfaces=32,txtid=blk,transparency=TRANSPARENT
# AUTO_WORKBENCH_ID = 152
block:id=bc-autoWorkbench,data=*,allsides=44,topbottom=4043
# QUARRY_ID = 153
block:id=bc-quarry,data=2,east=39,top=4040,north=38,south=38,west=38,bottom=38,txtid=blk
block:id=bc-quarry,data=3,west=39,top=4040,north=38,south=38,east=38,bottom=38,txtid=blk
block:id=bc-quarry,data=4,north=39,top=4040,east=38,west=38,south=38,bottom=38,txtid=blk
block:id=bc-quarry,data=5,south=39,top=4040,east=38,west=38,north=38,bottom=38,txtid=blk
# MARKER_ID = 154
block:id=bc-marker,data=*,allsides=57,txtid=blk,transparency=TRANSPARENT
# FILLER_ID = 155
block:id=bc-filler,data=*,allsides=66,topbottom=4065,txtid=blk
# BUILDER_ID = 157
block:id=bc-builder,data=2,east=55,top=4054,north=3,south=3,west=3,bottom=3,txtid=blk
block:id=bc-builder,data=3,west=55,top=4054,north=3,south=3,east=3,bottom=3,txtid=blk
block:id=bc-builder,data=4,north=55,top=4054,east=3,west=3,south=3,bottom=3,txtid=blk
block:id=bc-builder,data=5,south=55,top=4054,east=3,west=3,north=3,bottom=3,txtid=blk
# TEMPLATE_ID = 158
block:id=bc-template,data=2,east=52,top=4050,north=48,south=48,west=48,bottom=48,txtid=blk
block:id=bc-template,data=3,west=52,top=4050,north=48,south=48,east=48,bottom=48,txtid=blk
block:id=bc-template,data=4,north=52,top=4050,east=48,west=48,south=48,bottom=48,txtid=blk
block:id=bc-template,data=5,south=52,top=4050,east=48,west=48,north=48,bottom=48,txtid=blk
# FRAME_ID = 160
block:id=bc-frame,data=*,allfaces=34,txtid=blk,transparency=TRANSPARENT
# ENGINE_ID = 161
block:id=bc-engine,data=0,north=8004,east=8005,south=8006,west=8007,top=1,bottom=2,txtid=wood
block:id=bc-engine,data=1,north=8004,east=8005,south=8006,west=8007,top=1,bottom=2,txtid=stone
block:id=bc-engine,data=2,north=8004,east=8005,south=8006,west=8007,top=1,bottom=2,txtid=iron
# OIL_MOVING_ID = 162
block:id=bc-oilMoving,data=*,allfaces=223,txtid=blk
# OIL_STILL_ID = 163
block:id=bc-oilStill,data=*,allfaces=223,txtid=blk
# PUMP_ID = 164
block:id=bc-pump,data=*,allsides=99,top=4064,bottom=100,txtid=blk
# TANK_ID = 165
block:id=bc-tank,data=*,allsides=96,topbottom=98,txtid=blk,transparency=TRANSPARENT
# GENERIC_PIPE_ID = 166 : entity data based, so we can't handle it yet: just map to one type (iron)
block:id=bc-pipe,data=*,allfaces=18,txtid=blk,transparency=TRANSPARENT
# REFINERY_ID = 167 - funky texture mapping - just do tank for now
block:id=bc-refinery,data=*,allsides=96,topbottom=98,txtid=blk,transparency=TRANSPARENT
# DOCKING_STATION_ID = 168

View File

@ -1,203 +0,0 @@
# Industrial Craft 2 Texture mapping
# define ic2-support: true in configuration.txt to enable
enabled:ic2-support
# variables: set in configuration.txt to override
var: ic2-blockCable=228,ic2-blockFenceIron=232,ic2-blockMachine2=223,ic2-blockPersonal=225,ic2-blockLuminator=226,ic2-blockElectric=227,ic2-blockReactorChamber=233,ic2-blockNuke=237,ic2-blockGenerator=246,ic2blockMachine=250
# Wire - set render alg
linkmap:id=ic2-blockCable,linkalg=5,linkid=ic2-blockMachine2,linkid=ic2-blockPersonal,linkid=ic2-blockLuminator,linkid=ic2-blockElectric,linkid=ic2-blockCable,linkid=ic2-blockReactorChamber,linkid=ic2-blockNuke,linkid=ic2-blockGenerator,linkid=ic2blockMachine
# Wire - (data is faked: 1=north,2=east,4=south,8=west)
# Wire - no neighbors
block:id=ic2-blockCable,data=0,scale=16
layer:5,6,7,8,9,10
----------------
----------------
----------------
----------------
----------------
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
----------------
----------------
----------------
----------------
----------------
# Wire - just north neighbor
block:id=ic2-blockCable,data=1,scale=16
layer:5,6,7,8,9,10
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
----------------
----------------
----------------
----------------
----------------
# Wire - just east neighbor
block:id=ic2-blockCable,data=2,scale=16
rotate:id=ic2-blockCable,data=1,rot=90
# Wire - just south neighbor
block:id=ic2-blockCable,id=113,data=4,scale=16
rotate:id=ic2-blockCable,data=1,rot=180
# Wire - just south neighbor
block:id=ic2-blockCable,data=8,scale=16
rotate:id=ic2-blockCable,data=1,rot=270
# Wire - north and east neighbor
block:id=ic2-blockCable,data=3,scale=16
layer:5,6,7,8,9,10
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----***********
-----***********
-----***********
-----***********
-----***********
----------------
----------------
----------------
----------------
----------------
# Wire - east and south neighbor
block:id=ic2-blockCable,data=6,scale=16
rotate:id=ic2-blockCable,data=3,rot=90
# Wire - south and west neighbor
block:id=ic2-blockCable,data=12,scale=16
rotate:id=ic2-blockCable,data=3,rot=180
# Wire - west and north neighbor
block:id=ic2-blockCable,data=9,scale=16
rotate:id=ic2-blockCable,data=3,rot=270
# Wire - north and south neighbor
block:id=ic2-blockCable,data=5,scale=16
layer:5,6,7,8,9,10
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
# Wire - east and west neighbor
block:id=ic2-blockCable,data=10,scale=16
rotate:id=ic2-blockCable,data=5,rot=90
# Wire - north, east and south neighbor
block:id=ic2-blockCable,data=7,scale=16
layer:5,6,7,8,9,10
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
-----***********
-----***********
-----***********
-----***********
-----***********
-----***********
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
# Wire - east, south and west neighbor
block:id=ic2-blockCable,data=14,scale=16
rotate:id=ic2-blockCable,data=7,rot=90
# Wire - south, west and north neighbor
block:id=ic2-blockCable,data=13,scale=16
rotate:id=ic2-blockCable,data=7,rot=180
# Wire - west, north and east neighbor
block:id=ic2-blockCable,data=11,scale=16
rotate:id=ic2-blockCable,data=7,rot=270
# Wire - north, south, east, west neightbors
block:id=ic2-blockCable,data=15,scale=16
layer:5,6,7,8,9,10
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
****************
****************
****************
****************
****************
****************
-----******-----
-----******-----
-----******-----
-----******-----
-----******-----
# Iron Fence - set render algorithm
linkmap:id=ic2-blockFenceIron,linkalg=1
# Iron Fence - (data is faked: 1=north,2=east,4=south,8=west)
# Iron Fence - no neighbors
block:id=ic2-blockFenceIron,data=0,scale=16
rotate:id=85,data=0,rot=0
# Iron Fence - just north neighbor
block:id=ic2-blockFenceIron,data=1,scale=16
rotate:id=85,data=1,rot=0
# Iron Fence - just east neighbor
block:id=ic2-blockFenceIron,data=2,scale=16
rotate:id=ic2-blockFenceIron,data=1,rot=90
# Iron Fence - just south neighbor
block:id=ic2-blockFenceIron,data=4,scale=16
rotate:id=ic2-blockFenceIron,data=1,rot=180
# Iron Fence - just south neighbor
block:id=ic2-blockFenceIron,data=8,scale=16
rotate:id=ic2-blockFenceIron,data=1,rot=270
# Iron Fence - north and east neighbor
block:id=ic2-blockFenceIron,data=3,scale=16
rotate:id=85,data=3,rot=0
# Iron Fence - east and south neighbor
block:id=ic2-blockFenceIron,data=6,scale=16
rotate:id=ic2-blockFenceIron,data=3,rot=90
# Iron Fence - south and west neighbor
block:id=ic2-blockFenceIron,data=12,scale=16
rotate:id=85,data=3,rot=180
# Iron Fence - west and north neighbor
block:id=ic2-blockFenceIron,data=9,scale=16
rotate:id=85,data=3,rot=270
# Iron Fence - north and south neighbor
block:id=ic2-blockFenceIron,data=5,scale=16
rotate:id=85,data=5,rot=0
# Iron Fence - east and west neighbor
block:id=ic2-blockFenceIron,id=113,data=10,scale=16
rotate:id=ic2-blockFenceIron,data=5,rot=90
# Iron Fence - north, east and south neighbor
block:id=ic2-blockFenceIron,data=7,scale=16
rotate:id=85,data=7,rot=0
# Iron Fence - east, south and west neighbor
block:id=ic2-blockFenceIron,data=14,scale=16
rotate:id=ic2-blockFenceIron,data=7,rot=90
# Iron Fence - south, west and north neighbor
block:id=ic2-blockFenceIron,data=13,scale=16
rotate:id=ic2-blockFenceIron,data=7,rot=180
# Iron Fence - west, north and east neighbor
block:id=ic2-blockFenceIron,data=11,scale=16
rotate:id=ic2-blockFenceIron,data=7,rot=270
# Iron Fence - north, south, east, west neightbors
block:id=ic2-blockFenceIron,data=15,scale=16
rotate:id=ic2-blockFenceIron,data=15,rot=0

View File

@ -1,203 +0,0 @@
# Industrial Craft 2 Block mapping
# define ic2-support: true in configuration.txt to enable
enabled:ic2-support
# variables: set in configuration.txt to override
var:ic2-blockScaffold=220,ic2-blockWall=221,ic2-blockFoam=222,ic2-blockMachine2=223,ic2-blockMetal=224,ic2-blockPersonal=225,ic2-blockLuminator=226,ic2-blockElectric=227
var:ic2-blockCable=228,ic2-blockDoorAlloy=229,ic2-blockAlloyGlass=230,ic2-blockAlloy=231,ic2-blockFenceIron=232,ic2-blockReactorChamber=233
var:ic2-blockRubber=234,ic2-blockDynamiteRemote=235,ic2-blockDynamite=236,ic2-blockNuke=237,ic2-blockITNT=239,ic2-blockHarz=240,ic2-blockRubSapling=241
var:ic2-blockRubLeaves=242,ic2-blockRubWood=243,ic2-blockMiningTip=244,ic2-blockMiningPipe=245,ic2-blockGenerator=246
var:ic2-blockOreUran=247,ic2-blockOreTin=248,ic2-blockOreCopper=249,ic2-blockMachine=250
# Files
texturefile:id=blk0,filename=ic2/sprites/block_0.png,xcount=16,ycount=16
texturefile:id=cable,filename=ic2/sprites/block_cable.png,xcount=16,ycount=16
texturefile:id=elec,filename=ic2/sprites/block_electric.png,xcount=16,ycount=16
texturefile:id=gen,filename=ic2/sprites/block_generator.png,xcount=16,ycount=16
texturefile:id=mach,filename=ic2/sprites/block_machine.png,xcount=16,ycount=16
texturefile:id=mach2,filename=ic2/sprites/block_machine2.png,xcount=16,ycount=16
texturefile:id=pers,filename=ic2/sprites/block_personal.png,xcount=16,ycount=16
# Blocks
# blockScaffold=220
# data=*
block:id=ic2-blockScaffold,data=*,allsides=116,topbottom=117,txtid=blk0
# data=2
block:id=ic2-blockScaffold,data=2,allfaces=118,txtid=blk0
# blockWall=221
# data=0
block:id=ic2-blockWall,data=0,allfaces=96,txtid=blk0
# data=1
block:id=ic2-blockWall,data=1,allfaces=97,txtid=blk0
# data=2
block:id=ic2-blockWall,data=2,allfaces=98,txtid=blk0
# data=3
block:id=ic2-blockWall,data=3,allfaces=99,txtid=blk0
# data=4
block:id=ic2-blockWall,data=4,allfaces=100,txtid=blk0
# data=5
block:id=ic2-blockWall,data=5,allfaces=101,txtid=blk0
# data=6
block:id=ic2-blockWall,data=6,allfaces=102,txtid=blk0
# data=7
block:id=ic2-blockWall,data=7,allfaces=103,txtid=blk0
# data=8
block:id=ic2-blockWall,data=8,allfaces=104,txtid=blk0
# data=9
block:id=ic2-blockWall,data=9,allfaces=105,txtid=blk0
# data=10
block:id=ic2-blockWall,data=10,allfaces=106,txtid=blk0
# data=11
block:id=ic2-blockWall,data=11,allfaces=107,txtid=blk0
# data=12
block:id=ic2-blockWall,data=12,allfaces=108,txtid=blk0
# data=13
block:id=ic2-blockWall,data=13,allfaces=109,txtid=blk0
# data=14
block:id=ic2-blockWall,data=14,allfaces=110,txtid=blk0
# data=15
block:id=ic2-blockWall,data=15,allfaces=111,txtid=blk0
# blockFoam=222
block:id=ic2-blockFoam,data=*,allfaces=37
# blockMachine2=223
# data=0
block:id=ic2-blockMachine2,data=0,top=0,bottom=16,north=32,south=48,east=64,west=80,txtid=mach2
# data=1
block:id=ic2-blockMachine2,data=1,top=1,bottom=17,north=33,south=49,east=65,west=81,txtid=mach2
# blockMetal=224
# data=0 (copper)
block:id=ic2-blockMetal,data=0,allfaces=93,txtid=blk0
# data=1 (tin)
block:id=ic2-blockMetal,data=1,allfaces=94,txtid=blk0
# data=2 (bronze)
block:id=ic2-blockMetal,data=2,allfaces=78,txtid=blk0
# data=3 (uranium)
block:id=ic2-blockMetal,data=3,topbottom=79,allsides=95,txtid=blk0
# blockPersonal=225
# data=0
block:id=ic2-blockPersonal,data=0,bottom=0,top=16,north=32,south=48,east=64,west=80,txtid=pers
# data=1
block:id=ic2-blockPersonal,data=1,bottom=1,top=17,north=33,south=49,east=65,west=81,txtid=pers
# blockLuminator=226
block:id=ic2-blockLuminator,data=*,allfaces=31,txtid=blk0
# blockElectric=227
# data=0
block:id=ic2-blockElectric,data=0,bottom=0,top=16,north=32,south=48,east=64,west=80,txtid=elec
# data=1
block:id=ic2-blockElectric,data=1,bottom=1,top=17,north=33,south=49,east=65,west=81,txtid=elec
# data=2
block:id=ic2-blockElectric,data=2,bottom=2,top=18,north=34,south=50,east=66,west=82,txtid=elec
# data=3
block:id=ic2-blockElectric,data=3,bottom=3,top=19,north=35,south=51,east=67,west=83,txtid=elec
# data=4
block:id=ic2-blockElectric,data=4,bottom=4,top=20,north=36,south=52,east=68,west=84,txtid=elec
# data=5
block:id=ic2-blockElectric,data=5,bottom=5,top=21,north=37,south=53,east=69,west=85,txtid=elec
# blockCable=228
# data=0
block:id=ic2-blockCable,data=0,allfaces=0,txtid=cable
# data=1
block:id=ic2-blockCable,data=1,allfaces=16,txtid=cable
# data=2
block:id=ic2-blockCable,data=2,allfaces=32,txtid=cable
# data=3
block:id=ic2-blockCable,data=3,allfaces=48,txtid=cable
# data=4
block:id=ic2-blockCable,data=4,allfaces=64,txtid=cable
# data=5
block:id=ic2-blockCable,data=5,allfaces=80,txtid=cable
# data=6
block:id=ic2-blockCable,data=6,allfaces=96,txtid=cable
# data=7
block:id=ic2-blockCable,data=7,allfaces=112,txtid=cable
# data=8
block:id=ic2-blockCable,data=8,allfaces=128,txtid=cable
# data=9
block:id=ic2-blockCable,data=9,allfaces=144,txtid=cable
# data=10
block:id=ic2-blockCable,data=10,allfaces=160,txtid=cable
# blockDoorAlloy=229
# data=0-7 (bottom)
block:id=ic2-blockDoorAlloy,data=0,data=1,data=2,data=3,data=4,data=5,data=6,data=7,allsides=15,topbottom=12,transparency=TRANSPARENT,txtid=blk0
# data=8-15 (top)
block:id=ic2-blockDoorAlloy,data=8,data=9,data=10,data=11,data=12,data=13,data=14,data=15,allsides=14,topbottom=12,transparency=TRANSPARENT,txtid=blk0
# blockAlloyGlass=230
block:id=ic2-blockAlloyGlass,data=*,allfaces=13,txtid=blk0,transparency=TRANSPARENT
# blockAlloy=231
block:id=ic2-blockAlloy,data=*,allfaces=12,txtid=blk0
# blockFenceIron=232
block:id=ic2-blockFenceIron,data=*,allfaces=1,txtid=blk0,transparency=TRANSPARENT
# blockReactorChamber=233
block:id=ic2-blockReactorChamber,data=*,bottom=16,top=17,allsides=67,txtid=blk0
# blockRubber=234
block:id=ic2-blockRubber,data=*,allfaces=40,txtid=blk0
# blockDynamiteRemote=235
block:id=ic2-blockDynamiteRemote,data=*,allsides=56,txtid=blk0
# blockDynamite=236
block:id=ic2-blockDynamite,data=*,allsides=57,txtid=blk0
# blockNuke=237
block:id=ic2-blockNuke,data=*,bottom=61,top=62,allsides=63,txtid=blk0
# ?=238
# blockITNT=239
block:id=ic2-blockITNT,data=*,bottom=58,top=59,allsides=60,txtid=blk0
# blockHarz=240
block:id=ic2-blockHarz,data=*,allfaces=43,txtid=blk0
# blockRubSapling=241
block:id=ic2-blockRubSapling,data=*,allsides=2038,transparency=TRANSPARENT,txtid=blk0
# blockRubLeaves=242
block:id=ic2-blockRubLeaves,data=*,allfaces=2040,transparency=TRANSPARENT,txtid=blk0
# blockRubWood=243
block:id=ic2-blockRubWood,data=*,topbottom=47,allsides=44,txtid=blk0
# blockMiningTip=244
block:id=ic2-blockMiningTip,data=*,allfaces=36,txtid=blk0
# blockMiningPipe=245
block:id=ic2-blockMiningPipe,data=*,allfaces=35,txtid=blk0
# blockGenerator=246
# data=0
block:id=ic2-blockGenerator,data=0,bottom=0,top=16,north=32,south=48,east=64,west=80,txtid=gen
# data=1
block:id=ic2-blockGenerator,data=1,bottom=1,top=17,north=33,south=49,east=65,west=81,txtid=gen
# data=2
block:id=ic2-blockGenerator,data=2,bottom=2,top=18,north=34,south=50,east=66,west=82,txtid=gen
# data=3
block:id=ic2-blockGenerator,data=3,bottom=3,top=19,north=35,south=51,east=67,west=83,txtid=gen
# data=4
block:id=ic2-blockGenerator,data=4,bottom=4,top=20,north=36,south=52,east=68,west=84,txtid=gen
# data=5
block:id=ic2-blockGenerator,data=5,bottom=5,top=21,north=37,south=53,east=69,west=85,txtid=gen
# blockOreUran=247
block:id=ic2-blockOreUran,data=*,allfaces=34,txtid=blk0
# blockOreTin=248
block:id=ic2-blockOreTin,data=*,allfaces=33,txtid=blk0
# blockOreCopper=249
block:id=ic2-blockOreCopper,data=*,allfaces=32,txtid=blk0
# blockMachine=250
# data=0
block:id=ic2-blockMachine,data=0,bottom=0,top=16,north=32,south=48,east=64,west=80,txtid=mach
# data=1
block:id=ic2-blockMachine,data=1,bottom=1,top=17,north=33,south=49,east=65,west=81,txtid=mach
# data=2
block:id=ic2-blockMachine,data=2,bottom=2,top=18,north=34,south=50,east=66,west=82,txtid=mach
# data=3
block:id=ic2-blockMachine,data=3,bottom=3,top=19,north=35,south=51,east=67,west=83,txtid=mach
# data=4
block:id=ic2-blockMachine,data=4,bottom=4,top=20,north=36,south=52,east=68,west=84,txtid=mach
# data=5
block:id=ic2-blockMachine,data=5,bottom=5,top=21,north=37,south=53,east=69,west=85,txtid=mach
# data=6
block:id=ic2-blockMachine,data=6,bottom=6,top=22,north=38,south=54,east=70,west=86,txtid=mach
# data=7
block:id=ic2-blockMachine,data=7,bottom=7,top=23,north=39,south=55,east=71,west=87,txtid=mach
# data=8
block:id=ic2-blockMachine,data=8,bottom=8,top=24,north=40,south=56,east=72,west=88,txtid=mach
# data=9
block:id=ic2-blockMachine,data=9,bottom=9,top=25,north=41,south=57,east=73,west=89,txtid=mach
# data=10
block:id=ic2-blockMachine,data=10,bottom=10,top=26,north=42,south=58,east=74,west=90,txtid=mach
# data=11
block:id=ic2-blockMachine,data=11,bottom=11,top=27,north=43,south=59,east=75,west=91,txtid=mach
# data=12
block:id=ic2-blockMachine,data=12,bottom=12,top=28,north=44,south=60,east=76,west=92,txtid=mach
# data=13
block:id=ic2-blockMachine,data=13,bottom=13,top=29,north=45,south=61,east=77,west=93,txtid=mach
# data=14
block:id=ic2-blockMachine,data=14,bottom=14,top=30,north=46,south=62,east=78,west=94,txtid=mach
# data=15
block:id=ic2-blockMachine,data=15,bottom=15,top=31,north=47,south=63,east=79,west=95,txtid=mach

View File

@ -1,157 +0,0 @@
# RedPower2 block mapping
# define redpower2-support: true in configuration.txt to enable
enabled:redpower2-support
# Variables - can be altered in configuration.txt
var:rp2-base-appliance=137,rp2-base-microblock=136
var:rp2-world-plants=139,rp2-world-ores=140,rp2-world-leaves=141,rp2-world-stone=142,rp2-world-log=143,rp2-world-crops=144,rp2-world-storage=145
var:rp2-logic-logic=138
var:rp2-lighting-lampOn=146,rp2-lighting-lampOff=147
var:rp2-sensor-sensor=148
var:rp2-array-array=149
var:rp2-machine-machine=150,rp2-machine-machinePanel=151,rp2-machine-frame=152
# rp2-world-plants,*
block:id=rp2-world-plants,data=*,scale=16
layer:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
*--------------*
-*------------*-
--*----------*--
---*--------*---
----*------*----
-----*----*-----
------*--*------
-------**-------
-------**-------
------*--*------
-----*----*-----
----*------*----
---*--------*---
--*----------*--
-*------------*-
*--------------*
# Crops
block:id=rp2-world-crops,data=*,scale=16
layer:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
---*--------*---
---*--------*---
---*--------*---
****************
---*--------*---
---*--------*---
---*--------*---
---*--------*---
---*--------*---
---*--------*---
---*--------*---
---*--------*---
****************
---*--------*---
---*--------*---
---*--------*---
# Logic
block:id=rp2-logic-logic,data=*,scale=8
layer:0
********
********
********
********
********
********
********
********
# Array (array.array.id,0)
# Inv-Array (array.array.id,1)
# Non-Inv-Array (array.array.id,2)
block:id=rp2-array-array,data=0,data=1,data=2,scale=16
layer:0,1
****************
****************
****************
****************
****************
****************
****************
****************
****************
****************
****************
****************
****************
****************
****************
****************
layer:2,3
-------**-------
-------**-------
--*----**----*--
-------**-------
-------**-------
-------**-------
-------**-------
**-----**-----**
**-----**-----**
-------**-------
-------**-------
-------**-------
-------**-------
--*----**----*--
-------**-------
-------**-------
layer:4,5,6,7,8,9
----------------
----------------
--*----------*--
----------------
----------------
----------------
----------------
**------------**
**------------**
----------------
----------------
----------------
----------------
--*----------*--
----------------
----------------
layer:10
----------------
----------------
--*----------*--
--*----------*--
--*----------*--
--*----------*--
--*----------*--
***----------***
***----------***
--*----------*--
--*----------*--
--*----------*--
--*----------*--
--*----------*--
----------------
----------------
layer:11,12
----------------
----------------
----------------
----------------
----------------
----------------
----------------
****************
****************
----------------
----------------
----------------
----------------
----------------
----------------
----------------
# Solar panel (machine.machinePanel.id,0)
block:id=rp2-machine-machinePanel,data=0,scale=4
layer:0
****
****
****
****

View File

@ -1,217 +0,0 @@
# RedPower2 block mapping
# define redpower2-support: true in configuration.txt to enable
enabled:redpower2-support
# Variables - can be altered in configuration.txt
var:rp2-base-appliance=137,rp2-base-microblock=136
var:rp2-world-plants=139,rp2-world-ores=140,rp2-world-leaves=141,rp2-world-stone=142,rp2-world-log=143,rp2-world-crops=144,rp2-world-storage=145
var:rp2-logic-logic=138
var:rp2-lighting-lampOn=146,rp2-lighting-lampOff=147
var:rp2-sensor-sensor=148
var:rp2-array-array=149
var:rp2-machine-machine=150,rp2-machine-machinePanel=151,rp2-machine-frame=152
# Files
texturefile:id=base,filename=redpower2/base1.png,xcount=16,ycount=16
texturefile:id=world,filename=redpower2/world1.png,xcount=16,ycount=16
texturefile:id=worlditem,filename=redpower2/worlditems1.png,xcount=16,ycount=16
texturefile:id=logic,filename=redpower2/logic1.png,xcount=16,ycount=16
texturefile:id=lighting,filename=redpower2/lighting1.png,xcount=16,ycount=16
texturefile:id=array,filename=redpower2/array1.png,xcount=16,ycount=16
texturefile:id=machine,filename=redpower2/machine1.png,xcount=16,ycount=16
############
# Blocks from RedPowerCore-2
############
# Alloy Furnace (base.appliance.id, 0)
block:id=rp2-base-appliance,data=0,topbottom=19,north=18,south=18,east=16,west=16,txtid=base
# Microblocks (base.microblock.id, 0) - can't do this right yet, so just do it as cobblestone...
block:id=rp2-base-microblock,data=0,allfaces=16
############
# Blocks from RedPowerWorld-2
############
# Flower (world.plants.id, 0), (world.plants.id,3+)
block:id=rp2-world-plants,data=0,data=3,data=4,data=5,data=6,data=7,data=8,data=9,data=10,data=11,data=12,data=13,data=14,data=15,allsides=1,txtid=worlditem,transparency=TRANSPARENT
# Flower (world.plants.id, 1), (world.plants.id, 2)
block:id=rp2-world-plants,data=1,data=2,allsides=2,txtid=worlditem,transparency=TRANSPARENT
# Flax (world.crops.id,0)
block:id=rp2-world-crops,data=0,allsides=64,txtid=world,transparency=TRANSPARENT
# Flax (world.crops.id,1)
block:id=rp2-world-crops,data=1,allsides=65,txtid=world,transparency=TRANSPARENT
# Flax (world.crops.id,2)
block:id=rp2-world-crops,data=2,allsides=66,txtid=world,transparency=TRANSPARENT
# Flax (world.crops.id,3)
block:id=rp2-world-crops,data=3,allsides=67,txtid=world,transparency=TRANSPARENT
# Flax (world.crops.id,4)
block:id=rp2-world-crops,data=4,allsides=68,txtid=world,transparency=TRANSPARENT
# Flax (world.crops.id,5+)
block:id=rp2-world-crops,data=5,data=6,data=7,data=8,data=9,data=10,data=11,data=12,data13,data=14,data=15,allsides=69,txtid=world,transparency=TRANSPARENT
# Marble (world.stone.id,0)
block:id=rp2-world-stone,data=0,allfaces=16,txtid=world
# Basalt (world.stone.id,1)
block:id=rp2-world-stone,data=1,allfaces=17,txtid=world
# Marble bricks (world.stone.id,2)
block:id=rp2-world-stone,data=2,allfaces=18,txtid=world
# Basalt cobblestone (world.stone.id,3)
block:id=rp2-world-stone,data=3,allfaces=19,txtid=world
# Basalt bricks (world.stone.id,4)
block:id=rp2-world-stone,data=4,allfaces=20,txtid=world
# Ruby Ore (world.ores.id,0)
block:id=rp2-world-ores,data=0,allfaces=32,txtid=world
# Emerald Ore (world.ores.id,1)
block:id=rp2-world-ores,data=1,allfaces=33,txtid=world
# Sapphire Ore (world.ores.id,2)
block:id=rp2-world-ores,data=2,allfaces=34,txtid=world
# Silver Ore (world.ores.id,3)
block:id=rp2-world-ores,data=3,allfaces=35,txtid=world
# Tin Ore (world.ores.id,4)
block:id=rp2-world-ores,data=4,allfaces=36,txtid=world
# Copper Ore (world.ores.id,5)
block:id=rp2-world-ores,data=5,allfaces=37,txtid=world
# Tungsten Ore (world.ores.id,6)
block:id=rp2-world-ores,data=6,allfaces=38,txtid=world
# Nikolite Ore (world.ores.id,7)
block:id=rp2-world-ores,data=7,allfaces=39,txtid=world
# Rubber tree leaves (world.leaves.id,*)
block:id=rp2-world-leaves,data=*,allfaces=2049,txtid=world
# Ruby Block (world.storage.id,0)
block:id=rp2-world-storage,data=0,allfaces=80,txtid=world
# Emerald Block (world.storage.id,1)
block:id=rp2-world-storage,data=1,allfaces=81,txtid=world
# Sapphire Block (world.storage.id,2)
block:id=rp2-world-storage,data=2,allfaces=82,txtid=world
# Rubber log (world.log.id,*)
block:id=rp2-world-log,data=*,allsides=50,topbottom=51,txtid=world
############
# Blocks from RedPowerLogic-2
############
# Timer (logic.logic.id,0)
block:id=rp2-logic-logic,data=0,allsides=0,top=8,bottom=0,txtid=logic,transparency=TRANSPARENT
# Sequencer (logic.logic.id,1)
block:id=rp2-logic-logic,data=1,allsides=0,top=1,bottom=0,txtid=logic,transparency=TRANSPARENT
# Latch (logic.logic.id,2)
block:id=rp2-logic-logic,data=2,allsides=0,top=2,bottom=0,txtid=logic,transparency=TRANSPARENT
# Nor (logic.logic.id,3)
block:id=rp2-logic-logic,data=3,allsides=0,top=32,bottom=0,txtid=logic,transparency=TRANSPARENT
# Or (logic.logic.id,4)
block:id=rp2-logic-logic,data=4,allsides=0,top=144,bottom=0,txtid=logic,transparency=TRANSPARENT
# Nand (logic.logic.id,5)
block:id=rp2-logic-logic,data=5,allsides=0,top=96,bottom=0,txtid=logic,transparency=TRANSPARENT
# And (logic.logic.id,6)
block:id=rp2-logic-logic,data=6,allsides=0,top=160,bottom=0,txtid=logic,transparency=TRANSPARENT
# Xnor (logic.logic.id,7)
block:id=rp2-logic-logic,data=7,allsides=0,top=20,bottom=0,txtid=logic,transparency=TRANSPARENT
# Xor (logic.logic.id,8)
block:id=rp2-logic-logic,data=8,allsides=0,top=24,bottom=0,txtid=logic,transparency=TRANSPARENT
# Pulse (logic.logic.id,9)
block:id=rp2-logic-logic,data=9,allsides=0,top=216,bottom=0,txtid=logic,transparency=TRANSPARENT
# Toggle (logic.logic.id,10)
block:id=rp2-logic-logic,data=10,allsides=0,top=16,bottom=0,txtid=logic,transparency=TRANSPARENT
# Not (logic.logic.id,11)
block:id=rp2-logic-logic,data=11,allsides=0,top=192,bottom=0,txtid=logic,transparency=TRANSPARENT
# Buffer (logic.logic.id,12)
block:id=rp2-logic-logic,data=12,allsides=0,top=208,bottom=0,txtid=logic,transparency=TRANSPARENT
# Mux (logic.logic.id,13)
block:id=rp2-logic-logic,data=13,allsides=0,top=5,bottom=0,txtid=logic,transparency=TRANSPARENT
# Counter (logic.logic.id,14)
block:id=rp2-logic-logic,data=14,allsides=0,top=16,bottom=0,txtid=logic,transparency=TRANSPARENT
# Repeater (logic.logic.id,15)
block:id=rp2-logic-logic,data=15,allsides=0,top=188,bottom=0,txtid=logic,transparency=TRANSPARENT
############
# Blocks from RedPowerLighting-2
############
# White Lamp on
block:id=rp2-lighting-lampOn,data=0,allfaces=32,txtid=lighting
# Orange Lamp on
block:id=rp2-lighting-lampOn,data=1,allfaces=33,txtid=lighting
# Magenta Lamp on
block:id=rp2-lighting-lampOn,data=2,allfaces=34,txtid=lighting
# Light Blue Lamp on
block:id=rp2-lighting-lampOn,data=3,allfaces=35,txtid=lighting
# Yellow Lamp on
block:id=rp2-lighting-lampOn,data=4,allfaces=36,txtid=lighting
# Lime Lamp on
block:id=rp2-lighting-lampOn,data=5,allfaces=37,txtid=lighting
# Pink Lamp on
block:id=rp2-lighting-lampOn,data=6,allfaces=38,txtid=lighting
# Gray Lamp on
block:id=rp2-lighting-lampOn,data=7,allfaces=39,txtid=lighting
# Light Gray Lamp on
block:id=rp2-lighting-lampOn,data=8,allfaces=40,txtid=lighting
# Cyan Lamp on
block:id=rp2-lighting-lampOn,data=9,allfaces=41,txtid=lighting
# Purple Lamp on
block:id=rp2-lighting-lampOn,data=10,allfaces=42,txtid=lighting
# Blue Lamp on
block:id=rp2-lighting-lampOn,data=11,allfaces=43,txtid=lighting
# Brown Lamp on
block:id=rp2-lighting-lampOn,data=12,allfaces=44,txtid=lighting
# Green Lamp on
block:id=rp2-lighting-lampOn,data=13,allfaces=45,txtid=lighting
# Red Lamp on
block:id=rp2-lighting-lampOn,data=14,allfaces=46,txtid=lighting
# Black Lamp on
block:id=rp2-lighting-lampOn,data=15,allfaces=47,txtid=lighting
# White Lamp off
block:id=rp2-lighting-lampOff,data=0,allfaces=16,txtid=lighting
# Orange Lamp off
block:id=rp2-lighting-lampOff,data=1,allfaces=17,txtid=lighting
# Magenta Lamp off
block:id=rp2-lighting-lampOff,data=2,allfaces=18,txtid=lighting
# Light Blue Lamp off
block:id=rp2-lighting-lampOff,data=3,allfaces=19,txtid=lighting
# Yellow Lamp off
block:id=rp2-lighting-lampOff,data=4,allfaces=20,txtid=lighting
# Lime Lamp off
block:id=rp2-lighting-lampOff,data=5,allfaces=21,txtid=lighting
# Pink Lamp off
block:id=rp2-lighting-lampOff,data=6,allfaces=22,txtid=lighting
# Gray Lamp off
block:id=rp2-lighting-lampOff,data=7,allfaces=23,txtid=lighting
# Light Gray Lamp off
block:id=rp2-lighting-lampOff,data=8,allfaces=24,txtid=lighting
# Cyan Lamp off
block:id=rp2-lighting-lampOff,data=9,allfaces=25,txtid=lighting
# Purple Lamp off
block:id=rp2-lighting-lampOff,data=10,allfaces=26,txtid=lighting
# Blue Lamp off
block:id=rp2-lighting-lampOff,data=11,allfaces=27,txtid=lighting
# Brown Lamp off
block:id=rp2-lighting-lampOff,data=12,allfaces=28,txtid=lighting
# Green Lamp off
block:id=rp2-lighting-lampOff,data=13,allfaces=29,txtid=lighting
# Red Lamp off
block:id=rp2-lighting-lampOff,data=14,allfaces=30,txtid=lighting
# Black Lamp off
block:id=rp2-lighting-lampOff,data=15,allfaces=31,txtid=lighting
############
# Blocks from RedPowerArray-2
############
# Array (array.array.id,0)
block:id=rp2-array-array,data=0,allsides=0,top=2,bottom=0,txtid=array,transparency=TRANSPARENT
# Inv-Array (array.array.id,1)
block:id=rp2-array-array,data=1,allsides=0,top=3,bottom=0,txtid=array,transparency=TRANSPARENT
# Non-Inv-Array (array.array.id,2)
block:id=rp2-array-array,data=2,allsides=0,top=5,bottom=0,txtid=array,transparency=TRANSPARENT
############
# Blocks from RedPowerMachine-2
############
# Deployer (machine.machine.id,0) - no orientation data yet - just face east
block:id=rp2-machine-machine,data=0,east=53,west=48,top=6055,bottom=4055,north=4056,south=6056,txtid=machine
# Breaker (machine.machine.id,1) - no orientation data yet - just face east
block:id=rp2-machine-machine,data=1,east=49,west=58,top=6051,bottom=4051,north=4051,south=6051,txtid=machine
# Transposer (machine.machine.id,2) - no orientation data yet - just face east
block:id=rp2-machine-machine,data=2,east=57,west=58,top=6059,bottom=4059,north=4059,south=6059,txtid=machine
# Filter (machine.machine.id,3) - no orientation data yet - just face east
block:id=rp2-machine-machine,data=3,east=57,west=58,top=6061,bottom=4061,north=4061,south=6061,txtid=machine
# Item Detector (machine.machine.id,4) - no orientation data yet - just face east
block:id=rp2-machine-machine,data=4,east=103,west=102,top=6100,bottom=4101,north=4096,south=6097,txtid=machine
# Sorter (machine.machine.id,5) - no orientation data yet - just face east
block:id=rp2-machine-machine,data=5,east=112,west=113,top=6116,bottom=4116,north=4116,south=6116,txtid=machine
# BatBox (machine.machine.id,6)
block:id=rp2-machine-machine,data=6,allsides=134,topbottom=128,txtid=machine
# Retriever (machine.machine.id,8) - no orientation data yet - just face east
block:id=rp2-machine-machine,data=8,east=125,west=124,top=6123,bottom=4123,north=4123,south=6123,txtid=machine
# Solar Panel (machine.machinePanel.id,0)
block:id=rp2-machine-machinePanel,data=0,top=85,bottom=84,allsides=86,txtid=machine
# Blue Furnace (base.appliance.id, 1) - no orientation data yet - just face east
block:id=rp2-base-appliance,data=1,east=82,west=80,top=83,bottom=83,north=80,south=80,txtid=machine
# Buffer (base.appliance.id, 2) - no orientation data yet - just face east
block:id=rp2-base-appliance,data=2,east=89,west=88,top=6088,bottom=4088,north=4088,south=6088,txtid=machine

View File

@ -6,40 +6,16 @@
</formats>
<fileSets>
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>README*</include>
<include>LICENSE*</include>
<include>NOTICE*</include>
<include>CHANGELOG*</include>
</includes>
</fileSet>
<directory>${project.build.directory}/core</directory>
<outputDirectory>/dynmap</outputDirectory>
<excludes>
<exclude>web/version.js</exclude></excludes></fileSet>
<fileSet>
<directory>${project.basedir}/web/</directory>
<outputDirectory>/dynmap/web/</outputDirectory>
<includes>
<include>version.js</include>
</includes>
<filtered>true</filtered>
</fileSet>
<fileSet>
<directory>${project.basedir}/web</directory>
<outputDirectory>/dynmap/web</outputDirectory>
<excludes>
<exclude>version.js</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${project.basedir}/colorschemes</directory>
<outputDirectory>/dynmap/colorschemes</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.basedir}/texturepacks</directory>
<outputDirectory>/dynmap/texturepacks</outputDirectory></fileSet>
<fileSet>
<directory>${project.basedir}/renderdata</directory>
<outputDirectory>/dynmap/renderdata</outputDirectory></fileSet>
<directory>${project.build.directory}/core/web</directory>
<outputDirectory>/dynmap/web</outputDirectory>
<includes>
<include>version.js</include></includes>
<filtered>true</filtered></fileSet>
</fileSets>
<files>
<file>

View File

@ -1,161 +0,0 @@
package org.dynmap;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
public class AsynchronousQueue<T> {
private Object lock = new Object();
private Thread thread;
private LinkedBlockingQueue<T> queue = new LinkedBlockingQueue<T>();
private Set<T> set = new HashSet<T>();
private Handler<T> handler;
private int dequeueTime;
private int accelDequeueTime;
private int accelDequeueThresh;
private int pendingcnt;
private int pendinglimit;
private boolean normalprio;
public AsynchronousQueue(Handler<T> handler, int dequeueTime, int accelDequeueThresh, int accelDequeueTime, int pendinglimit, boolean normalprio) {
this.handler = handler;
this.dequeueTime = dequeueTime;
this.accelDequeueTime = accelDequeueTime;
this.accelDequeueThresh = accelDequeueThresh;
if(pendinglimit < 1) pendinglimit = 1;
this.pendinglimit = pendinglimit;
this.normalprio = normalprio;
}
public boolean push(T t) {
synchronized (lock) {
if (!set.add(t)) {
return false;
}
}
queue.offer(t);
return true;
}
private T pop() {
try {
T t = queue.take();
synchronized (lock) {
set.remove(t);
}
return t;
} catch (InterruptedException ix) {
return null;
}
}
public boolean remove(T t) {
synchronized (lock) {
if (set.remove(t)) {
queue.remove(t);
return true;
}
}
return false;
}
public int size() {
return set.size();
}
public List<T> popAll() {
List<T> s;
synchronized(lock) {
s = new ArrayList<T>(queue);
queue.clear();
set.clear();
}
return s;
}
public void start() {
synchronized (lock) {
thread = new Thread(new Runnable() {
@Override
public void run() {
running();
}
});
thread.start();
try {
if(!normalprio)
thread.setPriority(Thread.MIN_PRIORITY);
} catch (SecurityException e) {
Log.info("Failed to set minimum priority for worker thread!");
}
}
}
public void stop() {
synchronized (lock) {
if (thread == null)
return;
Thread oldThread = thread;
thread = null;
Log.info("Stopping map renderer...");
oldThread.interrupt();
try {
oldThread.join(1000);
} catch (InterruptedException e) {
Log.info("Waiting for map renderer to stop is interrupted");
}
}
}
private void running() {
try {
while (Thread.currentThread() == thread) {
synchronized(lock) {
while(pendingcnt >= pendinglimit) {
try {
lock.wait(accelDequeueTime);
} catch (InterruptedException ix) {
if(Thread.currentThread() != thread)
return;
throw ix;
}
}
}
T t = pop();
if (t != null) {
synchronized(lock) {
pendingcnt++;
}
handler.handle(t);
}
if(set.size() >= accelDequeueThresh)
sleep(accelDequeueTime);
else
sleep(dequeueTime);
}
} catch (Exception ex) {
Log.severe("Exception on rendering-thread", ex);
}
}
private boolean sleep(int time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
return false;
}
return true;
}
public void done(T t) {
synchronized (lock) {
if(pendingcnt > 0) pendingcnt--;
lock.notifyAll();
}
}
}

View File

@ -1,12 +0,0 @@
package org.dynmap;
public class ChatEvent {
public String source;
public String name;
public String message;
public ChatEvent(String source, String name, String message) {
this.source = source;
this.name = name;
this.message = message;
}
}

View File

@ -1,160 +0,0 @@
package org.dynmap;
import java.io.IOException;
import java.io.Writer;
import org.json.simple.JSONAware;
import org.json.simple.JSONStreamAware;
import org.dynmap.common.DynmapChatColor;
public class Client {
public static class Update implements JSONAware, JSONStreamAware {
public long timestamp = System.currentTimeMillis();
@Override
public String toJSONString() {
return org.dynmap.web.Json.stringifyJson(this);
}
@Override
public void writeJSONString(Writer w) throws IOException {
// TODO: This isn't the best...
w.write(toJSONString());
}
}
public static class ChatMessage extends Update {
public String type = "chat";
public String source;
public String playerName;
public String message;
public String account;
public String channel;
public ChatMessage(String source, String channel, String playerName, String message, String playeraccount) {
this.source = source;
this.playerName = Client.stripColor(playerName);
this.message = DynmapChatColor.stripColor(message);
this.account = playeraccount;
this.channel = channel;
}
@Override
public boolean equals(Object o) {
if(o instanceof ChatMessage) {
ChatMessage m = (ChatMessage)o;
return m.source.equals(source) && m.playerName.equals(playerName) && m.message.equals(message);
}
return false;
}
@Override
public int hashCode() {
return source.hashCode() ^ playerName.hashCode() ^ message.hashCode();
}
}
public static class PlayerJoinMessage extends Update {
public String type = "playerjoin";
public String playerName;
public String account;
public PlayerJoinMessage(String playerName, String playeraccount) {
this.playerName = Client.stripColor(playerName);
this.account = playeraccount;
}
@Override
public boolean equals(Object o) {
if(o instanceof PlayerJoinMessage) {
PlayerJoinMessage m = (PlayerJoinMessage)o;
return m.playerName.equals(playerName);
}
return false;
}
@Override
public int hashCode() {
return playerName.hashCode();
}
}
public static class PlayerQuitMessage extends Update {
public String type = "playerquit";
public String playerName;
public String account;
public PlayerQuitMessage(String playerName, String playeraccount) {
this.playerName = Client.stripColor(playerName);
this.account = playeraccount;
}
@Override
public boolean equals(Object o) {
if(o instanceof PlayerQuitMessage) {
PlayerQuitMessage m = (PlayerQuitMessage)o;
return m.playerName.equals(playerName);
}
return false;
}
@Override
public int hashCode() {
return playerName.hashCode();
}
}
public static class Tile extends Update {
public String type = "tile";
public String name;
public Tile(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if(o instanceof Tile) {
Tile m = (Tile)o;
return m.name.equals(name);
}
return false;
}
@Override
public int hashCode() {
return name.hashCode();
}
}
public static class DayNight extends Update {
public String type = "daynight";
public boolean isday;
public DayNight(boolean isday) {
this.isday = isday;
}
@Override
public boolean equals(Object o) {
if(o instanceof DayNight) {
return true;
}
return false;
}
@Override
public int hashCode() {
return 12345;
}
}
public static class ComponentMessage extends Update {
public String type = "component";
/* Each subclass must provide 'ctype' string for component 'type' */
}
public static String stripColor(String s) {
s = DynmapChatColor.stripColor(s); /* Strip standard color encoding */
/* Handle Essentials nickname encoding too */
int idx = 0;
while((idx = s.indexOf('&', idx)) >= 0) {
char c = s.charAt(idx+1); /* Get next character */
if(c == '&') { /* Another ampersand */
s = s.substring(0, idx) + s.substring(idx+1);
}
else {
s = s.substring(0, idx) + s.substring(idx+2);
}
idx++;
}
return s;
}
}

View File

@ -1,67 +0,0 @@
package org.dynmap;
import static org.dynmap.JSONUtils.a;
import static org.dynmap.JSONUtils.s;
import java.util.List;
import java.util.Map;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
public class ClientComponent extends Component {
private boolean disabled;
public ClientComponent(final DynmapCore plugin, final ConfigurationNode configuration) {
super(plugin, configuration);
plugin.events.addListener("buildclientconfiguration", new Event.Listener<JSONObject>() {
@Override
public void triggered(JSONObject root) {
if(!disabled)
buildClientConfiguration(root);
}
});
}
protected void disableComponent() {
disabled = true;
}
protected void buildClientConfiguration(JSONObject root) {
JSONObject o = createClientConfiguration();
a(root, "components", o);
}
protected JSONObject createClientConfiguration() {
JSONObject o = convertMap(configuration);
o.remove("class");
return o;
}
protected static final JSONObject convertMap(Map<String, ?> m) {
JSONObject o = new JSONObject();
for(Map.Entry<String, ?> entry : m.entrySet()) {
s(o, entry.getKey(), convert(entry.getValue()));
}
return o;
}
@SuppressWarnings("unchecked")
protected static final JSONArray convertList(List<?> l) {
JSONArray o = new JSONArray();
for(Object entry : l) {
o.add(convert(entry));
}
return o;
}
@SuppressWarnings("unchecked")
protected static final Object convert(Object o) {
if (o instanceof Map<?, ?>) {
return convertMap((Map<String, ?>)o);
} else if (o instanceof List<?>) {
return convertList((List<?>)o);
}
return o;
}
}

View File

@ -1,67 +0,0 @@
package org.dynmap;
import static org.dynmap.JSONUtils.a;
import static org.dynmap.JSONUtils.s;
import org.dynmap.Event.Listener;
import org.json.simple.JSONObject;
public class ClientConfigurationComponent extends Component {
public ClientConfigurationComponent(final DynmapCore core, ConfigurationNode configuration) {
super(core, configuration);
core.events.<JSONObject>addListener("buildclientconfiguration", new Listener<JSONObject>() {
@Override
public void triggered(JSONObject t) {
ConfigurationNode c = core.configuration;
s(t, "confighash", core.getConfigHashcode());
s(t, "updaterate", c.getFloat("updaterate", 1.0f));
s(t, "showplayerfacesinmenu", c.getBoolean("showplayerfacesinmenu", true));
s(t, "joinmessage", c.getString("joinmessage", "%playername% joined"));
s(t, "quitmessage", c.getString("quitmessage", "%playername% quit"));
s(t, "spammessage", c.getString("spammessage", "You may only chat once every %interval% seconds."));
s(t, "webprefix", unescapeString(c.getString("webprefix", "[WEB] ")));
s(t, "defaultzoom", c.getInteger("defaultzoom", 0));
s(t, "sidebaropened", c.getString("sidebaropened", "false"));
s(t, "dynmapversion", core.getDynmapCoreVersion());
s(t, "cyrillic", c.getBoolean("cyrillic-support", false));
s(t, "showlayercontrol", c.getString("showlayercontrol", "true"));
s(t, "grayplayerswhenhidden", c.getBoolean("grayplayerswhenhidden", true));
String sn = core.getServer().getServerName();
if(sn.equals("Unknown Server"))
sn = "Minecraft Dynamic Map";
s(t, "title", c.getString("webpage-title", sn));
s(t, "msg-maptypes", c.getString("msg/maptypes", "Map Types"));
s(t, "msg-players", c.getString("msg/players", "Players"));
DynmapWorld defaultWorld = null;
String defmap = null;
for(DynmapWorld world : core.mapManager.getWorlds()) {
if (defaultWorld == null) defaultWorld = world;
ConfigurationNode wn = world.configuration;
JSONObject wo = new JSONObject();
s(wo, "name", wn.getString("name"));
s(wo, "title", wn.getString("title"));
DynmapLocation spawn = world.getSpawnLocation();
s(wo, "center/x", wn.getDouble("center/x", spawn.x));
s(wo, "center/y", wn.getDouble("center/y", spawn.y));
s(wo, "center/z", wn.getDouble("center/z", spawn.z));
s(wo, "bigworld", world.bigworld);
s(wo, "extrazoomout", world.getExtraZoomOutLevels());
a(t, "worlds", wo);
for(MapType mt : world.maps) {
mt.buildClientConfiguration(wo, world);
if(defmap == null) defmap = mt.getName();
}
}
s(t, "defaultworld", c.getString("defaultworld", defaultWorld == null ? "world" : defaultWorld.getName()));
s(t, "defaultmap", c.getString("defaultmap", defmap == null ? "surface" : defmap));
if(c.getString("followmap", null) != null)
s(t, "followmap", c.getString("followmap"));
if(c.getInteger("followzoom",-1) >= 0)
s(t, "followzoom", c.getInteger("followzoom", 0));
}
});
}
}

View File

@ -1,118 +0,0 @@
package org.dynmap;
import static org.dynmap.JSONUtils.a;
import static org.dynmap.JSONUtils.s;
import java.util.List;
import org.dynmap.common.DynmapPlayer;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
public class ClientUpdateComponent extends Component {
public ClientUpdateComponent(final DynmapCore plugin, ConfigurationNode configuration) {
super(plugin, configuration);
plugin.events.addListener("buildclientupdate", new Event.Listener<ClientUpdateEvent>() {
@Override
public void triggered(ClientUpdateEvent e) {
buildClientUpdate(e);
}
});
}
protected void buildClientUpdate(ClientUpdateEvent e) {
DynmapWorld world = e.world;
JSONObject u = e.update;
long since = e.timestamp;
String worldName = world.getName();
int hideifshadow = configuration.getInteger("hideifshadow", 15);
int hideifunder = configuration.getInteger("hideifundercover", 15);
boolean hideifsneaking = configuration.getBoolean("hideifsneaking", false);
s(u, "confighash", core.getConfigHashcode());
s(u, "servertime", world.getTime() % 24000);
s(u, "hasStorm", world.hasStorm());
s(u, "isThundering", world.isThundering());
s(u, "players", new JSONArray());
List<DynmapPlayer> players = core.playerList.getVisiblePlayers();
for(DynmapPlayer p : players) {
DynmapLocation pl = p.getLocation();
DynmapWorld pw = core.getWorld(pl.world);
if(pw == null)
continue;
JSONObject jp = new JSONObject();
boolean hide = false;
s(jp, "type", "player");
s(jp, "name", Client.stripColor(p.getDisplayName()));
s(jp, "account", p.getName());
if(hideifshadow < 15) {
if(pw.getLightLevel((int)pl.x, (int)pl.y, (int)pl.z) <= hideifshadow)
hide = true;
}
if(hideifunder < 15) {
if(pw.canGetSkyLightLevel()) { /* If we can get real sky level */
if(pw.getSkyLightLevel((int)pl.x, (int)pl.y, (int)pl.z) <= hideifunder)
hide = true;
}
else {
if(pw.getHighestBlockYAt((int)pl.x, (int)pl.z) > pl.y)
hide = true;
}
}
if(hideifsneaking && p.isSneaking())
hide = true;
/* Don't leak player location for world not visible on maps, or if sendposition disbaled */
DynmapWorld pworld = MapManager.mapman.worldsLookup.get(pl.world);
/* Fix typo on 'sendpositon' to 'sendposition', keep bad one in case someone used it */
if(configuration.getBoolean("sendposition", true) && configuration.getBoolean("sendpositon", true) &&
(pworld != null) && pworld.sendposition && (!hide)) {
s(jp, "world", pl.world);
s(jp, "x", pl.x);
s(jp, "y", pl.y);
s(jp, "z", pl.z);
}
else {
s(jp, "world", "-some-other-bogus-world-");
s(jp, "x", 0.0);
s(jp, "y", 64.0);
s(jp, "z", 0.0);
}
/* Only send health if enabled AND we're on visible world */
if (configuration.getBoolean("sendhealth", false) && (pworld != null) && pworld.sendhealth && (!hide)) {
s(jp, "health", p.getHealth());
s(jp, "armor", p.getArmorPoints());
}
else {
s(jp, "health", 0);
s(jp, "armor", 0);
}
a(u, "players", jp);
}
if(configuration.getBoolean("includehiddenplayers", false)) {
List<DynmapPlayer> hidden = core.playerList.getHiddenPlayers();
for(DynmapPlayer p : hidden) {
JSONObject jp = new JSONObject();
s(jp, "type", "player");
s(jp, "name", Client.stripColor(p.getDisplayName()));
s(jp, "account", p.getName());
s(jp, "world", "-hidden-player-");
s(jp, "x", 0.0);
s(jp, "y", 64.0);
s(jp, "z", 0.0);
s(jp, "health", 0);
s(jp, "armor", 0);
a(u, "players", jp);
}
}
s(u, "updates", new JSONArray());
for(Object update : core.mapManager.getWorldUpdates(worldName, since)) {
a(u, "updates", (Client.Update)update);
}
}
}

View File

@ -1,15 +0,0 @@
package org.dynmap;
import org.json.simple.JSONObject;
public class ClientUpdateEvent {
public long timestamp;
public DynmapWorld world;
public JSONObject update;
public ClientUpdateEvent(long timestamp, DynmapWorld world, JSONObject update) {
this.timestamp = timestamp;
this.world = world;
this.update = update;
}
}

View File

@ -1,74 +0,0 @@
package org.dynmap;
/**
* Simple replacement for java.awt.Color for dynmap - it's not an invariant, so we don't make millions
* of them during rendering
*/
public class Color {
/* ARGB 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);
}
public Color(int red, int green, int blue) {
setRGBA(red, green, blue, 0xFF);
}
public Color() {
setTransparent();
}
public final int getRed() {
return (val >> 16) & 0xFF;
}
public final int getGreen() {
return (val >> 8) & 0xFF;
}
public final int getBlue() {
return val & 0xFF;
}
public final int getAlpha() {
return ((val >> 24) & 0xFF);
}
public final boolean isTransparent() {
return ((val & 0xFF000000) == TRANSPARENT);
}
public final void setTransparent() {
val = TRANSPARENT;
}
public final void setColor(Color c) {
val = c.val;
}
public final void setRGBA(int red, int green, int blue, int alpha) {
val = ((alpha & 0xFF) << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF);
}
public final int getARGB() {
return val;
}
public final void setARGB(int c) {
val = c;
}
public final int getComponent(int idx) {
return 0xFF & (val >> ((3-idx)*8));
}
public final void setAlpha(int v) {
val = (val & 0x00FFFFFF) | (v << 24);
}
/**
* Scale each color component, based on the corresponding component
*/
public final void blendColor(Color c) {
blendColor(c.val);
}
/**
* Scale each color component, based on the corresponding component
*/
public final void blendColor(int argb) {
int nval = (((((val >> 24) & 0xFF) * ((argb >> 24) & 0xFF)) / 255) << 24);
nval = nval | (((((val >> 16) & 0xFF) * ((argb >> 16) & 0xFF)) / 255) << 16);
nval = nval | (((((val >> 8) & 0xFF) * ((argb >> 8) & 0xFF)) / 255) << 8);
nval = nval | (((val & 0xFF) * (argb & 0xFF)) / 255);
val = nval;
}
}

View File

@ -1,250 +0,0 @@
package org.dynmap;
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 org.dynmap.common.BiomeMap;
import org.dynmap.debug.Debug;
public class ColorScheme {
private static final HashMap<String, ColorScheme> cache = new HashMap<String, ColorScheme>();
public String name;
/* Switch to arrays - faster than map */
public final Color[][] colors; /* [blk-type][step] */
public final Color[][][] datacolors; /* [bkt-type][blk-dat][step] */
public final Color[][] biomecolors; /* [Biome.ordinal][step] */
public final Color[][] raincolors; /* [rain * 63][step] */
public final Color[][] tempcolors; /* [temp * 63][step] */
public ColorScheme(String name, Color[][] colors, Color[][][] datacolors, Color[][] biomecolors, Color[][] raincolors, Color[][] tempcolors) {
this.name = name;
this.colors = colors;
this.datacolors = datacolors;
this.biomecolors = biomecolors;
this.raincolors = raincolors;
this.tempcolors = tempcolors;
if(MapManager.mapman.getHideOres()) {
for(int i = 0; i < colors.length; i++) {
int id = MapManager.mapman.getBlockIDAlias(i);
if(id != i) {
this.colors[i] = this.colors[id];
this.datacolors[i] = this.datacolors[id];
}
}
}
}
private static File getColorSchemeDirectory(DynmapCore core) {
return new File(core.getDataFolder(), "colorschemes");
}
public static ColorScheme getScheme(DynmapCore core, String name) {
if (name == null)
name = "default";
ColorScheme scheme = cache.get(name);
if (scheme == null) {
scheme = loadScheme(core, name);
cache.put(name, scheme);
}
return scheme;
}
public static ColorScheme loadScheme(DynmapCore core, String name) {
File colorSchemeFile = new File(getColorSchemeDirectory(core), name + ".txt");
Color[][] colors = new Color[256][];
Color[][][] datacolors = new Color[256][][];
Color[][] biomecolors = new Color[BiomeMap.values().length][];
Color[][] raincolors = new Color[64][];
Color[][] tempcolors = new Color[64][];
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;
}
/* Make parser less pedantic - tabs or spaces should be fine */
String[] split = line.split("[\t ]");
int cnt = 0;
for(String s: split) { if(s.length() > 0) cnt++; }
String[] nsplit = new String[cnt];
cnt = 0;
for(String s: split) { if(s.length() > 0) { nsplit[cnt] = s; cnt++; } }
split = nsplit;
if (split.length < 17) {
continue;
}
Integer id;
Integer dat = null;
boolean isbiome = false;
boolean istemp = false;
boolean israin = false;
int idx = split[0].indexOf(':');
if(idx > 0) { /* ID:data - data color */
id = new Integer(split[0].substring(0, idx));
dat = new Integer(split[0].substring(idx+1));
}
else if(split[0].charAt(0) == '[') { /* Biome color data */
String bio = split[0].substring(1);
idx = bio.indexOf(']');
if(idx >= 0) bio = bio.substring(0, idx);
isbiome = true;
id = -1;
for(BiomeMap b : BiomeMap.values()) {
if(b.toString().equalsIgnoreCase(bio)) {
id = b.ordinal();
break;
}
}
if(id < 0) { /* Not biome - check for rain or temp */
if(bio.startsWith("RAINFALL-")) {
try {
double v = Double.parseDouble(bio.substring(9));
if((v >= 0) && (v <= 1.00)) {
id = (int)(v * 63.0);
israin = true;
}
} catch (NumberFormatException nfx) {
}
}
else if(bio.startsWith("TEMPERATURE-")) {
try {
double v = Double.parseDouble(bio.substring(12));
if((v >= 0) && (v <= 1.00)) {
id = (int)(v * 63.0);
istemp = true;
}
} catch (NumberFormatException nfx) {
}
}
}
}
else {
id = new Integer(split[0]);
}
Color[] c = new Color[5];
/* 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]));
/* Blended color - for 'smooth' option on flat map */
c[4] = new Color((c[1].getRed()+c[3].getRed())/2, (c[1].getGreen()+c[3].getGreen())/2, (c[1].getBlue()+c[3].getBlue())/2, (c[1].getAlpha()+c[3].getAlpha())/2);
if(isbiome) {
if(istemp) {
tempcolors[id] = c;
}
else if(israin) {
raincolors[id] = c;
}
else if((id >= 0) && (id < biomecolors.length))
biomecolors[id] = c;
}
else if(dat != null) {
Color[][] dcolor = datacolors[id]; /* Existing list? */
if(dcolor == null) {
dcolor = new Color[16][]; /* Make 16 index long list */
datacolors[id] = dcolor;
}
if((dat >= 0) && (dat < 16)) { /* Add color to list */
dcolor[dat] = c;
}
if(dat == 0) { /* Index zero is base color too */
colors[id] = c;
}
}
else {
colors[id] = c;
}
nc += 1;
}
scanner.close();
/* Last, push base color into any open slots in data colors list */
for(int k = 0; k < 256; k++) {
Color[][] dc = datacolors[k]; /* see if data colors too */
if(dc != null) {
Color[] c = colors[k];
for(int i = 0; i < 16; i++) {
if(dc[i] == null)
dc[i] = c;
}
}
}
/* And interpolate any missing rain and temperature colors */
interpolateColorTable(tempcolors);
interpolateColorTable(raincolors);
} catch (RuntimeException e) {
Log.severe("Could not load colors '" + name + "' ('" + colorSchemeFile + "').", e);
return null;
} catch (FileNotFoundException e) {
Log.severe("Could not load colors '" + name + "' ('" + colorSchemeFile + "'): File not found.", e);
}
return new ColorScheme(name, colors, datacolors, biomecolors, raincolors, tempcolors);
}
public static void interpolateColorTable(Color[][] c) {
int idx = -1;
for(int k = 0; k < c.length; k++) {
if(c[k] == null) { /* Missing? */
if((idx >= 0) && (k == (c.length-1))) { /* We're last - so fill forward from last color */
for(int kk = idx+1; kk <= k; kk++) {
c[kk] = c[idx];
}
}
/* Skip - will backfill when we find next color */
}
else if(idx == -1) { /* No previous color, just backfill this color */
for(int kk = 0; kk < k; kk++) {
c[kk] = c[k];
}
idx = k; /* This is now last defined color */
}
else { /* Else, interpolate between last idx and this one */
int cnt = c[k].length;
for(int kk = idx+1; kk < k; kk++) {
double interp = (double)(kk-idx)/(double)(k-idx);
Color[] cc = new Color[cnt];
for(int jj = 0; jj < cnt; jj++) {
cc[jj] = new Color(
(int)((1.0-interp)*c[idx][jj].getRed() + interp*c[k][jj].getRed()),
(int)((1.0-interp)*c[idx][jj].getGreen() + interp*c[k][jj].getGreen()),
(int)((1.0-interp)*c[idx][jj].getBlue() + interp*c[k][jj].getBlue()),
(int)((1.0-interp)*c[idx][jj].getAlpha() + interp*c[k][jj].getAlpha()));
}
c[kk] = cc;
}
idx = k;
}
}
}
public Color[] getRainColor(double rain) {
int idx = (int)(rain * 63.0);
if((idx >= 0) && (idx < raincolors.length))
return raincolors[idx];
else
return null;
}
public Color[] getTempColor(double temp) {
int idx = (int)(temp * 63.0);
if((idx >= 0) && (idx < tempcolors.length))
return tempcolors[idx];
else
return null;
}
public static void reset() {
cache.clear();
}
}

View File

@ -1,21 +0,0 @@
package org.dynmap;
public abstract class Component {
protected DynmapCore core;
protected ConfigurationNode configuration;
public Component(DynmapCore core, ConfigurationNode configuration) {
this.core = core;
this.configuration = configuration;
}
public void dispose() {
}
/* Substitute proper values for escape sequences */
public static String unescapeString(String v) {
/* Replace color code &color; */
v = v.replace("&color;", "\u00A7");
return v;
}
}

View File

@ -1,47 +0,0 @@
package org.dynmap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ComponentManager {
public Set<Component> components = new HashSet<Component>();
public Map<String, List<Component>> componentLookup = new HashMap<String, List<Component>>();
public void add(Component c) {
if (components.add(c)) {
String key = c.getClass().toString();
List<Component> clist = componentLookup.get(key);
if (clist == null) {
clist = new ArrayList<Component>();
componentLookup.put(key, clist);
}
clist.add(c);
}
}
public void remove(Component c) {
if (components.remove(c)) {
String key = c.getClass().toString();
List<Component> clist = componentLookup.get(key);
if (clist != null) {
clist.remove(c);
}
}
}
public void clear() {
componentLookup.clear();
components.clear();
}
public Iterable<Component> getComponents(Class<Component> c) {
List<Component> list = componentLookup.get(c.toString());
if (list == null)
return new ArrayList<Component>();
return list;
}
}

View File

@ -1,426 +0,0 @@
package org.dynmap;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.introspector.Property;
import org.yaml.snakeyaml.nodes.CollectionNode;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.yaml.snakeyaml.nodes.SequenceNode;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.reader.UnicodeReader;
import org.yaml.snakeyaml.representer.Represent;
import org.yaml.snakeyaml.representer.Representer;
public class ConfigurationNode implements Map<String, Object> {
public Map<String, Object> entries;
private File f;
private Yaml yaml;
public ConfigurationNode() {
entries = new HashMap<String, Object>();
}
private void initparse() {
if(yaml == null) {
DumperOptions options = new DumperOptions();
options.setIndent(4);
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
yaml = new Yaml(new SafeConstructor(), new EmptyNullRepresenter(), options);
}
}
public ConfigurationNode(File f) {
this.f = f;
entries = new HashMap<String, Object>();
}
public ConfigurationNode(Map<String, Object> map) {
if (map == null) {
throw new IllegalArgumentException();
}
entries = map;
}
public ConfigurationNode(InputStream in) {
load(in);
}
@SuppressWarnings("unchecked")
public boolean load(InputStream in) {
initparse();
Object o = yaml.load(new UnicodeReader(in));
if((o != null) && (o instanceof Map))
entries = (Map<String, Object>)o;
return (entries != null);
}
@SuppressWarnings("unchecked")
public boolean load() {
initparse();
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
Object o = yaml.load(new UnicodeReader(fis));
if((o != null) && (o instanceof Map))
entries = (Map<String, Object>)o;
fis.close();
} catch(IOException iox) {
Log.severe("Error reading " + f.getPath());
return false;
} finally {
if(fis != null) {
try { fis.close(); } catch (IOException x) {}
}
}
return (entries != null);
}
public boolean save() {
return save(f);
}
public boolean save(File file) {
initparse();
FileOutputStream stream = null;
File parent = file.getParentFile();
if (parent != null) {
parent.mkdirs();
}
try {
stream = new FileOutputStream(file);
OutputStreamWriter writer = new OutputStreamWriter(stream, "UTF-8");
yaml.dump(entries, writer);
return true;
} catch (IOException e) {
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (IOException e) {}
}
return false;
}
@SuppressWarnings("unchecked")
public Object getObject(String path) {
if (path.isEmpty())
return entries;
int separator = path.indexOf('/');
if (separator < 0)
return get(path);
String localKey = path.substring(0, separator);
Object subvalue = get(localKey);
if (subvalue == null)
return null;
if (!(subvalue instanceof Map<?, ?>))
return null;
Map<String, Object> submap;
try {
submap = (Map<String, Object>)subvalue;
} catch (ClassCastException e) {
return null;
}
String subpath = path.substring(separator + 1);
return new ConfigurationNode(submap).getObject(subpath);
}
public Object getObject(String path, Object def) {
Object o = getObject(path);
if (o == null)
return def;
return o;
}
@SuppressWarnings("unchecked")
public <T> T getGeneric(String path, T def) {
Object o = getObject(path, def);
try {
return (T)o;
} catch(ClassCastException e) {
return def;
}
}
public int getInteger(String path, int def) {
return Integer.parseInt(getObject(path, def).toString());
}
public double getLong(String path, long def) {
return Long.parseLong(getObject(path, def).toString());
}
public float getFloat(String path, float def) {
return Float.parseFloat(getObject(path, def).toString());
}
public double getDouble(String path, double def) {
return Double.parseDouble(getObject(path, def).toString());
}
public boolean getBoolean(String path, boolean def) {
return Boolean.parseBoolean(getObject(path, def).toString());
}
public String getString(String path) {
return getString(path, null);
}
public List<String> getStrings(String path, List<String> def) {
Object o = getObject(path);
if (!(o instanceof List<?>)) {
return def;
}
ArrayList<String> strings = new ArrayList<String>();
for(Object i : (List<?>)o) {
strings.add(i.toString());
}
return strings;
}
public String getString(String path, String def) {
Object o = getObject(path, def);
if (o == null)
return null;
return o.toString();
}
@SuppressWarnings("unchecked")
public <T> List<T> getList(String path) {
try {
List<T> list = (List<T>)getObject(path, null);
return list;
} catch (ClassCastException e) {
try {
T o = (T)getObject(path, null);
if (o == null) {
return new ArrayList<T>();
}
ArrayList<T> al = new ArrayList<T>();
al.add(o);
return al;
} catch (ClassCastException e2) {
return new ArrayList<T>();
}
}
}
public List<Map<String,Object>> getMapList(String path) {
return getList(path);
}
public ConfigurationNode getNode(String path) {
Map<String, Object> v = null;
v = getGeneric(path, v);
if (v == null)
return null;
return new ConfigurationNode(v);
}
@SuppressWarnings("unchecked")
public List<ConfigurationNode> getNodes(String path) {
List<Object> o = getList(path);
if(o == null)
return new ArrayList<ConfigurationNode>();
ArrayList<ConfigurationNode> nodes = new ArrayList<ConfigurationNode>();
for(Object i : (List<?>)o) {
if (i instanceof Map<?, ?>) {
Map<String, Object> map;
try {
map = (Map<String, Object>)i;
} catch(ClassCastException e) {
continue;
}
nodes.add(new ConfigurationNode(map));
}
}
return nodes;
}
public void extend(Map<String, Object> other) {
if (other != null)
extendMap(this, other);
}
@SuppressWarnings("unchecked")
private final static void extendMap(Map<String, Object> left, Map<String, Object> right) {
ConfigurationNode original = new ConfigurationNode(left);
for(Map.Entry<String, Object> entry : right.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof Map<?, ?>) {
ConfigurationNode subnode = original.getNode(key);
if (subnode == null) {
original.put(key, subnode = new ConfigurationNode());
}
extendMap(subnode, (Map<String, Object>)value);
} else {
original.put(key, value);
}
}
}
public <T> T createInstance(Class<?>[] constructorParameters, Object[] constructorArguments) {
String typeName = getString("class");
try {
Class<?> mapTypeClass = Class.forName(typeName);
Class<?>[] constructorParameterWithConfiguration = new Class<?>[constructorParameters.length+1];
for(int i = 0; i < constructorParameters.length; i++) { constructorParameterWithConfiguration[i] = constructorParameters[i]; }
constructorParameterWithConfiguration[constructorParameterWithConfiguration.length-1] = ConfigurationNode.class;
Object[] constructorArgumentsWithConfiguration = new Object[constructorArguments.length+1];
for(int i = 0; i < constructorArguments.length; i++) { constructorArgumentsWithConfiguration[i] = constructorArguments[i]; }
constructorArgumentsWithConfiguration[constructorArgumentsWithConfiguration.length-1] = this;
Constructor<?> constructor = mapTypeClass.getConstructor(constructorParameterWithConfiguration);
@SuppressWarnings("unchecked")
T t = (T)constructor.newInstance(constructorArgumentsWithConfiguration);
return t;
} catch (Exception e) {
// TODO: Remove reference to MapManager.
Log.severe("Error loading maptype", e);
e.printStackTrace();
}
return null;
}
public <T> List<T> createInstances(String path, Class<?>[] constructorParameters, Object[] constructorArguments) {
List<ConfigurationNode> nodes = getNodes(path);
List<T> instances = new ArrayList<T>();
for(ConfigurationNode node : nodes) {
T instance = node.<T>createInstance(constructorParameters, constructorArguments);
if (instance != null) {
instances.add(instance);
}
}
return instances;
}
@Override
public int size() {
return entries.size();
}
@Override
public boolean isEmpty() {
return entries.isEmpty();
}
@Override
public boolean containsKey(Object key) {
return entries.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
return entries.containsValue(value);
}
@Override
public Object get(Object key) {
return entries.get(key);
}
@Override
public Object put(String key, Object value) {
return entries.put(key, value);
}
@Override
public Object remove(Object key) {
return entries.remove(key);
}
@Override
public void putAll(Map<? extends String, ? extends Object> m) {
entries.putAll(m);
}
@Override
public void clear() {
entries.clear();
}
@Override
public Set<String> keySet() {
return entries.keySet();
}
@Override
public Collection<Object> values() {
return entries.values();
}
@Override
public Set<java.util.Map.Entry<String, Object>> entrySet() {
return entries.entrySet();
}
private class EmptyNullRepresenter extends Representer {
public EmptyNullRepresenter() {
super();
this.nullRepresenter = new EmptyRepresentNull();
}
protected class EmptyRepresentNull implements Represent {
public Node representData(Object data) {
return representScalar(Tag.NULL, ""); // Changed "null" to "" so as to avoid writing nulls
}
}
// Code borrowed from snakeyaml (http://code.google.com/p/snakeyaml/source/browse/src/test/java/org/yaml/snakeyaml/issues/issue60/SkipBeanTest.java)
@Override
protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
NodeTuple tuple = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
Node valueNode = tuple.getValueNode();
if (valueNode instanceof CollectionNode) {
// Removed null check
if (Tag.SEQ.equals(valueNode.getTag())) {
SequenceNode seq = (SequenceNode) valueNode;
if (seq.getValue().isEmpty()) {
return null; // skip empty lists
}
}
if (Tag.MAP.equals(valueNode.getTag())) {
MappingNode seq = (MappingNode) valueNode;
if (seq.getValue().isEmpty()) {
return null; // skip empty maps
}
}
}
return tuple;
}
// End of borrowed code
}
}

View File

@ -1,10 +0,0 @@
package org.dynmap;
public class DynmapChunk {
public int x, z;
public DynmapChunk(int x, int z) {
this.x = x;
this.z = z;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +0,0 @@
package org.dynmap;
/**
* Generic block location
*/
public class DynmapLocation {
public double x, y, z;
public String world;
public DynmapLocation() {}
public DynmapLocation(String w, double x, double y, double z) {
world = w;
this.x = x; this.y = y; this.z = z;
}
}

View File

@ -1,525 +0,0 @@
package org.dynmap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.dynmap.debug.Debug;
import org.dynmap.utils.DynmapBufferedImage;
import org.dynmap.utils.FileLockManager;
import org.dynmap.utils.MapChunkCache;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import javax.imageio.ImageIO;
public abstract class DynmapWorld {
public enum AutoGenerateOption {
NONE,
FORMAPONLY,
PERMANENT
}
public List<MapType> maps = new ArrayList<MapType>();
public UpdateQueue updates = new UpdateQueue();
public ConfigurationNode configuration;
public List<DynmapLocation> seedloc;
public List<MapChunkCache.VisibilityLimit> visibility_limits;
public List<MapChunkCache.VisibilityLimit> hidden_limits;
public AutoGenerateOption do_autogenerate;
public MapChunkCache.HiddenChunkStyle hiddenchunkstyle;
public int servertime;
public boolean sendposition;
public boolean sendhealth;
public boolean bigworld; /* If true, deeper directory hierarchy */
private int extrazoomoutlevels; /* Number of additional zoom out levels to generate */
public File worldtilepath;
private Object lock = new Object();
@SuppressWarnings("unchecked")
private HashSet<String> zoomoutupdates[] = new HashSet[0];
private boolean checkts = true; /* Check timestamps on first run with new configuration */
private boolean cancelled;
private String wname;
protected DynmapWorld(String wname) {
this.wname = wname;
}
@SuppressWarnings("unchecked")
public void setExtraZoomOutLevels(int lvl) {
extrazoomoutlevels = lvl;
zoomoutupdates = new HashSet[lvl];
for(int i = 0; i < lvl; i++)
zoomoutupdates[i] = new HashSet<String>();
checkts = true;
}
public int getExtraZoomOutLevels() { return extrazoomoutlevels; }
public void enqueueZoomOutUpdate(File f) {
enqueueZoomOutUpdate(f, 0);
}
private void enqueueZoomOutUpdate(File f, int level) {
synchronized(lock) {
if(level >= zoomoutupdates.length) {
@SuppressWarnings("unchecked")
HashSet<String> new_zoomout[] = new HashSet[level+1];
System.arraycopy(zoomoutupdates, 0, new_zoomout, 0, zoomoutupdates.length);
for(int i = 0; i < new_zoomout.length; i++) {
if(i < zoomoutupdates.length)
new_zoomout[i] = zoomoutupdates[i];
else
new_zoomout[i] = new HashSet<String>();
}
zoomoutupdates = new_zoomout;
}
zoomoutupdates[level].add(f.getPath());
}
}
private boolean popQueuedUpdate(File f, int level) {
if(level >= zoomoutupdates.length)
return false;
synchronized(lock) {
return zoomoutupdates[level].remove(f.getPath());
}
}
private String[] peekQueuedUpdates(int level) {
if(level >= zoomoutupdates.length)
return new String[0];
synchronized(lock) {
return zoomoutupdates[level].toArray(new String[zoomoutupdates[level].size()]);
}
}
private static class DirFilter implements FilenameFilter {
public boolean accept(File f, String n) {
if(!n.equals("..") && !n.equals(".")) {
File fn = new File(f, n);
return fn.isDirectory();
}
return false;
}
}
private static final String COORDSTART = "-0123456789";
private static class PNGFileFilter implements FilenameFilter {
String prefix;
String suffix;
public PNGFileFilter(String pre, MapType.ImageFormat fmt) {
if((pre != null) && (pre.length() > 0))
prefix = pre;
suffix = "." + fmt.getFileExt();
}
public boolean accept(File f, String n) {
if(n.endsWith(suffix)) {
if((prefix != null) && (!n.startsWith(prefix)))
return false;
if((prefix == null) && (COORDSTART.indexOf(n.charAt(0)) < 0))
return false;
File fn = new File(f, n);
return fn.isFile();
}
return false;
}
}
public void freshenZoomOutFiles() {
boolean done = false;
int last_done = 0;
for(int i = 0; (!cancelled) && (!done); i++) {
done = freshenZoomOutFilesByLevel(i);
last_done = i;
}
/* Purge updates for levels above what any map needs */
for(int i = last_done; i < zoomoutupdates.length; i++) {
zoomoutupdates[i].clear();
}
checkts = false; /* Just handle queued updates after first scan */
}
public void cancelZoomOutFreshen() {
cancelled = true;
}
private static class PrefixData {
int stepsize;
int[] stepseq;
boolean neg_step_x;
boolean neg_step_y;
String baseprefix;
int zoomlevel;
int background;
String zoomprefix;
String fnprefix;
String zfnprefix;
int bigworldshift;
boolean isbigmap;
MapType.ImageFormat fmt;
}
public boolean freshenZoomOutFilesByLevel(int zoomlevel) {
int cnt = 0;
Debug.debug("freshenZoomOutFiles(" + wname + "," + zoomlevel + ")");
if(worldtilepath.exists() == false) /* Quit if not found */
return true;
HashMap<String, PrefixData> maptab = buildPrefixData(zoomlevel);
if(checkts) { /* If doing timestamp based scan (initial) */
DirFilter df = new DirFilter();
for(String pfx : maptab.keySet()) { /* Walk through prefixes */
if(cancelled) return true;
PrefixData pd = maptab.get(pfx);
if(pd.isbigmap) { /* If big world, next directories are map name specific */
File dname = new File(worldtilepath, pfx);
/* Now, go through subdirectories under this one, and process them */
String[] subdir = dname.list(df);
if(subdir == null) continue;
for(String s : subdir) {
if(cancelled) return true;
File sdname = new File(dname, s);
cnt += processZoomDirectory(sdname, pd);
}
}
else { /* Else, classic file layout */
cnt += processZoomDirectory(worldtilepath, maptab.get(pfx));
}
}
Debug.debug("freshenZoomOutFiles(" + wname + "," + zoomlevel + ") - done (" + cnt + " updated files)");
}
else { /* Else, only process updates */
String[] paths = peekQueuedUpdates(zoomlevel); /* Get pending updates */
HashMap<String, ProcessTileRec> toprocess = new HashMap<String, ProcessTileRec>();
/* Accumulate zoomed tiles to be processed (combine triggering subtiles) */
for(String p : paths) {
if(cancelled) return true;
File f = new File(p); /* Make file */
/* Find matching prefix */
for(PrefixData pd : maptab.values()) { /* Walk through prefixes */
if(cancelled) return true;
ProcessTileRec tr = null;
/* If big map and matches name pattern */
if(pd.isbigmap && f.getName().startsWith(pd.fnprefix) &&
f.getParentFile().getParentFile().getName().equals(pd.baseprefix)) {
tr = processZoomFile(f, pd);
}
/* If not big map and matches name pattern */
else if((!pd.isbigmap) && f.getName().startsWith(pd.fnprefix)) {
tr = processZoomFile(f, pd);
}
if(tr != null) {
String zfpath = tr.zf.getPath();
if(!toprocess.containsKey(zfpath)) {
toprocess.put(zfpath, tr);
}
}
}
}
/* Do processing */
for(ProcessTileRec s : toprocess.values()) {
if(cancelled) return true;
processZoomTile(s.pd, s.zf, s.zfname, s.x, s.y);
}
}
/* Return true when we have none left at the level */
return (maptab.size() == 0);
}
private HashMap<String, PrefixData> buildPrefixData(int zoomlevel) {
HashMap<String, PrefixData> maptab = new HashMap<String, PrefixData>();
/* Build table of file prefixes and step sizes */
for(MapType mt : maps) {
/* If level is above top needed for this map, skip */
if(zoomlevel > (this.extrazoomoutlevels + mt.getMapZoomOutLevels()))
continue;
List<MapType.ZoomInfo> pfx = mt.baseZoomFileInfo();
int stepsize = mt.baseZoomFileStepSize();
int bigworldshift = mt.getBigWorldShift();
boolean neg_step_x = false;
boolean neg_step_y = false;
switch(mt.zoomFileMapStep()) {
case X_PLUS_Y_PLUS:
break;
case X_MINUS_Y_PLUS:
neg_step_x = true;
break;
case X_PLUS_Y_MINUS:
neg_step_y = true;
break;
case X_MINUS_Y_MINUS:
neg_step_x = neg_step_y = true;
break;
}
int[] stepseq = mt.zoomFileStepSequence();
for(MapType.ZoomInfo p : pfx) {
PrefixData pd = new PrefixData();
pd.stepsize = stepsize;
pd.neg_step_x = neg_step_x;
pd.neg_step_y = neg_step_y;
pd.stepseq = stepseq;
pd.baseprefix = p.prefix;
pd.background = p.background_argb;
pd.zoomlevel = zoomlevel;
pd.zoomprefix = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz".substring(0, zoomlevel);
pd.bigworldshift = bigworldshift;
pd.isbigmap = mt.isBigWorldMap(this);
pd.fmt = mt.getImageFormat();
if(pd.isbigmap) {
if(zoomlevel > 0) {
pd.zoomprefix += "_";
pd.zfnprefix = "z" + pd.zoomprefix;
}
else {
pd.zfnprefix = "z_";
}
pd.fnprefix = pd.zoomprefix;
}
else {
pd.fnprefix = pd.zoomprefix + pd.baseprefix;
pd.zfnprefix = "z" + pd.fnprefix;
}
maptab.put(p.prefix, pd);
}
}
return maptab;
}
private static class ProcessTileRec {
File zf;
String zfname;
int x, y;
PrefixData pd;
}
private String makeFilePath(PrefixData pd, int x, int y, boolean zoomed) {
if(pd.isbigmap)
return pd.baseprefix + "/" + (x >> pd.bigworldshift) + "_" + (y >> pd.bigworldshift) + "/" + (zoomed?pd.zfnprefix:pd.fnprefix) + x + "_" + y + "." + pd.fmt.getFileExt();
else
return (zoomed?pd.zfnprefix:pd.fnprefix) + "_" + x + "_" + y + "." + pd.fmt.getFileExt();
}
private int processZoomDirectory(File dir, PrefixData pd) {
Debug.debug("processZoomDirectory(" + dir.getPath() + "," + pd.baseprefix + ")");
HashMap<String, ProcessTileRec> toprocess = new HashMap<String, ProcessTileRec>();
String[] files = dir.list(new PNGFileFilter(pd.fnprefix, pd.fmt));
if(files == null)
return 0;
for(String fn : files) {
ProcessTileRec tr = processZoomFile(new File(dir, fn), pd);
if(tr != null) {
String zfpath = tr.zf.getPath();
if(!toprocess.containsKey(zfpath)) {
toprocess.put(zfpath, tr);
}
}
}
int cnt = 0;
/* Do processing */
for(ProcessTileRec s : toprocess.values()) {
processZoomTile(s.pd, s.zf, s.zfname, s.x, s.y);
cnt++;
}
Debug.debug("processZoomDirectory(" + dir.getPath() + "," + pd.baseprefix + ") - done (" + cnt + " files)");
return cnt;
}
private ProcessTileRec processZoomFile(File f, PrefixData pd) {
/* If not checking timstamp, we're out if nothing queued for this file */
if(!checkts) {
if(!popQueuedUpdate(f, pd.zoomlevel))
return null;
}
int step = pd.stepsize << pd.zoomlevel;
String fn = f.getName();
/* Parse filename to predict zoomed out file */
fn = fn.substring(0, fn.lastIndexOf('.')); /* Strip off extension */
String[] tok = fn.split("_"); /* Split by underscores */
int x = 0;
int y = 0;
boolean parsed = false;
if(tok.length >= 2) {
try {
x = Integer.parseInt(tok[tok.length-2]);
y = Integer.parseInt(tok[tok.length-1]);
parsed = true;
} catch (NumberFormatException nfx) {
}
}
if(!parsed)
return null;
if(pd.neg_step_x) x = -x;
if(x >= 0)
x = x - (x % (2*step));
else
x = x + (x % (2*step));
if(pd.neg_step_x) x = -x;
if(pd.neg_step_y) y = -y;
if(y >= 0)
y = y - (y % (2*step));
else
y = y + (y % (2*step));
if(pd.neg_step_y) y = -y;
/* Make name of corresponding zoomed tile */
String zfname = makeFilePath(pd, x, y, true);
File zf = new File(worldtilepath, zfname);
if(checkts) { /* If checking timestamp, see if we need update based on enqueued update OR old file time */
/* If we're not updated, and zoom file exists and is older than our file, nothing to do */
if((!popQueuedUpdate(f, pd.zoomlevel)) && zf.exists() && (zf.lastModified() >= f.lastModified())) {
return null;
}
}
ProcessTileRec rec = new ProcessTileRec();
rec.zf = zf;
rec.x = x;
rec.y = y;
rec.zfname = zfname;
rec.pd = pd;
Debug.debug("Process " + zf.getPath() + " due to " + f.getPath());
return rec;
}
private void processZoomTile(PrefixData pd, File zf, String zfname, int tx, int ty) {
Debug.debug("processZoomFile(" + pd.baseprefix + "," + zf.getPath() + "," + tx + "," + ty + ")");
int width = 128, height = 128;
BufferedImage zIm = null;
DynmapBufferedImage kzIm = null;
boolean blank = true;
int[] argb = new int[width*height];
int step = pd.stepsize << pd.zoomlevel;
int ztx = tx;
int zty = ty;
tx = tx - (pd.neg_step_x?step:0); /* Adjust for negative step */
ty = ty - (pd.neg_step_y?step:0); /* Adjust for negative step */
/* create image buffer */
kzIm = DynmapBufferedImage.allocateBufferedImage(width, height);
zIm = kzIm.buf_img;
for(int i = 0; i < 4; i++) {
File f = new File(worldtilepath, makeFilePath(pd, (tx + step*(1&pd.stepseq[i])), (ty + step*(pd.stepseq[i]>>1)), false));
if(f.exists()) {
BufferedImage im = null;
FileLockManager.getReadLock(f);
popQueuedUpdate(f, pd.zoomlevel);
try {
im = ImageIO.read(f);
} catch (IOException e) {
} catch (IndexOutOfBoundsException e) {
} finally {
FileLockManager.releaseReadLock(f);
}
if(im != null) {
im.getRGB(0, 0, width, height, argb, 0, width); /* Read data */
im.flush();
blank = false;
/* Do binlinear scale to 64x64 */
int off = 0;
for(int y = 0; y < height; y += 2) {
off = y*width;
for(int x = 0; x < width; x += 2, off += 2) {
int p0 = argb[off];
int p1 = argb[off+1];
int p2 = argb[off+width];
int p3 = argb[off+width+1];
int alpha = ((p0 >> 24) & 0xFF) + ((p1 >> 24) & 0xFF) + ((p2 >> 24) & 0xFF) + ((p3 >> 24) & 0xFF);
int red = ((p0 >> 16) & 0xFF) + ((p1 >> 16) & 0xFF) + ((p2 >> 16) & 0xFF) + ((p3 >> 16) & 0xFF);
int green = ((p0 >> 8) & 0xFF) + ((p1 >> 8) & 0xFF) + ((p2 >> 8) & 0xFF) + ((p3 >> 8) & 0xFF);
int blue = (p0 & 0xFF) + (p1 & 0xFF) + (p2 & 0xFF) + (p3 & 0xFF);
argb[off>>1] = (((alpha>>2)&0xFF)<<24) | (((red>>2)&0xFF)<<16) | (((green>>2)&0xFF)<<8) | ((blue>>2)&0xFF);
}
}
/* blit scaled rendered tile onto zoom-out tile */
zIm.setRGB(((i>>1) != 0)?0:width/2, (i & 1) * height/2, width/2, height/2, argb, 0, width);
}
else {
Arrays.fill(argb, pd.background);
}
}
else {
Arrays.fill(argb, pd.background);
}
/* blit scaled rendered tile onto zoom-out tile */
zIm.setRGB(((i>>1) != 0)?0:width/2, (i & 1) * height/2, width/2, height/2, argb, 0, width);
}
FileLockManager.getWriteLock(zf);
try {
MapManager mm = MapManager.mapman;
if(mm == null)
return;
TileHashManager hashman = mm.hashman;
long crc = hashman.calculateTileHash(kzIm.argb_buf); /* Get hash of tile */
int tilex = ztx/step/2;
int tiley = zty/step/2;
String key = wname+".z"+pd.zoomprefix+pd.baseprefix;
if(blank) {
if(zf.exists()) {
zf.delete();
hashman.updateHashCode(key, null, tilex, tiley, -1);
MapManager.mapman.pushUpdate(this, new Client.Tile(zfname));
enqueueZoomOutUpdate(zf, pd.zoomlevel+1);
}
}
else if((!zf.exists()) || (crc != mm.hashman.getImageHashCode(key, null, tilex, tiley))) {
try {
if(!zf.getParentFile().exists())
zf.getParentFile().mkdirs();
FileLockManager.imageIOWrite(zIm, pd.fmt, zf);
Debug.debug("Saved zoom-out tile at " + zf.getPath());
} catch (IOException e) {
Debug.error("Failed to save zoom-out tile: " + zf.getName(), e);
} catch (java.lang.NullPointerException e) {
Debug.error("Failed to save zoom-out tile (NullPointerException): " + zf.getName(), e);
}
hashman.updateHashCode(key, null, tilex, tiley, crc);
MapManager.mapman.pushUpdate(this, new Client.Tile(zfname));
enqueueZoomOutUpdate(zf, pd.zoomlevel+1);
}
} finally {
FileLockManager.releaseWriteLock(zf);
DynmapBufferedImage.freeBufferedImage(kzIm);
}
}
/* Get world name */
public String getName() {
return wname;
}
/* Test if world is nether */
public abstract boolean isNether();
/* Get world spawn location */
public abstract DynmapLocation getSpawnLocation();
public int hashCode() {
return wname.hashCode();
}
/* Get world time */
public abstract long getTime();
/* World is storming */
public abstract boolean hasStorm();
/* World is thundering */
public abstract boolean isThundering();
/* World is loaded */
public abstract boolean isLoaded();
/* Get light level of block */
public abstract int getLightLevel(int x, int y, int z);
/* Get highest Y coord of given location */
public abstract int getHighestBlockYAt(int x, int z);
/* Test if sky light level is requestable */
public abstract boolean canGetSkyLightLevel();
/* Return sky light level */
public abstract int getSkyLightLevel(int x, int y, int z);
/**
* Get world environment ID (lower case - normal, the_end, nether)
*/
public abstract String getEnvironment();
/**
* Get map chunk cache for world
*/
public abstract MapChunkCache getChunkCache(List<DynmapChunk> chunks);
}

View File

@ -1,36 +0,0 @@
package org.dynmap;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Event<T> {
private List<Listener<T>> listeners = new LinkedList<Listener<T>>();
private Object lock = new Object();
public void addListener(Listener<T> l) {
synchronized(lock) {
listeners.add(l);
}
}
public void removeListener(Listener<T> l) {
synchronized(lock) {
listeners.remove(l);
}
}
public void trigger(T t) {
ArrayList<Listener<T>> iterlist;
synchronized(lock) {
iterlist = new ArrayList<Listener<T>>(listeners);
}
for (Listener<T> l : iterlist) {
l.triggered(t);
}
}
public interface Listener<T> {
void triggered(T t);
}
}

View File

@ -1,37 +0,0 @@
package org.dynmap;
import java.util.HashMap;
import java.util.Map;
public class Events {
public Map<String, Event<?>> events = new HashMap<String, Event<?>>();
@SuppressWarnings("unchecked")
public <T> void addListener(String eventName, Event.Listener<T> listener) {
Event<?> genericEvent = events.get(eventName);
Event<T> event = null;
if (genericEvent != null) {
event = (Event<T>)genericEvent;
} else {
events.put(eventName, event = new Event<T>());
}
event.addListener(listener);
}
@SuppressWarnings("unchecked")
public <T> void removeListener(String eventName, Event.Listener<T> listener) {
Event<?> genericEvent = events.get(eventName);
Event<T> event = null;
if (genericEvent != null) {
event = (Event<T>)genericEvent;
event.removeListener(listener);
}
}
@SuppressWarnings("unchecked")
public <T> void trigger(String eventName, T argument) {
Event<?> genericEvent = events.get(eventName);
if (genericEvent == null)
return;
((Event<T>)genericEvent).trigger(argument);
}
}

View File

@ -1,5 +0,0 @@
package org.dynmap;
public interface Handler<T> {
void handle(T t);
}

View File

@ -1,63 +0,0 @@
package org.dynmap;
import org.dynmap.servlet.ClientUpdateServlet;
import org.dynmap.servlet.SendMessageServlet;
import org.json.simple.JSONObject;
import static org.dynmap.JSONUtils.*;
public class InternalClientUpdateComponent extends ClientUpdateComponent {
public InternalClientUpdateComponent(final DynmapCore dcore, final ConfigurationNode configuration) {
super(dcore, configuration);
dcore.addServlet("/up/world/*", new ClientUpdateServlet(dcore));
final Boolean allowwebchat = configuration.getBoolean("allowwebchat", false);
final Boolean hidewebchatip = configuration.getBoolean("hidewebchatip", false);
final Boolean trust_client_name = configuration.getBoolean("trustclientname", false);
final float webchatInterval = configuration.getFloat("webchat-interval", 1);
final String spammessage = dcore.configuration.getString("spammessage", "You may only chat once every %interval% seconds.");
final Boolean use_player_ip = configuration.getBoolean("use-player-login-ip", true);
final Boolean req_player_ip = configuration.getBoolean("require-player-login-ip", false);
final Boolean block_banned_player_chat = configuration.getBoolean("block-banned-player-chat", false);
dcore.events.addListener("buildclientconfiguration", new Event.Listener<JSONObject>() {
@Override
public void triggered(JSONObject t) {
s(t, "allowwebchat", allowwebchat);
s(t, "webchat-interval", webchatInterval);
}
});
if (allowwebchat) {
@SuppressWarnings("serial")
SendMessageServlet messageHandler = new SendMessageServlet() {{
maximumMessageInterval = (int)(webchatInterval * 1000);
spamMessage = "\""+spammessage+"\"";
hideip = hidewebchatip;
this.trustclientname = trust_client_name;
this.use_player_login_ip = use_player_ip;
this.require_player_login_ip = req_player_ip;
this.check_user_ban = block_banned_player_chat;
this.core = dcore;
onMessageReceived.addListener(new Event.Listener<Message> () {
@Override
public void triggered(Message t) {
webChat(t.name, t.message);
}
});
}};
dcore.addServlet("/up/sendmessage", messageHandler);
}
}
protected void webChat(String name, String message) {
if(core.mapManager == null)
return;
// TODO: Change null to something meaningful.
core.mapManager.pushUpdate(new Client.ChatMessage("web", null, name, message, null));
Log.info(unescapeString(core.configuration.getString("webprefix", "\u00A72[WEB] ")) + name + ": " + unescapeString(core.configuration.getString("websuffix", "\u00A7f")) + message);
ChatEvent event = new ChatEvent("web", name, message);
core.events.trigger("webchat", event);
}
}

View File

@ -1,71 +0,0 @@
package org.dynmap;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
public class JSONUtils {
// Gets a value at the specified path.
public static Object g(JSONObject o, String path) {
int index = path.indexOf('/');
if (index == -1) {
return o.get(path);
} else {
String key = path.substring(0, index);
String subpath = path.substring(index+1);
Object oo = o.get(key);
JSONObject subobject;
if (oo == null) {
return null;
} else /*if (oo instanceof JSONObject)*/ {
subobject = (JSONObject)o;
}
return g(subobject, subpath);
}
}
// Sets a value on the specified path. If JSONObjects inside the path are missing, they'll be created.
@SuppressWarnings("unchecked")
public static void s(JSONObject o, String path, Object value) {
int index = path.indexOf('/');
if (index == -1) {
o.put(path, value);
} else {
String key = path.substring(0, index);
String subpath = path.substring(index+1);
Object oo = o.get(key);
JSONObject subobject;
if (oo == null) {
subobject = new JSONObject();
o.put(key, subobject);
} else /*if (oo instanceof JSONObject)*/ {
subobject = (JSONObject)oo;
}
s(subobject, subpath, value);
}
}
// Adds a value to the list at the specified path. If the list does not exist, it will be created.
@SuppressWarnings("unchecked")
public static void a(JSONObject o, String path, Object value) {
Object oo = g(o, path);
JSONArray array;
if (oo == null) {
array =new JSONArray();
s(o, path, array);
} else {
array = (JSONArray)oo;
}
array.add(value);
}
// Simply creates a JSONArray.
@SuppressWarnings("unchecked")
public static JSONArray l(Object... items) {
JSONArray arr = new JSONArray();
for(Object item : items) {
arr.add(item);
}
return arr;
}
}

View File

@ -1,271 +0,0 @@
package org.dynmap;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.Reader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.dynmap.web.Json;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import static org.dynmap.JSONUtils.*;
import java.nio.charset.Charset;
public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
protected long jsonInterval;
protected long currentTimestamp = 0;
protected long lastTimestamp = 0;
protected JSONParser parser = new JSONParser();
private boolean hidewebchatip;
private boolean useplayerloginip;
private boolean requireplayerloginip;
private boolean trust_client_name;
private boolean checkuserban;
private HashMap<String,String> useralias = new HashMap<String,String>();
private int aliasindex = 1;
private long last_confighash;
private Charset cs_utf8 = Charset.forName("UTF-8");
public JsonFileClientUpdateComponent(final DynmapCore plugin, final ConfigurationNode configuration) {
super(plugin, configuration);
final boolean allowwebchat = configuration.getBoolean("allowwebchat", false);
jsonInterval = (long)(configuration.getFloat("writeinterval", 1) * 1000);
hidewebchatip = configuration.getBoolean("hidewebchatip", false);
useplayerloginip = configuration.getBoolean("use-player-login-ip", true);
requireplayerloginip = configuration.getBoolean("require-player-login-ip", false);
trust_client_name = configuration.getBoolean("trustclientname", false);
checkuserban = configuration.getBoolean("block-banned-player-chat", true);
MapManager.scheduleDelayedJob(new Runnable() {
@Override
public void run() {
currentTimestamp = System.currentTimeMillis();
if(last_confighash != plugin.getConfigHashcode())
writeConfiguration();
writeUpdates();
if (allowwebchat) {
handleWebChat();
}
lastTimestamp = currentTimestamp;
MapManager.scheduleDelayedJob(this, jsonInterval);
}}, jsonInterval);
plugin.events.addListener("buildclientconfiguration", new Event.Listener<JSONObject>() {
@Override
public void triggered(JSONObject t) {
s(t, "jsonfile", true);
s(t, "allowwebchat", allowwebchat);
// For 'sendmessage.php'
s(t, "webchat-interval", configuration.getFloat("webchat-interval", 5.0f));
}
});
plugin.events.addListener("initialized", new Event.Listener<Object>() {
@Override
public void triggered(Object t) {
writeConfiguration();
}
});
plugin.events.addListener("worldactivated", new Event.Listener<DynmapWorld>() {
@Override
public void triggered(DynmapWorld t) {
writeConfiguration();
}
});
}
protected File getStandaloneFile(String filename) {
File webpath = new File(core.configuration.getString("webpath", "web"), "standalone/" + filename);
if (webpath.isAbsolute())
return webpath;
else
return new File(core.getDataFolder(), webpath.toString());
}
private static final int RETRY_LIMIT = 5;
protected void writeConfiguration() {
File outputFile;
File outputTempFile;
JSONObject clientConfiguration = new JSONObject();
core.events.trigger("buildclientconfiguration", clientConfiguration);
outputFile = getStandaloneFile("dynmap_config.json");
outputTempFile = getStandaloneFile("dynmap_config.json.new");
last_confighash = core.getConfigHashcode();
int retrycnt = 0;
boolean done = false;
while(!done) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(outputTempFile);
fos.write(clientConfiguration.toJSONString().getBytes("UTF-8"));
fos.close();
fos = null;
outputFile.delete();
outputTempFile.renameTo(outputFile);
done = true;
} catch (IOException ioe) {
if(retrycnt < RETRY_LIMIT) {
try { Thread.sleep(20 * (1 << retrycnt)); } catch (InterruptedException ix) {}
retrycnt++;
}
else {
Log.severe("Exception while writing JSON-configuration-file.", ioe);
done = true;
}
} finally {
if(fos != null) {
try {
fos.close();
} catch (IOException iox) {
}
fos = null;
}
}
}
}
@SuppressWarnings("unchecked")
protected void writeUpdates() {
File outputFile;
File outputTempFile;
if(core.mapManager == null) return;
//Handles Updates
for (DynmapWorld dynmapWorld : core.mapManager.getWorlds()) {
JSONObject update = new JSONObject();
update.put("timestamp", currentTimestamp);
ClientUpdateEvent clientUpdate = new ClientUpdateEvent(currentTimestamp - 30000, dynmapWorld, update);
core.events.trigger("buildclientupdate", clientUpdate);
outputFile = getStandaloneFile("dynmap_" + dynmapWorld.getName() + ".json");
outputTempFile = getStandaloneFile("dynmap_" + dynmapWorld.getName() + ".json.new");
int retrycnt = 0;
boolean done = false;
while(!done) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(outputTempFile);
fos.write(Json.stringifyJson(update).getBytes("UTF-8"));
fos.close();
fos = null;
outputFile.delete();
outputTempFile.renameTo(outputFile);
done = true;
} catch (IOException ioe) {
if(retrycnt < RETRY_LIMIT) {
try { Thread.sleep(20 * (1 << retrycnt)); } catch (InterruptedException ix) {}
retrycnt++;
}
else {
Log.severe("Exception while writing JSON-file.", ioe);
done = true;
}
} finally {
if(fos != null) {
try {
fos.close();
} catch (IOException iox) {
}
fos = null;
}
}
}
core.events.<ClientUpdateEvent>trigger("clientupdatewritten", clientUpdate);
}
core.events.<Object>trigger("clientupdateswritten", null);
}
protected void handleWebChat() {
File webchatFile = getStandaloneFile("dynmap_webchat.json");
if (webchatFile.exists() && lastTimestamp != 0) {
JSONArray jsonMsgs = null;
Reader inputFileReader = null;
try {
inputFileReader = new InputStreamReader(new FileInputStream(webchatFile), cs_utf8);
jsonMsgs = (JSONArray) parser.parse(inputFileReader);
} catch (IOException ex) {
Log.severe("Exception while reading JSON-file.", ex);
} catch (ParseException ex) {
Log.severe("Exception while parsing JSON-file.", ex);
} finally {
if(inputFileReader != null) {
try {
inputFileReader.close();
} catch (IOException iox) {
}
inputFileReader = null;
}
}
if (jsonMsgs != null) {
Iterator<?> iter = jsonMsgs.iterator();
while (iter.hasNext()) {
JSONObject o = (JSONObject) iter.next();
String ts = String.valueOf(o.get("timestamp"));
if(ts.equals("null")) ts = "0";
if (Long.parseLong(ts) >= (lastTimestamp)) {
String name = String.valueOf(o.get("name"));
String ip = String.valueOf(o.get("ip"));
boolean isip = true;
if((!trust_client_name) || (name == null) || (name.equals(""))) {
if(ip != null)
name = ip;
}
if(useplayerloginip) { /* Try to match using IPs of player logins */
List<String> ids = core.getIDsForIP(name);
if(ids != null) {
name = ids.get(0);
isip = false;
if(checkuserban) {
if(core.getServer().isPlayerBanned(name)) {
Log.info("Ignore message from '" + ip + "' - banned player (" + name + ")");
return;
}
}
}
else if(requireplayerloginip) {
Log.info("Ignore message from '" + name + "' - no matching player login recorded");
return;
}
}
if(hidewebchatip && isip) {
String n = useralias.get(name);
if(n == null) { /* Make ID */
n = String.format("web-%03d", aliasindex);
aliasindex++;
useralias.put(name, n);
}
name = n;
}
String message = String.valueOf(o.get("message"));
webChat(name, message);
}
}
}
}
}
protected void webChat(String name, String message) {
if(core.mapManager == null) return;
// TODO: Change null to something meaningful.
core.mapManager.pushUpdate(new Client.ChatMessage("web", null, name, message, null));
Log.info(unescapeString(core.configuration.getString("webprefix", "\u00A2[WEB] ")) + name + ": " + unescapeString(core.configuration.getString("websuffix", "\u00A7f")) + message);
ChatEvent event = new ChatEvent("web", name, message);
core.events.trigger("webchat", event);
}
@Override
public void dispose() {
super.dispose();
}
}

View File

@ -1,32 +0,0 @@
package org.dynmap;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Log {
protected static final Logger log = Logger.getLogger("Minecraft");
protected static final String LOG_PREFIX = "[dynmap] ";
public static boolean verbose = false;
public static void info(String msg) {
log.log(Level.INFO, LOG_PREFIX + msg);
}
public static void verboseinfo(String msg) {
if(verbose)
log.log(Level.INFO, LOG_PREFIX + msg);
}
public static void severe(Exception e) {
log.log(Level.SEVERE, LOG_PREFIX + "Exception occured: ", e);
}
public static void severe(String msg) {
log.log(Level.SEVERE, LOG_PREFIX + msg);
}
public static void severe(String msg, Exception e) {
log.log(Level.SEVERE, LOG_PREFIX + msg, e);
}
public static void warning(String msg) {
log.log(Level.WARNING, LOG_PREFIX + msg);
}
public static void warning(String msg, Exception e) {
log.log(Level.WARNING, LOG_PREFIX + msg, e);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,71 +0,0 @@
package org.dynmap;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import org.dynmap.utils.MapChunkCache;
public abstract class MapTile {
protected DynmapWorld world;
public abstract boolean render(MapChunkCache cache, String mapname);
public abstract List<DynmapChunk> getRequiredChunks();
public abstract MapTile[] getAdjecentTiles();
public DynmapWorld getDynmapWorld() {
return world;
}
public abstract String getFilename();
public abstract String getDayFilename();
public MapTile(DynmapWorld world) {
this.world = world;
}
@Override
public int hashCode() {
return getFilename().hashCode() ^ world.hashCode();
}
@Override
public abstract boolean equals(Object obj);
public abstract String getKey(String prefix);
public abstract boolean isBiomeDataNeeded();
public abstract boolean isHightestBlockYDataNeeded();
public abstract boolean isRawBiomeDataNeeded();
public abstract boolean isBlockTypeDataNeeded();
public abstract int tileOrdinalX();
public abstract int tileOrdinalY();
public ConfigurationNode saveTile() {
ConfigurationNode cn = new ConfigurationNode();
cn.put("class", this.getClass().getName());
cn.put("data", saveTileData());
return cn;
}
protected abstract String saveTileData();
public static MapTile restoreTile(DynmapWorld w, ConfigurationNode node) {
String cn = node.getString("class");
String dat = node.getString("data");
if((cn == null) || (dat == null)) return null;
try {
Class<?> cls = Class.forName(cn);
Constructor<?> con = cls.getConstructor(DynmapWorld.class, String.class);
return (MapTile)con.newInstance(w, dat);
} catch (ClassNotFoundException cnfx) {
} catch (NoSuchMethodException nsmx) {
} catch (InvocationTargetException itx) {
} catch (IllegalAccessException iax) {
} catch (InstantiationException ix) {
}
return null;
}
}

View File

@ -1,112 +0,0 @@
package org.dynmap;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import org.dynmap.utils.TileFlags;
import org.json.simple.JSONObject;
public abstract class MapType {
public enum ImageFormat {
FORMAT_PNG("png", "png", 0.0f),
FORMAT_JPG75("jpg-q75", "jpg", 0.75f),
FORMAT_JPG80("jpg-q80", "jpg", 0.80f),
FORMAT_JPG85("jpg-q85", "jpg", 0.85f),
FORMAT_JPG("jpg", "jpg", 0.85f),
FORMAT_JPG90("jpg-q90", "jpg", 0.90f),
FORMAT_JPG95("jpg-q95", "jpg", 0.95f),
FORMAT_JPG100("jpg-q100", "jpg", 1.00f);
String id;
String ext;
float qual;
ImageFormat(String id, String ext, float quality) {
this.id = id;
this.ext = ext;
this.qual = quality;
}
public String getID() { return id; }
public String getFileExt() { return ext; }
public float getQuality() { return qual; }
};
public static class ZoomInfo {
public String prefix;
public int background_argb;
public ZoomInfo(String pre, int bg) { prefix = pre; background_argb = bg; }
}
public abstract MapTile[] getTiles(DynmapWorld w, int x, int y, int z);
public abstract MapTile[] getTiles(DynmapWorld w, int minx, int miny, int minz, int maxx, int maxy, int maxz);
public abstract MapTile[] getAdjecentTiles(MapTile tile);
public abstract List<DynmapChunk> getRequiredChunks(MapTile tile);
public void buildClientConfiguration(JSONObject worldObject, DynmapWorld w) {
}
public abstract String getName();
/* Get maps rendered concurrently with this map in this world */
public abstract List<MapType> getMapsSharingRender(DynmapWorld w);
/* Get names of maps rendered concurrently with this map type in this world */
public abstract List<String> getMapNamesSharingRender(DynmapWorld w);
public enum MapStep {
X_PLUS_Y_PLUS,
X_PLUS_Y_MINUS,
X_MINUS_Y_PLUS,
X_MINUS_Y_MINUS
}
public abstract MapStep zoomFileMapStep();
public abstract List<ZoomInfo> baseZoomFileInfo();
public abstract int baseZoomFileStepSize();
/* How many bits of coordinate are shifted off to make big world directory name */
public abstract int getBigWorldShift();
/* Returns true if big world file structure is in effect for this map */
public abstract boolean isBigWorldMap(DynmapWorld w);
/* Return number of zoom levels needed by this map (before extra levels from extrazoomout) */
public int getMapZoomOutLevels() { return 0; }
public ImageFormat getImageFormat() { return ImageFormat.FORMAT_PNG; }
public int getBackgroundARGBNight() { return 0; }
public int getBackgroundARGBDay() { return 0; }
/**
* Step sequence for creating zoomed file: first index is top-left, second top-right, third bottom-left, forth bottom-right
* Values correspond to tile X,Y (0), X+step,Y (1), X,Y+step (2), X+step,Y+step (3)
*/
public abstract int[] zoomFileStepSequence();
public void purgeOldTiles(DynmapWorld world, TileFlags rendered) { }
public interface FileCallback {
public void fileFound(File f, File parent, boolean day);
}
protected void walkMapTree(File root, FileCallback cb, boolean day) {
LinkedList<File> dirs = new LinkedList<File>();
String ext = "." + getImageFormat().getFileExt();
dirs.add(root);
while(dirs.isEmpty() == false) {
File dir = dirs.pop();
String[] lst = dir.list();
for(String fn : lst) {
if(fn.equals(".") || fn.equals(".."))
continue;
File f = new File(dir, fn);
if(f.isDirectory()) { /* If directory, add to list to process */
dirs.add(f);
}
else if(fn.endsWith(ext)) { /* Else, if matches suffix */
cb.fileFound(f, dir, day);
}
}
}
}
}

View File

@ -1,207 +0,0 @@
package org.dynmap;
import org.dynmap.common.DynmapListenerManager.EventType;
import org.dynmap.common.DynmapListenerManager.WorldEventListener;
import org.dynmap.common.DynmapListenerManager.PlayerEventListener;
import org.dynmap.common.DynmapPlayer;
import org.dynmap.markers.Marker;
import org.dynmap.markers.MarkerIcon;
import org.dynmap.markers.MarkerSet;
import org.dynmap.markers.impl.MarkerAPIImpl;
import org.dynmap.markers.impl.MarkerSignManager;
/**
* Markers component - ties in the component system, both on the server and client
*/
public class MarkersComponent extends ClientComponent {
private MarkerAPIImpl api;
private MarkerSignManager signmgr;
private MarkerIcon spawnicon;
private String spawnlbl;
private MarkerSet offlineset;
private MarkerIcon offlineicon;
private MarkerSet spawnbedset;
private MarkerIcon spawnbedicon;
private String spawnbedformat;
private static final String OFFLINE_PLAYERS_SETID = "offline_players";
private static final String PLAYER_SPAWN_BED_SETID = "spawn_beds";
public MarkersComponent(final DynmapCore core, ConfigurationNode configuration) {
super(core, configuration);
/* Register API with plugin, if needed */
if(core.markerAPIInitialized()) {
api = (MarkerAPIImpl)core.getMarkerAPI();
}
else {
api = MarkerAPIImpl.initializeMarkerAPI(core);
core.registerMarkerAPI(api);
}
/* If configuration has enabled sign support, prime it too */
if(configuration.getBoolean("enablesigns", false)) {
signmgr = MarkerSignManager.initializeSignManager(core);
}
/* If we're posting spawn point markers, initialize and add world listener */
if(configuration.getBoolean("showspawn", false)) {
String ico = configuration.getString("spawnicon", MarkerIcon.WORLD);
spawnlbl = configuration.getString("spawnlabel", "Spawn");
spawnicon = api.getMarkerIcon(ico); /* Load it */
if(spawnicon == null) {
spawnicon = api.getMarkerIcon(MarkerIcon.WORLD);
}
/* Add listener for world loads */
WorldEventListener wel = new WorldEventListener() {
@Override
public void worldEvent(DynmapWorld w) {
DynmapLocation loc = w.getSpawnLocation(); /* Get location of spawn */
if(loc != null)
addUpdateWorld(w, loc);
}
};
core.listenerManager.addListener(EventType.WORLD_LOAD, wel);
/* Add listener for spawn changes */
core.listenerManager.addListener(EventType.WORLD_SPAWN_CHANGE, wel);
/* Initialize already loaded worlds */
for(DynmapWorld w : core.getMapManager().getWorlds()) {
DynmapLocation loc = w.getSpawnLocation();
if(loc != null)
addUpdateWorld(w, loc);
}
}
/* If showing offline players as markers */
if(configuration.getBoolean("showofflineplayers", false)) {
/* Make set, if needed */
offlineset = api.getMarkerSet(OFFLINE_PLAYERS_SETID);
if(offlineset == null) {
offlineset = api.createMarkerSet(OFFLINE_PLAYERS_SETID, configuration.getString("offlinelabel", "Offline"), null, true);
}
offlineset.setHideByDefault(configuration.getBoolean("offlinehidebydefault", true));
offlineset.setMinZoom(configuration.getInteger("offlineminzoom", 0));
offlineicon = api.getMarkerIcon(configuration.getString("offlineicon", "offlineuser"));
/* Add listener for players coming and going */
core.listenerManager.addListener(EventType.PLAYER_JOIN, new PlayerEventListener() {
@Override
public void playerEvent(DynmapPlayer p) {
Marker m = offlineset.findMarker(p.getName());
if(m != null) {
m.deleteMarker();
}
}
});
core.listenerManager.addListener(EventType.PLAYER_QUIT, new PlayerEventListener() {
@Override
public void playerEvent(DynmapPlayer p) {
String pname = p.getName();
Marker m = offlineset.findMarker(pname);
if(m != null) {
m.deleteMarker();
}
if(core.playerList.isVisiblePlayer(pname)) {
DynmapLocation loc = p.getLocation();
m = offlineset.createMarker(p.getName(), core.getServer().stripChatColor(p.getDisplayName()), false,
loc.world, loc.x, loc.y, loc.z, offlineicon, true);
}
}
});
}
else {
/* Make set, if needed */
offlineset = api.getMarkerSet(OFFLINE_PLAYERS_SETID);
if(offlineset != null) {
offlineset.deleteMarkerSet();
}
}
/* If showing player spawn bed locations as markers */
if(configuration.getBoolean("showspawnbeds", false)) {
/* Make set, if needed */
spawnbedset = api.getMarkerSet(PLAYER_SPAWN_BED_SETID);
if(spawnbedset == null) {
spawnbedset = api.createMarkerSet(PLAYER_SPAWN_BED_SETID, configuration.getString("spawnbedlabel", "Spawn Beds"), null, true);
}
spawnbedset.setHideByDefault(configuration.getBoolean("spawnbedhidebydefault", true));
spawnbedset.setMinZoom(configuration.getInteger("spawnbedminzoom", 0));
spawnbedicon = api.getMarkerIcon(configuration.getString("spawnbedicon", "bed"));
spawnbedformat = configuration.getString("spawnbedformat", "%name%'s bed");
/* Add listener for players coming and going */
core.listenerManager.addListener(EventType.PLAYER_JOIN, new PlayerEventListener() {
@Override
public void playerEvent(DynmapPlayer p) {
updatePlayer(p);
}
});
core.listenerManager.addListener(EventType.PLAYER_QUIT, new PlayerEventListener() {
@Override
public void playerEvent(DynmapPlayer p) {
Marker m = spawnbedset.findMarker(p.getName()+"_bed");
if(m != null) {
m.deleteMarker();
}
}
});
core.listenerManager.addListener(EventType.PLAYER_BED_LEAVE, new PlayerEventListener() {
@Override
public void playerEvent(final DynmapPlayer p) {
core.getServer().scheduleServerTask(new Runnable() {
public void run() {
updatePlayer(p);
}
}, 0);
}
});
}
else {
/* Make set, if needed */
spawnbedset = api.getMarkerSet(PLAYER_SPAWN_BED_SETID);
if(spawnbedset != null) {
spawnbedset.deleteMarkerSet();
}
}
}
private void updatePlayer(DynmapPlayer p) {
DynmapLocation bl = p.getBedSpawnLocation();
Marker m = spawnbedset.findMarker(p.getName()+"_bed");
if(bl == null) { /* No bed location */
if(m != null) {
m.deleteMarker();
}
}
else {
if(m != null)
m.setLocation(bl.world, bl.x, bl.y, bl.z);
else
m = spawnbedset.createMarker(p.getName()+"_bed", spawnbedformat.replace("%name%", core.getServer().stripChatColor(p.getDisplayName())), false,
bl.world, bl.x, bl.y, bl.z,
spawnbedicon, true);
}
}
private void addUpdateWorld(DynmapWorld w, DynmapLocation loc) {
MarkerSet ms = api.getMarkerSet(MarkerSet.DEFAULT);
if(ms != null) {
String spawnid = "_spawn_" + w.getName();
Marker m = ms.findMarker(spawnid); /* See if defined */
if(m == null) { /* Not defined yet, add it */
ms.createMarker(spawnid, spawnlbl, w.getName(), loc.x, loc.y, loc.z,
spawnicon, false);
}
else {
m.setLocation(w.getName(), loc.z, loc.y, loc.z);
}
}
}
@Override
public void dispose() {
if(signmgr != null) {
MarkerSignManager.terminateSignManager(this.core);
signmgr = null;
}
/* Don't unregister API - other plugins might be using it, and we want to keep non-persistent markers */
}
}

View File

@ -1,160 +0,0 @@
package org.dynmap;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.imageio.ImageIO;
import org.dynmap.MapType.ImageFormat;
import org.dynmap.common.DynmapListenerManager.EventType;
import org.dynmap.common.DynmapListenerManager.PlayerEventListener;
import org.dynmap.common.DynmapPlayer;
import org.dynmap.debug.Debug;
import org.dynmap.utils.DynmapBufferedImage;
import org.dynmap.utils.FileLockManager;
/**
* Listen for player logins, and process player faces by fetching skins *
*/
public class PlayerFaces {
private File facesdir;
private File faces8x8dir;
private File faces16x16dir;
private File faces32x32dir;
private boolean fetchskins;
private boolean refreshskins;
private class LoadPlayerImages implements Runnable {
public String playername;
public LoadPlayerImages(String playername) {
this.playername = playername;
}
public void run() {
File img_8x8 = new File(faces8x8dir, playername + ".png");
File img_16x16 = new File(faces16x16dir, playername + ".png");
File img_32x32 = new File(faces32x32dir, playername + ".png");
boolean has_8x8 = img_8x8.exists();
boolean has_16x16 = img_16x16.exists();
boolean has_32x32 = img_32x32.exists();
boolean missing_any = !(has_8x8 && has_16x16 && has_32x32);
BufferedImage img = null;
try {
if(fetchskins && (refreshskins || missing_any)) {
URL url = new URL("http://s3.amazonaws.com/MinecraftSkins/" + playername + ".png");
img = ImageIO.read(url); /* Load skin for player */
}
} catch (IOException iox) {
Debug.debug("Error loading skin for '" + playername + "' - " + iox);
}
if(img == null) {
try {
InputStream in = getClass().getResourceAsStream("/char.png");
img = ImageIO.read(in); /* Load generic skin for player */
in.close();
} catch (IOException iox) {
Debug.debug("Error loading default skin for '" + playername + "' - " + iox);
}
}
if(img == null) { /* No image to process? Quit */
return;
}
int[] faceaccessory = new int[64]; /* 8x8 of face accessory */
/* Get buffered image for face at 8x8 */
DynmapBufferedImage face8x8 = DynmapBufferedImage.allocateBufferedImage(8, 8);
img.getRGB(8, 8, 8, 8, face8x8.argb_buf, 0, 8); /* Read face from image */
img.getRGB(40, 8, 8, 8, faceaccessory, 0, 8); /* Read face accessory from image */
/* Apply accessory to face: see if anything is transparent (if so, apply accessory */
boolean transp = false;
for(int i = 0; i < 64; i++) {
if((faceaccessory[i] & 0xFF000000) == 0) {
transp = true;
break;
}
}
if(transp) {
for(int i = 0; i < 64; i++) {
if((faceaccessory[i] & 0xFF000000) != 0)
face8x8.argb_buf[i] = faceaccessory[i];
}
}
/* Write 8x8 file */
if(refreshskins || (!has_8x8)) {
FileLockManager.getWriteLock(img_8x8);
try {
FileLockManager.imageIOWrite(face8x8.buf_img, ImageFormat.FORMAT_PNG, img_8x8);
} catch (IOException iox) {
Log.severe("Cannot write player icon " + img_8x8.getPath());
}
FileLockManager.releaseWriteLock(img_8x8);
}
/* Write 16x16 file */
if(refreshskins || (!has_16x16)) {
/* Make 16x16 version */
DynmapBufferedImage face16x16 = DynmapBufferedImage.allocateBufferedImage(16, 16);
for(int i = 0; i < 16; i++) {
for(int j = 0; j < 16; j++) {
face16x16.argb_buf[i*16+j] = face8x8.argb_buf[(i/2)*8 + (j/2)];
}
}
FileLockManager.getWriteLock(img_16x16);
try {
FileLockManager.imageIOWrite(face16x16.buf_img, ImageFormat.FORMAT_PNG, img_16x16);
} catch (IOException iox) {
Log.severe("Cannot write player icon " + img_16x16.getPath());
}
FileLockManager.releaseWriteLock(img_16x16);
DynmapBufferedImage.freeBufferedImage(face16x16);
}
/* Write 32x32 file */
if(refreshskins || (!has_32x32)) {
/* Make 32x32 version */
DynmapBufferedImage face32x32 = DynmapBufferedImage.allocateBufferedImage(32, 32);
for(int i = 0; i < 32; i++) {
for(int j = 0; j < 32; j++) {
face32x32.argb_buf[i*32+j] = face8x8.argb_buf[(i/4)*8 + (j/4)];
}
}
FileLockManager.getWriteLock(img_32x32);
try {
FileLockManager.imageIOWrite(face32x32.buf_img, ImageFormat.FORMAT_PNG, img_32x32);
} catch (IOException iox) {
Log.severe("Cannot write player icon " + img_32x32.getPath());
}
FileLockManager.releaseWriteLock(img_32x32);
DynmapBufferedImage.freeBufferedImage(face32x32);
}
DynmapBufferedImage.freeBufferedImage(face8x8);
/* TODO: signal update for player icon to client */
}
}
public PlayerFaces(DynmapCore core) {
fetchskins = core.configuration.getBoolean("fetchskins", true); /* Control whether to fetch skins */
refreshskins = core.configuration.getBoolean("refreshskins", true); /* Control whether to update existing fetched skins or faces */
core.listenerManager.addListener(EventType.PLAYER_JOIN, new PlayerEventListener() {
@Override
public void playerEvent(DynmapPlayer p) {
Runnable job = new LoadPlayerImages(p.getName());
if(fetchskins)
MapManager.scheduleDelayedJob(job, 0);
else
job.run();
}
});
facesdir = new File(core.getTilesFolder(), "faces");
facesdir.mkdirs(); /* Make sure directory exists */
faces8x8dir = new File(facesdir, "8x8");
faces8x8dir.mkdirs();
faces16x16dir = new File(facesdir, "16x16");
faces16x16dir.mkdirs();
faces32x32dir = new File(facesdir, "32x32");
faces32x32dir.mkdirs();
}
}

View File

@ -1,130 +0,0 @@
package org.dynmap;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import org.dynmap.common.DynmapPlayer;
import org.dynmap.common.DynmapServerInterface;
public class PlayerList {
private DynmapServerInterface server;
private HashSet<String> hiddenPlayerNames = new HashSet<String>();
private File hiddenPlayersFile;
private ConfigurationNode configuration;
private DynmapPlayer[] online;
public PlayerList(DynmapServerInterface server, File hiddenPlayersFile, ConfigurationNode configuration) {
this.server = server;
this.hiddenPlayersFile = hiddenPlayersFile;
this.configuration = configuration;
updateOnlinePlayers(null);
}
public void save() {
OutputStream stream;
try {
stream = new FileOutputStream(hiddenPlayersFile);
OutputStreamWriter writer = new OutputStreamWriter(stream);
for (String player : hiddenPlayerNames) {
writer.write(player);
writer.write("\n");
}
writer.close();
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void load() {
try {
Scanner scanner = new Scanner(hiddenPlayersFile);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
hiddenPlayerNames.add(line);
}
scanner.close();
} catch (FileNotFoundException e) {
return;
}
}
public void hide(String playerName) {
hiddenPlayerNames.add(playerName.toLowerCase());
save();
}
public void show(String playerName) {
hiddenPlayerNames.remove(playerName.toLowerCase());
save();
}
public void setVisible(String playerName, boolean visible) {
if (visible ^ configuration.getBoolean("display-whitelist", false))
show(playerName);
else
hide(playerName);
}
public List<DynmapPlayer> getVisiblePlayers(String worldName) {
ArrayList<DynmapPlayer> visiblePlayers = new ArrayList<DynmapPlayer>();
DynmapPlayer[] onlinePlayers = online; /* Use copied list - we don't call from server thread */
boolean useWhitelist = configuration.getBoolean("display-whitelist", false);
for (int i = 0; i < onlinePlayers.length; i++) {
DynmapPlayer p = onlinePlayers[i];
if(p == null) continue;
if((worldName != null) && (p.getWorld().equals(worldName) == false)) continue;
if (!(useWhitelist ^ hiddenPlayerNames.contains(p.getName().toLowerCase()))) {
visiblePlayers.add(p);
}
}
return visiblePlayers;
}
public List<DynmapPlayer> getVisiblePlayers() {
return getVisiblePlayers(null);
}
public List<DynmapPlayer> getHiddenPlayers() {
ArrayList<DynmapPlayer> hidden = new ArrayList<DynmapPlayer>();
DynmapPlayer[] onlinePlayers = online; /* Use copied list - we don't call from server thread */
boolean useWhitelist = configuration.getBoolean("display-whitelist", false);
for (int i = 0; i < onlinePlayers.length; i++) {
DynmapPlayer p = onlinePlayers[i];
if(p == null) continue;
if (useWhitelist ^ hiddenPlayerNames.contains(p.getName().toLowerCase())) {
hidden.add(p);
}
}
return hidden;
}
public boolean isVisiblePlayer(String p) {
boolean useWhitelist = configuration.getBoolean("display-whitelist", false);
return (!(useWhitelist ^ hiddenPlayerNames.contains(p.toLowerCase())));
}
/**
* Call this from server thread to update player list safely
*/
void updateOnlinePlayers(String skipone) {
DynmapPlayer[] players = server.getOnlinePlayers();
DynmapPlayer[] pl = new DynmapPlayer[players.length];
System.arraycopy(players, 0, pl, 0, pl.length);
if(skipone != null) {
for(int i = 0; i < pl.length; i++)
if(pl[i].getName().equals(skipone))
pl[i] = null;
}
online = pl;
}
}

View File

@ -1,66 +0,0 @@
package org.dynmap;
import static org.dynmap.JSONUtils.s;
import org.dynmap.common.DynmapListenerManager;
import org.dynmap.common.DynmapListenerManager.ChatEventListener;
import org.dynmap.common.DynmapListenerManager.EventType;
import org.dynmap.common.DynmapPlayer;
import org.json.simple.JSONObject;
public class SimpleWebChatComponent extends Component {
public SimpleWebChatComponent(final DynmapCore plugin, final ConfigurationNode configuration) {
super(plugin, configuration);
plugin.events.addListener("webchat", new Event.Listener<ChatEvent>() {
@Override
public void triggered(ChatEvent t) {
if(plugin.getServer().sendWebChatEvent(t.source, t.name, t.message)) {
String msg;
String msgfmt = plugin.configuration.getString("webmsgformat", null);
if(msgfmt != null) {
msgfmt = unescapeString(msgfmt);
msg = msgfmt.replace("%playername%", t.name).replace("%message%", t.message);
}
else {
msg = unescapeString(plugin.configuration.getString("webprefix", "\u00A72[WEB] ")) + t.name + ": " + unescapeString(plugin.configuration.getString("websuffix", "\u00A7f")) + t.message;
}
plugin.getServer().broadcastMessage(msg);
}
}
});
plugin.events.addListener("buildclientconfiguration", new Event.Listener<JSONObject>() {
@Override
public void triggered(JSONObject t) {
s(t, "allowchat", configuration.getBoolean("allowchat", false));
}
});
if (configuration.getBoolean("allowchat", false)) {
plugin.listenerManager.addListener(EventType.PLAYER_CHAT, new ChatEventListener() {
@Override
public void chatEvent(DynmapPlayer p, String msg) {
if(core.mapManager != null)
core.mapManager.pushUpdate(new Client.ChatMessage("player", "", p.getDisplayName(), msg, p.getName()));
}
});
plugin.listenerManager.addListener(EventType.PLAYER_JOIN, new DynmapListenerManager.PlayerEventListener() {
@Override
public void playerEvent(DynmapPlayer p) {
if((core.mapManager != null) && (core.playerList != null) && (core.playerList.isVisiblePlayer(p.getName()))) {
core.mapManager.pushUpdate(new Client.PlayerJoinMessage(p.getDisplayName(), p.getName()));
}
}
});
plugin.listenerManager.addListener(EventType.PLAYER_QUIT, new DynmapListenerManager.PlayerEventListener() {
@Override
public void playerEvent(DynmapPlayer p) {
if((core.mapManager != null) && (core.playerList != null) && (core.playerList.isVisiblePlayer(p.getName()))) {
core.mapManager.pushUpdate(new Client.PlayerQuitMessage(p.getDisplayName(), p.getName()));
}
}
});
}
}
}

View File

@ -1,10 +0,0 @@
package org.dynmap;
public class TestComponent extends Component {
public TestComponent(DynmapCore plugin, ConfigurationNode configuration) {
super(plugin, configuration);
Log.info("Hello! I'm a component that does stuff! Like saying what is in my configuration: " + configuration.getString("stuff"));
}
}

View File

@ -1,195 +0,0 @@
package org.dynmap;
import java.io.File;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.LinkedList;
import java.io.IOException;
import java.util.zip.CRC32;
import org.dynmap.utils.LRULinkedHashMap;
/**
* Image hash code manager - used to reduce compression and notification of updated tiles that do not actually yield new content
*
*/
public class TileHashManager {
private File tiledir; /* Base tile directory */
private boolean enabled;
/**
* Each tile hash file is a 32x32 tile grid, with each file having a CRC32 hash code generated from its pre-compression frame buffer
*/
private static class TileHashFile {
final String key;
final String subtype;
final int x; /* minimum tile coordinate / 32 */
final int y; /* minimum tile coordinate / 32 */
private File hf;
TileHashFile(String key, String subtype, int x, int y) {
this.key = key;
if(subtype != null)
this.subtype = subtype;
else
this.subtype = "";
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if(!(o instanceof TileHashFile))
return false;
TileHashFile fo = (TileHashFile)o;
return (x == fo.x) && (y == fo.y) && key.equals(fo.key) && (subtype.equals(fo.subtype));
}
@Override
public int hashCode() {
return key.hashCode() ^ subtype.hashCode() ^ (x << 16) ^ y;
}
public File getHashFile(File tiledir) {
if(hf == null) {
String k;
int idx = key.lastIndexOf('.'); /* Find last '.' - world name split (allows dots in world name) */
if(idx > 0)
k = key.substring(0, idx) + File.separatorChar + key.substring(idx+1);
else
k = key;
hf = new File(tiledir, k + (subtype.equals("")?"":("." + subtype)) + "_" + x + "_" + y + ".hash");
}
return hf;
}
/* Write to file */
public void writeToFile(File tiledir, byte[] crcbuf) {
RandomAccessFile fd = null;
try {
fd = new RandomAccessFile(getHashFile(tiledir), "rw");
fd.seek(0);
fd.write(crcbuf);
} catch (IOException iox) {
Log.severe("Error writing hash file - " + getHashFile(tiledir).getPath());
} finally {
if(fd != null) {
try { fd.close(); } catch (IOException iox) {}
}
}
}
/* Read from file */
public void readFromFile(File tiledir, byte[] crcbuf) {
RandomAccessFile fd = null;
try {
fd = new RandomAccessFile(getHashFile(tiledir), "r");
fd.seek(0);
fd.read(crcbuf);
} catch (IOException iox) {
Arrays.fill(crcbuf, (byte)0xFF);
writeToFile(tiledir, crcbuf);
} finally {
if(fd != null) {
try { fd.close(); } catch (IOException iox) {}
}
}
}
/* Read CRC */
public long getCRC(int tx, int ty, byte[] crcbuf) {
int off = (128 * (ty & 0x1F)) + (4 * (tx & 0x1F));
long crc = 0;
for(int i = 0; i < 4; i++)
crc = (crc << 8) + (0xFF & (int)crcbuf[off+i]);
return crc;
}
/* Set CRC */
public void setCRC(int tx, int ty, byte[] crcbuf, long crc) {
int off = (128 * (ty & 0x1F)) + (4 * (tx & 0x1F));
for(int i = 0; i < 4; i++)
crcbuf[off+i] = (byte)((crc >> ((3-i)*8)) & 0xFF);
}
}
private static final int MAX_CACHED_TILEHASHFILES = 25;
private Object lock = new Object();
private LRULinkedHashMap<TileHashFile, byte[]> tilehash = new LRULinkedHashMap<TileHashFile, byte[]>(MAX_CACHED_TILEHASHFILES);
private LinkedList<byte[]> crcworkbufs = new LinkedList<byte[]>();
private LinkedList<CRC32> crcs = new LinkedList<CRC32>();
public TileHashManager(File tileroot, boolean enabled) {
tiledir = tileroot;
this.enabled = enabled;
}
/* Read cached hashcode for given tile */
public long getImageHashCode(String key, String subtype, int tx, int ty) {
if(!enabled) {
return -1; /* Return value that never matches */
}
TileHashFile thf = new TileHashFile(key, subtype, tx >> 5, ty >> 5);
synchronized(lock) {
byte[] crcbuf = tilehash.get(thf); /* See if we have it cached */
if(crcbuf == null) { /* If not in cache, load it */
crcbuf = new byte[32*32*4]; /* Get our space */
Arrays.fill(crcbuf, (byte)0xFF); /* Fill with -1 */
tilehash.put(thf, crcbuf); /* Add to cache */
thf.readFromFile(tiledir, crcbuf);
}
return thf.getCRC(tx & 0x1F, ty & 0x1F, crcbuf);
}
}
/* Calculate hash code for given buffer */
public long calculateTileHash(int[] newbuf) {
if(!enabled) {
return 0; /* Return value that doesn't match */
}
CRC32 crc32;
byte[] crcworkbuf;
synchronized(lock) {
if(crcworkbufs.isEmpty()) {
crcworkbuf = new byte[4*newbuf.length];
}
else {
crcworkbuf = crcworkbufs.removeFirst();
}
if(crcs.isEmpty()) {
crc32 = new CRC32();
}
else {
crc32 = crcs.removeFirst();
crc32.reset();
}
}
if(crcworkbuf.length < (4*newbuf.length)){
crcworkbuf = new byte[4*newbuf.length];
}
for(int i = 0, off = 0; i < newbuf.length; i++) {
int v = newbuf[i];
crcworkbuf[off++] = (byte)v;
crcworkbuf[off++] = (byte)(v>>8);
crcworkbuf[off++] = (byte)(v>>16);
crcworkbuf[off++] = (byte)(v>>24);
}
/* Calculate CRC-32 for buffer */
crc32.update(crcworkbuf, 0, 4*newbuf.length);
long v = crc32.getValue();
synchronized(lock) {
crcworkbufs.addFirst(crcworkbuf);
crcs.addFirst(crc32);
}
return v;
}
/* Update hashcode for given tile */
public void updateHashCode(String key, String subtype, int tx, int ty, long newcrc) {
if(!enabled)
return;
synchronized(lock) {
/* Now, find and check existing value */
TileHashFile thf = new TileHashFile(key, subtype, tx >> 5, ty >> 5);
byte[] crcbuf = tilehash.get(thf); /* See if we have it cached */
if(crcbuf == null) { /* If not in cache, load it */
crcbuf = new byte[32*32*4]; /* Get our space */
tilehash.put(thf, crcbuf); /* Add to cache */
thf.readFromFile(tiledir, crcbuf);
}
thf.setCRC(tx & 0x1F, ty & 0x1F, crcbuf, newcrc); /* Update field */
thf.writeToFile(tiledir, crcbuf); /* And write it out */
}
}
}

View File

@ -1,120 +0,0 @@
package org.dynmap;
import java.util.ArrayList;
import java.util.HashMap;
public class UpdateQueue {
public Object lock = new Object();
private HashMap<UpdateRec,UpdateRec> updateSet = new HashMap<UpdateRec,UpdateRec>();
private UpdateRec orderedlist = null; /* Oldest to youngest */
private static final long maxUpdateAge = 120000;
private static final long ageOutPeriod = 5000;
private long lastageout = 0;
private static class UpdateRec {
Client.Update u;
UpdateRec next;
UpdateRec prev;
@Override
public boolean equals(Object o) {
if(o instanceof UpdateRec)
return u.equals(((UpdateRec)o).u);
return false;
}
@Override
public int hashCode() {
return u.hashCode();
}
}
private void doAgeOut(long now) {
/* If we're due */
if((now < lastageout) || (now > (lastageout + ageOutPeriod))) {
lastageout = now;
long deadline = now - maxUpdateAge;
while((orderedlist != null) && (orderedlist.u.timestamp < deadline)) {
UpdateRec r = orderedlist;
updateSet.remove(r); /* Remove record from set */
if(r.next == r) {
orderedlist = null;
}
else {
orderedlist = r.next;
r.next.prev = r.prev;
r.prev.next = r.next;
}
r.next = r.prev = null;
}
}
}
public void pushUpdate(Client.Update obj) {
synchronized (lock) {
/* Do inside lock - prevent delay between time and actual work */
long now = System.currentTimeMillis();
doAgeOut(now); /* Consider age out */
UpdateRec r = new UpdateRec();
r.u = obj;
UpdateRec oldr = updateSet.remove(r); /* Try to remove redundant event */
if(oldr != null) { /* If found, remove from ordered list too */
if(oldr.next == oldr) { /* Only one? */
orderedlist = null;
}
else {
if(orderedlist == oldr) { /* We're oldest? */
orderedlist = oldr.next;
}
oldr.next.prev = oldr.prev;
oldr.prev.next = oldr.next;
}
oldr.next = oldr.prev = null;
}
updateSet.put(r, r);
/* Add to end of ordered list */
if(orderedlist == null) {
orderedlist = r;
r.next = r.prev = r;
}
else {
r.next = orderedlist;
r.prev = orderedlist.prev;
r.next.prev = r.prev.next = r;
}
}
}
private ArrayList<Client.Update> tmpupdates = new ArrayList<Client.Update>();
public Client.Update[] getUpdatedObjects(long since) {
Client.Update[] updates;
synchronized (lock) {
long now = System.currentTimeMillis();
doAgeOut(now); /* Consider age out */
tmpupdates.clear();
if(orderedlist != null) {
UpdateRec r = orderedlist.prev; /* Get newest */
while(r != null) {
if(r.u.timestamp >= since) {
tmpupdates.add(r.u);
if(r == orderedlist)
r = null;
else
r = r.prev;
}
else {
r = null;
}
}
}
// Reverse output.
updates = new Client.Update[tmpupdates.size()];
for (int i = 0; i < updates.length; i++) {
updates[i] = tmpupdates.get(updates.length-1-i);
}
}
return updates;
}
}

View File

@ -73,6 +73,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
private PermissionProvider permissions;
private String version;
public BukkitEventProcessor bep;
public SnapshotCache sscache;
private MapManager mapManager;
public static DynmapPlugin plugin;
@ -227,7 +228,14 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
bname[i] = b[i].toString();
return bname;
}
@Override
public double getCacheHitRate() {
return sscache.getHitRate();
}
@Override
public void resetCacheStats() {
sscache.resetStats();
}
}
/**
* Player access abstraction class
@ -365,6 +373,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
this.setEnabled(false);
return;
}
sscache = new SnapshotCache(core.getSnapShotCacheSize());
/* Get map manager from core */
mapManager = core.getMapManager();
/* Initialized the currently loaded worlds */
@ -384,7 +394,13 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
bep.cleanup();
/* Disable core */
core.disableCore();
if(sscache != null) {
sscache.cleanup();
sscache = null;
}
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
DynmapCommandSender dsender;
@ -548,7 +564,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
return;
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onplace) {
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockplace");
}
@ -560,7 +576,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
return;
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onbreak) {
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockbreak");
}
@ -572,7 +588,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
return;
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onleaves) {
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "leavesdecay");
}
@ -584,7 +600,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
return;
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onburn) {
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockburn");
}
@ -596,7 +612,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
return;
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onblockform) {
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockform");
}
@ -608,7 +624,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
return;
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onblockfade) {
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfade");
}
@ -620,7 +636,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
return;
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onblockspread) {
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockspread");
}
@ -632,12 +648,12 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
return;
Location loc = event.getToBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onblockfromto)
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfromto");
loc = event.getBlock().getLocation();
wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onblockfromto)
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfromto");
}
@ -648,7 +664,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
return;
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onblockphysics) {
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockphysics");
}
@ -668,14 +684,14 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
}
String wn = loc.getWorld().getName();
int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
mapManager.sscache.invalidateSnapshot(wn, x, y, z);
sscache.invalidateSnapshot(wn, x, y, z);
if(onpiston)
mapManager.touch(wn, x, y, z, "pistonretract");
for(int i = 0; i < 2; i++) {
x += dir.getModX();
y += dir.getModY();
z += dir.getModZ();
mapManager.sscache.invalidateSnapshot(wn, x, y, z);
sscache.invalidateSnapshot(wn, x, y, z);
if(onpiston)
mapManager.touch(wn, x, y, z, "pistonretract");
}
@ -694,14 +710,14 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
}
String wn = loc.getWorld().getName();
int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
mapManager.sscache.invalidateSnapshot(wn, x, y, z);
sscache.invalidateSnapshot(wn, x, y, z);
if(onpiston)
mapManager.touch(wn, x, y, z, "pistonretract");
for(int i = 0; i < 1+event.getLength(); i++) {
x += dir.getModX();
y += dir.getModY();
z += dir.getModZ();
mapManager.sscache.invalidateSnapshot(wn, x, y, z);
sscache.invalidateSnapshot(wn, x, y, z);
if(onpiston)
mapManager.touch(wn, x, y, z, "pistonretract");
}
@ -794,7 +810,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
if(z < minz) minz = z;
if(z > maxz) maxz = z;
}
mapManager.sscache.invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz);
sscache.invalidateSnapshot(wname, minx, miny, minz, maxx, maxy, maxz);
if(onexplosion) {
mapManager.touchVolume(wname, minx, miny, minz, maxx, maxy, maxz, "entityexplode");
}

View File

@ -481,7 +481,7 @@ public class NewMapChunkCache implements MapChunkCache {
}
}
/* Check if cached chunk snapshot found */
ChunkSnapshot ss = MapManager.mapman.sscache.getSnapshot(w.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty);
ChunkSnapshot ss = DynmapPlugin.plugin.sscache.getSnapshot(w.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty);
if(ss != null) {
if(!vis) {
if(hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN)
@ -518,7 +518,7 @@ public class NewMapChunkCache implements MapChunkCache {
else
ss = w.getEmptyChunkSnapshot(chunk.x, chunk.z, biome, biomeraw);
if(ss != null) {
MapManager.mapman.sscache.putSnapshot(w.getName(), chunk.x, chunk.z, ss, blockdata, biome, biomeraw, highesty);
DynmapPlugin.plugin.sscache.putSnapshot(w.getName(), chunk.x, chunk.z, ss, blockdata, biome, biomeraw, highesty);
}
}
snaparray[(chunk.x-x_min) + (chunk.z - z_min)*x_dim] = ss;

View File

@ -1,33 +0,0 @@
package org.dynmap.common;
/* Generic biome mapping */
public enum BiomeMap {
NULL,
RAINFOREST,
SWAMPLAND,
SEASONAL_FOREST,
FOREST,
SAVANNA,
SHRUBLAND,
TAIGA,
DESERT,
PLAINS,
ICE_DESERT,
TUNDRA,
HELL,
SKY,
OCEAN,
RIVER,
EXTREME_HILLS,
FROZEN_OCEAN,
FROZEN_RIVER,
ICE_PLAINS,
ICE_MOUNTAINS,
MUSHROOM_ISLAND,
MUSHROOM_SHORE,
BEACH,
DESERT_HILLS,
FOREST_HILLS,
TAIGA_HILLS,
SMALL_MOUNTAINS
}

View File

@ -1,37 +0,0 @@
package org.dynmap.common;
public enum DynmapChatColor {
BLACK(0x0),
DARK_BLUE(0x1),
DARK_GREEN(0x2),
DARK_AQUA(0x3),
DARK_RED(0x4),
DARK_PURPLE(0x5),
GOLD(0x6),
GRAY(0x7),
DARK_GRAY(0x8),
BLUE(0x9),
GREEN(0xA),
AQUA(0xB),
RED(0xC),
LIGHT_PURPLE(0xD),
YELLOW(0xE),
WHITE(0xF);
private final String str;
private DynmapChatColor(final int code) {
this.str = String.format("\u00A7%x", code);
}
@Override
public String toString() {
return str;
}
public static String stripColor(final String input) {
if (input == null) {
return null;
}
return input.replaceAll("(?i)\u00A7[0-9A-F]", "");
}
}

View File

@ -1,24 +0,0 @@
package org.dynmap.common;
public interface DynmapCommandSender {
/**
* Does command sender have given security privilege
* @param privid - privilege ID
* @return true if it does, false if it doesn't
*/
public boolean hasPrivilege(String privid);
/**
* Send given message to command sender
* @param msg - message to be sent (with color codes marked &0 to &F)
*/
public void sendMessage(String msg);
/**
* Test if command sender is still connected/online
* @return true if connected, false if not
*/
public boolean isConnected();
/**
* Is operator privilege
*/
public boolean isOp();
}

View File

@ -1,123 +0,0 @@
package org.dynmap.common;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.Map;
import org.dynmap.DynmapCore;
import org.dynmap.DynmapWorld;
/**
* Simple handler for managing event listeners and dispatch in a neutral fashion
*
*/
public class DynmapListenerManager {
private DynmapCore core;
public DynmapListenerManager(DynmapCore core) {
this.core = core;
}
public interface EventListener {
}
public interface WorldEventListener extends EventListener {
public void worldEvent(DynmapWorld w);
}
public interface PlayerEventListener extends EventListener {
public void playerEvent(DynmapPlayer p);
}
public interface ChatEventListener extends EventListener {
public void chatEvent(DynmapPlayer p, String msg);
}
public interface BlockEventListener extends EventListener {
public void blockEvent(int blkid, String w, int x, int y, int z);
}
public interface SignChangeEventListener extends EventListener {
public void signChangeEvent(int blkid, String w, int x, int y, int z, String[] lines, DynmapPlayer p);
}
public enum EventType {
WORLD_LOAD,
WORLD_UNLOAD,
WORLD_SPAWN_CHANGE,
PLAYER_JOIN,
PLAYER_QUIT,
PLAYER_BED_LEAVE,
PLAYER_CHAT,
BLOCK_BREAK,
SIGN_CHANGE
}
private Map<EventType, ArrayList<EventListener>> listeners = new EnumMap<EventType, ArrayList<EventListener>>(EventType.class);
public void addListener(EventType type, EventListener listener) {
ArrayList<EventListener> lst = listeners.get(type);
if(lst == null) {
lst = new ArrayList<EventListener>();
listeners.put(type, lst);
core.getServer().requestEventNotification(type);
}
lst.add(listener);
}
public void processWorldEvent(EventType type, DynmapWorld w) {
ArrayList<EventListener> lst = listeners.get(type);
if(lst == null) return;
int sz = lst.size();
for(int i = 0; i < sz; i++) {
EventListener el = lst.get(i);
if(el instanceof WorldEventListener) {
((WorldEventListener)el).worldEvent(w);
}
}
}
public void processPlayerEvent(EventType type, DynmapPlayer p) {
ArrayList<EventListener> lst = listeners.get(type);
if(lst == null) return;
int sz = lst.size();
for(int i = 0; i < sz; i++) {
EventListener el = lst.get(i);
if(el instanceof PlayerEventListener) {
((PlayerEventListener)el).playerEvent(p);
}
}
}
public void processChatEvent(EventType type, DynmapPlayer p, String msg) {
ArrayList<EventListener> lst = listeners.get(type);
if(lst == null) return;
int sz = lst.size();
for(int i = 0; i < sz; i++) {
EventListener el = lst.get(i);
if(el instanceof ChatEventListener) {
((ChatEventListener)el).chatEvent(p, msg);
}
}
}
public void processBlockEvent(EventType type, int blkid, String world, int x, int y, int z)
{
ArrayList<EventListener> lst = listeners.get(type);
if(lst == null) return;
int sz = lst.size();
for(int i = 0; i < sz; i++) {
EventListener el = lst.get(i);
if(el instanceof BlockEventListener) {
((BlockEventListener)el).blockEvent(blkid, world, x, y, z);
}
}
}
public void processSignChangeEvent(EventType type, int blkid, String world, int x, int y, int z, String[] lines, DynmapPlayer p)
{
ArrayList<EventListener> lst = listeners.get(type);
if(lst == null) return;
int sz = lst.size();
for(int i = 0; i < sz; i++) {
EventListener el = lst.get(i);
if(el instanceof SignChangeEventListener) {
((SignChangeEventListener)el).signChangeEvent(blkid, world, x, y, z, lines, p);
}
}
}
/* Clean up registered listeners */
public void cleanup() {
for(ArrayList<EventListener> l : listeners.values())
l.clear();
listeners.clear();
}
}

View File

@ -1,56 +0,0 @@
package org.dynmap.common;
import java.net.InetSocketAddress;
import org.dynmap.DynmapLocation;
/**
* Player (server neutral) - represents online or offline player
*/
public interface DynmapPlayer extends DynmapCommandSender {
/**
* Get player ID
* @return ID (case insensitive)
*/
public String getName();
/**
* Get player display name
* @return display name
*/
public String getDisplayName();
/**
* Is player online?
* @return true if online
*/
public boolean isOnline();
/**
* Get current location of player
* @return location
*/
public DynmapLocation getLocation();
/**
* Get world ID of player
* @return id
*/
public String getWorld();
/**
* Get connected address for player
*/
public InetSocketAddress getAddress();
/**
* Check if player is sneaking
*/
public boolean isSneaking();
/**
* Get health
*/
public int getHealth();
/**
* Get armor points
*/
public int getArmorPoints();
/**
* Get spawn bed location
*/
public DynmapLocation getBedSpawnLocation();
}

View File

@ -1,78 +0,0 @@
package org.dynmap.common;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import org.dynmap.common.DynmapListenerManager.EventType;
/**
* This interface defines a server-neutral interface for the DynmapCore and other neutral components to use to access server provided
* services. Platform-specific plugin must supply DynmapCore with an instance of an object implementing this interface.
*/
public interface DynmapServerInterface {
/**
* Schedule task to run on server-safe thread (one suitable for other server API calls)
* @param run - runnable method
* @param delay - delay in server ticks (50msec)
*/
public void scheduleServerTask(Runnable run, long delay);
/**
* Call method on server-safe thread
* @param call - Callable method
* @return future for completion of call
*/
public <T> Future<T> callSyncMethod(Callable<T> task);
/**
* Get list of online players
* @return list of online players
*/
public DynmapPlayer[] getOnlinePlayers();
/**
* Request reload of plugin
*/
public void reload();
/**
* Get active player
* @param name - player name
* @return player
*/
public DynmapPlayer getPlayer(String name);
/**
* Get banned IPs
*/
public Set<String> getIPBans();
/**
* Get server name
*/
public String getServerName();
/**
* Test if player ID is banned
*/
public boolean isPlayerBanned(String pid);
/**
* Strip out chat color
*/
public String stripChatColor(String s);
/**
* Request notificiation for given events (used by DynmapListenerManager)
*/
public boolean requestEventNotification(EventType type);
/**
* Send notification of web chat message
* @param source - source
* @param name - name
* @param msg - message text
* @return true if not cancelled
*/
public boolean sendWebChatEvent(String source, String name, String msg);
/**
* Broadcast message to players
* @param msg
*/
public void broadcastMessage(String msg);
/**
* Get Biome ID list
*/
public String[] getBiomeIDs();
}

View File

@ -1,31 +0,0 @@
package org.dynmap.debug;
import java.util.ArrayList;
public class Debug {
private static ArrayList<Debugger> debuggers = new ArrayList<Debugger>();
public synchronized static void addDebugger(Debugger d) {
debuggers.add(d);
}
public synchronized static void removeDebugger(Debugger d) {
debuggers.remove(d);
}
public synchronized static void clearDebuggers() {
debuggers.clear();
}
public synchronized static void debug(String message) {
for(int i = 0; i < debuggers.size(); i++) debuggers.get(i).debug(message);
}
public synchronized static void error(String message) {
for(int i = 0; i < debuggers.size(); i++) debuggers.get(i).error(message);
}
public synchronized static void error(String message, Throwable thrown) {
for(int i = 0; i < debuggers.size(); i++) debuggers.get(i).error(message, thrown);
}
}

View File

@ -1,9 +0,0 @@
package org.dynmap.debug;
public interface Debugger {
void debug(String message);
void error(String message);
void error(String message, Throwable thrown);
}

View File

@ -1,27 +0,0 @@
package org.dynmap.debug;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapCore;
import org.dynmap.Log;
public class LogDebugger implements Debugger {
public LogDebugger(DynmapCore core, ConfigurationNode configuration) {
}
@Override
public void debug(String message) {
Log.info(message);
}
@Override
public void error(String message) {
Log.severe(message);
}
@Override
public void error(String message, Throwable thrown) {
Log.severe(message);
thrown.printStackTrace();
}
}

View File

@ -1,21 +0,0 @@
package org.dynmap.debug;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapCore;
public class NullDebugger implements Debugger {
public static final NullDebugger instance = new NullDebugger(null, null);
public NullDebugger(DynmapCore core, ConfigurationNode configuration) {
}
public void debug(String message) {
}
public void error(String message) {
}
public void error(String message, Throwable thrown) {
}
}

View File

@ -1,592 +0,0 @@
package org.dynmap.flat;
import org.dynmap.DynmapWorld;
import static org.dynmap.JSONUtils.a;
import static org.dynmap.JSONUtils.s;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.dynmap.Client;
import org.dynmap.Color;
import org.dynmap.ColorScheme;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapChunk;
import org.dynmap.DynmapCore;
import org.dynmap.DynmapCore.CompassMode;
import org.dynmap.MapManager;
import org.dynmap.TileHashManager;
import org.dynmap.MapTile;
import org.dynmap.MapType;
import org.dynmap.debug.Debug;
import org.dynmap.utils.DynmapBufferedImage;
import org.dynmap.utils.FileLockManager;
import org.dynmap.utils.MapChunkCache;
import org.dynmap.utils.MapIterator;
import org.dynmap.utils.MapIterator.BlockStep;
import org.json.simple.JSONObject;
public class FlatMap extends MapType {
private ConfigurationNode configuration;
private String prefix;
private String name;
private ColorScheme colorScheme;
private int maximumHeight = 127;
private int ambientlight = 15;;
private int shadowscale[] = null;
private boolean night_and_day; /* If true, render both day (prefix+'-day') and night (prefix) tiles */
protected boolean transparency;
private enum Texture { NONE, SMOOTH, DITHER };
private Texture textured = Texture.NONE;
private boolean isbigmap;
public FlatMap(DynmapCore core, ConfigurationNode configuration) {
this.configuration = configuration;
name = configuration.getString("name", null);
prefix = configuration.getString("prefix", name);
colorScheme = ColorScheme.getScheme(core, (String) configuration.get("colorscheme"));
Object o = configuration.get("maximumheight");
if (o != null) {
maximumHeight = Integer.parseInt(String.valueOf(o));
if (maximumHeight > 127)
maximumHeight = 127;
}
o = configuration.get("shadowstrength");
if(o != null) {
double shadowweight = Double.parseDouble(String.valueOf(o));
if(shadowweight > 0.0) {
shadowscale = new int[16];
shadowscale[15] = 256;
/* Normal brightness weight in MC is a 20% relative dropoff per step */
for(int i = 14; i >= 0; i--) {
double v = shadowscale[i+1] * (1.0 - (0.2 * shadowweight));
shadowscale[i] = (int)v;
if(shadowscale[i] > 256) shadowscale[i] = 256;
if(shadowscale[i] < 0) shadowscale[i] = 0;
}
}
}
o = configuration.get("ambientlight");
if(o != null) {
ambientlight = Integer.parseInt(String.valueOf(o));
}
night_and_day = configuration.getBoolean("night-and-day", false);
transparency = configuration.getBoolean("transparency", false); /* Default off */
String tex = configuration.getString("textured", "none");
if(tex.equals("none"))
textured = Texture.NONE;
else if(tex.equals("dither"))
textured = Texture.DITHER;
else
textured = Texture.SMOOTH;
isbigmap = configuration.getBoolean("isbigmap", false);
}
@Override
public MapTile[] getTiles(DynmapWorld w, int x, int y, int z) {
return new MapTile[] { new FlatMapTile(w, this, x>>7, z>>7, 128) };
}
@Override
public MapTile[] getTiles(DynmapWorld w, int xmin, int ymin, int zmin, int xmax, int ymax, int zmax) {
ArrayList<MapTile> rslt = new ArrayList<MapTile>();
for(int i = xmin; i <= xmax; i++) {
for(int j = zmin; j < zmax; j++) {
rslt.add(new FlatMapTile(w, this, i, j, 128));
}
}
return rslt.toArray(new MapTile[rslt.size()]);
}
@Override
public MapTile[] getAdjecentTiles(MapTile tile) {
FlatMapTile t = (FlatMapTile) tile;
DynmapWorld w = t.getDynmapWorld();
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 List<DynmapChunk> getRequiredChunks(MapTile tile) {
FlatMapTile t = (FlatMapTile) tile;
int chunksPerTile = t.size / 16;
int sx = t.x * chunksPerTile;
int sz = t.y * chunksPerTile;
ArrayList<DynmapChunk> result = new ArrayList<DynmapChunk>(chunksPerTile * chunksPerTile);
for (int x = 0; x < chunksPerTile; x++)
for (int z = 0; z < chunksPerTile; z++) {
result.add(new DynmapChunk(sx + x, sz + z));
}
return result;
}
public boolean render(MapChunkCache cache, MapTile tile, File outputFile) {
FlatMapTile t = (FlatMapTile) tile;
boolean isnether = t.getDynmapWorld().isNether() && (maximumHeight == 127);
boolean didwrite = false;
Color rslt = new Color();
int[] pixel = new int[4];
int[] pixel_day = null;
DynmapBufferedImage im = DynmapBufferedImage.allocateBufferedImage(t.size, t.size);
int[] argb_buf = im.argb_buf;
DynmapBufferedImage im_day = null;
int[] argb_buf_day = null;
if(night_and_day) {
im_day = DynmapBufferedImage.allocateBufferedImage(t.size, t.size);
argb_buf_day = im_day.argb_buf;
pixel_day = new int[4];
}
MapIterator mapiter = cache.getIterator(t.x * t.size, 127, t.y * t.size);
for (int x = 0; x < t.size; x++) {
mapiter.initialize(t.x * t.size + x, 127, t.y * t.size);
for (int y = 0; y < t.size; y++, mapiter.stepPosition(BlockStep.Z_PLUS)) {
int blockType;
mapiter.setY(127);
if(isnether) {
while((blockType = mapiter.getBlockTypeID()) != 0) {
mapiter.stepPosition(BlockStep.Y_MINUS);
if(mapiter.getY() < 0) { /* Solid - use top */
mapiter.setY(127);
blockType = mapiter.getBlockTypeID();
break;
}
}
if(blockType == 0) { /* Hit air - now find non-air */
while((blockType = mapiter.getBlockTypeID()) == 0) {
mapiter.stepPosition(BlockStep.Y_MINUS);
if(mapiter.getY() < 0) {
mapiter.setY(0);
break;
}
}
}
}
else {
int my = mapiter.getHighestBlockYAt();
if(my > maximumHeight) my = maximumHeight;
mapiter.setY(my);
blockType = mapiter.getBlockTypeID();
if(blockType == 0) { /* If air, go down one - fixes ice */
my--;
if(my < 0)
continue;
mapiter.setY(my);
blockType = mapiter.getBlockTypeID();
}
}
int data = 0;
Color[] colors = colorScheme.colors[blockType];
if(colorScheme.datacolors[blockType] != null) {
data = mapiter.getBlockData();
colors = colorScheme.datacolors[blockType][data];
}
if (colors == null)
continue;
Color c;
if(textured == Texture.SMOOTH)
c = colors[4];
else if((textured == Texture.DITHER) && (((x+y) & 0x01) == 1)) {
c = colors[2];
}
else {
c = colors[0];
}
if (c == null)
continue;
pixel[0] = c.getRed();
pixel[1] = c.getGreen();
pixel[2] = c.getBlue();
pixel[3] = c.getAlpha();
/* If transparency needed, process it */
if(transparency && (pixel[3] < 255)) {
process_transparent(pixel, pixel_day, mapiter);
}
/* If ambient light less than 15, do scaling */
else if((shadowscale != null) && (ambientlight < 15)) {
if(mapiter.getY() < 127)
mapiter.stepPosition(BlockStep.Y_PLUS);
if(night_and_day) { /* Use unscaled color for day (no shadows from above) */
pixel_day[0] = pixel[0];
pixel_day[1] = pixel[1];
pixel_day[2] = pixel[2];
pixel_day[3] = 255;
}
int light = Math.max(ambientlight, mapiter.getBlockEmittedLight());
pixel[0] = (pixel[0] * shadowscale[light]) >> 8;
pixel[1] = (pixel[1] * shadowscale[light]) >> 8;
pixel[2] = (pixel[2] * shadowscale[light]) >> 8;
pixel[3] = 255;
}
else { /* Only do height keying if we're not messing with ambient light */
boolean below = mapiter.getY() < 64;
// Make height range from 0 - 1 (1 - 0 for below and 0 - 1 above)
float height = (below ? 64 - mapiter.getY() : mapiter.getY() - 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;
if (below) {
pixel[0] -= pixel[0] * scale;
pixel[1] -= pixel[1] * scale;
pixel[2] -= pixel[2] * scale;
pixel[3] = 255;
} else {
pixel[0] += (255-pixel[0]) * scale;
pixel[1] += (255-pixel[1]) * scale;
pixel[2] += (255-pixel[2]) * scale;
pixel[3] = 255;
}
if(night_and_day) {
pixel_day[0] = pixel[0];
pixel_day[1] = pixel[1];
pixel_day[2] = pixel[2];
pixel_day[3] = 255;
}
}
rslt.setRGBA(pixel[0], pixel[1], pixel[2], pixel[3]);
argb_buf[(t.size-y-1) + (x*t.size)] = rslt.getARGB();
if(night_and_day) {
rslt.setRGBA(pixel_day[0], pixel_day[1], pixel_day[2], pixel[3]);
argb_buf_day[(t.size-y-1) + (x*t.size)] = rslt.getARGB();
}
}
}
/* Test to see if we're unchanged from older tile */
TileHashManager hashman = MapManager.mapman.hashman;
long crc = hashman.calculateTileHash(argb_buf);
boolean tile_update = false;
FileLockManager.getWriteLock(outputFile);
try {
if((!outputFile.exists()) || (crc != hashman.getImageHashCode(tile.getKey(prefix), null, t.x, t.y))) {
/* Wrap buffer as buffered image */
Debug.debug("saving image " + outputFile.getPath());
if(!outputFile.getParentFile().exists())
outputFile.getParentFile().mkdirs();
try {
FileLockManager.imageIOWrite(im.buf_img, ImageFormat.FORMAT_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);
}
MapManager.mapman.pushUpdate(tile.getDynmapWorld(), new Client.Tile(tile.getFilename()));
hashman.updateHashCode(tile.getKey(prefix), null, t.x, t.y, crc);
tile.getDynmapWorld().enqueueZoomOutUpdate(outputFile);
tile_update = true;
didwrite = true;
}
else {
Debug.debug("skipping image " + outputFile.getPath() + " - hash match");
}
} finally {
FileLockManager.releaseWriteLock(outputFile);
DynmapBufferedImage.freeBufferedImage(im);
}
MapManager.mapman.updateStatistics(tile, prefix, true, tile_update, true);
/* If day too, handle it */
if(night_and_day) {
File dayfile = new File(tile.getDynmapWorld().worldtilepath, tile.getDayFilename());
crc = hashman.calculateTileHash(argb_buf_day);
FileLockManager.getWriteLock(dayfile);
try {
if((!dayfile.exists()) || (crc != hashman.getImageHashCode(tile.getKey(prefix), "day", t.x, t.y))) {
Debug.debug("saving image " + dayfile.getPath());
if(!dayfile.getParentFile().exists())
dayfile.getParentFile().mkdirs();
try {
FileLockManager.imageIOWrite(im_day.buf_img, ImageFormat.FORMAT_PNG, dayfile);
} catch (IOException e) {
Debug.error("Failed to save image: " + dayfile.getPath(), e);
} catch (java.lang.NullPointerException e) {
Debug.error("Failed to save image (NullPointerException): " + dayfile.getPath(), e);
}
MapManager.mapman.pushUpdate(tile.getDynmapWorld(), new Client.Tile(tile.getDayFilename()));
hashman.updateHashCode(tile.getKey(prefix), "day", t.x, t.y, crc);
tile.getDynmapWorld().enqueueZoomOutUpdate(dayfile);
tile_update = true;
didwrite = true;
}
else {
Debug.debug("skipping image " + dayfile.getPath() + " - hash match");
tile_update = false;
}
} finally {
FileLockManager.releaseWriteLock(dayfile);
DynmapBufferedImage.freeBufferedImage(im_day);
}
MapManager.mapman.updateStatistics(tile, prefix+"_day", true, tile_update, true);
}
return didwrite;
}
private void process_transparent(int[] pixel, int[] pixel_day, MapIterator mapiter) {
int r = pixel[0], g = pixel[1], b = pixel[2], a = pixel[3];
int r_day = 0, g_day = 0, b_day = 0, a_day = 0;
if(pixel_day != null) {
r_day = pixel[0]; g_day = pixel[1]; b_day = pixel[2]; a_day = pixel[3];
}
/* Scale alpha to be proportional to iso view (where we go through 4 blocks to go sqrt(6) or 2.45 units of distance */
if(a < 255)
a = a_day = 255 - ((255-a)*(255-a) >> 8);
/* Handle lighting on cube */
if((shadowscale != null) && (ambientlight < 15)) {
boolean did_inc = false;
if(mapiter.getY() < 127) {
mapiter.stepPosition(BlockStep.Y_PLUS);
did_inc = true;
}
if(night_and_day) { /* Use unscaled color for day (no shadows from above) */
r_day = r; g_day = g; b_day = b; a_day = a;
}
int light = Math.max(ambientlight, mapiter.getBlockEmittedLight());
r = (r * shadowscale[light]) >> 8;
g = (g * shadowscale[light]) >> 8;
b = (b * shadowscale[light]) >> 8;
if(did_inc)
mapiter.stepPosition(BlockStep.Y_MINUS);
}
if(a < 255) { /* If not opaque */
pixel[0] = pixel[1] = pixel[2] = pixel[3] = 0;
if(pixel_day != null)
pixel_day[0] = pixel_day[1] = pixel_day[2] = pixel_day[3] = 0;
mapiter.stepPosition(BlockStep.Y_MINUS);
if(mapiter.getY() >= 0) {
int blockType = mapiter.getBlockTypeID();
int data = 0;
Color[] colors = colorScheme.colors[blockType];
if(colorScheme.datacolors[blockType] != null) {
data = mapiter.getBlockData();
colors = colorScheme.datacolors[blockType][data];
}
if (colors != null) {
Color c = colors[0];
if (c != null) {
pixel[0] = c.getRed();
pixel[1] = c.getGreen();
pixel[2] = c.getBlue();
pixel[3] = c.getAlpha();
}
}
/* Recurse to resolve color here */
process_transparent(pixel, pixel_day, mapiter);
}
}
/* Blend colors from behind block and block, based on alpha */
r *= a;
g *= a;
b *= a;
int na = 255 - a;
pixel[0] = (pixel[0] * na + r) >> 8;
pixel[1] = (pixel[1] * na + g) >> 8;
pixel[2] = (pixel[2] * na + b) >> 8;
pixel[3] = 255;
if(pixel_day != null) {
r_day *= a_day;
g_day *= a_day;
b_day *= a_day;
na = 255 - a_day;
pixel_day[0] = (pixel_day[0] * na + r_day) >> 8;
pixel_day[1] = (pixel_day[1] * na + g_day) >> 8;
pixel_day[2] = (pixel_day[2] * na + b_day) >> 8;
pixel_day[3] = 255;
}
}
public String getName() {
return name;
}
public String getPrefix() {
return prefix;
}
/* Get maps rendered concurrently with this map in this world */
public List<MapType> getMapsSharingRender(DynmapWorld w) {
return Collections.singletonList((MapType)this);
}
/* Get names of maps rendered concurrently with this map type in this world */
public List<String> getMapNamesSharingRender(DynmapWorld w) {
return Collections.singletonList(name);
}
public List<ZoomInfo> baseZoomFileInfo() {
ArrayList<ZoomInfo> s = new ArrayList<ZoomInfo>();
s.add(new ZoomInfo(getPrefix() + "_128", 0));
if(night_and_day)
s.add(new ZoomInfo(getPrefix()+"_day_128", 0));
return s;
}
public int baseZoomFileStepSize() { return 1; }
private static final int[] stepseq = { 1, 3, 0, 2 };
public MapStep zoomFileMapStep() { return MapStep.X_PLUS_Y_PLUS; }
public int[] zoomFileStepSequence() { return stepseq; }
/* How many bits of coordinate are shifted off to make big world directory name */
public int getBigWorldShift() { return 5; }
/* Returns true if big world file structure is in effect for this map */
@Override
public boolean isBigWorldMap(DynmapWorld w) {
return w.bigworld || isbigmap;
}
public static class FlatMapTile extends MapTile {
FlatMap map;
public int x;
public int y;
public int size;
private String fname;
private String fname_day;
public FlatMapTile(DynmapWorld world, FlatMap map, int x, int y, int size) {
super(world);
this.map = map;
this.x = x;
this.y = y;
this.size = size;
}
public FlatMapTile(DynmapWorld world, String parm) throws Exception {
super(world);
String[] parms = parm.split(",");
if(parms.length < 4) throw new Exception("wrong parameter count");
this.x = Integer.parseInt(parms[0]);
this.y = Integer.parseInt(parms[1]);
this.size = Integer.parseInt(parms[2]);
for(MapType t : world.maps) {
if(t.getName().equals(parms[3]) && (t instanceof FlatMap)) {
this.map = (FlatMap)t;
break;
}
}
if(this.map == null) throw new Exception("invalid map");
}
@Override
protected String saveTileData() {
return String.format("%d,%d,%d,%s", x, y, size, map.getName());
}
@Override
public String getFilename() {
if(fname == null) {
if(world.bigworld)
fname = map.prefix + "_" + size + "/" + ((-(y+1))>>5) + "_" + (x>>5) + "/" + -(y+1) + "_" + x + ".png";
else
fname = map.prefix + "_" + size + "_" + -(y+1) + "_" + x + ".png";
}
return fname;
}
@Override
public String getDayFilename() {
if(fname_day == null) {
if(world.bigworld)
fname_day = map.prefix + "_day_" + size + "/" + ((-(y+1))>>5) + "_" + (x>>5) + "/" + -(y+1) + "_" + x + ".png";
else
fname_day = map.prefix + "_day_" + size + "_" + -(y+1) + "_" + x + ".png";
}
return fname_day;
}
public String toString() {
return world.getName() + ":" + getFilename();
}
@Override
public boolean render(MapChunkCache cache, String mapname) {
return map.render(cache, this, MapManager.mapman.getTileFile(this));
}
@Override
public List<DynmapChunk> getRequiredChunks() {
return map.getRequiredChunks(this);
}
@Override
public MapTile[] getAdjecentTiles() {
return map.getAdjecentTiles(this);
}
@Override
public int hashCode() {
return x ^ y ^ size ^ map.getName().hashCode();
}
@Override
public boolean equals(Object x) {
if(x instanceof FlatMapTile) {
return equals((FlatMapTile)x);
}
return false;
}
public boolean equals(FlatMapTile o) {
return (o.x == x) && (o.y == y) && (o.map == map);
}
@Override
public String getKey(String prefix) {
return world.getName() + "." + map.getPrefix();
}
public boolean isHightestBlockYDataNeeded() { return true; }
public boolean isBiomeDataNeeded() { return false; }
public boolean isRawBiomeDataNeeded() { return false; }
public boolean isBlockTypeDataNeeded() { return true; }
public int tileOrdinalX() { return x; }
public int tileOrdinalY() { return y; }
}
@Override
public void buildClientConfiguration(JSONObject worldObject, DynmapWorld world) {
ConfigurationNode c = configuration;
JSONObject o = new JSONObject();
s(o, "type", "FlatMapType");
s(o, "name", c.getString("name"));
s(o, "title", c.getString("title"));
s(o, "icon", c.getString("icon"));
s(o, "prefix", c.getString("prefix"));
s(o, "background", c.getString("background"));
s(o, "nightandday", c.getBoolean("night-and-day",false));
s(o, "backgroundday", c.getString("backgroundday"));
s(o, "backgroundnight", c.getString("backgroundnight"));
s(o, "bigmap", this.isBigWorldMap(world));
s(o, "mapzoomin", c.getInteger("mapzoomin", 3));
s(o, "mapzoomout", world.getExtraZoomOutLevels());
if(MapManager.mapman.getCompassMode() != CompassMode.PRE19)
s(o, "compassview", "E"); /* Always from east */
else
s(o, "compassview", "S"); /* Always from south */
s(o, "image-format", ImageFormat.FORMAT_PNG.getFileExt());
a(worldObject, "maps", o);
}
}

View File

@ -1,191 +0,0 @@
package org.dynmap.hdmap;
import static org.dynmap.JSONUtils.s;
import org.dynmap.Color;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapCore;
import org.dynmap.utils.MapChunkCache;
import org.dynmap.utils.MapIterator;
import org.json.simple.JSONObject;
public class CaveHDShader implements HDShader {
private String name;
private boolean iflit;
public CaveHDShader(DynmapCore core, ConfigurationNode configuration) {
name = (String) configuration.get("name");
iflit = configuration.getBoolean("onlyiflit", false);
}
@Override
public boolean isBiomeDataNeeded() {
return false;
}
@Override
public boolean isRawBiomeDataNeeded() {
return false;
}
@Override
public boolean isHightestBlockYDataNeeded() {
return false;
}
@Override
public boolean isBlockTypeDataNeeded() {
return true;
}
@Override
public boolean isSkyLightLevelNeeded() {
return false;
}
@Override
public boolean isEmittedLightLevelNeeded() {
return iflit;
}
@Override
public String getName() {
return name;
}
private class OurShaderState implements HDShaderState {
private Color color;
protected MapIterator mapiter;
protected HDMap map;
private boolean air;
private OurShaderState(MapIterator mapiter, HDMap map) {
this.mapiter = mapiter;
this.map = map;
this.color = new Color();
}
/**
* Get our shader
*/
public HDShader getShader() {
return CaveHDShader.this;
}
/**
* Get our map
*/
public HDMap getMap() {
return map;
}
/**
* Get our lighting
*/
public HDLighting getLighting() {
return map.getLighting();
}
/**
* Reset renderer state for new ray
*/
public void reset(HDPerspectiveState ps) {
color.setTransparent();
air = true;
}
/**
* Process next ray step - called for each block on route
* @return true if ray is done, false if ray needs to continue
*/
public boolean processBlock(HDPerspectiveState ps) {
int blocktype = ps.getBlockTypeID();
switch (blocktype) {
case 0:
case 17:
case 18:
case 20:
case 64:
case 71:
case 78:
case 79:
blocktype = 0;
break;
default:
air = false;
return false;
}
if ((blocktype == 0) && !air) {
if(iflit && (ps.getMapIterator().getBlockEmittedLight() == 0)) {
return false;
}
int cr, cg, cb;
int mult = 256;
if (mapiter.getY() < 64) {
cr = 0;
cg = 64 + mapiter.getY() * 3;
cb = 255 - mapiter.getY() * 4;
} else {
cr = (mapiter.getY() - 64) * 4;
cg = 255;
cb = 0;
}
/* Figure out which color to use */
switch(ps.getLastBlockStep()) {
case X_PLUS:
case X_MINUS:
mult = 224;
break;
case Z_PLUS:
case Z_MINUS:
mult = 256;
break;
default:
mult = 160;
break;
}
cr = cr * mult / 256;
cg = cg * mult / 256;
cb = cb * mult / 256;
color.setRGBA(cr, cg, cb, 255);
return true;
}
return false;
}
/**
* Ray ended - used to report that ray has exited map (called if renderer has not reported complete)
*/
public void rayFinished(HDPerspectiveState ps) {
}
/**
* Get result color - get resulting color for ray
* @param c - object to store color value in
* @param index - index of color to request (renderer specific - 0=default, 1=day for night/day renderer
*/
public void getRayColor(Color c, int index) {
c.setColor(color);
}
/**
* Clean up state object - called after last ray completed
*/
public void cleanup() {
}
}
/**
* Get renderer state object for use rendering a tile
* @param map - map being rendered
* @param cache - chunk cache containing data for tile to be rendered
* @param mapiter - iterator used when traversing rays in tile
* @return state object to use for all rays in tile
*/
public HDShaderState getStateInstance(HDMap map, MapChunkCache cache, MapIterator mapiter) {
return new OurShaderState(mapiter, map);
}
/* Add shader's contributions to JSON for map object */
public void addClientConfiguration(JSONObject mapObject) {
s(mapObject, "shader", name);
}
}

View File

@ -1,51 +0,0 @@
package org.dynmap.hdmap;
import org.dynmap.Color;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapCore;
import org.json.simple.JSONObject;
import static org.dynmap.JSONUtils.s;
public class DefaultHDLighting implements HDLighting {
private String name;
public DefaultHDLighting(DynmapCore core, ConfigurationNode configuration) {
name = (String) configuration.get("name");
}
/* Get lighting name */
public String getName() { return name; }
/* Apply lighting to given pixel colors (1 outcolor if normal, 2 if night/day) */
public void applyLighting(HDPerspectiveState ps, HDShaderState ss, Color incolor, Color[] outcolor) {
for(int i = 0; i < outcolor.length; i++)
outcolor[i].setColor(incolor);
}
/* Test if Biome Data is needed for this renderer */
public boolean isBiomeDataNeeded() { return false; }
/* Test if raw biome temperature/rainfall data is needed */
public boolean isRawBiomeDataNeeded() { return false; }
/* Test if highest block Y data is needed */
public boolean isHightestBlockYDataNeeded() { return false; }
/* Tet if block type data needed */
public boolean isBlockTypeDataNeeded() { return false; }
/* Test if night/day is enabled for this renderer */
public boolean isNightAndDayEnabled() { return false; }
/* Test if sky light level needed */
public boolean isSkyLightLevelNeeded() { return false; }
/* Test if emitted light level needed */
public boolean isEmittedLightLevelNeeded() { return false; }
/* Add shader's contributions to JSON for map object */
public void addClientConfiguration(JSONObject mapObject) {
s(mapObject, "lighting", name);
s(mapObject, "nightandday", isNightAndDayEnabled());
}
}

View File

@ -1,277 +0,0 @@
package org.dynmap.hdmap;
import static org.dynmap.JSONUtils.s;
import org.dynmap.Color;
import org.dynmap.ColorScheme;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapCore;
import org.dynmap.common.BiomeMap;
import org.dynmap.utils.MapChunkCache;
import org.dynmap.utils.MapIterator;
import org.json.simple.JSONObject;
public class DefaultHDShader implements HDShader {
private String name;
protected ColorScheme colorScheme;
protected boolean transparency; /* Is transparency support active? */
public enum BiomeColorOption {
NONE, BIOME, TEMPERATURE, RAINFALL
}
protected BiomeColorOption biomecolored = BiomeColorOption.NONE; /* Use biome for coloring */
public DefaultHDShader(DynmapCore core, ConfigurationNode configuration) {
name = (String) configuration.get("name");
colorScheme = ColorScheme.getScheme(core, configuration.getString("colorscheme", "default"));
transparency = configuration.getBoolean("transparency", true); /* Default on */
String biomeopt = configuration.getString("biomecolored", "none");
if(biomeopt.equals("biome")) {
biomecolored = BiomeColorOption.BIOME;
}
else if(biomeopt.equals("temperature")) {
biomecolored = BiomeColorOption.TEMPERATURE;
}
else if(biomeopt.equals("rainfall")) {
biomecolored = BiomeColorOption.RAINFALL;
}
else {
biomecolored = BiomeColorOption.NONE;
}
}
@Override
public boolean isBiomeDataNeeded() {
return biomecolored == BiomeColorOption.BIOME;
}
@Override
public boolean isRawBiomeDataNeeded() {
return (biomecolored == BiomeColorOption.RAINFALL) || (biomecolored == BiomeColorOption.TEMPERATURE);
}
@Override
public boolean isHightestBlockYDataNeeded() {
return false;
}
@Override
public boolean isBlockTypeDataNeeded() {
return true;
}
@Override
public boolean isSkyLightLevelNeeded() {
return false;
}
@Override
public boolean isEmittedLightLevelNeeded() {
return false;
}
@Override
public String getName() {
return name;
}
private class OurShaderState implements HDShaderState {
private Color color[];
protected MapIterator mapiter;
protected HDMap map;
private Color tmpcolor[];
private int pixelodd;
private HDLighting lighting;
private OurShaderState(MapIterator mapiter, HDMap map) {
this.mapiter = mapiter;
this.map = map;
this.lighting = map.getLighting();
if(lighting.isNightAndDayEnabled()) {
color = new Color[] { new Color(), new Color() };
tmpcolor = new Color[] { new Color(), new Color() };
}
else {
color = new Color[] { new Color() };
tmpcolor = new Color[] { new Color() };
}
}
/**
* Get our shader
*/
public HDShader getShader() {
return DefaultHDShader.this;
}
/**
* Get our map
*/
public HDMap getMap() {
return map;
}
/**
* Get our lighting
*/
public HDLighting getLighting() {
return lighting;
}
/**
* Reset renderer state for new ray
*/
public void reset(HDPerspectiveState ps) {
for(int i = 0; i < color.length; i++)
color[i].setTransparent();
pixelodd = (ps.getPixelX() & 0x3) + (ps.getPixelY()<<1);
}
protected Color[] getBlockColors(int blocktype, int blockdata) {
if((blockdata != 0) && (colorScheme.datacolors[blocktype] != null))
return colorScheme.datacolors[blocktype][blockdata];
else
return colorScheme.colors[blocktype];
}
/**
* Process next ray step - called for each block on route
* @return true if ray is done, false if ray needs to continue
*/
public boolean processBlock(HDPerspectiveState ps) {
int i;
int blocktype = ps.getBlockTypeID();
if(blocktype == 0)
return false;
Color[] colors = getBlockColors(blocktype, ps.getBlockData());
if (colors != null) {
int seq;
int subalpha = ps.getSubmodelAlpha();
/* Figure out which color to use */
switch(ps.getLastBlockStep()) {
case X_PLUS:
case X_MINUS:
seq = 2;
break;
case Z_PLUS:
case Z_MINUS:
seq = 0;
break;
default:
//if(subalpha >= 0) /* We hit a block in a model */
// seq = 4; /* Use smooth top */
//else
if(((pixelodd + mapiter.getY()) & 0x03) == 0)
seq = 3;
else
seq = 1;
break;
}
Color c = colors[seq];
if (c.getAlpha() > 0) {
/* Handle light level, if needed */
lighting.applyLighting(ps, this, c, tmpcolor);
/* If we got alpha from subblock model, use it instead */
if(subalpha >= 0) {
for(int j = 0; j < tmpcolor.length; j++)
tmpcolor[j].setAlpha(Math.max(subalpha,tmpcolor[j].getAlpha()));
}
/* Blend color with accumulated color (weighted by alpha) */
if(!transparency) { /* No transparency support */
for(i = 0; i < color.length; i++)
color[i].setARGB(tmpcolor[i].getARGB() | 0xFF000000);
return true; /* We're done */
}
/* If no previous color contribution, use new color */
else if(color[0].isTransparent()) {
for(i = 0; i < color.length; i++)
color[i].setColor(tmpcolor[i]);
return (color[0].getAlpha() == 255);
}
/* Else, blend and generate new alpha */
else {
int alpha = color[0].getAlpha();
int alpha2 = tmpcolor[0].getAlpha() * (255-alpha) / 255;
int talpha = alpha + alpha2;
for(i = 0; i < color.length; i++)
color[i].setRGBA((tmpcolor[i].getRed()*alpha2 + color[i].getRed()*alpha) / talpha,
(tmpcolor[i].getGreen()*alpha2 + color[i].getGreen()*alpha) / talpha,
(tmpcolor[i].getBlue()*alpha2 + color[i].getBlue()*alpha) / talpha, talpha);
return (talpha >= 254); /* If only one short, no meaningful contribution left */
}
}
}
return false;
}
/**
* Ray ended - used to report that ray has exited map (called if renderer has not reported complete)
*/
public void rayFinished(HDPerspectiveState ps) {
}
/**
* Get result color - get resulting color for ray
* @param c - object to store color value in
* @param index - index of color to request (renderer specific - 0=default, 1=day for night/day renderer
*/
public void getRayColor(Color c, int index) {
c.setColor(color[index]);
}
/**
* Clean up state object - called after last ray completed
*/
public void cleanup() {
}
}
private class OurBiomeShaderState extends OurShaderState {
private OurBiomeShaderState(MapIterator mapiter, HDMap map) {
super(mapiter, map);
}
protected Color[] getBlockColors(int blocktype, int blockdata) {
BiomeMap bio = mapiter.getBiome();
if(bio != null)
return colorScheme.biomecolors[bio.ordinal()];
return null;
}
}
private class OurBiomeRainfallShaderState extends OurShaderState {
private OurBiomeRainfallShaderState(MapIterator mapiter, HDMap map) {
super(mapiter, map);
}
protected Color[] getBlockColors(int blocktype, int blockdata) {
return colorScheme.getRainColor(mapiter.getRawBiomeRainfall());
}
}
private class OurBiomeTempShaderState extends OurShaderState {
private OurBiomeTempShaderState(MapIterator mapiter, HDMap map) {
super(mapiter, map);
}
protected Color[] getBlockColors(int blocktype, int blockdata) {
return colorScheme.getTempColor(mapiter.getRawBiomeTemperature());
}
}
/**
* Get renderer state object for use rendering a tile
* @param map - map being rendered
* @param cache - chunk cache containing data for tile to be rendered
* @param mapiter - iterator used when traversing rays in tile
* @return state object to use for all rays in tile
*/
public HDShaderState getStateInstance(HDMap map, MapChunkCache cache, MapIterator mapiter) {
switch(biomecolored) {
case NONE:
return new OurShaderState(mapiter, map);
case BIOME:
return new OurBiomeShaderState(mapiter, map);
case RAINFALL:
return new OurBiomeRainfallShaderState(mapiter, map);
case TEMPERATURE:
return new OurBiomeTempShaderState(mapiter, map);
}
return null;
}
/* Add shader's contributions to JSON for map object */
public void addClientConfiguration(JSONObject mapObject) {
s(mapObject, "shader", name);
}
}

View File

@ -1,518 +0,0 @@
package org.dynmap.hdmap;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dynmap.ConfigurationNode;
import org.dynmap.Log;
/**
* Custom block models - used for non-cube blocks to represent the physical volume associated with the block
* Used by perspectives to determine if rays have intersected a block that doesn't occupy its whole block
*/
public class HDBlockModels {
private int blockid;
private int databits;
private long blockflags[];
private int nativeres;
private HashMap<Integer, short[]> scaledblocks;
private static int linkalg[] = new int[256];
private static int linkmap[][] = new int[256][];
private static HashMap<Integer, HDBlockModels> models_by_id_data = new HashMap<Integer, HDBlockModels>();
public static class HDScaledBlockModels {
private short[][][] modelvectors;
public final short[] getScaledModel(int blocktype, int blockdata, int blockrenderdata) {
if(modelvectors[blocktype] == null) {
return null;
}
return modelvectors[blocktype][(blockrenderdata>=0)?blockrenderdata:blockdata];
}
}
private static HashMap<Integer, HDScaledBlockModels> scaled_models_by_scale = new HashMap<Integer, HDScaledBlockModels>();
/**
* Block definition - positions correspond to Bukkit coordinates (+X is south, +Y is up, +Z is west)
* @param blockid - block ID
* @param databits - bitmap of block data bits matching this model (bit N is set if data=N would match)
* @param nativeres - native subblocks per edge of cube (up to 64)
* @param blockflags - array of native^2 long integers representing volume of block (bit X of element (nativeres*Y+Z) is set if that subblock is filled)
* if array is short, other elements area are assumed to be zero (fills from bottom of block up)
*/
public HDBlockModels(int blockid, int databits, int nativeres, long[] blockflags) {
this.blockid = blockid;
this.databits = databits;
this.nativeres = nativeres;
this.blockflags = new long[nativeres * nativeres];
System.arraycopy(blockflags, 0, this.blockflags, 0, blockflags.length);
for(int i = 0; i < 16; i++) {
if((databits & (1<<i)) != 0) {
models_by_id_data.put((blockid<<4)+i, this);
}
}
}
/**
* Test if given native block is filled
*/
public final boolean isSubblockSet(int x, int y, int z) {
return ((blockflags[nativeres*y+z] & (1 << x)) != 0);
}
/**
* Set subblock value
*/
public final void setSubblock(int x, int y, int z, boolean isset) {
if(isset)
blockflags[nativeres*y+z] |= (1 << x);
else
blockflags[nativeres*y+z] &= ~(1 << x);
}
/**
* Get link algorithm
* @param blkid - block ID
* @return 0=no link alg
*/
public static final int getLinkAlgID(int blkid) {
return linkalg[blkid];
}
/**
* Get link block IDs
* @param blkid - block ID
* @return array of block IDs to link with
*/
public static final int[] getLinkIDs(int blkid) {
return linkmap[blkid];
}
/**
* Get scaled map of block: will return array of alpha levels, corresponding to how much of the
* scaled subblocks are occupied by the original blocks (indexed by Y*res*res + Z*res + X)
* @param res - requested scale (res subblocks per edge of block)
* @return array of alpha values (0-255), corresponding to resXresXres subcubes of block
*/
public short[] getScaledMap(int res) {
if(scaledblocks == null) { scaledblocks = new HashMap<Integer, short[]>(); }
short[] map = scaledblocks.get(Integer.valueOf(res));
if(map == null) {
map = new short[res*res*res];
if(res == nativeres) {
for(int i = 0; i < blockflags.length; i++) {
for(int j = 0; j < nativeres; j++) {
if((blockflags[i] & (1 << j)) != 0)
map[res*i+j] = 255;
}
}
}
/* If scaling from smaller sub-blocks to larger, each subblock contributes to 1-2 blocks
* on each axis: need to calculate crossovers for each, and iterate through smaller
* blocks to accumulate contributions
*/
else if(res > nativeres) {
int weights[] = new int[res];
int offsets[] = new int[res];
/* LCM of resolutions is used as length of line (res * nativeres)
* Each native block is (res) long, each scaled block is (nativeres) long
* Each scaled block overlaps 1 or 2 native blocks: starting with native block 'offsets[]' with
* 'weights[]' of its (res) width in the first, and the rest in the second
*/
for(int v = 0, idx = 0; v < res*nativeres; v += nativeres, idx++) {
offsets[idx] = (v/res); /* Get index of the first native block we draw from */
if((v+nativeres-1)/res == offsets[idx]) { /* If scaled block ends in same native block */
weights[idx] = nativeres;
}
else { /* Else, see how much is in first one */
weights[idx] = (offsets[idx] + res) - v;
weights[idx] = (offsets[idx]*res + res) - v;
}
}
/* Now, use weights and indices to fill in scaled map */
for(int y = 0, off = 0; y < res; y++) {
int ind_y = offsets[y];
int wgt_y = weights[y];
for(int z = 0; z < res; z++) {
int ind_z = offsets[z];
int wgt_z = weights[z];
for(int x = 0; x < res; x++, off++) {
int ind_x = offsets[x];
int wgt_x = weights[x];
int raw_w = 0;
for(int xx = 0; xx < 2; xx++) {
int wx = (xx==0)?wgt_x:(nativeres-wgt_x);
if(wx == 0) continue;
for(int yy = 0; yy < 2; yy++) {
int wy = (yy==0)?wgt_y:(nativeres-wgt_y);
if(wy == 0) continue;
for(int zz = 0; zz < 2; zz++) {
int wz = (zz==0)?wgt_z:(nativeres-wgt_z);
if(wz == 0) continue;
if(isSubblockSet(ind_x+xx, ind_y+yy, ind_z+zz)) {
raw_w += wx*wy*wz;
}
}
}
}
map[off] = (short)((255*raw_w) / (nativeres*nativeres*nativeres));
if(map[off] > 255) map[off] = 255;
if(map[off] < 0) map[off] = 0;
}
}
}
}
else { /* nativeres > res */
int weights[] = new int[nativeres];
int offsets[] = new int[nativeres];
/* LCM of resolutions is used as length of line (res * nativeres)
* Each native block is (res) long, each scaled block is (nativeres) long
* Each native block overlaps 1 or 2 scaled blocks: starting with scaled block 'offsets[]' with
* 'weights[]' of its (res) width in the first, and the rest in the second
*/
for(int v = 0, idx = 0; v < res*nativeres; v += res, idx++) {
offsets[idx] = (v/nativeres); /* Get index of the first scaled block we draw to */
if((v+res-1)/nativeres == offsets[idx]) { /* If native block ends in same scaled block */
weights[idx] = res;
}
else { /* Else, see how much is in first one */
weights[idx] = (offsets[idx]*nativeres + nativeres) - v;
}
}
/* Now, use weights and indices to fill in scaled map */
long accum[] = new long[map.length];
for(int y = 0; y < nativeres; y++) {
int ind_y = offsets[y];
int wgt_y = weights[y];
for(int z = 0; z < nativeres; z++) {
int ind_z = offsets[z];
int wgt_z = weights[z];
for(int x = 0; x < nativeres; x++) {
if(isSubblockSet(x, y, z)) {
int ind_x = offsets[x];
int wgt_x = weights[x];
for(int xx = 0; xx < 2; xx++) {
int wx = (xx==0)?wgt_x:(res-wgt_x);
if(wx == 0) continue;
for(int yy = 0; yy < 2; yy++) {
int wy = (yy==0)?wgt_y:(res-wgt_y);
if(wy == 0) continue;
for(int zz = 0; zz < 2; zz++) {
int wz = (zz==0)?wgt_z:(res-wgt_z);
if(wz == 0) continue;
accum[(ind_y+yy)*res*res + (ind_z+zz)*res + (ind_x+xx)] +=
wx*wy*wz;
}
}
}
}
}
}
}
for(int i = 0; i < map.length; i++) {
map[i] = (short)(accum[i]*255/nativeres/nativeres/nativeres);
if(map[i] > 255) map[i] = 255;
if(map[i] < 0) map[i] = 0;
}
}
scaledblocks.put(Integer.valueOf(res), map);
}
return map;
}
/**
* Get scaled set of models for all modelled blocks
* @param scale
* @return
*/
public static HDScaledBlockModels getModelsForScale(int scale) {
HDScaledBlockModels model = scaled_models_by_scale.get(Integer.valueOf(scale));
if(model == null) {
model = new HDScaledBlockModels();
short[][][] blockmodels = new short[256][][];
for(HDBlockModels m : models_by_id_data.values()) {
short[][] row = blockmodels[m.blockid];
if(row == null) {
row = new short[16][];
blockmodels[m.blockid] = row;
}
short[] smod = m.getScaledMap(scale);
/* See if scaled model is full block : much faster to not use it if it is */
if(smod != null) {
boolean keep = false;
for(int i = 0; (!keep) && (i < smod.length); i++) {
if(smod[i] == 0) keep = true;
}
if(keep) {
for(int i = 0; i < 16; i++) {
if((m.databits & (1 << i)) != 0) {
row[i] = smod;
}
}
}
}
}
model.modelvectors = blockmodels;
scaled_models_by_scale.put(scale, model);
}
return model;
}
/**
* Load models
*/
public static void loadModels(File datadir, ConfigurationNode config) {
/* Reset models-by-ID-Data cache */
models_by_id_data.clear();
/* Reset scaled models by scale cache */
scaled_models_by_scale.clear();
/* Load block models */
InputStream in = TexturePack.class.getResourceAsStream("/models.txt");
if(in != null) {
loadModelFile(in, "models.txt", config);
try { in.close(); } catch (IOException iox) {} in = null;
}
File customdir = new File(datadir, "renderdata");
String[] files = customdir.list();
if(files != null) {
for(String fn : files) {
if(fn.endsWith("-models.txt") == false)
continue;
File custom = new File(customdir, fn);
if(custom.canRead()) {
try {
in = new FileInputStream(custom);
loadModelFile(in, custom.getPath(), config);
} catch (IOException iox) {
Log.severe("Error loading " + custom.getPath());
} finally {
if(in != null) {
try { in.close(); } catch (IOException iox) {}
in = null;
}
}
}
}
}
}
private static Integer getIntValue(Map<String,Integer> vars, String val) throws NumberFormatException {
if(Character.isLetter(val.charAt(0))) {
Integer v = vars.get(val);
if(v == null)
throw new NumberFormatException("invalid ID - " + val);
return v;
}
else {
return Integer.valueOf(val);
}
}
/**
* Load models from file
*/
private static void loadModelFile(InputStream in, String fname, ConfigurationNode config) {
LineNumberReader rdr = null;
int cnt = 0;
try {
String line;
ArrayList<HDBlockModels> modlist = new ArrayList<HDBlockModels>();
HashMap<String,Integer> varvals = new HashMap<String,Integer>();
int layerbits = 0;
int rownum = 0;
int scale = 0;
rdr = new LineNumberReader(new InputStreamReader(in));
while((line = rdr.readLine()) != null) {
if(line.startsWith("block:")) {
ArrayList<Integer> blkids = new ArrayList<Integer>();
int databits = 0;
scale = 0;
line = line.substring(6);
String[] args = line.split(",");
for(String a : args) {
String[] av = a.split("=");
if(av.length < 2) continue;
if(av[0].equals("id")) {
blkids.add(getIntValue(varvals,av[1]));
}
else if(av[0].equals("data")) {
if(av[1].equals("*"))
databits = 0xFFFF;
else
databits |= (1 << getIntValue(varvals,av[1]));
}
else if(av[0].equals("scale")) {
scale = Integer.parseInt(av[1]);
}
}
/* If we have everything, build block */
if((blkids.size() > 0) && (databits != 0) && (scale > 0)) {
modlist.clear();
for(Integer id : blkids) {
modlist.add(new HDBlockModels(id.intValue(), databits, scale, new long[0]));
cnt++;
}
}
else {
Log.severe("Block model missing required parameters = line " + rdr.getLineNumber() + " of " + fname);
}
layerbits = 0;
}
else if(line.startsWith("layer:")) {
line = line.substring(6);
String args[] = line.split(",");
layerbits = 0;
rownum = 0;
for(String a: args) {
layerbits |= (1 << Integer.parseInt(a));
}
}
else if(line.startsWith("rotate:")) {
line = line.substring(7);
String args[] = line.split(",");
int id = -1;
int data = -1;
int rot = -1;
for(String a : args) {
String[] av = a.split("=");
if(av.length < 2) continue;
if(av[0].equals("id")) { id = getIntValue(varvals,av[1]); }
if(av[0].equals("data")) { data = getIntValue(varvals,av[1]); }
if(av[0].equals("rot")) { rot = Integer.parseInt(av[1]); }
}
/* get old model to be rotated */
HDBlockModels mod = models_by_id_data.get((id<<4)+data);
if((mod != null) && ((rot%90) == 0)) {
for(int x = 0; x < scale; x++) {
for(int y = 0; y < scale; y++) {
for(int z = 0; z < scale; z++) {
if(mod.isSubblockSet(x, y, z) == false) continue;
switch(rot) {
case 0:
for(HDBlockModels bm : modlist)
bm.setSubblock(x, y, z, true);
break;
case 90:
for(HDBlockModels bm : modlist)
bm.setSubblock(scale-z-1, y, x, true);
break;
case 180:
for(HDBlockModels bm : modlist)
bm.setSubblock(scale-x-1, y, scale-z-1, true);
break;
case 270:
for(HDBlockModels bm : modlist)
bm.setSubblock(z, y, scale-x-1, true);
break;
}
}
}
}
}
}
else if(line.startsWith("linkmap:")) {
ArrayList<Integer> blkids = new ArrayList<Integer>();
line = line.substring(8);
String[] args = line.split(",");
List<Integer> map = new ArrayList<Integer>();
int linktype = 0;
for(String a : args) {
String[] av = a.split("=");
if(av.length < 2) continue;
if(av[0].equals("id")) {
blkids.add(getIntValue(varvals,av[1]));
}
else if(av[0].equals("linkalg")) {
linktype = Integer.parseInt(av[1]);
}
else if(av[0].equals("linkid")) {
map.add(getIntValue(varvals,av[1]));
}
}
if(linktype > 0) {
int[] mapids = new int[map.size()];
for(int i = 0; i < mapids.length; i++)
mapids[i] = map.get(i);
for(Integer bid : blkids) {
linkalg[bid] = linktype;
linkmap[bid] = mapids;
}
}
}
else if(line.startsWith("#") || line.startsWith(";")) {
}
else if(line.startsWith("enabled:")) { /* Test if texture file is enabled */
line = line.substring(8).trim();
if(line.startsWith("true")) { /* We're enabled? */
/* Nothing to do - keep processing */
}
else if(line.startsWith("false")) { /* Disabled */
return; /* Quit */
}
/* If setting is not defined or false, quit */
else if(config.getBoolean(line, false) == false) {
return;
}
else {
Log.info(line + " models enabled");
}
}
else if(line.startsWith("var:")) { /* Test if variable declaration */
line = line.substring(4).trim();
String args[] = line.split(",");
for(int i = 0; i < args.length; i++) {
String[] v = args[i].split("=");
if(v.length < 2) {
Log.severe("Format error - line " + rdr.getLineNumber() + " of " + fname);
return;
}
try {
int val = Integer.valueOf(v[1]); /* Parse default value */
int parmval = config.getInteger(v[0], val); /* Read value, with applied default */
varvals.put(v[0], parmval); /* And save value */
} catch (NumberFormatException nfx) {
Log.severe("Format error - line " + rdr.getLineNumber() + " of " + fname);
return;
}
}
}
else if(layerbits != 0) { /* If we're working pattern lines */
/* Layerbits determine Y, rows count from North to South (X=0 to X=N-1), columns Z are West to East (N-1 to 0) */
for(int i = 0; (i < scale) && (i < line.length()); i++) {
if(line.charAt(i) == '*') { /* If an asterix, set flag */
for(int y = 0; y < scale; y++) {
if((layerbits & (1<<y)) != 0) {
for(HDBlockModels mod : modlist) {
mod.setSubblock(rownum, y, scale-i-1, true);
}
}
}
}
}
/* See if we're done with layer */
rownum++;
if(rownum >= scale) {
rownum = 0;
layerbits = 0;
}
}
}
Log.verboseinfo("Loaded " + cnt + " block models from " + fname);
} catch (IOException iox) {
Log.severe("Error reading models.txt - " + iox.toString());
} catch (NumberFormatException nfx) {
Log.severe("Format error - line " + rdr.getLineNumber() + " of " + fname);
} finally {
if(rdr != null) {
try {
rdr.close();
rdr = null;
} catch (IOException e) {
}
}
}
}
}

View File

@ -1,27 +0,0 @@
package org.dynmap.hdmap;
import org.dynmap.Color;
import org.json.simple.JSONObject;
public interface HDLighting {
/* Get lighting name */
String getName();
/* Apply lighting to given pixel colors (1 outcolor if normal, 2 if night/day) */
void applyLighting(HDPerspectiveState ps, HDShaderState ss, Color incolor, Color[] outcolor);
/* Test if Biome Data is needed for this renderer */
boolean isBiomeDataNeeded();
/* Test if raw biome temperature/rainfall data is needed */
boolean isRawBiomeDataNeeded();
/* Test if highest block Y data is needed */
boolean isHightestBlockYDataNeeded();
/* Tet if block type data needed */
boolean isBlockTypeDataNeeded();
/* Test if night/day is enabled for this renderer */
boolean isNightAndDayEnabled();
/* Test if sky light level needed */
boolean isSkyLightLevelNeeded();
/* Test if emitted light level needed */
boolean isEmittedLightLevelNeeded();
/* Add shader's contributions to JSON for map object */
void addClientConfiguration(JSONObject mapObject);
}

View File

@ -1,335 +0,0 @@
package org.dynmap.hdmap;
import static org.dynmap.JSONUtils.a;
import static org.dynmap.JSONUtils.s;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.dynmap.Client;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapChunk;
import org.dynmap.DynmapCore;
import org.dynmap.DynmapWorld;
import org.dynmap.Log;
import org.dynmap.MapManager;
import org.dynmap.MapTile;
import org.dynmap.MapType;
import org.dynmap.debug.Debug;
import org.dynmap.utils.TileFlags;
import org.json.simple.JSONObject;
public class HDMap extends MapType {
private String name;
private String prefix;
private HDPerspective perspective;
private HDShader shader;
private HDLighting lighting;
private ConfigurationNode configuration;
private int mapzoomout;
private MapType.ImageFormat imgformat;
private int bgcolornight;
private int bgcolorday;
public static final String IMGFORMAT_PNG = "png";
public static final String IMGFORMAT_JPG = "jpg";
public HDMap(DynmapCore core, ConfigurationNode configuration) {
name = configuration.getString("name", null);
if(name == null) {
Log.severe("HDMap missing required attribute 'name' - disabled");
return;
}
String perspectiveid = configuration.getString("perspective", "default");
perspective = MapManager.mapman.hdmapman.perspectives.get(perspectiveid);
if(perspective == null) {
/* Try to use default */
perspective = MapManager.mapman.hdmapman.perspectives.get("default");
if(perspective == null) {
Log.severe("HDMap '"+name+"' loaded invalid perspective '" + perspectiveid + "' - map disabled");
name = null;
return;
}
else {
Log.severe("HDMap '"+name+"' loaded invalid perspective '" + perspectiveid + "' - using 'default' perspective");
}
}
String shaderid = configuration.getString("shader", "default");
shader = MapManager.mapman.hdmapman.shaders.get(shaderid);
if(shader == null) {
shader = MapManager.mapman.hdmapman.shaders.get("default");
if(shader == null) {
Log.severe("HDMap '"+name+"' loading invalid shader '" + shaderid + "' - map disabled");
name = null;
return;
}
else {
Log.severe("HDMap '"+name+"' loading invalid shader '" + shaderid + "' - using 'default' shader");
}
}
String lightingid = configuration.getString("lighting", "default");
lighting = MapManager.mapman.hdmapman.lightings.get(lightingid);
if(lighting == null) {
lighting = MapManager.mapman.hdmapman.lightings.get("default");
if(lighting == null) {
Log.severe("HDMap '"+name+"' loading invalid lighting '" + lighting + "' - map disabled");
name = null;
return;
}
else {
Log.severe("HDMap '"+name+"' loading invalid lighting '" + lighting + "' - using 'default' lighting");
}
}
prefix = configuration.getString("prefix", name);
this.configuration = configuration;
/* Compute extra zoom outs needed for this map */
double scale = perspective.getScale();
mapzoomout = 0;
while(scale >= 1.0) {
mapzoomout++;
scale = scale / 2.0;
}
String fmt = configuration.getString("image-format", "png");
/* Only allow png or jpg */
for(ImageFormat f : ImageFormat.values()) {
if(fmt.equals(f.getID())) {
imgformat = f;
break;
}
}
if(imgformat == null) {
Log.severe("HDMap '"+name+"' set invalid image-format: " + fmt);
imgformat = ImageFormat.FORMAT_PNG;
}
/* Get color info */
String c = configuration.getString("background");
if(c != null) {
bgcolorday = bgcolornight = parseColor(c);
}
c = configuration.getString("backgroundday");
if(c != null) {
bgcolorday = parseColor(c);
}
c = configuration.getString("backgroundnight");
if(c != null) {
bgcolornight = parseColor(c);
}
if(imgformat != ImageFormat.FORMAT_PNG) { /* If JPG, set background color opacity */
bgcolorday |= 0xFF000000;
bgcolornight |= 0xFF000000;
}
}
public HDShader getShader() { return shader; }
public HDPerspective getPerspective() { return perspective; }
public HDLighting getLighting() { return lighting; }
@Override
public MapTile[] getTiles(DynmapWorld w, int x, int y, int z) {
return perspective.getTiles(w, x, y, z);
}
@Override
public MapTile[] getTiles(DynmapWorld w, int minx, int miny, int minz, int maxx, int maxy, int maxz) {
return perspective.getTiles(w, minx, miny, minz, maxx, maxy, maxz);
}
@Override
public MapTile[] getAdjecentTiles(MapTile tile) {
return perspective.getAdjecentTiles(tile);
}
@Override
public List<DynmapChunk> getRequiredChunks(MapTile tile) {
return perspective.getRequiredChunks(tile);
}
@Override
public List<ZoomInfo> baseZoomFileInfo() {
ArrayList<ZoomInfo> s = new ArrayList<ZoomInfo>();
s.add(new ZoomInfo(prefix, getBackgroundARGBNight()));
if(lighting.isNightAndDayEnabled())
s.add(new ZoomInfo(prefix + "_day", getBackgroundARGBDay()));
return s;
}
public int baseZoomFileStepSize() { return 1; }
private static final int[] stepseq = { 3, 1, 2, 0 };
public MapStep zoomFileMapStep() { return MapStep.X_PLUS_Y_MINUS; }
public int[] zoomFileStepSequence() { return stepseq; }
/* How many bits of coordinate are shifted off to make big world directory name */
public int getBigWorldShift() { return 5; }
/* Returns true if big world file structure is in effect for this map */
@Override
public boolean isBigWorldMap(DynmapWorld w) { return true; } /* We always use it on these maps */
/* Return number of zoom levels needed by this map (before extra levels from extrazoomout) */
public int getMapZoomOutLevels() {
return mapzoomout;
}
@Override
public String getName() {
return name;
}
public String getPrefix() {
return prefix;
}
/* Get maps rendered concurrently with this map in this world */
public List<MapType> getMapsSharingRender(DynmapWorld w) {
ArrayList<MapType> maps = new ArrayList<MapType>();
for(MapType mt : w.maps) {
if(mt instanceof HDMap) {
HDMap hdmt = (HDMap)mt;
if(hdmt.perspective == this.perspective) { /* Same perspective */
maps.add(hdmt);
}
}
}
return maps;
}
/* Get names of maps rendered concurrently with this map type in this world */
public List<String> getMapNamesSharingRender(DynmapWorld w) {
ArrayList<String> lst = new ArrayList<String>();
for(MapType mt : w.maps) {
if(mt instanceof HDMap) {
HDMap hdmt = (HDMap)mt;
if(hdmt.perspective == this.perspective) { /* Same perspective */
if(hdmt.lighting.isNightAndDayEnabled())
lst.add(hdmt.getName() + "(night/day)");
else
lst.add(hdmt.getName());
}
}
}
return lst;
}
@Override
public ImageFormat getImageFormat() { return imgformat; }
@Override
public void buildClientConfiguration(JSONObject worldObject, DynmapWorld world) {
ConfigurationNode c = configuration;
JSONObject o = new JSONObject();
s(o, "type", "HDMapType");
s(o, "name", name);
s(o, "title", c.getString("title"));
s(o, "icon", c.getString("icon"));
s(o, "prefix", prefix);
s(o, "background", c.getString("background"));
s(o, "backgroundday", c.getString("backgroundday"));
s(o, "backgroundnight", c.getString("backgroundnight"));
s(o, "bigmap", true);
s(o, "mapzoomout", (world.getExtraZoomOutLevels()+mapzoomout));
s(o, "mapzoomin", c.getInteger("mapzoomin", 2));
s(o, "image-format", imgformat.getFileExt());
perspective.addClientConfiguration(o);
shader.addClientConfiguration(o);
lighting.addClientConfiguration(o);
a(worldObject, "maps", o);
}
private static int parseColor(String c) {
int v = 0;
if(c.startsWith("#")) {
c = c.substring(1);
if(c.length() == 3) { /* #rgb */
try {
v = Integer.valueOf(c, 16);
} catch (NumberFormatException nfx) {
return 0;
}
v = 0xFF000000 | ((v & 0xF00) << 12) | ((v & 0x0F0) << 8) | ((v & 0x00F) << 4);
}
else if(c.length() == 6) { /* #rrggbb */
try {
v = Integer.valueOf(c, 16);
} catch (NumberFormatException nfx) {
return 0;
}
v = 0xFF000000 | (v & 0xFFFFFF);
}
}
return v;
}
public int getBackgroundARGBDay() {
return bgcolorday;
}
public int getBackgroundARGBNight() {
return bgcolornight;
}
private HDMapTile fileToTile(DynmapWorld world, File f) {
String n = f.getName();
n = n.substring(0, n.lastIndexOf('.'));
if(n == null) return null;
String[] nt = n.split("_");
if(nt.length != 2) return null;
int xx, zz;
try {
xx = Integer.parseInt(nt[0]);
zz = Integer.parseInt(nt[1]);
} catch (NumberFormatException nfx) {
return null;
}
return new HDMapTile(world, perspective, xx, zz);
}
public void purgeOldTiles(final DynmapWorld world, final TileFlags rendered) {
File basedir = new File(world.worldtilepath, prefix); /* Get base directory for map */
FileCallback cb = new FileCallback() {
public void fileFound(File f, File parent, boolean day) {
String n = f.getName();
if(n.startsWith("z")) { /* If zoom file */
if(n.startsWith("z_")) { /* First tier of zoom? */
File ff = new File(parent, n.substring(2)); /* Make file for render tier, and drive update */
HDMapTile tile = fileToTile(world, ff); /* Parse it */
if(tile == null) return;
if(rendered.getFlag(tile.tx, tile.ty) || rendered.getFlag(tile.tx+1, tile.ty) ||
rendered.getFlag(tile.tx, tile.ty-1) || rendered.getFlag(tile.tx+1, tile.ty-1))
return;
world.enqueueZoomOutUpdate(ff);
}
return;
}
HDMapTile tile = fileToTile(world, f);
if(tile == null) return;
if(rendered.getFlag(tile.tx, tile.ty)) { /* If we rendered this tile, its good */
return;
}
Debug.debug("clean up " + f.getPath());
/* Otherwise, delete tile */
f.delete();
/* Push updates, clear hash code, and signal zoom tile update */
MapManager.mapman.pushUpdate(world,
new Client.Tile(day?tile.getDayFilename(prefix, getImageFormat()):tile.getFilename(prefix, getImageFormat())));
MapManager.mapman.hashman.updateHashCode(tile.getKey(prefix), day?"day":null, tile.tx, tile.ty, -1);
world.enqueueZoomOutUpdate(f);
}
};
walkMapTree(basedir, cb, false);
if(lighting.isNightAndDayEnabled()) {
basedir = new File(world.worldtilepath, prefix+"_day");
walkMapTree(basedir, cb, true);
}
}
}

View File

@ -1,181 +0,0 @@
package org.dynmap.hdmap;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapCore;
import org.dynmap.DynmapWorld;
import org.dynmap.Log;
import org.dynmap.MapManager;
import org.dynmap.MapType;
import org.dynmap.utils.MapChunkCache;
import org.dynmap.utils.MapIterator;
public class HDMapManager {
public HashMap<String, HDShader> shaders = new HashMap<String, HDShader>();
public HashMap<String, HDPerspective> perspectives = new HashMap<String, HDPerspective>();
public HashMap<String, HDLighting> lightings = new HashMap<String, HDLighting>();
public HashSet<HDMap> maps = new HashSet<HDMap>();
public HashMap<String, ArrayList<HDMap>> maps_by_world_perspective = new HashMap<String, ArrayList<HDMap>>();
public static boolean usegeneratedtextures;
public static boolean waterlightingfix;
public static boolean biomeshadingfix;
public void loadHDShaders(DynmapCore core) {
Log.verboseinfo("Loading shaders...");
File f = new File(core.getDataFolder(), "shaders.txt");
if(!core.updateUsingDefaultResource("/shaders.txt", f, "shaders")) {
return;
}
ConfigurationNode shadercfg = new ConfigurationNode(f);
shadercfg.load();
for(HDShader shader : shadercfg.<HDShader>createInstances("shaders", new Class<?>[] { DynmapCore.class }, new Object[] { core })) {
if(shader.getName() == null) continue;
shaders.put(shader.getName(), shader);
}
/* Load custom shaders, if file is defined - or create empty one if not */
f = new File(core.getDataFolder(), "custom-shaders.txt");
core.createDefaultFileFromResource("/custom-shaders.txt", f);
if(f.exists()) {
ConfigurationNode customshadercfg = new ConfigurationNode(f);
customshadercfg.load();
for(HDShader shader : customshadercfg.<HDShader>createInstances("shaders", new Class<?>[] { DynmapCore.class }, new Object[] { core })) {
if(shader.getName() == null) continue;
shaders.put(shader.getName(), shader);
}
}
Log.info("Loaded " + shaders.size() + " shaders.");
/* Update ore mappings, if needed */
TexturePack.handleHideOres();
}
public void loadHDPerspectives(DynmapCore core) {
Log.verboseinfo("Loading perspectives...");
File f = new File(core.getDataFolder(), "perspectives.txt");
if(!core.updateUsingDefaultResource("/perspectives.txt", f, "perspectives")) {
return;
}
ConfigurationNode perspectivecfg = new ConfigurationNode(f);
perspectivecfg.load();
for(HDPerspective perspective : perspectivecfg.<HDPerspective>createInstances("perspectives", new Class<?>[] { DynmapCore.class }, new Object[] { core })) {
if(perspective.getName() == null) continue;
perspectives.put(perspective.getName(), perspective);
}
/* Load custom perspectives, if file is defined - or create empty one if not */
f = new File(core.getDataFolder(), "custom-perspectives.txt");
core.createDefaultFileFromResource("/custom-perspectives.txt", f);
if(f.exists()) {
perspectivecfg = new ConfigurationNode(f);
perspectivecfg.load();
for(HDPerspective perspective : perspectivecfg.<HDPerspective>createInstances("perspectives", new Class<?>[] { DynmapCore.class }, new Object[] { core })) {
if(perspective.getName() == null) continue;
perspectives.put(perspective.getName(), perspective);
}
}
Log.info("Loaded " + perspectives.size() + " perspectives.");
}
public void loadHDLightings(DynmapCore core) {
Log.verboseinfo("Loading lightings...");
File f = new File(core.getDataFolder(), "lightings.txt");
if(!core.updateUsingDefaultResource("/lightings.txt", f, "lightings")) {
return;
}
ConfigurationNode lightingcfg = new ConfigurationNode(f);
lightingcfg.load();
for(HDLighting lighting : lightingcfg.<HDLighting>createInstances("lightings", new Class<?>[] { DynmapCore.class }, new Object[] { core })) {
if(lighting.getName() == null) continue;
lightings.put(lighting.getName(), lighting);
}
/* Load custom lightings, if file is defined - or create empty one if not */
f = new File(core.getDataFolder(), "custom-lightings.txt");
core.createDefaultFileFromResource("/custom-lightings.txt", f);
if(f.exists()) {
lightingcfg = new ConfigurationNode(f);
lightingcfg.load();
for(HDLighting lighting : lightingcfg.<HDLighting>createInstances("lightings", new Class<?>[] { DynmapCore.class }, new Object[] { core })) {
if(lighting.getName() == null) continue;
lightings.put(lighting.getName(), lighting);
}
}
Log.info("Loaded " + lightings.size() + " lightings.");
}
/**
* Initialize shader states for all shaders for given tile
*/
public HDShaderState[] getShaderStateForTile(HDMapTile tile, MapChunkCache cache, MapIterator mapiter, String mapname) {
DynmapWorld w = MapManager.mapman.worldsLookup.get(tile.getDynmapWorld().getName());
if(w == null) return new HDShaderState[0];
ArrayList<HDShaderState> shaders = new ArrayList<HDShaderState>();
for(MapType map : w.maps) {
if(map instanceof HDMap) {
HDMap hdmap = (HDMap)map;
if(hdmap.getPerspective() == tile.perspective) {
/* If limited to one map, and this isn't it, skip */
if((mapname != null) && (!hdmap.getName().equals(mapname)))
continue;
shaders.add(hdmap.getShader().getStateInstance(hdmap, cache, mapiter));
}
}
}
return shaders.toArray(new HDShaderState[shaders.size()]);
}
private static final int BIOMEDATAFLAG = 0;
private static final int HIGHESTZFLAG = 1;
private static final int RAWBIOMEFLAG = 2;
private static final int BLOCKTYPEFLAG = 3;
public boolean isBiomeDataNeeded(HDMapTile t) {
return getCachedFlags(t)[BIOMEDATAFLAG];
}
public boolean isHightestBlockYDataNeeded(HDMapTile t) {
return getCachedFlags(t)[HIGHESTZFLAG];
}
public boolean isRawBiomeDataNeeded(HDMapTile t) {
return getCachedFlags(t)[RAWBIOMEFLAG];
}
public boolean isBlockTypeDataNeeded(HDMapTile t) {
return getCachedFlags(t)[BLOCKTYPEFLAG];
}
private HashMap<String, boolean[]> cached_data_flags_by_world_perspective = new HashMap<String, boolean[]>();
private boolean[] getCachedFlags(HDMapTile t) {
String w = t.getDynmapWorld().getName();
String k = w + "/" + t.perspective.getName();
boolean[] flags = cached_data_flags_by_world_perspective.get(k);
if(flags != null)
return flags;
flags = new boolean[4];
cached_data_flags_by_world_perspective.put(k, flags);
DynmapWorld dw = MapManager.mapman.worldsLookup.get(w);
if(dw == null) return flags;
for(MapType map : dw.maps) {
if(map instanceof HDMap) {
HDMap hdmap = (HDMap)map;
if(hdmap.getPerspective() == t.perspective) {
HDShader sh = hdmap.getShader();
HDLighting lt = hdmap.getLighting();
flags[BIOMEDATAFLAG] |= sh.isBiomeDataNeeded() | lt.isBiomeDataNeeded();
flags[HIGHESTZFLAG] |= sh.isHightestBlockYDataNeeded() | lt.isHightestBlockYDataNeeded();
flags[RAWBIOMEFLAG] |= sh.isRawBiomeDataNeeded() | lt.isRawBiomeDataNeeded();
flags[BLOCKTYPEFLAG] |= sh.isBlockTypeDataNeeded() | lt.isBlockTypeDataNeeded();
}
}
}
return flags;
}
}

View File

@ -1,110 +0,0 @@
package org.dynmap.hdmap;
import org.dynmap.DynmapChunk;
import org.dynmap.DynmapWorld;
import org.dynmap.MapManager;
import org.dynmap.MapType;
import java.util.List;
import org.dynmap.MapTile;
import org.dynmap.utils.MapChunkCache;
public class HDMapTile extends MapTile {
public HDPerspective perspective;
public int tx, ty; /* Tile X and Tile Y are in tile coordinates (pixels/tile-size) */
public HDMapTile(DynmapWorld world, HDPerspective perspective, int tx, int ty) {
super(world);
this.perspective = perspective;
this.tx = tx;
this.ty = ty;
}
public HDMapTile(DynmapWorld world, String parm) throws Exception {
super(world);
String[] parms = parm.split(",");
if(parms.length < 3) throw new Exception("wrong parameter count");
this.tx = Integer.parseInt(parms[0]);
this.ty = Integer.parseInt(parms[1]);
this.perspective = MapManager.mapman.hdmapman.perspectives.get(parms[2]);
if(this.perspective == null) throw new Exception("invalid perspective");
}
@Override
protected String saveTileData() {
return String.format("%d,%d,%s", tx, ty, perspective.getName());
}
@Override
public String getFilename() {
return getFilename("hdmap", MapType.ImageFormat.FORMAT_PNG);
}
public String getFilename(String prefix, MapType.ImageFormat format) {
return prefix + "/" + (tx >> 5) + '_' + (ty >> 5) + '/' + tx + "_" + ty + "." + format.getFileExt();
}
@Override
public String getDayFilename() {
return getDayFilename("hdmap", MapType.ImageFormat.FORMAT_PNG);
}
public String getDayFilename(String prefix, MapType.ImageFormat format) {
return prefix + "_day/" + (tx >> 5) + '_' + (ty >> 5) + '/' + tx + "_" + ty + "." + format.getFileExt();
}
@Override
public int hashCode() {
return tx ^ ty ^ perspective.getName().hashCode() ^ world.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof HDMapTile) {
return equals((HDMapTile) obj);
}
return false;
}
public boolean equals(HDMapTile o) {
return o.tx == tx && o.ty == ty && (perspective == o.perspective) && (o.world == world);
}
public String getKey(String prefix) {
return world.getName() + "." + prefix;
}
@Override
public String toString() {
return world.getName() + ":" + getFilename();
}
@Override
public boolean isBiomeDataNeeded() { return MapManager.mapman.hdmapman.isBiomeDataNeeded(this); }
@Override
public boolean isHightestBlockYDataNeeded() { return MapManager.mapman.hdmapman.isHightestBlockYDataNeeded(this); }
@Override
public boolean isRawBiomeDataNeeded() { return MapManager.mapman.hdmapman.isRawBiomeDataNeeded(this); }
@Override
public boolean isBlockTypeDataNeeded() { return MapManager.mapman.hdmapman.isBlockTypeDataNeeded(this); }
public boolean render(MapChunkCache cache, String mapname) {
return perspective.render(cache, this, mapname);
}
public List<DynmapChunk> getRequiredChunks() {
return perspective.getRequiredChunks(this);
}
public MapTile[] getAdjecentTiles() {
return perspective.getAdjecentTiles(this);
}
public int tileOrdinalX() { return tx; }
public int tileOrdinalY() { return ty; }
}

View File

@ -1,34 +0,0 @@
package org.dynmap.hdmap;
import java.util.List;
import org.dynmap.DynmapChunk;
import org.dynmap.DynmapWorld;
import org.dynmap.MapTile;
import org.dynmap.utils.MapChunkCache;
import org.json.simple.JSONObject;
public interface HDPerspective {
/* Get name of perspective */
String getName();
/* Get tiles invalidated by change at given location */
MapTile[] getTiles(DynmapWorld w, int x, int y, int z);
/* Get tiles invalidated by change at given volume, defined by 2 opposite corner locations */
MapTile[] getTiles(DynmapWorld w, int minx, int miny, int minz, int maxx, int maxy, int maxz);
/* Get tiles adjacent to given tile */
MapTile[] getAdjecentTiles(MapTile tile);
/* Get chunks needed for given tile */
List<DynmapChunk> getRequiredChunks(MapTile tile);
/* Render given tile */
boolean render(MapChunkCache cache, HDMapTile tile, String mapname);
public boolean isBiomeDataNeeded();
public boolean isHightestBlockYDataNeeded();
public boolean isRawBiomeDataNeeded();
public boolean isBlockTypeDataNeeded();
double getScale();
int getModelScale();
public void addClientConfiguration(JSONObject mapObject);
}

View File

@ -1,64 +0,0 @@
package org.dynmap.hdmap;
import org.dynmap.utils.MapIterator;
import org.dynmap.utils.MapIterator.BlockStep;
import org.dynmap.utils.Vector3D;
public interface HDPerspectiveState {
/**
* Get sky light level - only available if shader requested it
*/
int getSkyLightLevel();
/**
* Get emitted light level - only available if shader requested it
*/
int getEmittedLightLevel();
/**
* Get current block type ID
*/
int getBlockTypeID();
/**
* Get current block data
*/
int getBlockData();
/**
* Get current block render data
*/
int getBlockRenderData();
/**
* Get direction of last block step
*/
BlockStep getLastBlockStep();
/**
* Get perspective scale
*/
double getScale();
/**
* Get start of current ray, in world coordinates
*/
Vector3D getRayStart();
/**
* Get end of current ray, in world coordinates
*/
Vector3D getRayEnd();
/**
* Get pixel X coordinate
*/
int getPixelX();
/**
* Get pixel Y coordinate
*/
int getPixelY();
/**
* Return submodel alpha value (-1 if no submodel rendered)
*/
int getSubmodelAlpha();
/**
* Return subblock coordinates of current ray position
*/
int[] getSubblockCoord();
/**
* Get map iterator
*/
MapIterator getMapIterator();
}

View File

@ -1,34 +0,0 @@
package org.dynmap.hdmap;
import org.dynmap.utils.MapChunkCache;
import org.dynmap.utils.MapIterator;
import org.json.simple.JSONObject;
public interface HDShader {
/* Get shader name */
String getName();
/**
* Get renderer state object for use rendering a tile
* @param map - map being rendered
* @param cache - chunk cache containing data for tile to be rendered
* @param mapiter - iterator used when traversing rays in tile
* @return state object to use for all rays in tile
*/
HDShaderState getStateInstance(HDMap map, MapChunkCache cache, MapIterator mapiter);
/* Test if Biome Data is needed for this renderer */
boolean isBiomeDataNeeded();
/* Test if raw biome temperature/rainfall data is needed */
boolean isRawBiomeDataNeeded();
/* Test if highest block Y data is needed */
boolean isHightestBlockYDataNeeded();
/* Tet if block type data needed */
boolean isBlockTypeDataNeeded();
/* Test if sky light level needed */
boolean isSkyLightLevelNeeded();
/* Test if emitted light level needed */
boolean isEmittedLightLevelNeeded();
/* Add shader's contributions to JSON for map object */
void addClientConfiguration(JSONObject mapObject);
}

View File

@ -1,45 +0,0 @@
package org.dynmap.hdmap;
import org.dynmap.Color;
/**
* This interface is used to define the operational state of a renderer during raytracing
* All method should be considered performance critical
*/
public interface HDShaderState {
/**
* Get our shader
*/
HDShader getShader();
/**
* Get our lighting
*/
HDLighting getLighting();
/**
* Get our map
*/
HDMap getMap();
/**
* Reset renderer state for new ray - passes in pixel coordinate for ray
*/
void reset(HDPerspectiveState ps);
/**
* Process next ray step - called for each block on route
* @return true if ray is done, false if ray needs to continue
*/
boolean processBlock(HDPerspectiveState ps);
/**
* Ray ended - used to report that ray has exited map (called if renderer has not reported complete)
*/
void rayFinished(HDPerspectiveState ps);
/**
* Get result color - get resulting color for ray
* @param c - object to store color value in
* @param index - index of color to request (renderer specific - 0=default, 1=day for night/day renderer
*/
void getRayColor(Color c, int index);
/**
* Clean up state object - called after last ray completed
*/
void cleanup();
}

File diff suppressed because it is too large Load Diff

View File

@ -1,97 +0,0 @@
package org.dynmap.hdmap;
import org.dynmap.Color;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapCore;
import org.dynmap.Log;
public class ShadowHDLighting extends DefaultHDLighting {
protected int shadowscale[]; /* index=skylight level, value = 256 * scaling value */
protected int lightscale[]; /* scale skylight level (light = lightscale[skylight] */
protected boolean night_and_day; /* If true, render both day (prefix+'-day') and night (prefix) tiles */
public ShadowHDLighting(DynmapCore core, ConfigurationNode configuration) {
super(core, configuration);
double shadowweight = configuration.getDouble("shadowstrength", 0.0);
if(shadowweight > 0.0) {
shadowscale = new int[16];
shadowscale[15] = 256;
/* Normal brightness weight in MC is a 20% relative dropoff per step */
for(int i = 14; i >= 0; i--) {
double v = shadowscale[i+1] * (1.0 - (0.2 * shadowweight));
shadowscale[i] = (int)v;
if(shadowscale[i] > 256) shadowscale[i] = 256;
if(shadowscale[i] < 0) shadowscale[i] = 0;
}
}
int v = configuration.getInteger("ambientlight", -1);
if((v >= 0) && (v < 15)) {
lightscale = new int[16];
for(int i = 0; i < 16; i++) {
if(i < (15-v))
lightscale[i] = 0;
else
lightscale[i] = i - (15-v);
}
}
night_and_day = configuration.getBoolean("night-and-day", false);
if(night_and_day) {
if(lightscale == null) {
Log.severe("night-and-day in lighting '" + getName() + "' requires ambientlight<15");
night_and_day = false;
}
}
}
/* Apply lighting to given pixel colors (1 outcolor if normal, 2 if night/day) */
public void applyLighting(HDPerspectiveState ps, HDShaderState ss, Color incolor, Color[] outcolor) {
int lightlevel = 15, lightlevel_day = 15;
/* If processing for shadows, use sky light level as base lighting */
if(shadowscale != null) {
lightlevel = lightlevel_day = ps.getSkyLightLevel();
}
/* If ambient light, adjust base lighting for it */
if(lightscale != null)
lightlevel = lightscale[lightlevel];
/* If we're below max, see if emitted light helps */
if((lightlevel < 15) || (lightlevel_day < 15)) {
int emitted = ps.getEmittedLightLevel();
lightlevel = Math.max(emitted, lightlevel);
lightlevel_day = Math.max(emitted, lightlevel_day);
}
/* Figure out our color, with lighting if needed */
outcolor[0].setColor(incolor);
if(lightlevel < 15) {
shadowColor(outcolor[0], lightlevel);
}
if(outcolor.length > 1) {
if(lightlevel_day == lightlevel) {
outcolor[1].setColor(outcolor[0]);
}
else {
outcolor[1].setColor(incolor);
if(lightlevel_day < 15) {
shadowColor(outcolor[1], lightlevel_day);
}
}
}
}
private final void shadowColor(Color c, int lightlevel) {
int scale = shadowscale[lightlevel];
if(scale < 256)
c.setRGBA((c.getRed() * scale) >> 8, (c.getGreen() * scale) >> 8,
(c.getBlue() * scale) >> 8, c.getAlpha());
}
/* Test if night/day is enabled for this renderer */
public boolean isNightAndDayEnabled() { return night_and_day; }
/* Test if sky light level needed */
public boolean isSkyLightLevelNeeded() { return (shadowscale != null); }
/* Test if emitted light level needed */
public boolean isEmittedLightLevelNeeded() { return (shadowscale != null) || (lightscale != null); }
}

File diff suppressed because it is too large Load Diff

View File

@ -1,240 +0,0 @@
package org.dynmap.hdmap;
import static org.dynmap.JSONUtils.s;
import org.dynmap.Color;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapCore;
import org.dynmap.Log;
import org.dynmap.MapManager;
import org.dynmap.utils.MapChunkCache;
import org.dynmap.utils.MapIterator;
import org.json.simple.JSONObject;
public class TexturePackHDShader implements HDShader {
private String tpname;
private String name;
private TexturePack tp;
private boolean biome_shaded;
private boolean swamp_shaded;
private boolean waterbiomeshaded;
private boolean bettergrass;
public TexturePackHDShader(DynmapCore core, ConfigurationNode configuration) {
tpname = configuration.getString("texturepack", "minecraft");
name = configuration.getString("name", tpname);
tp = TexturePack.getTexturePack(core, tpname);
biome_shaded = configuration.getBoolean("biomeshaded", true);
swamp_shaded = configuration.getBoolean("swampshaded", MapManager.mapman.getSwampShading());
waterbiomeshaded = configuration.getBoolean("waterbiomeshaded", MapManager.mapman.getWaterBiomeShading());
bettergrass = configuration.getBoolean("better-grass", MapManager.mapman.getBetterGrass());
if(tp == null) {
Log.severe("Error: shader '" + name + "' cannot load texture pack '" + tpname + "'");
}
}
@Override
public boolean isBiomeDataNeeded() {
return swamp_shaded;
}
@Override
public boolean isRawBiomeDataNeeded() {
return biome_shaded;
}
@Override
public boolean isHightestBlockYDataNeeded() {
return false;
}
@Override
public boolean isBlockTypeDataNeeded() {
return true;
}
@Override
public boolean isSkyLightLevelNeeded() {
return false;
}
@Override
public boolean isEmittedLightLevelNeeded() {
return false;
}
@Override
public String getName() {
return name;
}
class ShaderState implements HDShaderState {
private Color color[];
private Color tmpcolor[];
private Color c;
protected MapIterator mapiter;
protected HDMap map;
private TexturePack scaledtp;
private HDLighting lighting;
private int lastblkid;
boolean do_biome_shading;
boolean do_swamp_shading;
boolean do_water_shading;
boolean do_better_grass;
private ShaderState(MapIterator mapiter, HDMap map, MapChunkCache cache) {
this.mapiter = mapiter;
this.map = map;
this.lighting = map.getLighting();
if(lighting.isNightAndDayEnabled()) {
color = new Color[] { new Color(), new Color() };
tmpcolor = new Color[] { new Color(), new Color() };
}
else {
color = new Color[] { new Color() };
tmpcolor = new Color[] { new Color() };
}
c = new Color();
scaledtp = tp.resampleTexturePack(map.getPerspective().getModelScale());
/* Biome raw data only works on normal worlds at this point */
do_biome_shading = biome_shaded; // && (cache.getWorld().getEnvironment() == Environment.NORMAL);
do_swamp_shading = do_biome_shading && swamp_shaded;
do_water_shading = do_biome_shading && waterbiomeshaded;
do_better_grass = bettergrass;
}
/**
* Get our shader
*/
public HDShader getShader() {
return TexturePackHDShader.this;
}
/**
* Get our map
*/
public HDMap getMap() {
return map;
}
/**
* Get our lighting
*/
public HDLighting getLighting() {
return lighting;
}
/**
* Reset renderer state for new ray
*/
public void reset(HDPerspectiveState ps) {
for(int i = 0; i < color.length; i++)
color[i].setTransparent();
lastblkid = 0;
}
/**
* Process next ray step - called for each block on route
* @return true if ray is done, false if ray needs to continue
*/
public boolean processBlock(HDPerspectiveState ps) {
int blocktype = ps.getBlockTypeID();
int lastblocktype = lastblkid;
lastblkid = blocktype;
if(blocktype == 0) {
return false;
}
/* Get color from textures */
scaledtp.readColor(ps, mapiter, c, blocktype, lastblocktype, ShaderState.this);
if (c.getAlpha() > 0) {
/* Scale brightness depending upon face */
switch(ps.getLastBlockStep()) {
case X_MINUS:
case X_PLUS:
/* 60% brightness */
c.blendColor(0xFFA0A0A0);
break;
case Y_MINUS:
case Y_PLUS:
/* 85% brightness for even, 90% for even*/
if((mapiter.getY() & 0x01) == 0)
c.blendColor(0xFFD9D9D9);
else
c.blendColor(0xFFE6E6E6);
break;
}
/* Handle light level, if needed */
lighting.applyLighting(ps, this, c, tmpcolor);
/* If we got alpha from subblock model, use it instead if it is lower */
/* (disable for now: weighting is wrong, as crosssection is 2D, not 3D based) */
// if(subalpha >= 0) {
// for(Color clr : tmpcolor) {
// int a = clr.getAlpha();
// if(subalpha < a)
// clr.setAlpha(subalpha);
// }
// }
/* If no previous color contribution, use new color */
if(color[0].isTransparent()) {
for(int i = 0; i < color.length; i++)
color[i].setColor(tmpcolor[i]);
return (color[0].getAlpha() == 255);
}
/* Else, blend and generate new alpha */
else {
int alpha = color[0].getAlpha();
int alpha2 = tmpcolor[0].getAlpha() * (255-alpha) / 255;
int talpha = alpha + alpha2;
if(talpha > 0)
for(int i = 0; i < color.length; i++)
color[i].setRGBA((tmpcolor[i].getRed()*alpha2 + color[i].getRed()*alpha) / talpha,
(tmpcolor[i].getGreen()*alpha2 + color[i].getGreen()*alpha) / talpha,
(tmpcolor[i].getBlue()*alpha2 + color[i].getBlue()*alpha) / talpha, talpha);
else
for(int i = 0; i < color.length; i++)
color[i].setTransparent();
return (talpha >= 254); /* If only one short, no meaningful contribution left */
}
}
return false;
}
/**
* Ray ended - used to report that ray has exited map (called if renderer has not reported complete)
*/
public void rayFinished(HDPerspectiveState ps) {
}
/**
* Get result color - get resulting color for ray
* @param c - object to store color value in
* @param index - index of color to request (renderer specific - 0=default, 1=day for night/day renderer
*/
public void getRayColor(Color c, int index) {
c.setColor(color[index]);
}
/**
* Clean up state object - called after last ray completed
*/
public void cleanup() {
}
}
/**
* Get renderer state object for use rendering a tile
* @param map - map being rendered
* @param cache - chunk cache containing data for tile to be rendered
* @param mapiter - iterator used when traversing rays in tile
* @return state object to use for all rays in tile
*/
public HDShaderState getStateInstance(HDMap map, MapChunkCache cache, MapIterator mapiter) {
return new ShaderState(mapiter, map, cache);
}
/* Add shader's contributions to JSON for map object */
public void addClientConfiguration(JSONObject mapObject) {
s(mapObject, "shader", name);
}
}

View File

@ -1,235 +0,0 @@
package org.dynmap.hdmap;
import static org.dynmap.JSONUtils.s;
import org.dynmap.Color;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapCore;
import org.dynmap.Log;
import org.dynmap.utils.MapChunkCache;
import org.dynmap.utils.MapIterator;
import org.dynmap.utils.MapIterator.BlockStep;
import org.json.simple.JSONObject;
public class TopoHDShader implements HDShader {
private String name;
private Color linecolor; /* Color for topo lines */
private Color fillcolor[]; /* Color for nontopo surfaces */
private Color watercolor;
private Color readColor(String id, ConfigurationNode cfg) {
String lclr = cfg.getString(id, null);
if((lclr != null) && (lclr.startsWith("#"))) {
try {
int c = Integer.parseInt(lclr.substring(1), 16);
return new Color((c>>16)&0xFF, (c>>8)&0xFF, c&0xFF);
} catch (NumberFormatException nfx) {
Log.severe("Invalid color value: " + lclr + " for '" + id + "'");
}
}
return null;
}
public TopoHDShader(DynmapCore core, ConfigurationNode configuration) {
name = (String) configuration.get("name");
fillcolor = new Color[128]; /* Color by Y */
/* Load defined colors from parameters */
for(int i = 0; i < 128; i++) {
fillcolor[i] = readColor("color" + i, configuration);
}
linecolor = readColor("linecolor", configuration);
watercolor = readColor("watercolor", configuration);
/* Now, interpolate missing colors */
if(fillcolor[0] == null) {
fillcolor[0] = new Color(0, 0, 0);
}
if(fillcolor[127] == null) {
fillcolor[127] = new Color(255, 255, 255);
}
int starty = 0;
for(int i = 1; i < 128; i++) {
if(fillcolor[i] != null) { /* Found color? */
int delta = i - starty;
Color c0 = fillcolor[starty];
Color c1 = fillcolor[i];
/* Interpolate missing colors since last one */
for(int j = 1; j < delta; j++) {
fillcolor[starty + j] = new Color((c0.getRed()*(delta-j) + c1.getRed()*j)/delta, (c0.getGreen()*(delta-j) + c1.getGreen()*j)/delta, (c0.getBlue()*(delta-j) + c1.getBlue()*j)/delta);
}
starty = i; /* New start color */
}
}
}
@Override
public boolean isBiomeDataNeeded() {
return false;
}
@Override
public boolean isRawBiomeDataNeeded() {
return false;
}
@Override
public boolean isHightestBlockYDataNeeded() {
return false;
}
@Override
public boolean isBlockTypeDataNeeded() {
return true;
}
@Override
public boolean isSkyLightLevelNeeded() {
return false;
}
@Override
public boolean isEmittedLightLevelNeeded() {
return false;
}
@Override
public String getName() {
return name;
}
private class OurShaderState implements HDShaderState {
private Color color[];
private Color tmpcolor[];
private Color c;
protected MapIterator mapiter;
protected HDMap map;
private HDLighting lighting;
private int scale;
private OurShaderState(MapIterator mapiter, HDMap map, MapChunkCache cache) {
this.mapiter = mapiter;
this.map = map;
this.lighting = map.getLighting();
if(lighting.isNightAndDayEnabled()) {
color = new Color[] { new Color(), new Color() };
tmpcolor = new Color[] { new Color(), new Color() };
}
else {
color = new Color[] { new Color() };
tmpcolor = new Color[] { new Color() };
}
scale = (int)map.getPerspective().getScale();
c = new Color();
}
/**
* Get our shader
*/
public HDShader getShader() {
return TopoHDShader.this;
}
/**
* Get our map
*/
public HDMap getMap() {
return map;
}
/**
* Get our lighting
*/
public HDLighting getLighting() {
return lighting;
}
/**
* Reset renderer state for new ray
*/
public void reset(HDPerspectiveState ps) {
for(int i = 0; i < color.length; i++)
color[i].setTransparent();
}
/**
* Process next ray step - called for each block on route
* @return true if ray is done, false if ray needs to continue
*/
public boolean processBlock(HDPerspectiveState ps) {
int blocktype = ps.getBlockTypeID();
if(blocktype == 0) {
return false;
}
/* See if we're close to an edge */
int[] xyz = ps.getSubblockCoord();
/* See which face we're on (only do lines on top face) */
switch(ps.getLastBlockStep()) {
case Y_MINUS:
case Y_PLUS:
if((linecolor != null) &&
(((xyz[0] == 0) && (mapiter.getBlockTypeIDAt(BlockStep.X_MINUS) == 0)) ||
((xyz[0] == (scale-1)) && (mapiter.getBlockTypeIDAt(BlockStep.X_PLUS) == 0)) ||
((xyz[2] == 0) && (mapiter.getBlockTypeIDAt(BlockStep.Z_MINUS) == 0)) ||
((xyz[2] == (scale-1)) && (mapiter.getBlockTypeIDAt(BlockStep.Z_PLUS) == 0)))) {
c.setColor(linecolor);
}
else if((watercolor != null) && ((blocktype == 8) || (blocktype == 9))) {
c.setColor(watercolor);
}
else {
c.setColor(fillcolor[mapiter.getY()]);
}
break;
default:
if((linecolor != null) && (xyz[1] == (scale-1)))
c.setColor(linecolor);
else if((watercolor != null) && ((blocktype == 8) || (blocktype == 9))) {
c.setColor(watercolor);
}
else
c.setColor(fillcolor[mapiter.getY()]);
break;
}
/* Handle light level, if needed */
lighting.applyLighting(ps, this, c, tmpcolor);
for(int i = 0; i < color.length; i++)
color[i] = tmpcolor[i];
return true;
}
/**
* Ray ended - used to report that ray has exited map (called if renderer has not reported complete)
*/
public void rayFinished(HDPerspectiveState ps) {
}
/**
* Get result color - get resulting color for ray
* @param c - object to store color value in
* @param index - index of color to request (renderer specific - 0=default, 1=day for night/day renderer
*/
public void getRayColor(Color c, int index) {
c.setColor(color[index]);
}
/**
* Clean up state object - called after last ray completed
*/
public void cleanup() {
}
}
/**
* Get renderer state object for use rendering a tile
* @param map - map being rendered
* @param cache - chunk cache containing data for tile to be rendered
* @param mapiter - iterator used when traversing rays in tile
* @return state object to use for all rays in tile
*/
public HDShaderState getStateInstance(HDMap map, MapChunkCache cache, MapIterator mapiter) {
return new OurShaderState(mapiter, map, cache);
}
/* Add shader's contributions to JSON for map object */
public void addClientConfiguration(JSONObject mapObject) {
s(mapObject, "shader", name);
}
}

View File

@ -1,113 +0,0 @@
package org.dynmap.kzedmap;
import org.dynmap.Color;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapCore;
import org.dynmap.DynmapWorld;
import org.dynmap.utils.MapIterator;
import org.dynmap.utils.MapIterator.BlockStep;
public class CaveTileRenderer extends DefaultTileRenderer {
private boolean iflit;
public CaveTileRenderer(DynmapCore core, ConfigurationNode configuration) {
super(core, configuration);
iflit = configuration.getBoolean("onlyiflit", false);
}
public boolean isNightAndDayEnabled() { return false; }
@Override
protected void scan(DynmapWorld world, int seq, boolean isnether, final Color result, final Color result_day,
MapIterator mapiter) {
boolean air = true;
int emitted = 0;
result.setTransparent();
for (;;) {
if (mapiter.getY() < 0)
return;
int id = mapiter.getBlockTypeID();
if(isnether) { /* Make ceiling into air in nether */
if(id != 0)
id = 0;
else
isnether = false;
}
if(iflit && (!air))
emitted = mapiter.getBlockEmittedLight();
switch (seq) {
case 0:
mapiter.stepPosition(BlockStep.X_MINUS);
break;
case 1:
case 3:
mapiter.stepPosition(BlockStep.Y_MINUS);
break;
case 2:
mapiter.stepPosition(BlockStep.Z_PLUS);
break;
}
seq = (seq + 1) & 3;
switch (id) {
case 17:
case 18:
case 20:
case 64:
case 71:
case 78:
case 79:
id = 0;
break;
default:
}
if (id != 0) {
air = false;
continue;
}
if (id == 0 && !air) {
if(iflit && (emitted == 0)) {
continue;
}
int cr, cg, cb;
int mult = 256;
if (mapiter.getY() < 64) {
cr = 0;
cg = 64 + mapiter.getY() * 3;
cb = 255 - mapiter.getY() * 4;
} else {
cr = (mapiter.getY() - 64) * 4;
cg = 255;
cb = 0;
}
switch (seq) {
case 0:
mult = 224;
break;
case 1:
mult = 256;
break;
case 2:
mult = 192;
break;
case 3:
mult = 160;
break;
}
cr = cr * mult / 256;
cg = cg * mult / 256;
cb = cb * mult / 256;
result.setRGBA(cr, cg, cb, 255);
return;
}
}
}
}

View File

@ -1,596 +0,0 @@
package org.dynmap.kzedmap;
import static org.dynmap.JSONUtils.a;
import static org.dynmap.JSONUtils.s;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import javax.imageio.ImageIO;
import org.dynmap.Client;
import org.dynmap.Color;
import org.dynmap.ColorScheme;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapCore;
import org.dynmap.DynmapWorld;
import org.dynmap.MapManager;
import org.dynmap.DynmapCore.CompassMode;
import org.dynmap.MapType.ImageFormat;
import org.dynmap.TileHashManager;
import org.dynmap.common.BiomeMap;
import org.dynmap.debug.Debug;
import org.dynmap.utils.DynmapBufferedImage;
import org.dynmap.utils.FileLockManager;
import org.dynmap.utils.MapChunkCache;
import org.dynmap.utils.MapIterator;
import org.dynmap.utils.MapIterator.BlockStep;
import org.json.simple.JSONObject;
public class DefaultTileRenderer implements MapTileRenderer {
protected static final Color translucent = new Color(0, 0, 0, 0);
protected String name;
protected String prefix;
protected ConfigurationNode configuration;
protected int maximumHeight = 127;
protected ColorScheme colorScheme;
protected HashSet<Integer> highlightBlocks = new HashSet<Integer>();
protected Color highlightColor = new Color(255, 0, 0);
protected int shadowscale[]; /* index=skylight level, value = 256 * scaling value */
protected int lightscale[]; /* scale skylight level (light = lightscale[skylight] */
protected boolean night_and_day; /* If true, render both day (prefix+'-day') and night (prefix) tiles */
protected boolean transparency; /* Is transparency support active? */
public enum BiomeColorOption {
NONE, BIOME, TEMPERATURE, RAINFALL
}
protected BiomeColorOption biomecolored = BiomeColorOption.NONE; /* Use biome for coloring */
@Override
public String getPrefix() {
return prefix;
}
public String getName() {
return name;
}
public boolean isNightAndDayEnabled() { return night_and_day; }
public DefaultTileRenderer(DynmapCore core, ConfigurationNode configuration) {
this.configuration = configuration;
name = configuration.getString("name", null);
prefix = configuration.getString("prefix", name);
Object o = configuration.get("maximumheight");
if (o != null) {
maximumHeight = Integer.parseInt(String.valueOf(o));
if (maximumHeight > 127)
maximumHeight = 127;
}
o = configuration.get("shadowstrength");
if(o != null) {
double shadowweight = Double.parseDouble(String.valueOf(o));
if(shadowweight > 0.0) {
shadowscale = new int[16];
shadowscale[15] = 256;
/* Normal brightness weight in MC is a 20% relative dropoff per step */
for(int i = 14; i >= 0; i--) {
double v = shadowscale[i+1] * (1.0 - (0.2 * shadowweight));
shadowscale[i] = (int)v;
if(shadowscale[i] > 256) shadowscale[i] = 256;
if(shadowscale[i] < 0) shadowscale[i] = 0;
}
}
}
o = configuration.get("ambientlight");
if(o != null) {
int v = Integer.parseInt(String.valueOf(o));
lightscale = new int[16];
for(int i = 0; i < 16; i++) {
if(i < (15-v))
lightscale[i] = 0;
else
lightscale[i] = i - (15-v);
}
}
colorScheme = ColorScheme.getScheme(core, (String)configuration.get("colorscheme"));
night_and_day = configuration.getBoolean("night-and-day", false);
transparency = configuration.getBoolean("transparency", true); /* Default on */
String biomeopt = configuration.getString("biomecolored", "none");
if(biomeopt.equals("biome")) {
biomecolored = BiomeColorOption.BIOME;
}
else if(biomeopt.equals("temperature")) {
biomecolored = BiomeColorOption.TEMPERATURE;
}
else if(biomeopt.equals("rainfall")) {
biomecolored = BiomeColorOption.RAINFALL;
}
else {
biomecolored = BiomeColorOption.NONE;
}
}
public boolean isBiomeDataNeeded() { return biomecolored.equals(BiomeColorOption.BIOME); }
public boolean isRawBiomeDataNeeded() {
return biomecolored.equals(BiomeColorOption.RAINFALL) || biomecolored.equals(BiomeColorOption.TEMPERATURE);
}
public boolean render(MapChunkCache cache, KzedMapTile tile, File outputFile) {
DynmapWorld world = tile.getDynmapWorld();
boolean isnether = world.isNether();
DynmapBufferedImage im = DynmapBufferedImage.allocateBufferedImage(KzedMap.tileWidth, KzedMap.tileHeight);
DynmapBufferedImage zim = DynmapBufferedImage.allocateBufferedImage(KzedMap.tileWidth/2, KzedMap.tileHeight/2);
DynmapBufferedImage im_day = null;
DynmapBufferedImage zim_day = null;
if(night_and_day) {
im_day = DynmapBufferedImage.allocateBufferedImage(KzedMap.tileWidth, KzedMap.tileHeight);
zim_day = DynmapBufferedImage.allocateBufferedImage(KzedMap.tileWidth/2, KzedMap.tileHeight/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 + ((127-maximumHeight)/2);
/* Don't mess with existing height-clipped renders */
if(maximumHeight < 127)
isnether = false;
int jx, jz;
int x, y;
MapIterator mapiter = cache.getIterator(ix, iy, iz);
Color c1 = new Color();
Color c2 = new Color();
int[] argb = im.argb_buf;
int[] zargb = zim.argb_buf;
Color c1_day = null;
Color c2_day = null;
int[] argb_day = null;
int[] zargb_day = null;
if(night_and_day) {
c1_day = new Color();
c2_day = new Color();
argb_day = im_day.argb_buf;
zargb_day = zim_day.argb_buf;
}
int rowoff = 0;
/* draw the map */
for (y = 0; y < KzedMap.tileHeight;) {
jx = ix;
jz = iz;
for (x = KzedMap.tileWidth - 1; x >= 0; x -= 2) {
mapiter.initialize(jx, iy, jz);
scan(world, 0, isnether, c1, c1_day, mapiter);
mapiter.initialize(jx, iy, jz);
scan(world, 2, isnether, c2, c2_day, mapiter);
argb[rowoff+x] = c1.getARGB();
argb[rowoff+x-1] = c2.getARGB();
if(night_and_day) {
argb_day[rowoff+x] = c1_day.getARGB();
argb_day[rowoff+x-1] = c2_day.getARGB();
}
jx++;
jz++;
}
y++;
rowoff += KzedMap.tileWidth;
jx = ix;
jz = iz - 1;
for (x = KzedMap.tileWidth - 1; x >= 0; x -= 2) {
mapiter.initialize(jx, iy, jz);
scan(world, 2, isnether, c1, c1_day, mapiter);
jx++;
jz++;
mapiter.initialize(jx, iy, jz);
scan(world, 0, isnether, c2, c2_day, mapiter);
argb[rowoff+x] = c1.getARGB();
argb[rowoff+x-1] = c2.getARGB();
if(night_and_day) {
argb_day[rowoff+x] = c1_day.getARGB();
argb_day[rowoff+x-1] = c2_day.getARGB();
}
}
y++;
rowoff += KzedMap.tileWidth;
ix++;
iz--;
}
/* Now, compute zoomed tile - bilinear filter 2x2 -> 1x1 */
doScaleWithBilinear(argb, zargb, KzedMap.tileWidth, KzedMap.tileHeight);
if(night_and_day) {
doScaleWithBilinear(argb_day, zargb_day, KzedMap.tileWidth, KzedMap.tileHeight);
}
/* Hand encoding and writing file off to MapManager */
KzedZoomedMapTile zmtile = new KzedZoomedMapTile(tile.getDynmapWorld(), tile);
File zoomFile = MapManager.mapman.getTileFile(zmtile);
return doFileWrites(outputFile, tile, im, im_day, zmtile, zoomFile, zim, zim_day);
}
private void doScaleWithBilinear(int[] argb, int[] zargb, int width, int height) {
Color c1 = new Color();
/* Now, compute zoomed tile - bilinear filter 2x2 -> 1x1 */
for(int y = 0; y < height; y += 2) {
for(int x = 0; x < width; x += 2) {
int red = 0;
int green = 0;
int blue = 0;
int alpha = 0;
for(int yy = y; yy < y+2; yy++) {
for(int xx = x; xx < x+2; xx++) {
c1.setARGB(argb[(yy*width)+xx]);
red += c1.getRed();
green += c1.getGreen();
blue += c1.getBlue();
alpha += c1.getAlpha();
}
}
c1.setRGBA(red>>2, green>>2, blue>>2, alpha>>2);
zargb[(y*width/4) + (x/2)] = c1.getARGB();
}
}
}
private boolean doFileWrites(final File fname, final KzedMapTile mtile,
final DynmapBufferedImage img, final DynmapBufferedImage img_day,
final KzedZoomedMapTile zmtile, final File zoomFile,
final DynmapBufferedImage zimg, final DynmapBufferedImage zimg_day) {
boolean didwrite = false;
/* Get coordinates of zoomed tile */
int ox = (mtile.px == zmtile.getTileX())?0:KzedMap.tileWidth/2;
int oy = (mtile.py == zmtile.getTileY())?0:KzedMap.tileHeight/2;
/* Test to see if we're unchanged from older tile */
TileHashManager hashman = MapManager.mapman.hashman;
long crc = hashman.calculateTileHash(img.argb_buf);
boolean updated_fname = false;
int tx = mtile.px/KzedMap.tileWidth;
int ty = mtile.py/KzedMap.tileHeight;
FileLockManager.getWriteLock(fname);
try {
if((!fname.exists()) || (crc != hashman.getImageHashCode(mtile.getKey(prefix), null, tx, ty))) {
Debug.debug("saving image " + fname.getPath());
if(!fname.getParentFile().exists())
fname.getParentFile().mkdirs();
try {
FileLockManager.imageIOWrite(img.buf_img, ImageFormat.FORMAT_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);
}
MapManager.mapman.pushUpdate(mtile.getDynmapWorld(), new Client.Tile(mtile.getFilename()));
hashman.updateHashCode(mtile.getKey(prefix), null, tx, ty, crc);
updated_fname = true;
didwrite = true;
}
} finally {
FileLockManager.releaseWriteLock(fname);
DynmapBufferedImage.freeBufferedImage(img);
}
MapManager.mapman.updateStatistics(mtile, prefix, true, updated_fname, true);
mtile.file = fname;
boolean updated_dfname = false;
File dfname = new File(mtile.getDynmapWorld().worldtilepath, mtile.getDayFilename());
if(img_day != null) {
crc = hashman.calculateTileHash(img.argb_buf);
FileLockManager.getWriteLock(dfname);
try {
if((!dfname.exists()) || (crc != hashman.getImageHashCode(mtile.getKey(prefix), "day", tx, ty))) {
Debug.debug("saving image " + dfname.getPath());
if(!dfname.getParentFile().exists())
dfname.getParentFile().mkdirs();
try {
FileLockManager.imageIOWrite(img_day.buf_img, ImageFormat.FORMAT_PNG, dfname);
} catch (IOException e) {
Debug.error("Failed to save image: " + dfname.getPath(), e);
} catch (java.lang.NullPointerException e) {
Debug.error("Failed to save image (NullPointerException): " + dfname.getPath(), e);
}
MapManager.mapman.pushUpdate(mtile.getDynmapWorld(), new Client.Tile(mtile.getDayFilename()));
hashman.updateHashCode(mtile.getKey(prefix), "day", tx, ty, crc);
updated_dfname = true;
didwrite = true;
}
} finally {
FileLockManager.releaseWriteLock(dfname);
DynmapBufferedImage.freeBufferedImage(img_day);
}
MapManager.mapman.updateStatistics(mtile, prefix+"_day", true, updated_dfname, true);
}
// Since we've already got the new tile, and we're on an async thread, just
// make the zoomed tile here
boolean ztile_updated = false;
FileLockManager.getWriteLock(zoomFile);
try {
if(updated_fname || (!zoomFile.exists())) {
saveZoomedTile(zmtile, zoomFile, zimg, ox, oy, null);
MapManager.mapman.pushUpdate(zmtile.getDynmapWorld(),
new Client.Tile(zmtile.getFilename()));
zmtile.getDynmapWorld().enqueueZoomOutUpdate(zoomFile);
ztile_updated = true;
}
} finally {
FileLockManager.releaseWriteLock(zoomFile);
DynmapBufferedImage.freeBufferedImage(zimg);
}
MapManager.mapman.updateStatistics(zmtile, null, true, ztile_updated, true);
if(zimg_day != null) {
File zoomFile_day = new File(zmtile.getDynmapWorld().worldtilepath, zmtile.getDayFilename());
ztile_updated = false;
FileLockManager.getWriteLock(zoomFile_day);
try {
if(updated_dfname || (!zoomFile_day.exists())) {
saveZoomedTile(zmtile, zoomFile_day, zimg_day, ox, oy, "day");
MapManager.mapman.pushUpdate(zmtile.getDynmapWorld(),
new Client.Tile(zmtile.getDayFilename()));
zmtile.getDynmapWorld().enqueueZoomOutUpdate(zoomFile_day);
ztile_updated = true;
}
} finally {
FileLockManager.releaseWriteLock(zoomFile_day);
DynmapBufferedImage.freeBufferedImage(zimg_day);
}
MapManager.mapman.updateStatistics(zmtile, "day", true, ztile_updated, true);
}
return didwrite;
}
private void saveZoomedTile(final KzedZoomedMapTile zmtile, final File zoomFile,
final DynmapBufferedImage zimg, int ox, int oy, String subkey) {
BufferedImage zIm = null;
DynmapBufferedImage kzIm = null;
try {
zIm = ImageIO.read(zoomFile);
} catch (IOException e) {
} catch (IndexOutOfBoundsException e) {
}
boolean zIm_allocated = false;
if (zIm == null) {
/* create new one */
kzIm = DynmapBufferedImage.allocateBufferedImage(KzedMap.tileWidth, KzedMap.tileHeight);
zIm = kzIm.buf_img;
zIm_allocated = true;
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 */
zIm.setRGB(ox, oy, KzedMap.tileWidth/2, KzedMap.tileHeight/2, zimg.argb_buf, 0, KzedMap.tileWidth/2);
/* save zoom-out tile */
if(!zoomFile.getParentFile().exists())
zoomFile.getParentFile().mkdirs();
try {
FileLockManager.imageIOWrite(zIm, ImageFormat.FORMAT_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);
}
if(zIm_allocated)
DynmapBufferedImage.freeBufferedImage(kzIm);
else
zIm.flush();
}
protected void scan(DynmapWorld world, int seq, boolean isnether, final Color result, final Color result_day,
MapIterator mapiter) {
int lightlevel = 15;
int lightlevel_day = 15;
BiomeMap bio = null;
double rain = 0.0;
double temp = 0.0;
result.setTransparent();
if(result_day != null)
result_day.setTransparent();
for (;;) {
if (mapiter.getY() < 0) {
return;
}
int id = mapiter.getBlockTypeID();
int 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(id != 0) { /* No update needed for air */
switch(biomecolored) {
case NONE:
if(colorScheme.datacolors[id] != null) { /* If data colored */
data = mapiter.getBlockData();
}
break;
case BIOME:
bio = mapiter.getBiome();
break;
case RAINFALL:
rain = mapiter.getRawBiomeRainfall();
break;
case TEMPERATURE:
temp = mapiter.getRawBiomeTemperature();
break;
}
if((shadowscale != null) && (mapiter.getY() < 127)) {
/* Find light level of previous chunk */
BlockStep last = mapiter.unstepPosition();
lightlevel = lightlevel_day = mapiter.getBlockSkyLight();
if(lightscale != null)
lightlevel = lightscale[lightlevel];
if((lightlevel < 15) || (lightlevel_day < 15)) {
int emitted = mapiter.getBlockEmittedLight();
lightlevel = Math.max(emitted, lightlevel);
lightlevel_day = Math.max(emitted, lightlevel_day);
}
mapiter.stepPosition(last);
}
}
switch (seq) {
case 0:
mapiter.stepPosition(BlockStep.X_MINUS);
break;
case 1:
case 3:
mapiter.stepPosition(BlockStep.Y_MINUS);
break;
case 2:
mapiter.stepPosition(BlockStep.Z_PLUS);
break;
}
seq = (seq + 1) & 3;
if (id != 0) {
if (highlightBlocks.contains(id)) {
result.setColor(highlightColor);
return;
}
Color[] colors = null;
switch(biomecolored) {
case NONE:
if(data != 0)
colors = colorScheme.datacolors[id][data];
else
colors = colorScheme.colors[id];
break;
case BIOME:
if(bio != null)
colors = colorScheme.biomecolors[bio.ordinal()];
break;
case RAINFALL:
colors = colorScheme.getRainColor(rain);
break;
case TEMPERATURE:
colors = colorScheme.getTempColor(temp);
break;
}
if (colors != null) {
Color c = colors[seq];
if (c.getAlpha() > 0) {
/* we found something that isn't transparent, or not doing transparency */
if ((!transparency) || (c.getAlpha() == 255)) {
/* it's opaque - the ray ends here */
result.setARGB(c.getARGB() | 0xFF000000);
if(lightlevel < 15) { /* Not full light? */
shadowColor(result, lightlevel);
}
if(result_day != null) {
if(lightlevel_day == lightlevel) /* Same light = same result */
result_day.setColor(result);
else {
result_day.setColor(c);
if(lightlevel_day < 15)
shadowColor(result_day, lightlevel_day);
}
}
return;
}
/* this block is transparent, so recurse */
scan(world, seq, isnether, result, result_day, mapiter);
int cr = c.getRed();
int cg = c.getGreen();
int cb = c.getBlue();
int ca = c.getAlpha();
if(lightlevel < 15) {
int scale = shadowscale[lightlevel];
cr = (cr * scale) >> 8;
cg = (cg * scale) >> 8;
cb = (cb * scale) >> 8;
}
cr *= ca;
cg *= ca;
cb *= ca;
int na = 255 - ca;
result.setRGBA((result.getRed() * na + cr) >> 8, (result.getGreen() * na + cg) >> 8, (result.getBlue() * na + cb) >> 8, 255);
/* Handle day also */
if(result_day != null) {
cr = c.getRed();
cg = c.getGreen();
cb = c.getBlue();
if(lightlevel_day < 15) {
int scale = shadowscale[lightlevel_day];
cr = (cr * scale) >> 8;
cg = (cg * scale) >> 8;
cb = (cb * scale) >> 8;
}
cr *= ca;
cg *= ca;
cb *= ca;
result_day.setRGBA((result_day.getRed() * na + cr) >> 8, (result_day.getGreen() * na + cg) >> 8, (result_day.getBlue() * na + cb) >> 8,
255);
}
return;
}
}
}
}
}
private final void shadowColor(Color c, int lightlevel) {
int scale = shadowscale[lightlevel];
if(scale < 256)
c.setRGBA((c.getRed() * scale) >> 8, (c.getGreen() * scale) >> 8,
(c.getBlue() * scale) >> 8, c.getAlpha());
}
@Override
public void buildClientConfiguration(JSONObject worldObject, DynmapWorld world, KzedMap map) {
ConfigurationNode c = configuration;
JSONObject o = new JSONObject();
s(o, "type", "KzedMapType");
s(o, "name", c.getString("name"));
s(o, "title", c.getString("title"));
s(o, "icon", c.getString("icon"));
s(o, "prefix", c.getString("prefix"));
s(o, "background", c.getString("background"));
s(o, "nightandday", c.getBoolean("night-and-day", false));
s(o, "backgroundday", c.getString("backgroundday"));
s(o, "backgroundnight", c.getString("backgroundnight"));
s(o, "bigmap", map.isBigWorldMap(world));
s(o, "mapzoomin", c.getInteger("mapzoomin", 2));
s(o, "mapzoomout", world.getExtraZoomOutLevels()+1);
if(MapManager.mapman.getCompassMode() != CompassMode.PRE19)
s(o, "compassview", "NE"); /* Always from northeast */
else
s(o, "compassview", "SE"); /* Always from southeast */
s(o, "image-format", ImageFormat.FORMAT_PNG.getFileExt());
a(worldObject, "maps", o);
}
}

View File

@ -1,107 +0,0 @@
package org.dynmap.kzedmap;
import java.util.HashSet;
import java.util.List;
import org.dynmap.Color;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapCore;
import org.dynmap.DynmapWorld;
import org.dynmap.utils.MapIterator;
import org.dynmap.utils.MapIterator.BlockStep;
public class HighlightTileRenderer extends DefaultTileRenderer {
protected HashSet<Integer> highlightBlocks = new HashSet<Integer>();
public HighlightTileRenderer(DynmapCore core, ConfigurationNode configuration) {
super(core, configuration);
List<Integer> highlight = configuration.<Integer>getList("highlight");
for(Integer i : highlight) {
highlightBlocks.add(i);
}
}
@Override
protected void scan(DynmapWorld world,int seq, boolean isnether, final Color result, final Color result_day,
MapIterator mapiter) {
result.setTransparent();
for (;;) {
if (mapiter.getY() < 0) {
break;
}
int id = mapiter.getBlockTypeID();
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;
}
int data = 0;
if(colorScheme.datacolors[id] != null) { /* If data colored */
data = mapiter.getBlockData();
}
switch (seq) {
case 0:
mapiter.stepPosition(BlockStep.X_MINUS);
break;
case 1:
case 3:
mapiter.stepPosition(BlockStep.Y_MINUS);
break;
case 2:
mapiter.stepPosition(BlockStep.Z_PLUS);
break;
}
seq = (seq + 1) & 3;
if (id != 0) {
Color[] colors;
if(data != 0)
colors = colorScheme.datacolors[id][data];
else
colors = colorScheme.colors[id];
if (colors != null) {
Color c = colors[seq];
if (highlightBlocks.contains(id)) {
result.setColor(c);
return;
}
if (c.getAlpha() > 0) {
/* we found something that isn't transparent! */
/*
* if (c.getAlpha() == 255) { return c; }
*/
/* this block is transparent, so recurse */
// No need to blend if result is opaque.
if (result.getAlpha() < 255) {
int cr = result.getRed();
int cg = result.getGreen();
int cb = result.getBlue();
int ca = result.getAlpha();
cr *= ca;
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.
);
}
}
}
}
}
}
}

View File

@ -1,336 +0,0 @@
package org.dynmap.kzedmap;
import org.dynmap.DynmapWorld;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapChunk;
import org.dynmap.DynmapCore;
import org.dynmap.Log;
import org.dynmap.MapTile;
import org.dynmap.MapType;
import org.dynmap.utils.MapChunkCache;
import org.json.simple.JSONObject;
public class KzedMap extends MapType {
protected static final Logger log = Logger.getLogger("Minecraft");
protected static final String LOG_PREFIX = "[dynmap] ";
/* dimensions of a map tile */
public static final int tileWidth = 128;
public static final int tileHeight = 128;
/*
* (logical!) dimensions of a zoomed out map tile must be twice the size of
* the normal tile
*/
public static final int zTileWidth = 256;
public static final int zTileHeight = 256;
/* map x, y, z for projection origin */
public static final int anchorx = 0;
public static final int anchory = 127;
public static final int anchorz = 0;
MapTileRenderer[] renderers;
private boolean isbigmap;
public KzedMap(DynmapCore core, ConfigurationNode configuration) {
Log.verboseinfo("Loading renderers for map '" + getClass().toString() + "'...");
List<MapTileRenderer> renderers = configuration.<MapTileRenderer>createInstances("renderers", new Class<?>[] { DynmapCore.class }, new Object[] { core } );
this.renderers = new MapTileRenderer[renderers.size()];
renderers.toArray(this.renderers);
Log.verboseinfo("Loaded " + renderers.size() + " renderers for map '" + getClass().toString() + "'.");
isbigmap = configuration.getBoolean("isbigmap", false);
}
@Override
public MapTile[] getTiles(DynmapWorld world, int x, int y, int z) {
int dx = x - anchorx;
int dy = y - anchory;
int dz = z - anchorz;
int px = dx + dz;
int py = dx - dz - dy;
int tx = tilex(px);
int ty = tiley(py);
ArrayList<MapTile> tiles = new ArrayList<MapTile>();
addTile(tiles, world, tx, ty);
boolean ledge = tilex(px - 4) != tx;
boolean tedge = tiley(py - 4) != ty;
boolean redge = tilex(px + 4) != tx;
boolean bedge = tiley(py + 4) != ty;
if (ledge)
addTile(tiles, world, tx - tileWidth, ty);
if (redge)
addTile(tiles, world, tx + tileWidth, ty);
if (tedge)
addTile(tiles, world, tx, ty - tileHeight);
if (bedge)
addTile(tiles, world, tx, ty + tileHeight);
if (ledge && tedge)
addTile(tiles, world, tx - tileWidth, ty - tileHeight);
if (ledge && bedge)
addTile(tiles, world, tx - tileWidth, ty + tileHeight);
if (redge && tedge)
addTile(tiles, world, tx + tileWidth, ty - tileHeight);
if (redge && bedge)
addTile(tiles, world, tx + tileWidth, ty + tileHeight);
MapTile[] result = new MapTile[tiles.size()];
tiles.toArray(result);
return result;
}
@Override
public MapTile[] getTiles(DynmapWorld world, int minx, int miny, int minz, int maxx, int maxy, int maxz) {
ArrayList<MapTile> tiles = new ArrayList<MapTile>();
/* Transform both to tile coordinates */
int dx = minx - anchorx;
int dy = miny - anchory;
int dz = minz - anchorz;
int px0 = dx + dz;
int py0 = dx - dz - dy;
dx = maxx - anchorx;
dy = maxy - anchory;
dz = maxz - anchorz;
int px1 = dx + dz;
int py1 = dx - dz - dy;
/* Compute ranges */
int mintx = (px1<px0)?px0:px1;
int maxtx = (px1<px0)?px1+1:px0+1;
int minty = (py1<py0)?py0:py1;
int maxty = (py1<py0)?py1+1:py0+1;
/* Now, add the tiles for the ranges - not perfect, but it works (some extra tiles on corners possible) */
for(int i = mintx >> 7; i <= maxtx >> 7; i++) {
for(int j = minty >> 7; j < maxty >> 7; j++) {
addTile(tiles, world, i << 7, j << 7);
}
}
return tiles.toArray(new MapTile[tiles.size()]);
}
@Override
public MapTile[] getAdjecentTiles(MapTile tile) {
if (tile instanceof KzedMapTile) {
KzedMapTile t = (KzedMapTile) tile;
DynmapWorld world = tile.getDynmapWorld();
MapTileRenderer renderer = t.renderer;
return new MapTile[] {
new KzedMapTile(world, this, renderer, t.px - tileWidth, t.py + tileHeight),
new KzedMapTile(world, this, renderer, t.px + tileWidth, t.py - tileHeight),
new KzedMapTile(world, this, renderer, t.px - tileWidth, t.py - tileHeight),
new KzedMapTile(world, this, renderer, t.px + tileWidth, t.py + tileHeight),
new KzedMapTile(world, this, renderer, t.px - tileWidth, t.py),
new KzedMapTile(world, this, renderer, t.px + tileWidth, t.py),
new KzedMapTile(world, this, renderer, t.px, t.py - tileHeight),
new KzedMapTile(world, this, renderer, t.px, t.py + tileHeight) };
}
return new MapTile[0];
}
public void addTile(ArrayList<MapTile> tiles, DynmapWorld world, int px, int py) {
for (int i = 0; i < renderers.length; i++) {
tiles.add(new KzedMapTile(world, this, renderers[i], px, py));
}
}
/**
* 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) {
int xr = x - r0x;
int zr = z - r0z; /* Get position relative to rectangle corner */
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
*/
if((dots1 >= 0) && (dots1 <= (s1x*s1x+s1z*s1z)) &&
(dots2 >= 0) && (dots2 <= (s2x*s2x+s2z*s2z))) {
return true;
}
return false;
}
@Override
public List<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;
int z1 = iz - KzedMap.tileHeight / 2;
int z2 = iz + KzedMap.tileWidth / 2 + KzedMap.tileHeight / 2;
int x, z;
/* Actual pattern of chunks needed is create by the slanted
* square prism corresponding to the render path of the tile.
* Top of prism (corresponding to y=127) is diamond shape from
* ix, iz to ix+64,iz+64 to ix+128,iz to ix+64,iz-64
* Bottom is same shape, offset by -64 on x, +64 on z (net
* 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 outside this are not needed - we scan a simple rectangle
* (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>();
for (x = x1; x < x2; x += 16) {
for (z = z1; z < z2; z += 16) {
/* If any of the chunk corners are inside the rectangle, we need it */
if((!testPointInRectangle(x, z, x1, iz + KzedMap.tileWidth/2,
KzedMap.tileWidth/2, KzedMap.tileHeight/2,
KzedMap.tileWidth, -KzedMap.tileHeight)) &&
(!testPointInRectangle(x+15, z, x1, iz + KzedMap.tileWidth/2,
KzedMap.tileWidth/2, KzedMap.tileHeight/2,
KzedMap.tileWidth, -KzedMap.tileHeight)) &&
(!testPointInRectangle(x+15, z+15, x1, iz + KzedMap.tileWidth/2,
KzedMap.tileWidth/2, KzedMap.tileHeight/2,
KzedMap.tileWidth, -KzedMap.tileHeight)) &&
(!testPointInRectangle(x, z+15, x1, iz + KzedMap.tileWidth/2,
KzedMap.tileWidth/2, KzedMap.tileHeight/2,
KzedMap.tileWidth, -KzedMap.tileHeight)))
continue;
DynmapChunk chunk = new DynmapChunk(x / 16, z / 16);
chunks.add(chunk);
}
}
return chunks;
} else {
return new ArrayList<DynmapChunk>();
}
}
public boolean render(MapChunkCache cache, MapTile tile, File outputFile) {
if (tile instanceof KzedMapTile) {
return ((KzedMapTile) tile).renderer.render(cache, (KzedMapTile) tile, outputFile);
}
return false;
}
/* tile X for position x */
static int tilex(int x) {
if (x < 0)
return x - (tileWidth + (x % tileWidth));
else
return x - (x % tileWidth);
}
/* tile Y for position y */
static int tiley(int y) {
if (y < 0)
return y - (tileHeight + (y % tileHeight));
else
return y - (y % tileHeight);
}
/* zoomed-out tile X for tile position x */
static int ztilex(int x) {
if (x < 0)
return x + x % zTileWidth;
else
return x - (x % zTileWidth);
}
/* zoomed-out tile Y for tile position y */
static int ztiley(int y) {
if (y < 0)
return y + y % zTileHeight;
// return y - (zTileHeight + (y % zTileHeight));
else
return y - (y % zTileHeight);
}
public boolean isBiomeDataNeeded() {
for(MapTileRenderer r : renderers) {
if(r.isBiomeDataNeeded())
return true;
}
return false;
}
public boolean isRawBiomeDataNeeded() {
for(MapTileRenderer r : renderers) {
if(r.isRawBiomeDataNeeded())
return true;
}
return false;
}
public List<ZoomInfo> baseZoomFileInfo() {
ArrayList<ZoomInfo> s = new ArrayList<ZoomInfo>();
for(MapTileRenderer r : renderers) {
s.add(new ZoomInfo("z" + r.getPrefix(), 0));
if(r.isNightAndDayEnabled())
s.add(new ZoomInfo("z" + r.getPrefix() + "_day", 0));
}
return s;
}
public int baseZoomFileStepSize() { return zTileWidth; }
public MapStep zoomFileMapStep() { return MapStep.X_MINUS_Y_PLUS; }
private static final int[] stepseq = { 0, 2, 1, 3 };
public int[] zoomFileStepSequence() { return stepseq; }
/* How many bits of coordinate are shifted off to make big world directory name */
public int getBigWorldShift() { return 12; }
/* Returns true if big world file structure is in effect for this map */
@Override
public boolean isBigWorldMap(DynmapWorld w) {
return w.bigworld || isbigmap;
}
public String getName() {
return "KzedMap";
}
/* Get maps rendered concurrently with this map in this world */
public List<MapType> getMapsSharingRender(DynmapWorld w) {
return Collections.singletonList((MapType)this);
}
/* Get names of maps rendered concurrently with this map type in this world */
public List<String> getMapNamesSharingRender(DynmapWorld w) {
ArrayList<String> lst = new ArrayList<String>();
for(MapTileRenderer rend : renderers) {
if(rend.isNightAndDayEnabled())
lst.add(rend.getName() + "(night/day)");
else
lst.add(rend.getName());
}
return lst;
}
@Override
public void buildClientConfiguration(JSONObject worldObject, DynmapWorld world) {
for(MapTileRenderer renderer : renderers) {
renderer.buildClientConfiguration(worldObject, world, this);
}
}
}

View File

@ -1,133 +0,0 @@
package org.dynmap.kzedmap;
import org.dynmap.DynmapChunk;
import org.dynmap.DynmapWorld;
import org.dynmap.MapManager;
import org.dynmap.MapType;
import java.io.File;
import java.util.List;
import org.dynmap.MapTile;
import org.dynmap.utils.MapChunkCache;
public class KzedMapTile extends MapTile {
public KzedMap map;
public MapTileRenderer renderer;
public int px, py;
private String fname;
private String fname_day;
// Hack.
public File file = null;
public KzedMapTile(DynmapWorld world, KzedMap map, MapTileRenderer renderer, int px, int py) {
super(world);
this.map = map;
this.renderer = renderer;
this.px = px;
this.py = py;
}
public KzedMapTile(DynmapWorld world, String parm) throws Exception {
super(world);
String[] parms = parm.split(",");
if(parms.length < 4) throw new Exception("wrong parameter count");
this.px = Integer.parseInt(parms[0]);
this.py = Integer.parseInt(parms[1]);
for(MapType t : world.maps) {
if(t.getName().equals(parms[2]) && (t instanceof KzedMap)) {
this.map = (KzedMap)t;
break;
}
}
if(this.map == null) throw new Exception("invalid map");
for(MapTileRenderer r : map.renderers) {
if(r.getName().equals(parms[3])) {
this.renderer = r;
break;
}
}
if(this.renderer == null) throw new Exception("invalid renderer");
}
@Override
protected String saveTileData() {
return String.format("%d,%d,%s,%s", px, py, map.getName(), renderer.getName());
}
@Override
public String getFilename() {
if(fname == null) {
if(map.isBigWorldMap(world))
fname = renderer.getPrefix() + "/" + (px >> 12) + '_' + (py >> 12) + '/' + px + "_" + py + ".png";
else
fname = renderer.getPrefix() + "_" + px + "_" + py + ".png";
}
return fname;
}
@Override
public String getDayFilename() {
if(fname_day == null) {
if(map.isBigWorldMap(world))
fname_day = renderer.getPrefix() + "_day/" + (px >> 12) + '_' + (py >> 12) + '/' + px + "_" + py + ".png";
else
fname_day = renderer.getPrefix() + "_day_" + px + "_" + py + ".png";
}
return fname_day;
}
@Override
public int hashCode() {
return px ^ py ^ map.getName().hashCode() ^ world.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof KzedMapTile) {
return equals((KzedMapTile) obj);
}
return false;
}
public boolean equals(KzedMapTile o) {
return o.px == px && o.py == py && (o.map == map) && (o.world == world);
}
public String getKey(String prefix) {
return world.getName() + "." + prefix;
}
public String toString() {
return world.getName() + ":" + getFilename();
}
public boolean render(MapChunkCache cache, String mapname) {
boolean rslt = false;
for(MapTileRenderer r : map.renderers) {
if((mapname == null) || (r.getName().equals(mapname))) {
KzedMapTile t = new KzedMapTile(world, map, r, px, py);
rslt |= map.render(cache, t, MapManager.mapman.getTileFile(t));
}
}
return rslt;
}
public List<DynmapChunk> getRequiredChunks() {
return map.getRequiredChunks(this);
}
public MapTile[] getAdjecentTiles() {
return map.getAdjecentTiles(this);
}
public boolean isBiomeDataNeeded() { return map.isBiomeDataNeeded(); }
public boolean isHightestBlockYDataNeeded() { return false; }
public boolean isRawBiomeDataNeeded() { return map.isRawBiomeDataNeeded(); }
public boolean isBlockTypeDataNeeded() { return true; }
public int tileOrdinalX() { return px >> 7; }
public int tileOrdinalY() { return py >> 7; }
}

View File

@ -1,113 +0,0 @@
package org.dynmap.kzedmap;
import java.util.List;
import org.dynmap.DynmapChunk;
import org.dynmap.DynmapWorld;
import org.dynmap.MapTile;
import org.dynmap.utils.MapChunkCache;
public class KzedZoomedMapTile extends MapTile {
private String fname;
private String fname_day;
@Override
public String getFilename() {
if(fname == null) {
if(world.bigworld)
fname = "z" + originalTile.renderer.getPrefix() + "/" + (getTileX()>>12) + '_' +
(getTileY() >> 12) + '/' + getTileX() + "_" + getTileY() + ".png";
else
fname = "z" + originalTile.renderer.getPrefix() + "_" + getTileX() + "_" + getTileY() + ".png";
}
return fname;
}
@Override
public String getDayFilename() {
if(fname_day == null) {
if(world.bigworld)
fname_day = "z" + originalTile.renderer.getPrefix() + "_day/" + (getTileX()>>12) + '_' +
(getTileY() >> 12) + '/' + getTileX() + "_" + getTileY() + ".png";
else
fname_day = "z" + originalTile.renderer.getPrefix() + "_day_" + getTileX() + "_" + getTileY() + ".png";
}
return fname_day;
}
public KzedMapTile originalTile;
public KzedZoomedMapTile(DynmapWorld world, KzedMapTile original) {
super(world);
this.originalTile = original;
}
@Override
protected String saveTileData() {
return originalTile.saveTileData();
}
public int getTileX() {
return ztilex(originalTile.px + KzedMap.tileWidth);
}
public int getTileY() {
return ztiley(originalTile.py);
}
private static int ztilex(int x) {
if (x < 0)
return x + (x % (KzedMap.tileWidth * 2));
else
return x - (x % (KzedMap.tileWidth * 2));
}
/* zoomed-out tile Y for tile position y */
private static int ztiley(int y) {
if (y < 0)
return y + (y % (KzedMap.tileHeight * 2));
else
return y - (y % (KzedMap.tileHeight * 2));
}
@Override
public int hashCode() {
return getFilename().hashCode() ^ world.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof KzedZoomedMapTile) {
return ((KzedZoomedMapTile) obj).originalTile.equals(originalTile);
}
return false;
}
public String getKey(String prefix) {
return world.getName() + ".z" + prefix;
}
@Override
public boolean render(MapChunkCache cache, String mapname) {
return false;
}
@Override
public List<DynmapChunk> getRequiredChunks() {
return null;
}
@Override
public MapTile[] getAdjecentTiles() {
return null;
}
public boolean isBiomeDataNeeded() { return originalTile.isBiomeDataNeeded(); }
public boolean isHightestBlockYDataNeeded() { return false; }
public boolean isRawBiomeDataNeeded() { return originalTile.isRawBiomeDataNeeded(); }
public boolean isBlockTypeDataNeeded() { return true; }
public int tileOrdinalX() { return originalTile.px >> 8; }
public int tileOrdinalY() { return originalTile.py >> 8; }
}

View File

@ -1,21 +0,0 @@
package org.dynmap.kzedmap;
import java.io.File;
import org.dynmap.DynmapWorld;
import org.dynmap.utils.MapChunkCache;
import org.json.simple.JSONObject;
public interface MapTileRenderer {
String getPrefix();
String getName();
boolean render(MapChunkCache cache, KzedMapTile tile, File outputFile);
void buildClientConfiguration(JSONObject worldObject, DynmapWorld w, KzedMap map);
boolean isBiomeDataNeeded();
boolean isRawBiomeDataNeeded();
boolean isNightAndDayEnabled();
}

View File

@ -1,332 +0,0 @@
package org.dynmap.markers.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dynmap.ConfigurationNode;
import org.dynmap.markers.AreaMarker;
import org.dynmap.markers.MarkerSet;
import org.dynmap.markers.impl.MarkerAPIImpl.MarkerUpdate;
class AreaMarkerImpl implements AreaMarker {
private String markerid;
private String label;
private boolean markup;
private String desc;
private MarkerSetImpl markerset;
private String world;
private boolean ispersistent;
private ArrayList<Coord> corners;
private int lineweight = 3;
private double lineopacity = 0.8;
private int linecolor = 0xFF0000;
private double fillopacity = 0.35;
private int fillcolor = 0xFF0000;
private double ytop = 64.0;
private double ybottom = 64.0;
private static class Coord {
double x, z;
Coord(double x, double z) {
this.x = x; this.z = z;
}
}
/**
* Create area marker
* @param id - marker ID
* @param lbl - label
* @param markup - if true, label is HTML markup
* @param world - world id
* @param x - x coord list
* @param z - z coord list
* @param persistent - true if persistent
* @param set - marker set
*/
AreaMarkerImpl(String id, String lbl, boolean markup, String world, double x[], double z[], boolean persistent, MarkerSetImpl set) {
markerid = id;
if(lbl != null)
label = lbl;
else
label = id;
this.markup = markup;
this.corners = new ArrayList<Coord>();
for(int i = 0; i < x.length; i++) {
this.corners.add(new Coord(x[i], z[i]));
}
this.world = world;
this.desc = null;
ispersistent = persistent;
markerset = set;
}
/**
* Make bare area marker - used for persistence load
* @param id - marker ID
* @param set - marker set
*/
AreaMarkerImpl(String id, MarkerSetImpl set) {
markerid = id;
markerset = set;
label = id;
markup = false;
desc = null;
corners = new ArrayList<Coord>();
world = "world";
}
/**
* Load marker from configuration node
* @param node - configuration node
*/
boolean loadPersistentData(ConfigurationNode node) {
label = node.getString("label", markerid);
markup = node.getBoolean("markup", false);
ytop = node.getDouble("ytop", 64.0);
ybottom = node.getDouble("ybottom", 64.0);
List<Double> xx = node.getList("x");
List<Double> zz = node.getList("z");
corners.clear();
if((xx != null) && (zz != null)) {
for(int i = 0; (i < xx.size()) && (i < zz.size()); i++)
corners.add(new Coord(xx.get(i), zz.get(i)));
}
world = node.getString("world", "world");
desc = node.getString("desc", null);
lineweight = node.getInteger("strokeWeight", 3);
lineopacity = node.getDouble("strokeOpacity", 0.8);
linecolor = node.getInteger("strokeColor", 0xFF0000);
fillopacity = node.getDouble("fillOpacity", 0.35);
fillcolor = node.getInteger("fillColor", 0xFF0000);
ispersistent = true; /* Loaded from config, so must be */
return true;
}
void cleanup() {
corners.clear();
markerset = null;
}
@Override
public String getMarkerID() {
return markerid;
}
@Override
public MarkerSet getMarkerSet() {
return markerset;
}
@Override
public void deleteMarker() {
markerset.removeAreaMarker(this); /* Remove from our marker set (notified by set) */
cleanup();
}
@Override
public boolean isPersistentMarker() {
return ispersistent;
}
@Override
public String getLabel() {
return label;
}
@Override
public void setLabel(String lbl) {
setLabel(lbl, false);
}
@Override
public void setLabel(String lbl, boolean markup) {
label = lbl;
this.markup = markup;
MarkerAPIImpl.areaMarkerUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
/**
* Get configuration node to be saved
* @return node
*/
Map<String, Object> getPersistentData() {
if(!ispersistent) /* Nothing if not persistent */
return null;
HashMap<String, Object> node = new HashMap<String, Object>();
node.put("label", label);
node.put("markup", markup);
List<Double> xx = new ArrayList<Double>();
List<Double> zz = new ArrayList<Double>();
for(int i = 0; i < corners.size(); i++) {
xx.add(corners.get(i).x);
zz.add(corners.get(i).z);
}
node.put("x", xx);
node.put("ytop", Double.valueOf(ytop));
node.put("ybottom", Double.valueOf(ybottom));
node.put("z", zz);
node.put("world", world);
if(desc != null)
node.put("desc", desc);
node.put("stokeWeight", lineweight);
node.put("strokeOpacity", lineopacity);
node.put("strokeColor", linecolor);
node.put("fillOpacity", fillopacity);
node.put("fillColor", fillcolor);
return node;
}
@Override
public String getWorld() {
return world;
}
@Override
public boolean isLabelMarkup() {
return markup;
}
@Override
public void setDescription(String desc) {
if((this.desc == null) || (this.desc.equals(desc) == false)) {
this.desc = desc;
MarkerAPIImpl.areaMarkerUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
}
/**
* Get marker description
* @return descrption
*/
public String getDescription() {
return this.desc;
}
@Override
public double getTopY() {
return ytop;
}
@Override
public double getBottomY() {
return ybottom;
}
@Override
public void setRangeY(double ytop, double ybottom) {
if((this.ytop != ytop) || (this.ybottom != ybottom)) {
this.ytop = ytop;
this.ybottom = ybottom;
MarkerAPIImpl.areaMarkerUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
}
@Override
public int getCornerCount() {
return corners.size();
}
@Override
public double getCornerX(int n) {
Coord c = corners.get(n);
if(c != null)
return c.x;
return 0;
}
@Override
public double getCornerZ(int n) {
Coord c = corners.get(n);
if(c != null)
return c.z;
return 0;
}
@Override
public void setCornerLocation(int n, double x, double z) {
Coord c;
if(n >= corners.size()) {
corners.add(new Coord(x, z));
}
else {
c = corners.get(n);
if((c.x == x) && (c.z == z))
return;
c.x = x;
c.z = z;
}
MarkerAPIImpl.areaMarkerUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
@Override
public void deleteCorner(int n) {
if(n < corners.size()) {
corners.remove(n);
MarkerAPIImpl.areaMarkerUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
}
@Override
public void setCornerLocations(double[] x, double[] z) {
/* Check if equals */
if(x.length == corners.size()) {
boolean match = true;
for(int i = 0; i < x.length; i++) {
Coord c = corners.get(i);
if((c.x != x[i]) || (c.z != z[i])) {
match = false;
break;
}
}
if(match)
return;
}
corners.clear();
for(int i = 0; (i < x.length) && (i < z.length); i++) {
corners.add(new Coord(x[i], z[i]));
}
MarkerAPIImpl.areaMarkerUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
@Override
public void setLineStyle(int weight, double opacity, int color) {
if((weight != lineweight) || (opacity != lineopacity) || (color != linecolor)) {
lineweight = weight;
lineopacity = opacity;
linecolor = color;
MarkerAPIImpl.areaMarkerUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
}
@Override
public int getLineWeight() {
return lineweight;
}
@Override
public double getLineOpacity() {
return lineopacity;
}
@Override
public int getLineColor() {
return linecolor;
}
@Override
public void setFillStyle(double opacity, int color) {
if((opacity != fillopacity) || (color != fillcolor)) {
fillopacity = opacity;
fillcolor = color;
MarkerAPIImpl.areaMarkerUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
}
@Override
public double getFillOpacity() {
return fillopacity;
}
@Override
public int getFillColor() {
return fillcolor;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,101 +0,0 @@
package org.dynmap.markers.impl;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.dynmap.ConfigurationNode;
import org.dynmap.markers.MarkerIcon;
class MarkerIconImpl implements MarkerIcon {
private String iconid;
private String label;
private boolean is_builtin;
private MarkerSize size = MarkerSize.MARKER_16x16;
MarkerIconImpl(String id) {
iconid = id;
label = id;
is_builtin = false;
}
MarkerIconImpl(String id, String lbl, boolean is_builtin) {
iconid = id;
if(lbl != null)
label = lbl;
else
label = id;
this.is_builtin = is_builtin;
}
void cleanup() {
}
@Override
public String getMarkerIconID() {
return iconid;
}
@Override
public String getMarkerIconLabel() {
return label;
}
@Override
public void setMarkerIconLabel(String lbl) {
if(lbl == null) lbl = iconid;
if(label.equals(lbl) == false) {
label = lbl;
MarkerAPIImpl.saveMarkers();
}
}
@Override
public void setMarkerIconImage(InputStream in) {
if(MarkerAPIImpl.api.loadMarkerIconStream(this.iconid, in))
MarkerAPIImpl.api.publishMarkerIcon(this);
}
@Override
public void deleteIcon() {
MarkerAPIImpl.removeIcon(this);
}
@Override
public boolean isBuiltIn() {
return is_builtin;
}
/**
* Get configuration node to be saved
* @return node
*/
Map<String, Object> getPersistentData() {
if(is_builtin)
return null;
HashMap<String, Object> node = new HashMap<String, Object>();
node.put("label", label);
return node;
}
boolean loadPersistentData(ConfigurationNode node) {
if(is_builtin)
return false;
label = node.getString("label", iconid);
return true;
}
@Override
public MarkerSize getMarkerIconSize() {
return size;
}
void setMarkerIconSize(MarkerSize sz) {
size = sz;
}
}

View File

@ -1,217 +0,0 @@
package org.dynmap.markers.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.dynmap.ConfigurationNode;
import org.dynmap.markers.Marker;
import org.dynmap.markers.MarkerIcon;
import org.dynmap.markers.MarkerSet;
import org.dynmap.markers.impl.MarkerAPIImpl.MarkerUpdate;
class MarkerImpl implements Marker {
private String markerid;
private String label;
private boolean markup;
private String desc;
private MarkerSetImpl markerset;
private double x, y, z;
private String world;
private MarkerIconImpl icon;
private boolean ispersistent;
/**
* Create marker
* @param id - marker ID
* @param lbl - label
* @param markup - if true, label is HTML markup
* @param world - world id
* @param x - x coord
* @param y - y coord
* @param z - z coord
* @param icon - marker icon
* @param persistent - true if persistent
*/
MarkerImpl(String id, String lbl, boolean markup, String world, double x, double y, double z, MarkerIconImpl icon, boolean persistent, MarkerSetImpl set) {
markerid = id;
if(lbl != null)
label = lbl;
else
label = id;
this.markup = markup;
this.x = x; this.y = y; this.z = z;
this.world = world;
this.icon = icon;
this.desc = null;
ispersistent = persistent;
markerset = set;
}
/**
* Make bare marker - used for persistence load
* @param id - marker ID
* @param set - marker set
*/
MarkerImpl(String id, MarkerSetImpl set) {
markerid = id;
markerset = set;
label = id;
markup = false;
desc = null;
x = z = 0; y = 64; world = "world";
icon = MarkerAPIImpl.getMarkerIconImpl(MarkerIcon.DEFAULT);
}
/**
* Load marker from configuration node
* @param node - configuration node
*/
boolean loadPersistentData(ConfigurationNode node) {
label = node.getString("label", markerid);
markup = node.getBoolean("markup", false);
x = node.getDouble("x", 0);
y = node.getDouble("y", 64);
z = node.getDouble("z", 0);
world = node.getString("world", "world");
desc = node.getString("desc", null);
icon = MarkerAPIImpl.getMarkerIconImpl(node.getString("icon", MarkerIcon.DEFAULT));
ispersistent = true; /* Loaded from config, so must be */
return true;
}
void cleanup() {
icon = null;
markerset = null;
}
@Override
public String getMarkerID() {
return markerid;
}
@Override
public MarkerSet getMarkerSet() {
return markerset;
}
@Override
public void deleteMarker() {
markerset.removeMarker(this); /* Remove from our marker set (notified by set) */
cleanup();
}
@Override
public MarkerIcon getMarkerIcon() {
return icon;
}
@Override
public boolean setMarkerIcon(MarkerIcon icon) {
if(!(icon instanceof MarkerIconImpl)) {
return false;
}
/* Check if icons restricted for this set */
Set<MarkerIcon> icns = markerset.getAllowedMarkerIcons();
if((icns != null) && (icns.contains(icon) == false)) {
return false;
}
this.icon = (MarkerIconImpl)icon;
MarkerAPIImpl.markerUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
return true;
}
@Override
public boolean isPersistentMarker() {
return ispersistent;
}
@Override
public String getLabel() {
return label;
}
@Override
public void setLabel(String lbl) {
setLabel(lbl, false);
}
@Override
public void setLabel(String lbl, boolean markup) {
label = lbl;
this.markup = markup;
MarkerAPIImpl.markerUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
/**
* Get configuration node to be saved
* @return node
*/
Map<String, Object> getPersistentData() {
if(!ispersistent) /* Nothing if not persistent */
return null;
HashMap<String, Object> node = new HashMap<String, Object>();
node.put("label", label);
node.put("markup", markup);
node.put("x", Double.valueOf(x));
node.put("y", Double.valueOf(y));
node.put("z", Double.valueOf(z));
node.put("world", world);
node.put("icon", icon.getMarkerIconID());
if(desc != null)
node.put("desc", desc);
return node;
}
@Override
public String getWorld() {
return world;
}
@Override
public double getX() {
return x;
}
@Override
public double getY() {
return y;
}
@Override
public double getZ() {
return z;
}
@Override
public void setLocation(String worldid, double x, double y, double z) {
this.world = worldid;
this.x = x;
this.y = y;
this.z = z;
MarkerAPIImpl.markerUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
@Override
public boolean isLabelMarkup() {
return markup;
}
@Override
public void setDescription(String desc) {
if((this.desc == null) || (this.desc.equals(desc) == false)) {
this.desc = desc;
MarkerAPIImpl.markerUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
}
/**
* Get marker description
* @return descrption
*/
public String getDescription() {
return this.desc;
}
}

View File

@ -1,389 +0,0 @@
package org.dynmap.markers.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.dynmap.ConfigurationNode;
import org.dynmap.Log;
import org.dynmap.markers.AreaMarker;
import org.dynmap.markers.Marker;
import org.dynmap.markers.MarkerIcon;
import org.dynmap.markers.MarkerSet;
import org.dynmap.markers.impl.MarkerAPIImpl.MarkerUpdate;
class MarkerSetImpl implements MarkerSet {
private HashMap<String, MarkerImpl> markers = new HashMap<String, MarkerImpl>();
private HashMap<String, AreaMarkerImpl> areamarkers = new HashMap<String, AreaMarkerImpl>();
private String setid;
private String label;
private HashMap<String, MarkerIconImpl> allowedicons = null;
private boolean hide_by_def;
private boolean ispersistent;
private int prio = 0;
private int minzoom = 0;
MarkerSetImpl(String id) {
setid = id;
label = id;
}
MarkerSetImpl(String id, String lbl, Set<MarkerIcon> iconlimit, boolean persistent) {
setid = id;
if(lbl != null)
label = lbl;
else
label = id;
if(iconlimit != null) {
allowedicons = new HashMap<String, MarkerIconImpl>();
for(MarkerIcon ico : iconlimit) {
if(ico instanceof MarkerIconImpl) {
allowedicons.put(ico.getMarkerIconID(), (MarkerIconImpl)ico);
}
}
}
ispersistent = persistent;
}
void cleanup() {
for(MarkerImpl m : markers.values())
m.cleanup();
for(AreaMarkerImpl m : areamarkers.values())
m.cleanup();
markers.clear();
}
@Override
public Set<Marker> getMarkers() {
return new HashSet<Marker>(markers.values());
}
@Override
public Set<AreaMarker> getAreaMarkers() {
return new HashSet<AreaMarker>(areamarkers.values());
}
@Override
public Marker createMarker(String id, String label, String world, double x, double y, double z, MarkerIcon icon, boolean is_persistent) {
return createMarker(id, label, false, world, x, y, z, icon, is_persistent);
}
@Override
public Marker createMarker(String id, String label, boolean markup, String world, double x, double y, double z, MarkerIcon icon, boolean is_persistent) {
if(id == null) { /* If not defined, generate unique one */
int i = 0;
do {
i++;
id = "marker_" + i;
} while(markers.containsKey(id));
}
if(markers.containsKey(id)) return null; /* Duplicate ID? */
if(!(icon instanceof MarkerIconImpl)) return null;
/* If limited icons, and this isn't valid one, quit */
if((allowedicons != null) && (allowedicons.containsKey(icon.getMarkerIconID()) == false)) return null;
/* Create marker */
is_persistent = is_persistent && this.ispersistent;
MarkerImpl marker = new MarkerImpl(id, label, markup, world, x, y, z, (MarkerIconImpl)icon, is_persistent, this);
markers.put(id, marker); /* Add to set */
if(is_persistent)
MarkerAPIImpl.saveMarkers();
MarkerAPIImpl.markerUpdated(marker, MarkerUpdate.CREATED); /* Signal create */
return marker;
}
@Override
public Marker findMarker(String id) {
return markers.get(id);
}
@Override
public Marker findMarkerByLabel(String lbl) {
Marker match = null;
int matchlen = Integer.MAX_VALUE;
for(Marker m : markers.values()) {
if(m.getLabel().contains(lbl)) {
if(matchlen > m.getLabel().length()) {
match = m;
matchlen = m.getLabel().length();
}
}
}
return match;
}
@Override
public String getMarkerSetID() {
return setid;
}
@Override
public String getMarkerSetLabel() {
return label;
}
@Override
public void setMarkerSetLabel(String lbl) {
label = lbl;
MarkerAPIImpl.markerSetUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
@Override
public boolean isMarkerSetPersistent() {
return ispersistent;
}
@Override
public Set<MarkerIcon> getAllowedMarkerIcons() {
if(allowedicons != null)
return new HashSet<MarkerIcon>(allowedicons.values());
else
return null;
}
@Override
public void addAllowedMarkerIcon(MarkerIcon icon) {
if(!(icon instanceof MarkerIconImpl)) return;
if(allowedicons == null) return;
allowedicons.put(icon.getMarkerIconID(), (MarkerIconImpl)icon);
MarkerAPIImpl.markerSetUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
@Override
public void removeAllowedMarkerIcon(MarkerIcon icon) {
if(!(icon instanceof MarkerIconImpl)) return;
if(allowedicons == null) return;
allowedicons.remove(icon.getMarkerIconID());
MarkerAPIImpl.markerSetUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
@Override
public boolean isAllowedMarkerIcon(MarkerIcon icon) {
if(allowedicons == null) return true;
return allowedicons.containsKey(icon.getMarkerIconID());
}
@Override
public Set<MarkerIcon> getMarkerIconsInUse() {
HashSet<String> ids = new HashSet<String>();
HashSet<MarkerIcon> icons = new HashSet<MarkerIcon>();
for(Marker m : markers.values()) {
MarkerIcon mi = m.getMarkerIcon();
if(!ids.contains(mi.getMarkerIconID())) {
ids.add(mi.getMarkerIconID());
icons.add(mi);
}
}
return icons;
}
@Override
public void deleteMarkerSet() {
MarkerAPIImpl.removeMarkerSet(this); /* Remove from top level sets (notification from there) */
if(ispersistent)
MarkerAPIImpl.saveMarkers();
cleanup();
}
/**
* Remove marker from set
*
* @param marker
*/
void removeMarker(MarkerImpl marker) {
markers.remove(marker.getMarkerID()); /* Remove from set */
if(ispersistent && marker.isPersistentMarker()) { /* If persistent */
MarkerAPIImpl.saveMarkers(); /* Drive save */
}
MarkerAPIImpl.markerUpdated(marker, MarkerUpdate.DELETED);
}
/**
* Remove marker from set
*
* @param marker
*/
void removeAreaMarker(AreaMarkerImpl marker) {
areamarkers.remove(marker.getMarkerID()); /* Remove from set */
if(ispersistent && marker.isPersistentMarker()) { /* If persistent */
MarkerAPIImpl.saveMarkers(); /* Drive save */
}
MarkerAPIImpl.areaMarkerUpdated(marker, MarkerUpdate.DELETED);
}
/**
* Get configuration node to be saved
* @return node
*/
Map<String, Object> getPersistentData() {
if(!ispersistent) /* Nothing if not persistent */
return null;
HashMap<String, Object> node = new HashMap<String, Object>();
for(String id : markers.keySet()) {
MarkerImpl m = markers.get(id);
if(m.isPersistentMarker()) {
node.put(id, m.getPersistentData());
}
}
HashMap<String, Object> anode = new HashMap<String, Object>();
for(String id : areamarkers.keySet()) {
AreaMarkerImpl m = areamarkers.get(id);
if(m.isPersistentMarker()) {
anode.put(id, m.getPersistentData());
}
}
/* Make top level node */
HashMap<String, Object> setnode = new HashMap<String, Object>();
setnode.put("label", label);
if(allowedicons != null) {
ArrayList<String> allowed = new ArrayList<String>(allowedicons.keySet());
setnode.put("allowedicons", allowed);
}
setnode.put("markers", node);
setnode.put("areas", anode);
setnode.put("hide", hide_by_def);
setnode.put("layerprio", prio);
setnode.put("minzoom", minzoom);
return setnode;
}
/**
* Load marker from configuration node
* @param node - configuration node
*/
boolean loadPersistentData(ConfigurationNode node) {
label = node.getString("label", setid); /* Get label */
ConfigurationNode markernode = node.getNode("markers");
if(markernode != null) {
for(String id : markernode.keySet()) {
MarkerImpl marker = new MarkerImpl(id, this); /* Make and load marker */
if(marker.loadPersistentData(markernode.getNode(id))) {
markers.put(id, marker);
}
else {
Log.info("Error loading marker '" + id + "' for set '" + setid + "'");
marker.cleanup();
}
}
}
ConfigurationNode areamarkernode = node.getNode("areas");
if(areamarkernode != null) {
for(String id : areamarkernode.keySet()) {
AreaMarkerImpl marker = new AreaMarkerImpl(id, this); /* Make and load marker */
if(marker.loadPersistentData(areamarkernode.getNode(id))) {
areamarkers.put(id, marker);
}
else {
Log.info("Error loading area marker '" + id + "' for set '" + setid + "'");
marker.cleanup();
}
}
}
List<String> allowed = node.getList("allowedicons");
if(allowed != null) {
for(String id : allowed) {
MarkerIconImpl icon = MarkerAPIImpl.getMarkerIconImpl(id);
if(icon != null)
allowedicons.put(id, icon);
else
Log.info("Error loading allowed icon '" + id + "' for set '" + setid + "'");
}
}
hide_by_def = node.getBoolean("hide", false);
prio = node.getInteger("layerprio", 0);
minzoom = node.getInteger("minzoom", 0);
ispersistent = true;
return true;
}
@Override
public void setHideByDefault(boolean hide) {
if(hide_by_def != hide) {
hide_by_def = hide;
MarkerAPIImpl.markerSetUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
}
@Override
public boolean getHideByDefault() {
return hide_by_def;
}
@Override
public void setLayerPriority(int prio) {
if(this.prio != prio) {
this.prio = prio;
MarkerAPIImpl.markerSetUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
}
@Override
public int getLayerPriority() {
return this.prio;
}
@Override
public AreaMarker createAreaMarker(String id, String lbl, boolean markup, String world, double[] x, double[] z, boolean persistent) {
if(id == null) { /* If not defined, generate unique one */
int i = 0;
do {
i++;
id = "area_" + i;
} while(areamarkers.containsKey(id));
}
if(areamarkers.containsKey(id)) return null; /* Duplicate ID? */
/* Create marker */
persistent = persistent && this.ispersistent;
AreaMarkerImpl marker = new AreaMarkerImpl(id, lbl, markup, world, x, z, persistent, this);
areamarkers.put(id, marker); /* Add to set */
if(persistent)
MarkerAPIImpl.saveMarkers();
MarkerAPIImpl.areaMarkerUpdated(marker, MarkerUpdate.CREATED); /* Signal create */
return marker;
}
@Override
public AreaMarker findAreaMarker(String id) {
return areamarkers.get(id);
}
@Override
public AreaMarker findAreaMarkerByLabel(String lbl) {
AreaMarker match = null;
int matchlen = Integer.MAX_VALUE;
for(AreaMarker m : areamarkers.values()) {
if(m.getLabel().contains(lbl)) {
if(matchlen > m.getLabel().length()) {
match = m;
matchlen = m.getLabel().length();
}
}
}
return match;
}
@Override
public void setMinZoom(int minzoom) {
if(this.minzoom != minzoom) {
this.minzoom = minzoom;
MarkerAPIImpl.markerSetUpdated(this, MarkerUpdate.UPDATED);
if(ispersistent)
MarkerAPIImpl.saveMarkers();
}
}
@Override
public int getMinZoom() {
return this.minzoom;
}
}

View File

@ -1,127 +0,0 @@
package org.dynmap.markers.impl;
import java.util.Set;
import org.dynmap.DynmapCore;
import org.dynmap.common.DynmapChatColor;
import org.dynmap.common.DynmapListenerManager;
import org.dynmap.common.DynmapListenerManager.EventType;
import org.dynmap.common.DynmapPlayer;
import org.dynmap.markers.Marker;
import org.dynmap.markers.MarkerIcon;
import org.dynmap.markers.MarkerSet;
public class MarkerSignManager {
private static MarkerSignManager mgr = null;
private static DynmapCore plugin = null;
private static final int SIGNPOST_ID = 63;
private static final int WALLSIGN_ID = 68;
private static class SignListener implements DynmapListenerManager.BlockEventListener, DynmapListenerManager.SignChangeEventListener {
@Override
public void signChangeEvent(int blkid, String wname, int x, int y, int z, String[] lines, DynmapPlayer p) {
if(mgr == null)
return;
if(!lines[0].equalsIgnoreCase("[dynmap]")) { /* If not dynmap sign, quit */
return;
}
/* If allowed to do marker signs */
if((p == null) || ((plugin != null) && (plugin.checkPlayerPermission(p, "marker.sign")))) {
String id = getSignMarkerID(wname, x, y, z); /* Get marker ID */
String set = MarkerSet.DEFAULT;
String icon = MarkerIcon.SIGN;
String label = "";
lines[0] = ""; /* Blank out [dynmap] */
for(int i = 1; i < 4; i++) { /* Check other lines for icon: or set: */
String v = plugin.getServer().stripChatColor(lines[i]);
if(v.startsWith("icon:")) { /* icon: */
icon = v.substring(5);
lines[i] = "";
}
else if(v.startsWith("set:")) { /* set: */
set = v.substring(4);
lines[i] = "";
}
else if(v.length() > 0) {
if(label.length() > 0) {
label = label + "<br/>";
}
label = label + escapeMarkup(v);
}
}
/* Get the set and see if the marker is already defined */
MarkerSet ms = MarkerAPIImpl.api.getMarkerSet(set);
if(ms == null) {
if(p != null) p.sendMessage("Bad marker set - [dynmap] sign invalid");
lines[0] = DynmapChatColor.RED + "<Bad Marker Set>";
return;
}
MarkerIcon mi = MarkerAPIImpl.api.getMarkerIcon(icon); /* Get icon */
if(mi == null) {
if(p != null) p.sendMessage("Bad marker icon - [dynmap] sign invalid");
lines[0] = DynmapChatColor.RED + "<Bad Marker Icon>";
return;
}
Marker marker = ms.findMarker(id);
/* If exists, update it */
if(marker != null) {
marker.setLabel(label, true);
marker.setMarkerIcon(mi);
}
else { /* Make new marker */
marker = ms.createMarker(id, label, true, wname, (double)x + 0.5, (double)y + 0.5, (double)z + 0.5,
mi, true);
if(marker == null) {
if(p != null) p.sendMessage("Bad marker - [dynmap] sign invalid");
lines[0] = DynmapChatColor.RED + "<Bad Marker>";
return;
}
}
}
}
@Override
public void blockEvent(int blkid, String wname, int x, int y, int z) {
if(mgr == null)
return;
if((blkid == WALLSIGN_ID) || (blkid == SIGNPOST_ID)) { /* If sign */
String id = getSignMarkerID(wname, x, y, z); /* Marker sign? */
Set<MarkerSet> sets = MarkerAPIImpl.api.getMarkerSets();
for(MarkerSet ms : sets) {
Marker marker = ms.findMarker(id); /* See if in this set */
if(marker != null) {
marker.deleteMarker();
}
}
}
}
}
private static SignListener sl = null; /* Do once - /dynmap reload doesn't reset listeners */
private static String escapeMarkup(String v) {
v = v.replace("&", "&amp;");
v = v.replace("\"", "&quote;");
v = v.replace("<", "&lt;");
v = v.replace(">", "&gt;");
return v;
}
public static MarkerSignManager initializeSignManager(DynmapCore plugin) {
mgr = new MarkerSignManager();
if(sl == null) {
sl = new SignListener();
plugin.listenerManager.addListener(EventType.BLOCK_BREAK, sl);
plugin.listenerManager.addListener(EventType.SIGN_CHANGE, sl);
}
MarkerSignManager.plugin = plugin;
return mgr;
}
public static void terminateSignManager(DynmapCore plugin) {
mgr = null;
}
private static String getSignMarkerID(String wname, int x, int y, int z) {
return "_sign_" + wname + "_" + x + "_" + y + "_" + z;
}
}

View File

@ -1,23 +0,0 @@
package org.dynmap.regions;
import org.dynmap.Component;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapCore;
import org.dynmap.Log;
public class RegionsComponent extends Component {
private static String deprecated_ids[] = { "Residence", "Factions", "Towny", "WorldGuard" };
private static String deprecated_new_plugins[] = { "dynmap-residence", "Dynmap-Factions", "Dynmap-Towny", "Dynmap-WorldGuard" };
public RegionsComponent(final DynmapCore plugin, final ConfigurationNode configuration) {
super(plugin, configuration);
String regiontype = configuration.getString("name", "WorldGuard");
/* Check if a deprecated component */
for(int i = 0; i < deprecated_ids.length; i++) {
if(regiontype.equals(deprecated_ids[i])) { /* If match */
Log.info("Region component for '" + regiontype + "' has been RETIRED - migrate to '" + deprecated_new_plugins[i] + "' plugin");
}
}
}
}

View File

@ -1,55 +0,0 @@
package org.dynmap.servlet;
import java.io.IOException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dynmap.DynmapCore;
import org.dynmap.DynmapWorld;
import org.dynmap.Event;
import org.json.simple.JSONObject;
public class ClientConfigurationServlet extends HttpServlet {
private static final long serialVersionUID = 9106801553080522469L;
private DynmapCore plugin;
private byte[] cachedConfiguration = null;
private int cached_config_hashcode = 0;
public ClientConfigurationServlet(DynmapCore plugin) {
this.plugin = plugin;
plugin.events.addListener("worldactivated", new Event.Listener<DynmapWorld>() {
@Override
public void triggered(DynmapWorld t) {
cachedConfiguration = null;
}
});
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
byte[] outputBytes = cachedConfiguration;
if ((outputBytes == null) || (cached_config_hashcode != plugin.getConfigHashcode())) {
JSONObject json = new JSONObject();
plugin.events.<JSONObject>trigger("buildclientconfiguration", json);
String s = json.toJSONString();
outputBytes = s.getBytes("UTF-8");
}
if (outputBytes != null) {
cachedConfiguration = outputBytes;
cached_config_hashcode = plugin.getConfigHashcode();
}
String dateStr = new Date().toString();
res.addHeader("Date", dateStr);
res.setContentType("text/plain; charset=utf-8");
res.addHeader("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
res.addHeader("Last-modified", dateStr);
res.setContentLength(outputBytes.length);
res.getOutputStream().write(outputBytes);
}
}

View File

@ -1,74 +0,0 @@
package org.dynmap.servlet;
import static org.dynmap.JSONUtils.s;
import java.io.IOException;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dynmap.ClientUpdateEvent;
import org.dynmap.DynmapCore;
import org.dynmap.DynmapWorld;
import org.dynmap.web.HttpField;
import org.json.simple.JSONObject;
@SuppressWarnings("serial")
public class ClientUpdateServlet extends HttpServlet {
private DynmapCore plugin;
public ClientUpdateServlet(DynmapCore plugin) {
this.plugin = plugin;
}
Pattern updatePathPattern = Pattern.compile("/([^/]+)/([0-9]*)");
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path = req.getPathInfo();
Matcher match = updatePathPattern.matcher(path);
if (!match.matches()) {
resp.sendError(404, "World not found");
return;
}
String worldName = match.group(1);
String timeKey = match.group(2);
DynmapWorld dynmapWorld = null;
if(plugin.mapManager != null) {
dynmapWorld = plugin.mapManager.getWorld(worldName);
}
if (dynmapWorld == null || !dynmapWorld.isLoaded()) {
resp.sendError(404, "World not found");
return;
}
long current = System.currentTimeMillis();
long since = 0;
try {
since = Long.parseLong(timeKey);
} catch (NumberFormatException e) {
}
JSONObject u = new JSONObject();
s(u, "timestamp", current);
plugin.events.trigger("buildclientupdate", new ClientUpdateEvent(since, dynmapWorld, u));
byte[] bytes = u.toJSONString().getBytes("UTF-8");
String dateStr = new Date().toString();
resp.addHeader(HttpField.Date, dateStr);
resp.addHeader(HttpField.ContentType, "text/plain; charset=utf-8");
resp.addHeader(HttpField.Expires, "Thu, 01 Dec 1994 16:00:00 GMT");
resp.addHeader(HttpField.LastModified, dateStr);
resp.addHeader(HttpField.ContentLength, Integer.toString(bytes.length));
resp.getOutputStream().write(bytes);
}
}

View File

@ -1,579 +0,0 @@
/*
* net/balusc/webapp/FileServlet.java
*
* Copyright (C) 2009 BalusC
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU Lesser General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library.
* If not, see <http://www.gnu.org/licenses/>.
*/
package org.dynmap.servlet;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.URLDecoder;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* A file servlet supporting resume of downloads and client-side caching and GZIP of text content.
* This servlet can also be used for images, client-side caching would become more efficient.
* This servlet can also be used for text files, GZIP would decrease network bandwidth.
*
* @author BalusC
* @link http://balusc.blogspot.com/2009/02/fileservlet-supporting-resume-and.html
*/
@SuppressWarnings("serial")
public class FileServlet extends HttpServlet {
// Constants ----------------------------------------------------------------------------------
private static final int DEFAULT_BUFFER_SIZE = 10240; // ..bytes = 10KB.
private static final String MULTIPART_BOUNDARY = "MULTIPART_BYTERANGES";
// Properties ---------------------------------------------------------------------------------
private String basePath = null;
private boolean allow_symlinks = true;
private String[] indexFiles = new String[] {
"index.html"
};
// Actions ------------------------------------------------------------------------------------
public FileServlet() {
}
public FileServlet(String basePath, boolean allow_symlinks) {
this.basePath = new File(basePath).getAbsolutePath();
this.allow_symlinks = allow_symlinks;
}
/**
* Initialize the servlet.
* @see HttpServlet#init().
*/
public void init() throws ServletException {
if (basePath == null) {
setBasePath(new File(getServletContext().getRealPath(getInitParameter("basePath"))).getAbsolutePath());
}
}
public void setBasePath(String basePath) {
// Validate base path.
if (basePath == null) {
throw new InvalidParameterException("'basePath' is required.");
} else {
File path = new File(basePath);
if (!path.exists()) {
throw new InvalidParameterException("'basePath' value '"
+ basePath + "' does actually not exist in file system.");
} else if (!path.isDirectory()) {
throw new InvalidParameterException("'basePath' value '"
+ basePath + "' is actually not a directory in file system.");
} else if (!path.canRead()) {
throw new InvalidParameterException("'basePath' value '"
+ basePath + "' is actually not readable in file system.");
}
}
this.basePath = basePath;
}
/**
* Process HEAD request. This returns the same headers as GET request, but without content.
* @see HttpServlet#doHead(HttpServletRequest, HttpServletResponse).
*/
protected void doHead(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
// Process request without content.
processRequest(request, response, false);
}
/**
* Process GET request.
* @see HttpServlet#doGet(HttpServletRequest, HttpServletResponse).
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
// Process request with content.
processRequest(request, response, true);
}
private static String getNormalizedPath(String p) {
p = p.replace('\\', '/');
String[] tok = p.split("/");
int i, j;
for(i = 0, j = 0; i < tok.length; i++) {
if((tok[i] == null) || (tok[i].length() == 0) || (tok[i].equals("."))) {
tok[i] = null;
}
else if(tok[i].equals("..")) {
if(j > 0) { j--; tok[j] = null; }
tok[i] = null;
}
else {
tok[j] = tok[i];
j++;
}
}
String path = "";
for(i = 0; i < j; i++) {
if(tok[i] != null)
path = path + "/" + tok[i];
}
return path;
}
/**
* Process the actual request.
* @param request The request to be processed.
* @param response The response to be created.
* @param content Whether the request body should be written (GET) or not (HEAD).
* @throws IOException If something fails at I/O level.
*/
private void processRequest
(HttpServletRequest request, HttpServletResponse response, boolean content)
throws IOException
{
// Validate the requested file ------------------------------------------------------------
// Get requested file by path info.
String requestedFile = request.getPathInfo();
if (requestedFile != null)
requestedFile = getNormalizedPath(requestedFile);
// Check if file is actually supplied to the request URL.
if (requestedFile == null) {
// Do your thing if the file is not supplied to the request URL.
// Throw an exception, or send 404, or show default/warning page, or just ignore it.
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// URL-decode the file name (might contain spaces and on) and prepare file object.
File file = new File(basePath, URLDecoder.decode(requestedFile, "UTF-8"));
String fpath = null;
if(allow_symlinks)
fpath = file.getAbsolutePath();
else
fpath = file.getCanonicalPath();
if (!fpath.startsWith(basePath)) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
if (file.isDirectory()) {
File directory = file;
for (int i = 0; i < indexFiles.length; i++) {
file = new File(directory, indexFiles[i]);
if (file.isFile())
break;
}
}
// Check if file actually exists in filesystem.
if (!file.exists()) {
// Do your thing if the file appears to be non-existing.
// Throw an exception, or send 404, or show default/warning page, or just ignore it.
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// Prepare some variables. The ETag is an unique identifier of the file.
String fileName = file.getName();
long length = file.length();
long lastModified = file.lastModified();
String eTag = fileName + "_" + length + "_" + lastModified;
// Validate request headers for caching ---------------------------------------------------
// If-None-Match header should contain "*" or ETag. If so, then return 304.
String ifNoneMatch = request.getHeader("If-None-Match");
if (ifNoneMatch != null && matches(ifNoneMatch, eTag)) {
response.setHeader("ETag", eTag); // Required in 304.
response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
// If-Modified-Since header should be greater than LastModified. If so, then return 304.
// This header is ignored if any If-None-Match header is specified.
long ifModifiedSince = request.getDateHeader("If-Modified-Since");
if (ifNoneMatch == null && ifModifiedSince != -1 && ifModifiedSince + 1000 > lastModified) {
response.setHeader("ETag", eTag); // Required in 304.
response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
// Validate request headers for resume ----------------------------------------------------
// If-Match header should contain "*" or ETag. If not, then return 412.
String ifMatch = request.getHeader("If-Match");
if (ifMatch != null && !matches(ifMatch, eTag)) {
response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
return;
}
// If-Unmodified-Since header should be greater than LastModified. If not, then return 412.
long ifUnmodifiedSince = request.getDateHeader("If-Unmodified-Since");
if (ifUnmodifiedSince != -1 && ifUnmodifiedSince + 1000 <= lastModified) {
response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
return;
}
// Validate and process range -------------------------------------------------------------
// Prepare some variables. The full Range represents the complete file.
Range full = new Range(0, length - 1, length);
List<Range> ranges = new ArrayList<Range>();
// Validate and process Range and If-Range headers.
String range = request.getHeader("Range");
if (range != null) {
// Range header should match format "bytes=n-n,n-n,n-n...". If not, then return 416.
if (!range.matches("^bytes=\\d*-\\d*(,\\d*-\\d*)*$")) {
response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return;
}
// If-Range header should either match ETag or be greater then LastModified. If not,
// then return full file.
String ifRange = request.getHeader("If-Range");
if (ifRange != null && !ifRange.equals(eTag)) {
try {
long ifRangeTime = request.getDateHeader("If-Range"); // Throws IAE if invalid.
if (ifRangeTime != -1 && ifRangeTime + 1000 < lastModified) {
ranges.add(full);
}
} catch (IllegalArgumentException ignore) {
ranges.add(full);
}
}
// If any valid If-Range header, then process each part of byte range.
if (ranges.isEmpty()) {
String[] rangesParts = range.substring(6).split(",");
if (rangesParts.length > 1) {
response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return;
}
for (String part : rangesParts) {
// Assuming a file with length of 100, the following examples returns bytes at:
// 50-80 (50 to 80), 40- (40 to length=100), -20 (length-20=80 to length=100).
long start = sublong(part, 0, part.indexOf("-"));
long end = sublong(part, part.indexOf("-") + 1, part.length());
if (start == -1) {
start = length - end;
end = length - 1;
} else if (end == -1 || end > length - 1) {
end = length - 1;
}
// Check if Range is syntactically valid. If not, then return 416.
if (start > end) {
response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return;
}
// Add range.
ranges.add(new Range(start, end, length));
}
}
}
// Prepare and initialize response --------------------------------------------------------
// Get content type by file name and set default GZIP support and content disposition.
boolean acceptsGzip = false;
String disposition = "inline";
String contentType = getContentType(fileName);
// If content type is text, then determine whether GZIP content encoding is supported by
// the browser and expand content type with the one and right character encoding.
if (contentType.startsWith("text")) {
String acceptEncoding = request.getHeader("Accept-Encoding");
acceptsGzip = acceptEncoding != null && accepts(acceptEncoding, "gzip");
contentType += ";charset=UTF-8";
}
// Else, expect for images, determine content disposition. If content type is supported by
// the browser, then set to inline, else attachment which will pop a 'save as' dialogue.
else if (!contentType.startsWith("image")) {
String accept = request.getHeader("Accept");
disposition = accept != null && accepts(accept, contentType) ? "inline" : "attachment";
}
// Initialize response.
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setHeader("Content-Disposition", disposition + ";filename=\"" + fileName + "\"");
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("ETag", eTag);
response.setDateHeader("Last-Modified", lastModified);
// Send requested file (part(s)) to client ------------------------------------------------
// Prepare streams.
RandomAccessFile input = null;
OutputStream output = null;
try {
// Open streams.
input = new RandomAccessFile(file, "r");
output = response.getOutputStream();
if (ranges.isEmpty() || ranges.get(0) == full) {
// Return full file.
Range r = full;
response.setContentType(contentType);
response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);
if (content) {
if (acceptsGzip) {
// The browser accepts GZIP, so GZIP the content.
response.setHeader("Content-Encoding", "gzip");
output = new GZIPOutputStream(output, DEFAULT_BUFFER_SIZE);
} else {
// Content length is not directly predictable in case of GZIP.
// So only add it if there is no means of GZIP, else browser will hang.
response.setHeader("Content-Length", String.valueOf(r.length));
}
// Copy full range.
copy(input, output, r.start, r.length);
}
} else if (ranges.size() == 1) {
// Return single part of file.
Range r = ranges.get(0);
response.setContentType(contentType);
response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);
response.setHeader("Content-Length", String.valueOf(r.length));
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.
if (content) {
// Copy single part range.
copy(input, output, r.start, r.length);
}
} else {
// Return multiple parts of file.
response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY);
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.
if (content) {
// Cast back to ServletOutputStream to get the easy println methods.
ServletOutputStream sos = (ServletOutputStream) output;
// Copy multi part range.
for (Range r : ranges) {
// Add multipart boundary and header fields for every range.
sos.println();
sos.println("--" + MULTIPART_BOUNDARY);
sos.println("Content-Type: " + contentType);
sos.println("Content-Range: bytes " + r.start + "-" + r.end + "/" + r.total);
// Copy single part range of multi part range.
copy(input, output, r.start, r.length);
}
// End with multipart boundary.
sos.println();
sos.println("--" + MULTIPART_BOUNDARY + "--");
}
}
} finally {
// Gently close streams.
close(output);
close(input);
}
}
// Helpers (can be refactored to public utility class) ----------------------------------------
final static Map<String, String> mimeTypes = new HashMap<String, String>() {{
this.put(".html", "text/html");
this.put(".htm", "text/html");
this.put(".js", "text/javascript");
this.put(".png", "image/png");
this.put(".jpg", "image/jpeg");
this.put(".css", "text/css");
this.put(".txt", "text/plain");
}};
public String getContentType(String fileName) {
// Don't use getServetContext!
/*String contentType = getServletContext().getMimeType(fileName);
*/
String contentType = null;
int i = fileName.lastIndexOf('.');
if (i >= 0) {
String extension = fileName.substring(i);
contentType = mimeTypes.get(extension);
}
if (contentType == null) {
contentType = "application/octet-stream";
}
return contentType;
}
/**
* Returns true if the given accept header accepts the given value.
* @param acceptHeader The accept header.
* @param toAccept The value to be accepted.
* @return True if the given accept header accepts the given value.
*/
private static boolean accepts(String acceptHeader, String toAccept) {
String[] acceptValues = acceptHeader.split("\\s*(,|;)\\s*");
Arrays.sort(acceptValues);
return Arrays.binarySearch(acceptValues, toAccept) > -1
|| Arrays.binarySearch(acceptValues, toAccept.replaceAll("/.*$", "/*")) > -1
|| Arrays.binarySearch(acceptValues, "*/*") > -1;
}
/**
* Returns true if the given match header matches the given value.
* @param matchHeader The match header.
* @param toMatch The value to be matched.
* @return True if the given match header matches the given value.
*/
private static boolean matches(String matchHeader, String toMatch) {
String[] matchValues = matchHeader.split("\\s*,\\s*");
Arrays.sort(matchValues);
return Arrays.binarySearch(matchValues, toMatch) > -1
|| Arrays.binarySearch(matchValues, "*") > -1;
}
/**
* Returns a substring of the given string value from the given begin index to the given end
* index as a long. If the substring is empty, then -1 will be returned
* @param value The string value to return a substring as long for.
* @param beginIndex The begin index of the substring to be returned as long.
* @param endIndex The end index of the substring to be returned as long.
* @return A substring of the given string value as long or -1 if substring is empty.
*/
private static long sublong(String value, int beginIndex, int endIndex) {
String substring = value.substring(beginIndex, endIndex);
return (substring.length() > 0) ? Long.parseLong(substring) : -1;
}
/**
* Copy the given byte range of the given input to the given output.
* @param input The input to copy the given range to the given output for.
* @param output The output to copy the given range from the given input for.
* @param start Start of the byte range.
* @param length Length of the byte range.
* @throws IOException If something fails at I/O level.
*/
private static void copy(RandomAccessFile input, OutputStream output, long start, long length)
throws IOException
{
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int read;
if (input.length() == length) {
// Write full range.
while ((read = input.read(buffer)) > 0) {
output.write(buffer, 0, read);
}
} else {
// Write partial range.
input.seek(start);
long toRead = length;
while ((read = input.read(buffer)) > 0) {
if ((toRead -= read) > 0) {
output.write(buffer, 0, read);
} else {
output.write(buffer, 0, (int) toRead + read);
break;
}
}
}
}
/**
* Close the given resource.
* @param resource The resource to be closed.
*/
private static void close(Closeable resource) {
if (resource != null) {
try {
resource.close();
} catch (IOException ignore) {
// Ignore IOException. If you want to handle this anyway, it might be useful to know
// that this will generally only be thrown when the client aborted the request.
}
}
}
// Inner classes ------------------------------------------------------------------------------
/**
* This class represents a byte range.
*/
protected class Range {
long start;
long end;
long length;
long total;
/**
* Construct a byte range.
* @param start Start of the byte range.
* @param end End of the byte range.
* @param total Total length of the byte source.
*/
public Range(long start, long end, long total) {
this.start = start;
this.end = end;
this.length = end - start + 1;
this.total = total;
}
}
}

View File

@ -1,17 +0,0 @@
package org.dynmap.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import org.json.simple.JSONStreamAware;
public class JSONServlet {
public static void respond(HttpServletResponse response, JSONStreamAware json) throws IOException {
response.setContentType("application/json");
PrintWriter writer = response.getWriter();
json.writeJSONString(writer);
writer.close();
}
}

View File

@ -1,145 +0,0 @@
package org.dynmap.servlet;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
public class MainServlet extends HttpServlet {
public static class Header {
public String name;
public String value;
public Header(String name, String value) {
this.name = name;
this.value = value;
}
}
private static class Registration {
public String pattern;
public HttpServlet servlet;
public Registration(String pattern, HttpServlet servlet) {
this.pattern = pattern;
this.servlet = servlet;
}
}
List<Registration> registrations = new LinkedList<Registration>();
public List<Header> customHeaders = new LinkedList<Header>();
public void addServlet(String pattern, HttpServlet servlet) {
registrations.add(new Registration(pattern, servlet));
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HashMap<String, Object> properties = new HashMap<String, Object>();
String path = req.getPathInfo();
for(Header header : customHeaders) {
resp.setHeader(header.name, header.value);
}
Registration bestMatch = null;
String bestMatchPart = null;
HashMap<String, Object> bestProperties = null;
for (Registration r : registrations) {
String matchingPart = match(r.pattern, path, properties);
if (matchingPart != null) {
if (bestMatchPart == null || bestMatchPart.length() < matchingPart.length()) {
bestMatch = r;
bestMatchPart = matchingPart;
bestProperties = properties;
properties = new HashMap<String, Object>();
}
}
}
if (bestMatch == null) {
resp.sendError(404);
} else {
String leftOverPath = path.substring(bestMatchPart.length());
HttpServletRequest newreq = new RequestWrapper(req, leftOverPath);
for(String key : bestProperties.keySet()) {
newreq.setAttribute(key, bestProperties.get(key));
}
bestMatch.servlet.service(newreq, resp);
}
}
public String match(String pattern, String path, Map<String, Object> properties) {
int patternStart = 0;
int pathStart = 0;
while (patternStart < pattern.length()) {
if (pattern.charAt(patternStart) == '{') {
// Found a variable.
int endOfVariable = pattern.indexOf('}', patternStart+1);
String variableName = pattern.substring(patternStart+1, endOfVariable);
int endOfSection = indexOfAny(path, new char[] { '/', '?' }, pathStart);
if (endOfSection < 0) {
endOfSection = path.length();
}
String variableValue = path.substring(pathStart, endOfSection);
// Store variable.
properties.put(variableName, variableValue);
patternStart = endOfVariable+1;
pathStart = endOfSection;
} else {
int endOfLiteral = pattern.indexOf('{', patternStart);
if (endOfLiteral < 0) {
endOfLiteral = pattern.length();
}
String literal = pattern.substring(patternStart, endOfLiteral);
int endOfPathLiteral = pathStart + literal.length();
if (endOfPathLiteral > path.length()) {
return null;
}
String matchingLiteral = path.substring(pathStart, endOfPathLiteral);
if (!literal.equals(matchingLiteral)) {
return null;
}
patternStart = endOfLiteral;
pathStart = endOfPathLiteral;
}
}
// Return the part of the url that matches the pattern. (if the pattern does not contain any variables, this will be equal to the pattern)
return path.substring(0, pathStart);
}
private int indexOfAny(String s, char[] cs, int startIndex) {
for(int i = startIndex; i < s.length(); i++) {
char c = s.charAt(i);
for(int j = 0; j < cs.length; j++) {
if (c == cs[j]) {
return i;
}
}
}
return -1;
}
class RequestWrapper extends HttpServletRequestWrapper {
String pathInfo;
public RequestWrapper(HttpServletRequest request, String pathInfo) {
super(request);
this.pathInfo = pathInfo;
}
@Override
public String getPathInfo() {
return pathInfo;
}
}
}

View File

@ -1,148 +0,0 @@
package org.dynmap.servlet;
import org.dynmap.DynmapCore;
import org.dynmap.Event;
import org.dynmap.Log;
import org.dynmap.web.HttpStatus;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;
@SuppressWarnings("serial")
public class SendMessageServlet extends HttpServlet {
protected static final Logger log = Logger.getLogger("Minecraft");
private static final JSONParser parser = new JSONParser();
public Event<Message> onMessageReceived = new Event<Message>();
private Charset cs_utf8 = Charset.forName("UTF-8");
public int maximumMessageInterval = 1000;
public boolean hideip = false;
public boolean trustclientname = false;
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();
private HashMap<String,String> useralias = new HashMap<String,String>();
private int aliasindex = 1;
public boolean use_player_login_ip = false;
public boolean require_player_login_ip = false;
public boolean check_user_ban = false;
public DynmapCore core;
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
InputStreamReader reader = new InputStreamReader(request.getInputStream(), cs_utf8);
JSONObject o = null;
try {
o = (JSONObject)parser.parse(reader);
} catch (ParseException e) {
response.sendError(HttpStatus.BadRequest.getCode());
return;
}
final Message message = new Message();
message.name = "";
if(trustclientname) {
message.name = String.valueOf(o.get("name"));
}
boolean isip = true;
if((message.name == null) || message.name.equals("")) {
/* If proxied client address, get original */
if(request.getHeader("X-Forwarded-For") != null)
message.name = request.getHeader("X-Forwarded-For");
/* If from loopback, we're probably getting from proxy - need to trust client */
else if(request.getRemoteAddr() == "127.0.0.1")
message.name = String.valueOf(o.get("name"));
else
message.name = request.getRemoteAddr();
}
if (use_player_login_ip) {
List<String> ids = core.getIDsForIP(message.name);
if (ids != null) {
String id = ids.get(0);
if (check_user_ban) {
if (core.getServer().isPlayerBanned(id)) {
Log.info("Ignore message from '" + message.name + "' - banned player (" + id + ")");
response.sendError(HttpStatus.Forbidden.getCode());
return;
}
}
message.name = ids.get(0);
isip = false;
} else if (require_player_login_ip) {
Log.info("Ignore message from '" + message.name + "' - no matching player login recorded");
response.sendError(HttpStatus.Forbidden.getCode());
return;
}
}
if (hideip && isip) { /* If hiding IP, find or assign alias */
synchronized (disallowedUsersLock) {
String n = useralias.get(message.name);
if (n == null) { /* Make ID */
n = String.format("web-%03d", aliasindex);
aliasindex++;
useralias.put(message.name, n);
}
message.name = n;
}
}
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()) {
WebUser wu = disallowedUserQueue.getFirst();
if (now >= wu.nextMessageTime) {
disallowedUserQueue.remove();
disallowedUsers.remove(wu.name);
} else {
break;
}
}
WebUser user = disallowedUsers.get(message.name);
if (user == null) {
user = new WebUser() {
{
name = message.name;
nextMessageTime = now + maximumMessageInterval;
}
};
disallowedUsers.put(user.name, user);
disallowedUserQueue.add(user);
} else {
response.sendError(HttpStatus.Forbidden.getCode());
return;
}
}
onMessageReceived.trigger(message);
}
public static class Message {
public String name;
public String message;
}
public static class WebUser {
public long nextMessageTime;
public String name;
}
}

View File

@ -1,88 +0,0 @@
package org.dynmap.utils;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
public class DynmapBufferedImage {
public BufferedImage buf_img;
public int[] argb_buf;
public int width;
public int height;
/* BufferedImage cache - we use the same things a lot... */
private static Object lock = new Object();
private static HashMap<Long, LinkedList<DynmapBufferedImage>> imgcache =
new HashMap<Long, LinkedList<DynmapBufferedImage>>(); /* Indexed by resolution - X<<32+Y */
private static final int CACHE_LIMIT = 10;
/**
* Allocate buffered image from pool, if possible
* @param x - x dimension
* @param y - y dimension
*/
public static DynmapBufferedImage allocateBufferedImage(int x, int y) {
DynmapBufferedImage img = null;
synchronized(lock) {
long k = (x<<16) + y;
LinkedList<DynmapBufferedImage> ll = imgcache.get(k);
if(ll != null) {
img = ll.poll();
}
}
if(img != null) { /* Got it - reset it for use */
Arrays.fill(img.argb_buf, 0);
}
else {
img = new DynmapBufferedImage();
img.width = x;
img.height = y;
img.argb_buf = new int[x*y];
}
img.buf_img = createBufferedImage(img.argb_buf, img.width, img.height);
return img;
}
/**
* Return buffered image to pool
*/
public static void freeBufferedImage(DynmapBufferedImage img) {
img.buf_img.flush();
img.buf_img = null; /* Toss bufferedimage - seems to hold on to other memory */
synchronized(lock) {
long k = (img.width<<16) + img.height;
LinkedList<DynmapBufferedImage> ll = imgcache.get(k);
if(ll == null) {
ll = new LinkedList<DynmapBufferedImage>();
imgcache.put(k, ll);
}
if(ll.size() < CACHE_LIMIT) {
ll.add(img);
img = null;
}
}
}
/* ARGB band masks */
private static final int [] band_masks = {0xFF0000, 0xFF00, 0xff, 0xff000000};
/**
* Build BufferedImage from provided ARGB array and dimensions
*/
public static BufferedImage createBufferedImage(int[] argb_buf, int w, int h) {
/* Create integer-base data buffer */
DataBuffer db = new DataBufferInt (argb_buf, w*h);
/* Create writable raster */
WritableRaster raster = Raster.createPackedRaster(db, w, h, w, band_masks, null);
/* RGB color model */
ColorModel color_model = ColorModel.getRGBdefault ();
/* Return buffered image */
return new BufferedImage (color_model, raster, false, null);
}
}

View File

@ -1,227 +0,0 @@
package org.dynmap.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.awt.image.BufferedImage;
import java.awt.image.DirectColorModel;
import java.awt.image.WritableRaster;
import java.io.IOException;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import org.dynmap.Log;
import org.dynmap.MapType.ImageFormat;
import org.dynmap.debug.Debug;
/**
* Implements soft-locks for prevent concurrency issues with file updates
*/
public class FileLockManager {
private static Object lock = new Object();
private static HashMap<String, Integer> filelocks = new HashMap<String, Integer>();
private static final Integer WRITELOCK = new Integer(-1);
/**
* Get write lock on file - exclusive lock, no other writers or readers
* @throws InterruptedException
*/
public static boolean getWriteLock(File f) {
String fn = f.getPath();
synchronized(lock) {
boolean got_lock = false;
while(!got_lock) {
Integer lockcnt = filelocks.get(fn); /* Get lock count */
if(lockcnt != null) { /* If any locks, can't get write lock */
try {
lock.wait();
} catch (InterruptedException ix) {
Log.severe("getWriteLock(" + fn + ") interrupted");
return false;
}
}
else {
filelocks.put(fn, WRITELOCK);
got_lock = true;
}
}
}
//Log.info("getWriteLock(" + f + ")");
return true;
}
/**
* Release write lock
*/
public static void releaseWriteLock(File f) {
String fn = f.getPath();
synchronized(lock) {
Integer lockcnt = filelocks.get(fn); /* Get lock count */
if(lockcnt == null)
Log.severe("releaseWriteLock(" + fn + ") on unlocked file");
else if(lockcnt.equals(WRITELOCK)) {
filelocks.remove(fn); /* Remove lock */
lock.notifyAll(); /* Wake up folks waiting for locks */
}
else
Log.severe("releaseWriteLock(" + fn + ") on read-locked file");
}
//Log.info("releaseWriteLock(" + f + ")");
}
/**
* Get read lock on file - multiple readers allowed, blocks writers
*/
public static boolean getReadLock(File f) {
return getReadLock(f, -1);
}
/**
* Get read lock on file - multiple readers allowed, blocks writers - with timeout (msec)
*/
public static boolean getReadLock(File f, long timeout) {
String fn = f.getPath();
synchronized(lock) {
boolean got_lock = false;
long starttime = 0;
if(timeout > 0)
starttime = System.currentTimeMillis();
while(!got_lock) {
Integer lockcnt = filelocks.get(fn); /* Get lock count */
if(lockcnt == null) {
filelocks.put(fn, Integer.valueOf(1)); /* First lock */
got_lock = true;
}
else if(!lockcnt.equals(WRITELOCK)) { /* Other read locks */
filelocks.put(fn, Integer.valueOf(lockcnt+1));
got_lock = true;
}
else { /* Write lock in place */
try {
if(timeout < 0) {
lock.wait();
}
else {
long now = System.currentTimeMillis();
long elapsed = now-starttime;
if(elapsed > timeout) /* Give up on timeout */
return false;
lock.wait(timeout-elapsed);
}
} catch (InterruptedException ix) {
Log.severe("getReadLock(" + fn + ") interrupted");
return false;
}
}
}
}
//Log.info("getReadLock(" + f + ")");
return true;
}
/**
* Release read lock
*/
public static void releaseReadLock(File f) {
String fn = f.getPath();
synchronized(lock) {
Integer lockcnt = filelocks.get(fn); /* Get lock count */
if(lockcnt == null)
Log.severe("releaseReadLock(" + fn + ") on unlocked file");
else if(lockcnt.equals(WRITELOCK))
Log.severe("releaseReadLock(" + fn + ") on write-locked file");
else if(lockcnt > 1) {
filelocks.put(fn, Integer.valueOf(lockcnt-1));
}
else {
filelocks.remove(fn); /* Remove lock */
lock.notifyAll(); /* Wake up folks waiting for locks */
}
}
//Log.info("releaseReadLock(" + f + ")");
}
private static final int MAX_WRITE_RETRIES = 6;
private static LinkedList<ByteArrayOutputStream> baoslist = new LinkedList<ByteArrayOutputStream>();
private static Object baos_lock = new Object();
/**
* Wrapper for IOImage.write - implements retries for busy files
*/
public static void imageIOWrite(BufferedImage img, ImageFormat fmt, File fname) throws IOException {
int retrycnt = 0;
boolean done = false;
byte[] rslt;
ByteArrayOutputStream baos;
synchronized(baos_lock) {
if(baoslist.isEmpty()) {
baos = new ByteArrayOutputStream();
}
else {
baos = baoslist.removeFirst();
baos.reset();
}
}
ImageIO.setUseCache(false); /* Don't use file cache - too small to be worth it */
if(fmt.getFileExt().equals("jpg")) {
WritableRaster raster = img.getRaster();
WritableRaster newRaster = raster.createWritableChild(0, 0, img.getWidth(),
img.getHeight(), 0, 0, new int[] {0, 1, 2});
DirectColorModel cm = (DirectColorModel)img.getColorModel();
DirectColorModel newCM = new DirectColorModel(cm.getPixelSize(),
cm.getRedMask(), cm.getGreenMask(), cm.getBlueMask());
// now create the new buffer that is used ot write the image:
BufferedImage rgbBuffer = new BufferedImage(newCM, newRaster, false, null);
// Find a jpeg writer
ImageWriter writer = null;
Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpg");
if (iter.hasNext()) {
writer = iter.next();
}
if(writer == null) {
Log.severe("No JPEG ENCODER - Java VM does not support JPEG encoding");
return;
}
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(fmt.getQuality());
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
writer.setOutput(ios);
writer.write(null, new IIOImage(rgbBuffer, null, null), iwp);
writer.dispose();
rgbBuffer.flush();
}
else {
ImageIO.write(img, fmt.getFileExt(), baos); /* Write to byte array stream - prevent bogus I/O errors */
}
rslt = baos.toByteArray();
synchronized(baos_lock) {
baoslist.addFirst(baos);
}
while(!done) {
RandomAccessFile f = null;
try {
f = new RandomAccessFile(fname, "rw");
f.write(rslt);
done = true;
} catch (IOException fnfx) {
if(retrycnt < MAX_WRITE_RETRIES) {
Debug.debug("Image file " + fname.getPath() + " - unable to write - retry #" + retrycnt);
try { Thread.sleep(50 << retrycnt); } catch (InterruptedException ix) { throw fnfx; }
retrycnt++;
}
else {
Log.info("Image file " + fname.getPath() + " - unable to write - failed");
throw fnfx;
}
} finally {
if(f != null) {
try { f.close(); } catch (IOException iox) {}
}
}
}
}
}

View File

@ -1,16 +0,0 @@
package org.dynmap.utils;
import java.util.LinkedHashMap;
import java.util.Map;
@SuppressWarnings("serial")
public class LRULinkedHashMap<T, K> extends LinkedHashMap<T, K> {
private int limit;
public LRULinkedHashMap(int lim) {
super(16, (float)0.75, true);
limit = lim;
}
protected boolean removeEldestEntry(Map.Entry<T, K> last) {
return(size() >= limit);
}
}

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