diff --git a/build.xml b/build.xml deleted file mode 100644 index 5bf53e8c..00000000 --- a/build.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build_parameters.xml b/build_parameters.xml deleted file mode 100644 index f274865c..00000000 --- a/build_parameters.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/colorschemes/default.txt b/colorschemes/default.txt deleted file mode 100644 index f860a2d1..00000000 --- a/colorschemes/default.txt +++ /dev/null @@ -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 diff --git a/colorschemes/flames.txt b/colorschemes/flames.txt deleted file mode 100644 index fe48ffa0..00000000 --- a/colorschemes/flames.txt +++ /dev/null @@ -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 diff --git a/colorschemes/ovocean.txt b/colorschemes/ovocean.txt deleted file mode 100644 index 352a09ed..00000000 --- a/colorschemes/ovocean.txt +++ /dev/null @@ -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 diff --git a/colorschemes/sk89q.txt b/colorschemes/sk89q.txt deleted file mode 100644 index 6e06a041..00000000 --- a/colorschemes/sk89q.txt +++ /dev/null @@ -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 diff --git a/pom.xml b/pom.xml index 5a4ef515..75f43a5f 100644 --- a/pom.xml +++ b/pom.xml @@ -43,6 +43,31 @@ + + org.apache.maven.plugins + maven-dependency-plugin + 2.4 + + + unpack + package + unpack + + + + org.dynmap + DynmapCore + ${project.version} + bin + zip + ${project.build.directory}/core + + + + + + + org.apache.maven.plugins maven-shade-plugin @@ -57,8 +82,7 @@ org.dynmap:dynmap-api:jar:* - org.eclipse.jetty:jetty-*:jar:* - javax.servlet:javax.servlet-api:jar:* + org.dynmap:DynmapCore:jar:* @@ -106,7 +130,7 @@ org.dynmap dynmap-api - [0.25,) + ${version} jar compile @@ -126,5 +150,12 @@ 8.0.1.v20110908 + + org.dynmap + DynmapCore + ${version} + jar + compile + diff --git a/renderdata/bc-models.txt b/renderdata/bc-models.txt deleted file mode 100644 index e7801c74..00000000 --- a/renderdata/bc-models.txt +++ /dev/null @@ -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 --------- --******- --******- --******- --******- --******- --******- --------- diff --git a/renderdata/bc-texture.txt b/renderdata/bc-texture.txt deleted file mode 100644 index 599a5d75..00000000 --- a/renderdata/bc-texture.txt +++ /dev/null @@ -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 diff --git a/renderdata/ic2-models.txt b/renderdata/ic2-models.txt deleted file mode 100644 index b7d7ef65..00000000 --- a/renderdata/ic2-models.txt +++ /dev/null @@ -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 diff --git a/renderdata/ic2-texture.txt b/renderdata/ic2-texture.txt deleted file mode 100644 index 6cafbcc0..00000000 --- a/renderdata/ic2-texture.txt +++ /dev/null @@ -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 diff --git a/renderdata/rp2-models.txt b/renderdata/rp2-models.txt deleted file mode 100644 index b32d424f..00000000 --- a/renderdata/rp2-models.txt +++ /dev/null @@ -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 -**** -**** -**** -**** - diff --git a/renderdata/rp2-texture.txt b/renderdata/rp2-texture.txt deleted file mode 100644 index 5ee4cfe4..00000000 --- a/renderdata/rp2-texture.txt +++ /dev/null @@ -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 diff --git a/src/main/assembly/package.xml b/src/main/assembly/package.xml index ad84a28f..f2279364 100644 --- a/src/main/assembly/package.xml +++ b/src/main/assembly/package.xml @@ -6,40 +6,16 @@ - ${project.basedir} - / - - README* - LICENSE* - NOTICE* - CHANGELOG* - - + ${project.build.directory}/core + /dynmap + + web/version.js - ${project.basedir}/web/ - /dynmap/web/ - - version.js - - true - - - ${project.basedir}/web - /dynmap/web - - version.js - - - - ${project.basedir}/colorschemes - /dynmap/colorschemes - - - ${project.basedir}/texturepacks - /dynmap/texturepacks - - ${project.basedir}/renderdata - /dynmap/renderdata + ${project.build.directory}/core/web + /dynmap/web + + version.js + true diff --git a/src/main/java/org/dynmap/AsynchronousQueue.java b/src/main/java/org/dynmap/AsynchronousQueue.java deleted file mode 100644 index e2d31c4d..00000000 --- a/src/main/java/org/dynmap/AsynchronousQueue.java +++ /dev/null @@ -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 { - private Object lock = new Object(); - private Thread thread; - private LinkedBlockingQueue queue = new LinkedBlockingQueue(); - private Set set = new HashSet(); - private Handler handler; - private int dequeueTime; - private int accelDequeueTime; - private int accelDequeueThresh; - private int pendingcnt; - private int pendinglimit; - private boolean normalprio; - - public AsynchronousQueue(Handler 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 popAll() { - List s; - synchronized(lock) { - s = new ArrayList(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(); - } - } -} diff --git a/src/main/java/org/dynmap/ChatEvent.java b/src/main/java/org/dynmap/ChatEvent.java deleted file mode 100644 index 99f0a830..00000000 --- a/src/main/java/org/dynmap/ChatEvent.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/java/org/dynmap/Client.java b/src/main/java/org/dynmap/Client.java deleted file mode 100644 index 74b6831b..00000000 --- a/src/main/java/org/dynmap/Client.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/java/org/dynmap/ClientComponent.java b/src/main/java/org/dynmap/ClientComponent.java deleted file mode 100644 index f27cf284..00000000 --- a/src/main/java/org/dynmap/ClientComponent.java +++ /dev/null @@ -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() { - @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 m) { - JSONObject o = new JSONObject(); - for(Map.Entry 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)o); - } else if (o instanceof List) { - return convertList((List)o); - } - return o; - } - -} diff --git a/src/main/java/org/dynmap/ClientConfigurationComponent.java b/src/main/java/org/dynmap/ClientConfigurationComponent.java deleted file mode 100644 index ec1d52eb..00000000 --- a/src/main/java/org/dynmap/ClientConfigurationComponent.java +++ /dev/null @@ -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.addListener("buildclientconfiguration", new Listener() { - @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)); - } - }); - } - -} diff --git a/src/main/java/org/dynmap/ClientUpdateComponent.java b/src/main/java/org/dynmap/ClientUpdateComponent.java deleted file mode 100644 index ea60abc9..00000000 --- a/src/main/java/org/dynmap/ClientUpdateComponent.java +++ /dev/null @@ -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() { - @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 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 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); - } - } - -} diff --git a/src/main/java/org/dynmap/ClientUpdateEvent.java b/src/main/java/org/dynmap/ClientUpdateEvent.java deleted file mode 100644 index 5a5274c4..00000000 --- a/src/main/java/org/dynmap/ClientUpdateEvent.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/java/org/dynmap/Color.java b/src/main/java/org/dynmap/Color.java deleted file mode 100644 index 4b0e2221..00000000 --- a/src/main/java/org/dynmap/Color.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/java/org/dynmap/ColorScheme.java b/src/main/java/org/dynmap/ColorScheme.java deleted file mode 100644 index f512bb35..00000000 --- a/src/main/java/org/dynmap/ColorScheme.java +++ /dev/null @@ -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 cache = new HashMap(); - - 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(); - } -} diff --git a/src/main/java/org/dynmap/Component.java b/src/main/java/org/dynmap/Component.java deleted file mode 100644 index 0d6a47f6..00000000 --- a/src/main/java/org/dynmap/Component.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/java/org/dynmap/ComponentManager.java b/src/main/java/org/dynmap/ComponentManager.java deleted file mode 100644 index ce737940..00000000 --- a/src/main/java/org/dynmap/ComponentManager.java +++ /dev/null @@ -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 components = new HashSet(); - public Map> componentLookup = new HashMap>(); - - public void add(Component c) { - if (components.add(c)) { - String key = c.getClass().toString(); - List clist = componentLookup.get(key); - if (clist == null) { - clist = new ArrayList(); - componentLookup.put(key, clist); - } - clist.add(c); - } - } - - public void remove(Component c) { - if (components.remove(c)) { - String key = c.getClass().toString(); - List clist = componentLookup.get(key); - if (clist != null) { - clist.remove(c); - } - } - } - - public void clear() { - componentLookup.clear(); - components.clear(); - } - - public Iterable getComponents(Class c) { - List list = componentLookup.get(c.toString()); - if (list == null) - return new ArrayList(); - return list; - } -} diff --git a/src/main/java/org/dynmap/ConfigurationNode.java b/src/main/java/org/dynmap/ConfigurationNode.java deleted file mode 100644 index 8a0e89b0..00000000 --- a/src/main/java/org/dynmap/ConfigurationNode.java +++ /dev/null @@ -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 { - public Map entries; - private File f; - private Yaml yaml; - - public ConfigurationNode() { - entries = new HashMap(); - } - - 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(); - } - - public ConfigurationNode(Map 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)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)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 submap; - try { - submap = (Map)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 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 getStrings(String path, List def) { - Object o = getObject(path); - if (!(o instanceof List)) { - return def; - } - ArrayList strings = new ArrayList(); - 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 List getList(String path) { - try { - List list = (List)getObject(path, null); - return list; - } catch (ClassCastException e) { - try { - T o = (T)getObject(path, null); - if (o == null) { - return new ArrayList(); - } - ArrayList al = new ArrayList(); - al.add(o); - return al; - } catch (ClassCastException e2) { - return new ArrayList(); - } - } - } - - public List> getMapList(String path) { - return getList(path); - } - - public ConfigurationNode getNode(String path) { - Map v = null; - v = getGeneric(path, v); - if (v == null) - return null; - return new ConfigurationNode(v); - } - - @SuppressWarnings("unchecked") - public List getNodes(String path) { - List o = getList(path); - - if(o == null) - return new ArrayList(); - - ArrayList nodes = new ArrayList(); - for(Object i : (List)o) { - if (i instanceof Map) { - Map map; - try { - map = (Map)i; - } catch(ClassCastException e) { - continue; - } - nodes.add(new ConfigurationNode(map)); - } - } - return nodes; - } - - public void extend(Map other) { - if (other != null) - extendMap(this, other); - } - - @SuppressWarnings("unchecked") - private final static void extendMap(Map left, Map right) { - ConfigurationNode original = new ConfigurationNode(left); - for(Map.Entry 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)value); - } else { - original.put(key, value); - } - } - } - - public 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 List createInstances(String path, Class[] constructorParameters, Object[] constructorArguments) { - List nodes = getNodes(path); - List instances = new ArrayList(); - for(ConfigurationNode node : nodes) { - T instance = node.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 m) { - entries.putAll(m); - } - - @Override - public void clear() { - entries.clear(); - } - - @Override - public Set keySet() { - return entries.keySet(); - } - - @Override - public Collection values() { - return entries.values(); - } - - @Override - public Set> 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 - } - -} diff --git a/src/main/java/org/dynmap/DynmapChunk.java b/src/main/java/org/dynmap/DynmapChunk.java deleted file mode 100644 index e070b9ab..00000000 --- a/src/main/java/org/dynmap/DynmapChunk.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/java/org/dynmap/DynmapCore.java b/src/main/java/org/dynmap/DynmapCore.java deleted file mode 100644 index 7050da7f..00000000 --- a/src/main/java/org/dynmap/DynmapCore.java +++ /dev/null @@ -1,1213 +0,0 @@ -package org.dynmap; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Constructor; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.URL; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.dynmap.common.DynmapCommandSender; -import org.dynmap.common.DynmapListenerManager; -import org.dynmap.common.DynmapListenerManager.EventType; -import org.dynmap.common.DynmapPlayer; -import org.dynmap.common.DynmapServerInterface; -import org.dynmap.debug.Debug; -import org.dynmap.debug.Debugger; -import org.dynmap.hdmap.HDBlockModels; -import org.dynmap.hdmap.HDMapManager; -import org.dynmap.hdmap.TexturePack; -import org.dynmap.markers.MarkerAPI; -import org.dynmap.markers.impl.MarkerAPIImpl; -import org.dynmap.web.BanIPFilter; -import org.dynmap.web.CustomHeaderFilter; -import org.dynmap.web.FilterHandler; -import org.dynmap.web.HandlerRouter; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.ResourceHandler; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.util.resource.FileResource; -import org.yaml.snakeyaml.Yaml; - -import javax.servlet.*; -import javax.servlet.http.HttpServlet; - -public class DynmapCore { - private DynmapServerInterface server; - private String version; - private Server webServer = null; - private HandlerRouter router = null; - public MapManager mapManager = null; - public PlayerList playerList; - public ConfigurationNode configuration; - public ComponentManager componentManager = new ComponentManager(); - public DynmapListenerManager listenerManager = new DynmapListenerManager(this); - public PlayerFaces playerfacemgr; - public Events events = new Events(); - public String deftemplatesuffix = ""; - boolean swampshading = false; - boolean waterbiomeshading = false; - boolean fencejoin = false; - boolean bettergrass = false; - private HashSet enabledTriggers = new HashSet(); - - public CompassMode compassmode = CompassMode.PRE19; - private int config_hashcode; /* Used to signal need to reload web configuration (world changes, config update, etc) */ - private int fullrenderplayerlimit; /* Number of online players that will cause fullrender processing to pause */ - private boolean didfullpause; - private Map> ids_by_ip = new HashMap>(); - private boolean persist_ids_by_ip = false; - - public enum CompassMode { - PRE19, /* Default for 1.8 and earlier (east is Z+) */ - NEWROSE, /* Use same map orientation, fix rose */ - NEWNORTH /* Use new map orientation */ - }; - - /* Flag to let code know that we're doing reload - make sure we don't double-register event handlers */ - public boolean is_reload = false; - public static boolean ignore_chunk_loads = false; /* Flag keep us from processing our own chunk loads */ - - private MarkerAPIImpl markerapi; - - private File dataDirectory; - private File tilesDirectory; - private String plugin_ver; - private String mc_ver; - - /* Constructor for core */ - public DynmapCore() { - } - - /* Cleanup method */ - public void cleanup() { - server = null; - markerapi = null; - } - - /* Dependencies - need to be supplied by plugin wrapper */ - public void setPluginVersion(String pluginver) { - plugin_ver = pluginver; - } - public void setDataFolder(File dir) { - dataDirectory = dir; - } - public final File getDataFolder() { - return dataDirectory; - } - public final File getTilesFolder() { - return tilesDirectory; - } - public void setMinecraftVersion(String mcver) { - mc_ver = mcver; - } - public void setServer(DynmapServerInterface srv) { - server = srv; - } - public final DynmapServerInterface getServer() { return server; } - - public final MapManager getMapManager() { - return mapManager; - } - - /* Add/Replace branches in configuration tree with contribution from a separate file */ - private void mergeConfigurationBranch(ConfigurationNode cfgnode, String branch, boolean replace_existing, boolean islist) { - Object srcbranch = cfgnode.getObject(branch); - if(srcbranch == null) - return; - /* See if top branch is in configuration - if not, just add whole thing */ - Object destbranch = configuration.getObject(branch); - if(destbranch == null) { /* Not found */ - configuration.put(branch, srcbranch); /* Add new tree to configuration */ - return; - } - /* If list, merge by "name" attribute */ - if(islist) { - List dest = configuration.getNodes(branch); - List src = cfgnode.getNodes(branch); - /* Go through new records : see what to do with each */ - for(ConfigurationNode node : src) { - String name = node.getString("name", null); - if(name == null) continue; - /* Walk destination - see if match */ - boolean matched = false; - for(ConfigurationNode dnode : dest) { - String dname = dnode.getString("name", null); - if(dname == null) continue; - if(dname.equals(name)) { /* Match? */ - if(replace_existing) { - dnode.clear(); - dnode.putAll(node); - } - matched = true; - break; - } - } - /* If no match, add to end */ - if(!matched) { - dest.add(node); - } - } - configuration.put(branch,dest); - } - /* If configuration node, merge by key */ - else { - ConfigurationNode src = cfgnode.getNode(branch); - ConfigurationNode dest = configuration.getNode(branch); - for(String key : src.keySet()) { /* Check each contribution */ - if(dest.containsKey(key)) { /* Exists? */ - if(replace_existing) { /* If replacing, do so */ - dest.put(key, src.getObject(key)); - } - } - else { /* Else, always add if not there */ - dest.put(key, src.getObject(key)); - } - } - } - } - /* Table of default templates - all are resources in dynmap.jar unnder templates/, and go in templates directory when needed */ - private static final String[] stdtemplates = { "normal.txt", "nether.txt", "skylands.txt", "normal-lowres.txt", - "nether-lowres.txt", "skylands-lowres.txt", "normal-hires.txt", "nether-hires.txt", "skylands-hires.txt", - "normal-vlowres.txt", "skylands-vlowres.txt", "nether-vlowres.txt", "the_end.txt", "the_end-vlowres.txt", - "the_end-lowres.txt", "the_end-hires.txt" - }; - - private static final String CUSTOM_PREFIX = "custom-"; - /* Load templates from template folder */ - private void loadTemplates() { - File templatedir = new File(dataDirectory, "templates"); - templatedir.mkdirs(); - /* First, prime the templates directory with default standard templates, if needed */ - for(String stdtemplate : stdtemplates) { - File f = new File(templatedir, stdtemplate); - createDefaultFileFromResource("/templates/" + stdtemplate, f); - } - /* Now process files */ - String[] templates = templatedir.list(); - /* Go through list - process all ones not starting with 'custom' first */ - for(String tname: templates) { - /* If matches naming convention */ - if(tname.endsWith(".txt") && (!tname.startsWith(CUSTOM_PREFIX))) { - File tf = new File(templatedir, tname); - ConfigurationNode cn = new ConfigurationNode(tf); - cn.load(); - /* Supplement existing values (don't replace), since configuration.txt is more custom than these */ - mergeConfigurationBranch(cn, "templates", false, false); - } - } - /* Go through list again - this time do custom- ones */ - for(String tname: templates) { - /* If matches naming convention */ - if(tname.endsWith(".txt") && tname.startsWith(CUSTOM_PREFIX)) { - File tf = new File(templatedir, tname); - ConfigurationNode cn = new ConfigurationNode(tf); - cn.load(); - /* This are overrides - replace even configuration.txt content */ - mergeConfigurationBranch(cn, "templates", true, false); - } - } - } - - public boolean enableCore() { - /* Start with clean events */ - events = new Events(); - - /* Load plugin version info */ - loadVersion(); - - /* Initialize confguration.txt if needed */ - File f = new File(dataDirectory, "configuration.txt"); - if(!createDefaultFileFromResource("/configuration.txt", f)) { - return false; - } - - /* Load configuration.txt */ - configuration = new ConfigurationNode(f); - configuration.load(); - - /* Add options to avoid 0.29 re-render (fixes very inconsistent with previous maps) */ - HDMapManager.usegeneratedtextures = configuration.getBoolean("use-generated-textures", false); - HDMapManager.waterlightingfix = configuration.getBoolean("correct-water-lighting", false); - HDMapManager.biomeshadingfix = configuration.getBoolean("correct-biome-shading", false); - - /* Load block models */ - HDBlockModels.loadModels(dataDirectory, configuration); - /* Load texture mappings */ - TexturePack.loadTextureMapping(dataDirectory, configuration); - - /* Now, process worlds.txt - merge it in as an override of existing values (since it is only user supplied values) */ - f = new File(dataDirectory, "worlds.txt"); - if(!createDefaultFileFromResource("/worlds.txt", f)) { - return false; - } - ConfigurationNode cn = new ConfigurationNode(f); - cn.load(); - mergeConfigurationBranch(cn, "worlds", true, true); - - /* Now, process templates */ - loadTemplates(); - - Log.verbose = configuration.getBoolean("verbose", true); - deftemplatesuffix = configuration.getString("deftemplatesuffix", ""); - /* Default swamp shading off for 1.8, on after */ - boolean post_1_8 = !mc_ver.contains("1.8."); - swampshading = configuration.getBoolean("swampshaded", post_1_8); - /* Default water biome shading off for 1.8, on after */ - waterbiomeshading = configuration.getBoolean("waterbiomeshaded", post_1_8); - /* Default fence-to-block-join off for 1.8, on after */ - fencejoin = configuration.getBoolean("fence-to-block-join", post_1_8); - - /* Default compassmode to pre19, to newrose after */ - String cmode = configuration.getString("compass-mode", post_1_8?"newrose":"pre19"); - if(cmode.equals("newnorth")) - compassmode = CompassMode.NEWNORTH; - else if(cmode.equals("newrose")) - compassmode = CompassMode.NEWROSE; - else - compassmode = CompassMode.PRE19; - /* Default better-grass */ - bettergrass = configuration.getBoolean("better-grass", false); - /* Load full render processing player limit */ - fullrenderplayerlimit = configuration.getInteger("fullrenderplayerlimit", 0); - /* If we're persisting ids-by-ip, load it */ - persist_ids_by_ip = configuration.getBoolean("persist-ids-by-ip", true); - if(persist_ids_by_ip) - loadIDsByIP(); - - loadDebuggers(); - - tilesDirectory = getFile(configuration.getString("tilespath", "web/tiles")); - if (!tilesDirectory.isDirectory() && !tilesDirectory.mkdirs()) { - Log.warning("Could not create directory for tiles ('" + tilesDirectory + "')."); - } - - playerList = new PlayerList(getServer(), getFile("hiddenplayers.txt"), configuration); - playerList.load(); - - mapManager = new MapManager(this, configuration); - mapManager.startRendering(); - - playerfacemgr = new PlayerFaces(this); - - updateConfigHashcode(); /* Initialize/update config hashcode */ - - loadWebserver(); - - enabledTriggers.clear(); - List triggers = configuration.getStrings("render-triggers", new ArrayList()); - if (triggers != null) - { - for (Object trigger : triggers) { - enabledTriggers.add((String) trigger); - } - } - - // Load components. - for(Component component : configuration.createInstances("components", new Class[] { DynmapCore.class }, new Object[] { this })) { - componentManager.add(component); - } - Log.verboseinfo("Loaded " + componentManager.components.size() + " components."); - - if (!configuration.getBoolean("disable-webserver", false)) { - startWebserver(); - } - - /* Add login/logoff listeners */ - listenerManager.addListener(EventType.PLAYER_JOIN, new DynmapListenerManager.PlayerEventListener() { - @Override - public void playerEvent(DynmapPlayer p) { - playerJoined(p); - } - }); - listenerManager.addListener(EventType.PLAYER_QUIT, new DynmapListenerManager.PlayerEventListener() { - @Override - public void playerEvent(DynmapPlayer p) { - playerQuit(p); - } - }); - - /* Print version info */ - Log.info("version " + plugin_ver + " is enabled - core version " + version ); - - events.trigger("initialized", null); - - return true; - } - - private void playerJoined(DynmapPlayer p) { - playerList.updateOnlinePlayers(null); - if(fullrenderplayerlimit > 0) { - if((getServer().getOnlinePlayers().length+1) >= fullrenderplayerlimit) { - if(getPauseFullRadiusRenders() == false) { /* If not paused, pause it */ - setPauseFullRadiusRenders(true); - Log.info("Pause full/radius renders - player limit reached"); - didfullpause = true; - } - } - } - /* Add player info to IP-to-ID table */ - InetSocketAddress addr = p.getAddress(); - if(addr != null) { - String ip = addr.getAddress().getHostAddress(); - LinkedList ids = ids_by_ip.get(ip); - if(ids == null) { - ids = new LinkedList(); - ids_by_ip.put(ip, ids); - } - String pid = p.getName(); - if(ids.indexOf(pid) != 0) { - ids.remove(pid); /* Remove from list */ - ids.addFirst(pid); /* Put us first on list */ - } - } - /* And re-attach to active jobs */ - if(mapManager != null) - mapManager.connectTasksToPlayer(p); - } - - /* Called by plugin each time a player quits the server */ - private void playerQuit(DynmapPlayer p) { - playerList.updateOnlinePlayers(p.getName()); - if(fullrenderplayerlimit > 0) { - if((getServer().getOnlinePlayers().length-1) < fullrenderplayerlimit) { - if(didfullpause) { /* Only unpause if we did the pause */ - setPauseFullRadiusRenders(false); - Log.info("Resume full/radius renders - below player limit"); - didfullpause = false; - } - } - } - } - - public void updateConfigHashcode() { - config_hashcode = (int)System.currentTimeMillis(); - } - - public int getConfigHashcode() { - return config_hashcode; - } - - private FileResource createFileResource(String path) { - try { - return new FileResource(new URL("file://" + path)); - } catch(Exception e) { - Log.info("Could not create file resource"); - return null; - } - } - - public void loadWebserver() { - webServer = new Server(new InetSocketAddress(configuration.getString("webserver-bindaddress", "0.0.0.0"), configuration.getInteger("webserver-port", 8123))); - webServer.setStopAtShutdown(true); - webServer.setGracefulShutdown(1000); - - final boolean allow_symlinks = configuration.getBoolean("allow-symlinks", false); - int maxconnections = configuration.getInteger("max-sessions", 30); - if(maxconnections < 2) maxconnections = 2; - router = new HandlerRouter() {{ - this.addHandler("/", new ResourceHandler() {{ - this.setAliases(allow_symlinks); - this.setWelcomeFiles(new String[] { "index.html" }); - this.setDirectoriesListed(true); - this.setBaseResource(createFileResource(getFile(getWebPath()).getAbsolutePath())); - }}); - this.addHandler("/tiles/*", new ResourceHandler() {{ - this.setAliases(allow_symlinks); - this.setWelcomeFiles(new String[] { }); - this.setDirectoriesListed(true); - this.setBaseResource(createFileResource(tilesDirectory.getAbsolutePath())); - }}); - }}; - - if(allow_symlinks) - Log.verboseinfo("Web server is permitting symbolic links"); - else - Log.verboseinfo("Web server is not permitting symbolic links"); - - List filters = new LinkedList(); - - /* Check for banned IPs */ - boolean checkbannedips = configuration.getBoolean("check-banned-ips", true); - if (checkbannedips) { - filters.add(new BanIPFilter(this)); - } - - /* Load customized response headers, if any */ - filters.add(new CustomHeaderFilter(configuration.getNode("http-response-headers"))); - - webServer.setHandler(new FilterHandler(router, filters)); - - addServlet("/up/configuration", new org.dynmap.servlet.ClientConfigurationServlet(this)); - - } - - public Set getIPBans() { - return getServer().getIPBans(); - } - - public void addServlet(String path, HttpServlet servlet) { - new ServletHolder(servlet); - router.addServlet(path, servlet); - } - - - public void startWebserver() { - try { - webServer.start(); - } catch (Exception e) { - Log.severe("Failed to start WebServer!", e); - } - } - - public void disableCore() { - if(persist_ids_by_ip) - saveIDsByIP(); - if (componentManager != null) { - int componentCount = componentManager.components.size(); - for(Component component : componentManager.components) { - component.dispose(); - } - componentManager.clear(); - Log.info("Unloaded " + componentCount + " components."); - } - - if (mapManager != null) { - mapManager.stopRendering(); - mapManager = null; - } - - if (webServer != null) { - try { - webServer.stop(); - while(webServer.isStopping()) - Thread.sleep(100); - } catch (Exception e) { - Log.severe("Failed to stop WebServer!", e); - } - webServer = null; - } - playerfacemgr = null; - /* Clean up registered listeners */ - listenerManager.cleanup(); - - /* Don't clean up markerAPI - other plugins may still be accessing it */ - - Debug.clearDebuggers(); - } - - private static File combinePaths(File parent, String path) { - return combinePaths(parent, new File(path)); - } - - private static File combinePaths(File parent, File path) { - if (path.isAbsolute()) - return path; - return new File(parent, path.getPath()); - } - - public File getFile(String path) { - return combinePaths(getDataFolder(), path); - } - - protected void loadDebuggers() { - List debuggersConfiguration = configuration.getNodes("debuggers"); - Debug.clearDebuggers(); - for (ConfigurationNode debuggerConfiguration : debuggersConfiguration) { - try { - Class debuggerClass = Class.forName((String) debuggerConfiguration.getString("class")); - Constructor constructor = debuggerClass.getConstructor(DynmapCore.class, ConfigurationNode.class); - Debugger debugger = (Debugger) constructor.newInstance(this, debuggerConfiguration); - Debug.addDebugger(debugger); - } catch (Exception e) { - Log.severe("Error loading debugger: " + e); - e.printStackTrace(); - continue; - } - } - } - - /* Parse argument strings : handle quoted strings */ - public static String[] parseArgs(String[] args, DynmapCommandSender snd) { - ArrayList rslt = new ArrayList(); - /* Build command line, so we can parse our way - make sure there is trailing space */ - String cmdline = ""; - for(int i = 0; i < args.length; i++) { - cmdline += args[i] + " "; - } - boolean inquote = false; - StringBuilder sb = new StringBuilder(); - for(int i = 0; i < cmdline.length(); i++) { - char c = cmdline.charAt(i); - if(inquote) { /* If in quote, accumulate until end or another quote */ - if(c == '\"') { /* End quote */ - inquote = false; - } - else { - sb.append(c); - } - } - else if(c == '\"') { /* Start of quote? */ - inquote = true; - } - else if(c == ' ') { /* Ending space? */ - rslt.add(sb.toString()); - sb.setLength(0); - } - else { - sb.append(c); - } - } - if(inquote) { /* If still in quote, syntax error */ - snd.sendMessage("Error: unclosed doublequote"); - return null; - } - return rslt.toArray(new String[rslt.size()]); - } - - private static final Set commands = new HashSet(Arrays.asList(new String[] { - "render", - "hide", - "show", - "fullrender", - "cancelrender", - "radiusrender", - "updaterender", - "reload", - "stats", - "triggerstats", - "resetstats", - "sendtoweb", - "pause", - "purgequeue", - "ids-for-ip", - "ips-for-id", - "add-id-for-ip", - "del-id-for-ip"})); - - public boolean processCommand(DynmapCommandSender sender, String cmd, String commandLabel, String[] args) { - if(cmd.equalsIgnoreCase("dmarker")) { - return MarkerAPIImpl.onCommand(this, sender, cmd, commandLabel, args); - } - if (!cmd.equalsIgnoreCase("dynmap")) - return false; - DynmapPlayer player = null; - if (sender instanceof DynmapPlayer) - player = (DynmapPlayer) sender; - /* Re-parse args - handle doublequotes */ - args = parseArgs(args, sender); - - if(args == null) - return false; - - if (args.length > 0) { - String c = args[0]; - if (!commands.contains(c)) { - return false; - } - - if (c.equals("render") && checkPlayerPermission(sender,"render")) { - if (player != null) { - DynmapLocation loc = player.getLocation(); - - mapManager.touch(loc.world, (int)loc.x, (int)loc.y, (int)loc.z, "render"); - - sender.sendMessage("Tile render queued."); - } - else { - sender.sendMessage("Command can only be issued by player."); - } - } - else if(c.equals("radiusrender") && checkPlayerPermission(sender,"radiusrender")) { - int radius = 0; - String mapname = null; - DynmapLocation loc = null; - if(args.length == 2) { /* Just radius */ - radius = Integer.parseInt(args[1]); /* Parse radius */ - if(radius < 0) - radius = 0; - if(args.length > 2) - mapname = args[2]; - if (player != null) - loc = player.getLocation(); - else - sender.sendMessage("Command require if issued from console."); - } - else if(args.length > 3) { /* */ - DynmapWorld w = mapManager.worldsLookup.get(args[1]); /* Look up world */ - if(w == null) { - sender.sendMessage("World '" + args[1] + "' not defined/loaded"); - } - int x = 0, z = 0; - x = Integer.parseInt(args[2]); - z = Integer.parseInt(args[3]); - if(args.length > 4) - radius = Integer.parseInt(args[4]); - if(args.length > 5) - mapname = args[5]; - if(w != null) - loc = new DynmapLocation(w.getName(), x, 64, z); - } - if(loc != null) - mapManager.renderWorldRadius(loc, sender, mapname, radius); - } else if(c.equals("updaterender") && checkPlayerPermission(sender,"updaterender")) { - String mapname = null; - DynmapLocation loc = null; - if(args.length <= 3) { /* Just command, or command plus map */ - if(args.length > 2) - mapname = args[2]; - if (player != null) - loc = player.getLocation(); - else - sender.sendMessage("Command require if issued from console."); - } - else { /* */ - DynmapWorld w = mapManager.worldsLookup.get(args[1]); /* Look up world */ - if(w == null) { - sender.sendMessage("World '" + args[1] + "' not defined/loaded"); - } - int x = 0, z = 0; - x = Integer.parseInt(args[2]); - z = Integer.parseInt(args[3]); - if(args.length > 4) - mapname = args[4]; - if(w != null) - loc = new DynmapLocation(w.getName(), x, 64, z); - } - if(loc != null) - mapManager.renderFullWorld(loc, sender, mapname, true); - } else if (c.equals("hide")) { - if (args.length == 1) { - if(player != null && checkPlayerPermission(sender,"hide.self")) { - playerList.setVisible(player.getName(),false); - sender.sendMessage("You are now hidden on Dynmap."); - } - } else if (checkPlayerPermission(sender,"hide.others")) { - for (int i = 1; i < args.length; i++) { - playerList.setVisible(args[i],false); - sender.sendMessage(args[i] + " is now hidden on Dynmap."); - } - } - } else if (c.equals("show")) { - if (args.length == 1) { - if(player != null && checkPlayerPermission(sender,"show.self")) { - playerList.setVisible(player.getName(),true); - sender.sendMessage("You are now visible on Dynmap."); - } - } else if (checkPlayerPermission(sender,"show.others")) { - for (int i = 1; i < args.length; i++) { - playerList.setVisible(args[i],true); - sender.sendMessage(args[i] + " is now visible on Dynmap."); - } - } - } else if (c.equals("fullrender") && checkPlayerPermission(sender,"fullrender")) { - String map = null; - if (args.length > 1) { - for (int i = 1; i < args.length; i++) { - int dot = args[i].indexOf(":"); - DynmapWorld w; - String wname = args[i]; - if(dot >= 0) { - wname = args[i].substring(0, dot); - map = args[i].substring(dot+1); - } - w = mapManager.getWorld(wname); - if(w != null) { - DynmapLocation spawn = w.getSpawnLocation(); - DynmapLocation loc = new DynmapLocation(wname, w.configuration.getDouble("center/x", spawn.x), w.configuration.getDouble("center/y", spawn.y), w.configuration.getDouble("center/z", spawn.z)); - mapManager.renderFullWorld(loc,sender, map, false); - } - else - sender.sendMessage("World '" + wname + "' not defined/loaded"); - } - } else if (player != null) { - DynmapLocation loc = player.getLocation(); - if(args.length > 1) - map = args[1]; - if(loc != null) - mapManager.renderFullWorld(loc, sender, map, false); - } else { - sender.sendMessage("World name is required"); - } - } else if (c.equals("cancelrender") && checkPlayerPermission(sender,"cancelrender")) { - if (args.length > 1) { - for (int i = 1; i < args.length; i++) { - DynmapWorld w = mapManager.getWorld(args[i]); - if(w != null) - mapManager.cancelRender(w.getName(), sender); - else - sender.sendMessage("World '" + args[i] + "' not defined/loaded"); - } - } else if (player != null) { - DynmapLocation loc = player.getLocation(); - if(loc != null) - mapManager.cancelRender(loc.world, sender); - } else { - sender.sendMessage("World name is required"); - } - } else if (c.equals("purgequeue") && checkPlayerPermission(sender, "purgequeue")) { - mapManager.purgeQueue(sender); - } else if (c.equals("reload") && checkPlayerPermission(sender, "reload")) { - sender.sendMessage("Reloading Dynmap..."); - getServer().reload(); - sender.sendMessage("Dynmap reloaded"); - } else if (c.equals("stats") && checkPlayerPermission(sender, "stats")) { - if(args.length == 1) - mapManager.printStats(sender, null); - else - mapManager.printStats(sender, args[1]); - } else if (c.equals("triggerstats") && checkPlayerPermission(sender, "stats")) { - mapManager.printTriggerStats(sender); - } else if (c.equals("pause") && checkPlayerPermission(sender, "pause")) { - if(args.length == 1) { - } - else if(args[1].equals("full")) { - setPauseFullRadiusRenders(true); - setPauseUpdateRenders(false); - } - else if(args[1].equals("update")) { - setPauseFullRadiusRenders(false); - setPauseUpdateRenders(true); - } - else if(args[1].equals("all")) { - setPauseFullRadiusRenders(true); - setPauseUpdateRenders(true); - } - else { - setPauseFullRadiusRenders(false); - setPauseUpdateRenders(false); - } - if(getPauseFullRadiusRenders()) - sender.sendMessage("Full/Radius renders are PAUSED"); - else - sender.sendMessage("Full/Radius renders are ACTIVE"); - if(getPauseUpdateRenders()) - sender.sendMessage("Update renders are PAUSED"); - else - sender.sendMessage("Update renders are ACTIVE"); - } else if (c.equals("resetstats") && checkPlayerPermission(sender, "resetstats")) { - if(args.length == 1) - mapManager.resetStats(sender, null); - else - mapManager.resetStats(sender, args[1]); - } else if (c.equals("sendtoweb") && checkPlayerPermission(sender, "sendtoweb")) { - String msg = ""; - for(int i = 1; i < args.length; i++) { - msg += args[i] + " "; - } - this.sendBroadcastToWeb("dynmap", msg); - } else if(c.equals("ids-for-ip") && checkPlayerPermission(sender, "ids-for-ip")) { - if(args.length > 1) { - List ids = getIDsForIP(args[1]); - sender.sendMessage("IDs logged in from address " + args[1] + " (most recent to least):"); - if(ids != null) { - for(String id : ids) - sender.sendMessage(" " + id); - } - } - else { - sender.sendMessage("IP address required as parameter"); - } - } else if(c.equals("ips-for-id") && checkPlayerPermission(sender, "ips-for-id")) { - if(args.length > 1) { - sender.sendMessage("IP addresses logged for player " + args[1] + ":"); - for(String ip: ids_by_ip.keySet()) { - LinkedList ids = ids_by_ip.get(ip); - if((ids != null) && ids.contains(args[1])) { - sender.sendMessage(" " + ip); - } - } - } - else { - sender.sendMessage("Player ID required as parameter"); - } - } else if((c.equals("add-id-for-ip") && checkPlayerPermission(sender, "add-id-for-ip")) || - (c.equals("del-id-for-ip") && checkPlayerPermission(sender, "del-id-for-ip"))) { - if(args.length > 2) { - String ipaddr = ""; - try { - InetAddress ip = InetAddress.getByName(args[2]); - ipaddr = ip.getHostAddress(); - } catch (UnknownHostException uhx) { - sender.sendMessage("Invalid address : " + args[2]); - return false; - } - LinkedList ids = ids_by_ip.get(ipaddr); - if(ids == null) { - ids = new LinkedList(); - ids_by_ip.put(ipaddr, ids); - } - ids.remove(args[1]); /* Remove existing, if any */ - if(c.equals("add-id-for-ip")) { - ids.addFirst(args[1]); /* And add us first */ - sender.sendMessage("Added player ID '" + args[1] + "' to address '" + ipaddr + "'"); - } - else { - sender.sendMessage("Removed player ID '" + args[1] + "' from address '" + ipaddr + "'"); - } - saveIDsByIP(); - } - else { - sender.sendMessage("Needs player ID and IP address"); - } - } - return true; - } - return false; - } - - public boolean checkPlayerPermission(DynmapCommandSender sender, String permission) { - if (!(sender instanceof DynmapPlayer) || sender.isOp()) { - return true; - } else if (!sender.hasPrivilege(permission.toLowerCase())) { - sender.sendMessage("You don't have permission to use this command!"); - return false; - } - return true; - } - - public ConfigurationNode getWorldConfiguration(DynmapWorld world) { - ConfigurationNode finalConfiguration = new ConfigurationNode(); - finalConfiguration.put("name", world.getName()); - finalConfiguration.put("title", world.getName()); - - ConfigurationNode worldConfiguration = getWorldConfigurationNode(world.getName()); - - // Get the template. - ConfigurationNode templateConfiguration = null; - if (worldConfiguration != null) { - String templateName = worldConfiguration.getString("template"); - if (templateName != null) { - templateConfiguration = getTemplateConfigurationNode(templateName); - } - } - - // Template not found, using default template. - if (templateConfiguration == null) { - templateConfiguration = getDefaultTemplateConfigurationNode(world); - } - - // Merge the finalConfiguration, templateConfiguration and worldConfiguration. - finalConfiguration.extend(templateConfiguration); - finalConfiguration.extend(worldConfiguration); - - Log.verboseinfo("Configuration of world " + world.getName()); - for(Map.Entry e : finalConfiguration.entrySet()) { - Log.verboseinfo(e.getKey() + ": " + e.getValue()); - } - - return finalConfiguration; - } - - private ConfigurationNode getDefaultTemplateConfigurationNode(DynmapWorld world) { - String environmentName = world.getEnvironment(); - if(deftemplatesuffix.length() > 0) { - environmentName += "-" + deftemplatesuffix; - } - Log.verboseinfo("Using environment as template: " + environmentName); - return getTemplateConfigurationNode(environmentName); - } - - private ConfigurationNode getWorldConfigurationNode(String worldName) { - for(ConfigurationNode worldNode : configuration.getNodes("worlds")) { - if (worldName.equals(worldNode.getString("name"))) { - return worldNode; - } - } - return new ConfigurationNode(); - } - - private ConfigurationNode getTemplateConfigurationNode(String templateName) { - ConfigurationNode templatesNode = configuration.getNode("templates"); - if (templatesNode != null) { - return templatesNode.getNode(templateName); - } - return null; - } - - - public String getWebPath() { - return configuration.getString("webpath", "web"); - } - - public static void setIgnoreChunkLoads(boolean ignore) { - ignore_chunk_loads = ignore; - } - /* Uses resource to create default file, if file does not yet exist */ - public boolean createDefaultFileFromResource(String resourcename, File deffile) { - if(deffile.canRead()) - return true; - Log.info(deffile.getPath() + " not found - creating default"); - InputStream in = getClass().getResourceAsStream(resourcename); - if(in == null) { - Log.severe("Unable to find default resource - " + resourcename); - return false; - } - else { - FileOutputStream fos = null; - try { - fos = new FileOutputStream(deffile); - byte[] buf = new byte[512]; - int len; - while((len = in.read(buf)) > 0) { - fos.write(buf, 0, len); - } - } catch (IOException iox) { - Log.severe("ERROR creatomg default for " + deffile.getPath()); - return false; - } finally { - if(fos != null) - try { fos.close(); } catch (IOException iox) {} - if(in != null) - try { in.close(); } catch (IOException iox) {} - } - return true; - } - } - - /* - * Add in any missing sections to existing file, using resource - */ - public boolean updateUsingDefaultResource(String resourcename, File deffile, String basenode) { - InputStream in = getClass().getResourceAsStream(resourcename); - if(in == null) { - Log.severe("Unable to find resource - " + resourcename); - return false; - } - if(deffile.canRead() == false) { /* Doesn't exist? */ - return createDefaultFileFromResource(resourcename, deffile); - } - /* Load default from resource */ - ConfigurationNode def_fc = new ConfigurationNode(in); - /* Load existing from file */ - ConfigurationNode fc = new ConfigurationNode(deffile); - fc.load(); - /* Now, get the list associated with the base node default */ - List> existing = fc.getMapList(basenode); - Set existing_names = new HashSet(); - /* Make map, indexed by 'name' in map */ - if(existing != null) { - for(Map m : existing) { - Object name = m.get("name"); - if(name instanceof String) - existing_names.add((String)name); - } - } - boolean did_update = false; - /* Now, loop through defaults, and see if any are missing */ - List> defmaps = def_fc.getMapList(basenode); - if(defmaps != null) { - for(Map m : defmaps) { - Object name = m.get("name"); - if(name instanceof String) { - /* If not an existing one, need to add it */ - if(existing_names.contains((String)name) == false) { - existing.add(m); - did_update = true; - } - } - } - } - /* If we did update, save existing */ - if(did_update) { - fc.put(basenode, existing); - fc.save(deffile); - Log.info("Updated file " + deffile.getPath()); - } - return true; - } - - - /** - * ** This is the public API for other plugins to use for accessing the Marker API ** - * This method can return null if the 'markers' component has not been configured - - * a warning message will be issued to the server.log in this event. - * - * @return MarkerAPI, or null if not configured - */ - public MarkerAPI getMarkerAPI() { - if(markerapi == null) { - Log.warning("Marker API has been requested, but is not enabled. Uncomment or add 'markers' component to configuration.txt."); - } - return markerapi; - } - public boolean markerAPIInitialized() { - return (markerapi != null); - } - /** - * Send generic message to all web users - * @param sender - label for sender of message ("[] nessage") - if null, no from notice - * @param msg - message to be sent - */ - public boolean sendBroadcastToWeb(String sender, String msg) { - if(mapManager != null) { - mapManager.pushUpdate(new Client.ChatMessage("plugin", sender, "", msg, "")); - return true; - } - return false; - } - /** - * Register markers API - used by component to supply marker API to plugin - */ - public void registerMarkerAPI(MarkerAPIImpl api) { - markerapi = api; - } - /* - * Pause full/radius render processing - * @param dopause - true to pause, false to unpause - */ - public void setPauseFullRadiusRenders(boolean dopause) { - mapManager.setPauseFullRadiusRenders(dopause); - } - /* - * Test if full renders are paused - */ - public boolean getPauseFullRadiusRenders() { - return mapManager.getPauseFullRadiusRenders(); - } - /* - * Pause update render processing - * @param dopause - true to pause, false to unpause - */ - public void setPauseUpdateRenders(boolean dopause) { - mapManager.setPauseUpdateRenders(dopause); - } - /* - * Test if update renders are paused - */ - public boolean getPauseUpdateRenders() { - return mapManager.getPauseUpdateRenders(); - } - /** - * Get list of IDs seen on give IP (most recent to least recent) - */ - public List getIDsForIP(InetAddress addr) { - return getIDsForIP(addr.getHostAddress()); - } - /** - * Get list of IDs seen on give IP (most recent to least recent) - */ - public List getIDsForIP(String ip) { - LinkedList ids = ids_by_ip.get(ip); - if(ids != null) - return new ArrayList(ids); - return null; - } - - private void loadIDsByIP() { - File f = new File(getDataFolder(), "ids-by-ip.txt"); - if(f.exists() == false) - return; - ConfigurationNode fc = new ConfigurationNode(new File(getDataFolder(), "ids-by-ip.txt")); - try { - fc.load(); - ids_by_ip.clear(); - for(String k : fc.keySet()) { - List ids = fc.getList(k); - if(ids != null) { - k = k.replace("_", "."); - ids_by_ip.put(k, new LinkedList(ids)); - } - } - } catch (Exception iox) { - Log.severe("Error loading " + f.getPath() + " - " + iox.getMessage()); - } - } - private void saveIDsByIP() { - File f = new File(getDataFolder(), "ids-by-ip.txt"); - ConfigurationNode fc = new ConfigurationNode(); - for(String k : ids_by_ip.keySet()) { - List v = ids_by_ip.get(k); - if(v != null) { - k = k.replace(".", "_"); - fc.put(k, v); - } - } - try { - fc.save(f); - } catch (Exception x) { - Log.severe("Error saving " + f.getPath() + " - " + x.getMessage()); - } - } - - public void setPlayerVisiblity(String player, boolean is_visible) { - playerList.setVisible(player, is_visible); - } - - public boolean getPlayerVisbility(String player) { - return playerList.isVisiblePlayer(player); - } - - public void postPlayerMessageToWeb(String playerid, String playerdisplay, String message) { - if(playerdisplay == null) playerdisplay = playerid; - if(mapManager != null) - mapManager.pushUpdate(new Client.ChatMessage("player", "", playerid, message, playerdisplay)); - } - - public void postPlayerJoinQuitToWeb(String playerid, String playerdisplay, boolean isjoin) { - if(playerdisplay == null) playerdisplay = playerid; - if((mapManager != null) && (playerList != null) && (playerList.isVisiblePlayer(playerid))) { - if(isjoin) - mapManager.pushUpdate(new Client.PlayerJoinMessage(playerid, playerdisplay)); - else - mapManager.pushUpdate(new Client.PlayerQuitMessage(playerid, playerdisplay)); - } - } - - public String getDynmapCoreVersion() { - return version; - } - - public int triggerRenderOfBlock(String wid, int x, int y, int z) { - if(mapManager != null) - mapManager.touch(wid, x, y, z, "api"); - return 0; - } - - public int triggerRenderOfVolume(String wid, int minx, int miny, int minz, int maxx, int maxy, int maxz) { - if(mapManager != null) { - if((minx == maxx) && (miny == maxy) && (minz == maxz)) - mapManager.touch(wid, minx, miny, minz, "api"); - else - mapManager.touchVolume(wid, minx, miny, minz, maxx, maxy, maxz, "api"); - } - return 0; - } - - public boolean isTrigger(String s) { - return enabledTriggers.contains(s); - } - - public DynmapWorld getWorld(String wid) { - if(mapManager != null) - return mapManager.getWorld(wid); - return null; - } - /* Called by plugin when world loaded */ - public boolean processWorldLoad(DynmapWorld w) { - return mapManager.activateWorld(w); - } - - /* Load core version */ - private void loadVersion() { - InputStream in = getClass().getResourceAsStream("/core.yml"); - if(in == null) - return; - Yaml yaml = new Yaml(); - @SuppressWarnings("unchecked") - Map val = (Map)yaml.load(in); - if(val != null) - version = (String)val.get("version"); - } -} diff --git a/src/main/java/org/dynmap/DynmapLocation.java b/src/main/java/org/dynmap/DynmapLocation.java deleted file mode 100644 index 89f41e8c..00000000 --- a/src/main/java/org/dynmap/DynmapLocation.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/java/org/dynmap/DynmapWorld.java b/src/main/java/org/dynmap/DynmapWorld.java deleted file mode 100644 index b547c54c..00000000 --- a/src/main/java/org/dynmap/DynmapWorld.java +++ /dev/null @@ -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 maps = new ArrayList(); - public UpdateQueue updates = new UpdateQueue(); - public ConfigurationNode configuration; - public List seedloc; - public List visibility_limits; - public List 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 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(); - 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 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(); - } - 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 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 toprocess = new HashMap(); - /* 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 buildPrefixData(int zoomlevel) { - HashMap maptab = new HashMap(); - /* 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 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 toprocess = new HashMap(); - 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 chunks); - -} diff --git a/src/main/java/org/dynmap/Event.java b/src/main/java/org/dynmap/Event.java deleted file mode 100644 index 5d3acd81..00000000 --- a/src/main/java/org/dynmap/Event.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.dynmap; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - -public class Event { - private List> listeners = new LinkedList>(); - private Object lock = new Object(); - - public void addListener(Listener l) { - synchronized(lock) { - listeners.add(l); - } - } - - public void removeListener(Listener l) { - synchronized(lock) { - listeners.remove(l); - } - } - - public void trigger(T t) { - ArrayList> iterlist; - synchronized(lock) { - iterlist = new ArrayList>(listeners); - } - for (Listener l : iterlist) { - l.triggered(t); - } - } - - public interface Listener { - void triggered(T t); - } -} diff --git a/src/main/java/org/dynmap/Events.java b/src/main/java/org/dynmap/Events.java deleted file mode 100644 index 3804fc56..00000000 --- a/src/main/java/org/dynmap/Events.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.dynmap; -import java.util.HashMap; -import java.util.Map; - - -public class Events { - public Map> events = new HashMap>(); - @SuppressWarnings("unchecked") - public void addListener(String eventName, Event.Listener listener) { - Event genericEvent = events.get(eventName); - Event event = null; - if (genericEvent != null) { - event = (Event)genericEvent; - } else { - events.put(eventName, event = new Event()); - } - event.addListener(listener); - } - - @SuppressWarnings("unchecked") - public void removeListener(String eventName, Event.Listener listener) { - Event genericEvent = events.get(eventName); - Event event = null; - if (genericEvent != null) { - event = (Event)genericEvent; - event.removeListener(listener); - } - } - - @SuppressWarnings("unchecked") - public void trigger(String eventName, T argument) { - Event genericEvent = events.get(eventName); - if (genericEvent == null) - return; - ((Event)genericEvent).trigger(argument); - } -} diff --git a/src/main/java/org/dynmap/Handler.java b/src/main/java/org/dynmap/Handler.java deleted file mode 100644 index 2a72acd4..00000000 --- a/src/main/java/org/dynmap/Handler.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.dynmap; - -public interface Handler { - void handle(T t); -} diff --git a/src/main/java/org/dynmap/InternalClientUpdateComponent.java b/src/main/java/org/dynmap/InternalClientUpdateComponent.java deleted file mode 100644 index 3de6459a..00000000 --- a/src/main/java/org/dynmap/InternalClientUpdateComponent.java +++ /dev/null @@ -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() { - @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 () { - @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); - } -} diff --git a/src/main/java/org/dynmap/JSONUtils.java b/src/main/java/org/dynmap/JSONUtils.java deleted file mode 100644 index 333eadb9..00000000 --- a/src/main/java/org/dynmap/JSONUtils.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/java/org/dynmap/JsonFileClientUpdateComponent.java b/src/main/java/org/dynmap/JsonFileClientUpdateComponent.java deleted file mode 100644 index 96221878..00000000 --- a/src/main/java/org/dynmap/JsonFileClientUpdateComponent.java +++ /dev/null @@ -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 useralias = new HashMap(); - 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() { - @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() { - @Override - public void triggered(Object t) { - writeConfiguration(); - } - }); - plugin.events.addListener("worldactivated", new Event.Listener() { - @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.trigger("clientupdatewritten", clientUpdate); - } - - core.events.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 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(); - } -} diff --git a/src/main/java/org/dynmap/Log.java b/src/main/java/org/dynmap/Log.java deleted file mode 100644 index 85ffcad9..00000000 --- a/src/main/java/org/dynmap/Log.java +++ /dev/null @@ -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); - } -} diff --git a/src/main/java/org/dynmap/MapManager.java b/src/main/java/org/dynmap/MapManager.java deleted file mode 100644 index 8f68c114..00000000 --- a/src/main/java/org/dynmap/MapManager.java +++ /dev/null @@ -1,1500 +0,0 @@ -package org.dynmap; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.TreeSet; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; - -import org.dynmap.DynmapCore.CompassMode; -import org.dynmap.DynmapWorld.AutoGenerateOption; -import org.dynmap.bukkit.SnapshotCache; -import org.dynmap.common.DynmapCommandSender; -import org.dynmap.common.DynmapPlayer; -import org.dynmap.debug.Debug; -import org.dynmap.hdmap.HDMapManager; -import org.dynmap.utils.MapChunkCache; -import org.dynmap.utils.TileFlags; - -public class MapManager { - public AsynchronousQueue tileQueue; - - private static final int DEFAULT_CHUNKS_PER_TICK = 200; - private static final int DEFAULT_ZOOMOUT_PERIOD = 60; - public List worlds = new ArrayList(); - public Map worldsLookup = new HashMap(); - private DynmapCore core; - private long timeslice_int = 0; /* In milliseconds */ - private int max_chunk_loads_per_tick = DEFAULT_CHUNKS_PER_TICK; - private int parallelrendercnt = 0; - private int progressinterval = 100; - private boolean saverestorepending = true; - private boolean hideores = false; - private boolean usenormalpriority = false; - - private boolean pauseupdaterenders = false; - private boolean pausefullrenders = false; - - private boolean did_start = false; - - private int zoomout_period = DEFAULT_ZOOMOUT_PERIOD; /* Zoom-out tile processing period, in seconds */ - /* Which fullrenders are active */ - private HashMap active_renders = new HashMap(); - - /* Chunk load handling */ - private Object loadlock = new Object(); - private int chunks_in_cur_tick = 0; - private long cur_tick; - - /* Chunk load performance numbers */ - AtomicInteger chunk_caches_created = new AtomicInteger(0); - AtomicInteger chunk_caches_attempted = new AtomicInteger(0); - AtomicLong total_chunk_cache_loadtime_ns = new AtomicLong(0); - AtomicInteger chunks_read = new AtomicInteger(0);; - AtomicInteger chunks_attempted = new AtomicInteger(0); - AtomicLong total_loadtime_ns = new AtomicLong(0L); - AtomicLong total_exceptions = new AtomicLong(0L); - AtomicInteger ticklistcalls = new AtomicInteger(0); - - /* Tile hash manager */ - public TileHashManager hashman; - /* lock for our data structures */ - public static final Object lock = new Object(); - - public static MapManager mapman; /* Our singleton */ - public HDMapManager hdmapman; - public SnapshotCache sscache; - - /* Thread pool for processing renders */ - private DynmapScheduledThreadPoolExecutor render_pool; - private static final int POOL_SIZE = 3; - - /* Touch event queues */ - private static class TouchEvent { - int x, y, z; - String world; - String reason; - @Override - public int hashCode() { - return (x << 16) ^ (y << 24) ^ z; - } - @Override - public boolean equals(Object o) { - if(this == o) return true; - TouchEvent te = (TouchEvent)o; - if((x != te.x) || (y != te.y) || (z != te.z) || (world.equals(te.world) == false)) - return false; - return true; - } - } - private static class TouchVolumeEvent { - int xmin, ymin, zmin; - int xmax, ymax, zmax; - String world; - String reason; - } - private ConcurrentHashMap touch_events = new ConcurrentHashMap(); - private LinkedList touch_volume_events = new LinkedList(); - private Object touch_lock = new Object(); - - private HashMap mapstats = new HashMap(); - - private static class MapStats { - int loggedcnt; - int renderedcnt; - int updatedcnt; - int transparentcnt; - } - /* synchronized using 'lock' */ - private HashMap trigstats = new HashMap(); - - - private static class TriggerStats { - long callsmade; - long callswithtiles; - long tilesqueued; - } - - public DynmapWorld getWorld(String name) { - DynmapWorld world = worldsLookup.get(name); - return world; - } - - public Collection getWorlds() { - return worlds; - } - - private static class OurThreadFactory implements ThreadFactory { - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r); - t.setDaemon(true); - if(!mapman.usenormalpriority) - t.setPriority(Thread.MIN_PRIORITY); - t.setName("Dynmap Render Thread"); - return t; - } - } - - private class DynmapScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { - DynmapScheduledThreadPoolExecutor() { - super(POOL_SIZE + parallelrendercnt); - this.setThreadFactory(new OurThreadFactory()); - /* Set shutdown policy to stop everything */ - setContinueExistingPeriodicTasksAfterShutdownPolicy(false); - setExecuteExistingDelayedTasksAfterShutdownPolicy(false); - } - - protected void afterExecute(Runnable r, Throwable x) { - if(r instanceof FullWorldRenderState) { - ((FullWorldRenderState)r).cleanup(); - } - if(x != null) { - Log.severe("Exception during render job: " + r); - x.printStackTrace(); - } - } - @Override - public void execute(final Runnable r) { - try { - super.execute(new Runnable() { - public void run() { - try { - r.run(); - } catch (Exception x) { - Log.severe("Exception during render job: " + r); - x.printStackTrace(); - } - } - }); - } catch (RejectedExecutionException rxe) { /* Pool shutdown - nominal for reload or unload */ - } - } - @Override - public ScheduledFuture schedule(final Runnable command, long delay, TimeUnit unit) { - try { - return super.schedule(new Runnable() { - public void run() { - try { - command.run(); - } catch (Exception x) { - Log.severe("Exception during render job: " + command); - x.printStackTrace(); - } - } - }, delay, unit); - } catch (RejectedExecutionException rxe) { - return null; /* Pool shut down when we reload or unload */ - } - } - } - private static final String RENDERTYPE_FULLRENDER = "Full render"; - private static final String RENDERTYPE_RADIUSRENDER = "Radius render"; - private static final String RENDERTYPE_UPDATERENDER = "Update render"; - - /* This always runs on render pool threads - no bukkit calls from here */ - private class FullWorldRenderState implements Runnable { - DynmapWorld world; /* Which world are we rendering */ - DynmapLocation loc; - int map_index = -1; /* Which map are we on */ - MapType map; - TileFlags found = null; - TileFlags rendered = null; - LinkedList renderQueue = null; - MapTile tile0 = null; - int rendercnt = 0; - DynmapCommandSender sender; - String player; - long timeaccum; - HashSet renderedmaps = new HashSet(); - String activemaps; - int activemapcnt; - /* Min and max limits for chunk coords (for radius limit) */ - int cxmin, cxmax, czmin, czmax; - String rendertype; - boolean cancelled; - boolean updaterender = false; - String mapname; - AtomicLong total_render_ns = new AtomicLong(0L); - AtomicInteger rendercalls = new AtomicInteger(0); - - /* Full world, all maps render */ - FullWorldRenderState(DynmapWorld dworld, DynmapLocation l, DynmapCommandSender sender, String mapname, boolean updaterender) { - this(dworld, l, sender, mapname, -1); - if(updaterender) { - rendertype = RENDERTYPE_UPDATERENDER; - this.updaterender = true; - } - else - rendertype = RENDERTYPE_FULLRENDER; - } - - /* Full world, all maps render, with optional render radius */ - FullWorldRenderState(DynmapWorld dworld, DynmapLocation l, DynmapCommandSender sender, String mapname, int radius) { - world = dworld; - loc = l; - found = new TileFlags(); - rendered = new TileFlags(); - renderQueue = new LinkedList(); - this.sender = sender; - if(sender instanceof DynmapPlayer) - this.player = ((DynmapPlayer)sender).getName(); - else - this.player = ""; - if(radius < 0) { - cxmin = czmin = Integer.MIN_VALUE; - cxmax = czmax = Integer.MAX_VALUE; - rendertype = RENDERTYPE_FULLRENDER; - } - else { - cxmin = ((int)l.x - radius)>>4; - czmin = ((int)l.z - radius)>>4; - cxmax = ((int)l.x + radius + 15)>>4; - czmax = ((int)l.z + radius + 15)>>4; - rendertype = RENDERTYPE_RADIUSRENDER; - } - this.mapname = mapname; - } - - /* Single tile render - used for incremental renders */ - FullWorldRenderState(MapTile t) { - world = getWorld(t.getDynmapWorld().getName()); - tile0 = t; - cxmin = czmin = Integer.MIN_VALUE; - cxmax = czmax = Integer.MAX_VALUE; - } - - FullWorldRenderState(ConfigurationNode n) throws Exception { - String w = n.getString("world", ""); - world = getWorld(w); - if(world == null) throw new Exception(); - loc = new DynmapLocation(); - loc.world = world.getName(); - loc.x = (int)n.getDouble("locX", 0.0); - loc.y = (int)n.getDouble("locY", 0.0); - loc.z = (int)n.getDouble("locZ", 0.0); - String m = n.getString("map",""); - map_index = n.getInteger("mapindex", -1); - map = world.maps.get(map_index); - if((map == null) || (map.getName().equals(m) == false)) throw new Exception(); - found = new TileFlags(); - List sl = n.getStrings("found", null); - if(sl != null) - found.load(sl); - rendered = new TileFlags(); - sl = n.getStrings("rendered", null); - if(sl != null) - rendered.load(sl); - renderQueue = new LinkedList(); - List tl = n.getNodes("queue"); - if(tl != null) { - for(ConfigurationNode cn : tl) { - MapTile mt = MapTile.restoreTile(world, cn); - if(mt != null) { - renderQueue.add(mt); - } - } - } - rendercnt = n.getInteger("count", 0); - timeaccum = n.getInteger("timeaccum", 0); - renderedmaps = new HashSet(); - sl = n.getStrings("renderedmaps", null); - if(sl != null) { - for(String s : sl) { - for(int i = 0; i < world.maps.size(); i++) { - MapType mt = world.maps.get(i); - if(mt.getName().equals(s)) { - renderedmaps.add(mt); - break; - } - } - } - if(sl.size() > renderedmaps.size()) { /* Missed one or more? */ - throw new Exception(); - } - } - activemaps = n.getString("activemaps", ""); - activemapcnt = n.getInteger("activemapcnt", 0); - cxmin = n.getInteger("cxmin", 0); - cxmax = n.getInteger("cxmax", 0); - czmin = n.getInteger("czmin", 0); - czmax = n.getInteger("czmax", 0); - rendertype = n.getString("rendertype", ""); - mapname = n.getString("mapname", null); - player = n.getString("player", ""); - updaterender = rendertype.equals(RENDERTYPE_UPDATERENDER); - sender = null; - if(player.length() > 0) { - sender = core.getServer().getPlayer(player); - } - } - - public HashMap saveState() { - HashMap v = new HashMap(); - - v.put("world", world.getName()); - v.put("locX", loc.x); - v.put("locY", loc.y); - v.put("locZ", loc.z); - v.put("mapindex", map_index); - v.put("map", map.getName()); - v.put("found", found.save()); - v.put("rendered", rendered.save()); - LinkedList queue = new LinkedList(); - for(MapTile tq : renderQueue) { - ConfigurationNode n = tq.saveTile(); - if(n != null) - queue.add(n); - } - v.put("queue", queue); - v.put("count", rendercnt); - v.put("timeaccum", timeaccum); - LinkedList rmaps = new LinkedList(); - for(MapType mt : renderedmaps) { - rmaps.add(mt.getName()); - } - v.put("renderedmaps", rmaps); - v.put("activemaps", activemaps); - v.put("activemapcnt", activemapcnt); - v.put("cxmin", cxmin); - v.put("cxmax", cxmax); - v.put("czmin", czmin); - v.put("czmax", czmax); - v.put("rendertype", rendertype); - if(mapname != null) - v.put("mapname", mapname); - v.put("player", player); - return v; - } - - public String toString() { - return "world=" + world.getName() + ", map=" + map; - } - - public void cleanup() { - if(tile0 == null) { - synchronized(lock) { - active_renders.remove(world.getName()); - } - } - else { - tileQueue.done(tile0); - } - } - public void run() { - long tstart = System.currentTimeMillis(); - MapTile tile = null; - List tileset = null; - - if(cancelled) { - cleanup(); - return; - } - if(tile0 == null) { /* Not single tile render */ - if(pausefullrenders) { /* Update renders are paused? */ - scheduleDelayedJob(this, 20*5); /* Delay 5 seconds and retry */ - return; - } - /* If render queue is empty, start next map */ - if(renderQueue.isEmpty()) { - if(map_index >= 0) { /* Finished a map? */ - double msecpertile = (double)timeaccum / (double)((rendercnt>0)?rendercnt:1)/(double)activemapcnt; - double rendtime = total_render_ns.doubleValue() * 0.000001 / rendercalls.get(); - if(activemapcnt > 1) - sendMessage(String.format("%s of maps [%s] of '%s' completed - %d tiles rendered each (%.2f msec/map-tile, %.2f msec per render)", - rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime)); - else - sendMessage(String.format("%s of map '%s' of '%s' completed - %d tiles rendered (%.2f msec/map-tile, %.2f msec per render)", - rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime)); - /* Now, if fullrender, use the render bitmap to purge obsolete tiles */ - if(rendertype.equals(RENDERTYPE_FULLRENDER)) { - if(activemapcnt == 1) { - map.purgeOldTiles(world, rendered); - } - else { - for(MapType mt : map.getMapsSharingRender(world)) { - mt.purgeOldTiles(world, rendered); - } - } - } - } - found.clear(); - rendered.clear(); - rendercnt = 0; - timeaccum = 0; - total_render_ns.set(0); - rendercalls.set(0); - /* Advance to next unrendered map */ - while(map_index < world.maps.size()) { - map_index++; /* Move to next one */ - if(map_index >= world.maps.size()) break; - /* If single map render, see if this is our target */ - if(mapname != null) { - if(world.maps.get(map_index).getName().equals(mapname)) { - break; - } - } - else { - if(renderedmaps.contains(world.maps.get(map_index)) == false) - break; - } - } - if(map_index >= world.maps.size()) { /* Last one done? */ - sendMessage(rendertype + " of '" + world.getName() + "' finished."); - cleanup(); - return; - } - map = world.maps.get(map_index); - List activemaplist = map.getMapNamesSharingRender(world); - /* Build active map list */ - activemaps = ""; - if(mapname != null) { - activemaps = mapname; - activemapcnt = 1; - } - else { - activemapcnt = 0; - for(String n : activemaplist) { - if(activemaps.length() > 0) - activemaps += ","; - activemaps += n; - activemapcnt++; - } - } - /* Mark all the concurrently rendering maps rendered */ - renderedmaps.addAll(map.getMapsSharingRender(world)); - - /* Now, prime the render queue */ - for (MapTile mt : map.getTiles(world, (int)loc.x, (int)loc.y, (int)loc.z)) { - if (!found.getFlag(mt.tileOrdinalX(), mt.tileOrdinalY())) { - found.setFlag(mt.tileOrdinalX(), mt.tileOrdinalY(), true); - renderQueue.add(mt); - } - } - if(!updaterender) { /* Only add other seed points for fullrender */ - /* Add spawn location too (helps with some worlds where 0,64,0 may not be generated */ - DynmapLocation sloc = world.getSpawnLocation(); - for (MapTile mt : map.getTiles(world, (int)sloc.x, (int)sloc.y, (int)sloc.z)) { - if (!found.getFlag(mt.tileOrdinalX(), mt.tileOrdinalY())) { - found.setFlag(mt.tileOrdinalX(), mt.tileOrdinalY(), true); - renderQueue.add(mt); - } - } - if(world.seedloc != null) { - for(DynmapLocation seed : world.seedloc) { - for (MapTile mt : map.getTiles(world, (int)seed.x, (int)seed.y, (int)seed.z)) { - if (!found.getFlag(mt.tileOrdinalX(),mt.tileOrdinalY())) { - found.setFlag(mt.tileOrdinalX(),mt.tileOrdinalY(), true); - renderQueue.add(mt); - } - } - } - } - } - } - if(parallelrendercnt > 1) { /* Doing parallel renders? */ - tileset = new ArrayList(); - for(int i = 0; i < parallelrendercnt; i++) { - tile = renderQueue.pollFirst(); - if(tile != null) - tileset.add(tile); - } - } - else { - tile = renderQueue.pollFirst(); - } - } - else { /* Else, single tile render */ - if(pauseupdaterenders) { - scheduleDelayedJob(this, 5*20); /* Retry after 5 seconds */ - return; - } - tile = tile0; - } - - boolean notdone = true; - - if(tileset != null) { - long save_timeaccum = timeaccum; - List> rslt = new ArrayList>(); - final int cnt = tileset.size(); - for(int i = 1; i < cnt; i++) { /* Do all but first on other threads */ - final MapTile mt = tileset.get(i); - if((mapman != null) && (mapman.render_pool != null)) { - final long ts = tstart; - Future future = mapman.render_pool.submit(new Callable() { - public Boolean call() { - return processTile(mt, ts, cnt); - } - }); - rslt.add(future); - } - } - /* Now, do our render (first one) */ - notdone = processTile(tileset.get(0), tstart, cnt); - /* Now, join with others */ - for(int i = 0; i < rslt.size(); i++) { - try { - notdone = notdone && rslt.get(i).get(); - } catch (ExecutionException xx) { - Log.severe(xx); - notdone = false; - } catch (InterruptedException ix) { - notdone = false; - } - } - timeaccum = save_timeaccum + System.currentTimeMillis() - tstart; - } - else { - notdone = processTile(tile, tstart, 1); - } - - if(notdone) { - if(tile0 == null) { /* fullrender */ - long tend = System.currentTimeMillis(); - if(timeslice_int > (tend-tstart)) { /* We were fast enough */ - scheduleDelayedJob(this, timeslice_int - (tend-tstart)); - } - else { /* Schedule to run ASAP */ - scheduleDelayedJob(this, 0); - } - } - else { - cleanup(); - } - } - else { - cleanup(); - } - } - - private boolean processTile(MapTile tile, long tstart, int parallelcnt) { - /* Get list of chunks required for tile */ - List requiredChunks = tile.getRequiredChunks(); - /* If we are doing radius limit render, see if any are inside limits */ - if(cxmin != Integer.MIN_VALUE) { - boolean good = false; - for(DynmapChunk c : requiredChunks) { - if((c.x >= cxmin) && (c.x <= cxmax) && (c.z >= czmin) && (c.z <= czmax)) { - good = true; - break; - } - } - if(!good) requiredChunks = Collections.emptyList(); - } - /* Fetch chunk cache from server thread */ - long clt0 = System.nanoTime(); - MapChunkCache cache = createMapChunkCache(world, requiredChunks, tile.isBlockTypeDataNeeded(), - tile.isHightestBlockYDataNeeded(), tile.isBiomeDataNeeded(), - tile.isRawBiomeDataNeeded()); - total_chunk_cache_loadtime_ns.addAndGet(System.nanoTime() - clt0); - chunk_caches_attempted.incrementAndGet(); - if(cache == null) { - return false; /* Cancelled/aborted */ - } - /* Update stats */ - chunk_caches_created.incrementAndGet(); - chunks_read.addAndGet(cache.getChunksLoaded()); - chunks_attempted.addAndGet(cache.getChunkLoadsAttempted()); - total_loadtime_ns.addAndGet(cache.getTotalRuntimeNanos()); - total_exceptions.addAndGet(cache.getExceptionCount()); - if(tile0 != null) { /* Single tile? */ - if(cache.isEmpty() == false) - tile.render(cache, null); - } - else { - /* Remove tile from tile queue, since we're processing it already */ - tileQueue.remove(tile); - /* Switch to not checking if rendered tile is blank - breaks us on skylands, where tiles can be nominally blank - just work off chunk cache empty */ - if (cache.isEmpty() == false) { - long rt0 = System.nanoTime(); - boolean upd = tile.render(cache, mapname); - total_render_ns.addAndGet(System.nanoTime()-rt0); - rendercalls.incrementAndGet(); - synchronized(lock) { - rendered.setFlag(tile.tileOrdinalX(), tile.tileOrdinalY(), true); - if(upd || (!updaterender)) { /* If updated or not an update render */ - /* Add adjacent unrendered tiles to queue */ - for (MapTile adjTile : map.getAdjecentTiles(tile)) { - if (!found.getFlag(adjTile.tileOrdinalX(),adjTile.tileOrdinalY())) { - found.setFlag(adjTile.tileOrdinalX(), adjTile.tileOrdinalY(), true); - renderQueue.add(adjTile); - } - } - } - } - } - synchronized(lock) { - if(!cache.isEmpty()) { - rendercnt++; - timeaccum += System.currentTimeMillis() - tstart; - if((rendercnt % progressinterval) == 0) { - double rendtime = total_render_ns.doubleValue() * 0.000001 / rendercalls.get(); - double msecpertile = (double)timeaccum / (double)rendercnt / (double)activemapcnt; - if(activemapcnt > 1) - sendMessage(String.format("%s of maps [%s] of '%s' in progress - %d tiles rendered each (%.2f msec/map-tile, %.2f msec per render)", - rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime)); - else - sendMessage(String.format("%s of map '%s' of '%s' in progress - %d tiles rendered (%.2f msec/tile, %.2f msec per render)", - rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime)); - } - } - } - } - /* And unload what we loaded */ - cache.unloadChunks(); - - return true; - } - - public void cancelRender() { - cancelled = true; - } - - public void sendMessage(String msg) { - if(sender != null) { - sender.sendMessage(msg); - } - else { - Log.info(msg); - } - } - } - - private class CheckWorldTimes implements Runnable { - public void run() { - Future f = core.getServer().callSyncMethod(new Callable() { - public Integer call() throws Exception { - for(DynmapWorld w : worlds) { - int new_servertime = (int)(w.getTime() % 24000); - /* Check if we went from night to day */ - boolean wasday = w.servertime >= 0 && w.servertime < 13700; - boolean isday = new_servertime >= 0 && new_servertime < 13700; - w.servertime = new_servertime; - if(wasday != isday) { - pushUpdate(w, new Client.DayNight(isday)); - } - } - return 0; - } - }); - try { - f.get(); - } catch (Exception ix) { - Log.severe(ix); - } - scheduleDelayedJob(this, 5000); - } - } - - private class DoZoomOutProcessing implements Runnable { - public void run() { - Debug.debug("DoZoomOutProcessing started"); - ArrayList wl = new ArrayList(worlds); - for(DynmapWorld w : wl) { - w.freshenZoomOutFiles(); - } - scheduleDelayedJob(this, zoomout_period*1000); - Debug.debug("DoZoomOutProcessing finished"); - } - } - - private class DoTouchProcessing implements Runnable { - public void run() { - processTouchEvents(); - scheduleDelayedJob(this, 1000); /* Once per second */ - } - } - - public MapManager(DynmapCore core, ConfigurationNode configuration) { - this.core = core; - mapman = this; - - /* Get block hiding data, if any */ - hideores = configuration.getBoolean("hideores", false); - - /* See what priority to use */ - usenormalpriority = configuration.getBoolean("usenormalthreadpriority", false); - - /* Clear color scheme */ - ColorScheme.reset(); - - /* Initialize HD map manager */ - hdmapman = new HDMapManager(); - hdmapman.loadHDShaders(core); - hdmapman.loadHDPerspectives(core); - hdmapman.loadHDLightings(core); - sscache = new SnapshotCache(configuration.getInteger("snapshotcachesize", 500)); - parallelrendercnt = configuration.getInteger("parallelrendercnt", 0); - progressinterval = configuration.getInteger("progressloginterval", 100); - if(progressinterval < 100) progressinterval = 100; - saverestorepending = configuration.getBoolean("saverestorepending", true); - - this.tileQueue = new AsynchronousQueue( - new Handler() { - @Override - public void handle(MapTile t) { - FullWorldRenderState job = new FullWorldRenderState(t); - if(!scheduleDelayedJob(job, 0)) - job.cleanup(); - } - }, - (int) (configuration.getDouble("renderinterval", 0.5) * 1000), - configuration.getInteger("renderacceleratethreshold", 30), - (int)(configuration.getDouble("renderaccelerateinterval", 0.2) * 1000), - configuration.getInteger("tiles-rendered-at-once", (Runtime.getRuntime().availableProcessors()+1)/2), - usenormalpriority); - - /* On dedicated thread, so default to no delays */ - timeslice_int = (long)(configuration.getDouble("timesliceinterval", 0.0) * 1000); - max_chunk_loads_per_tick = configuration.getInteger("maxchunkspertick", DEFAULT_CHUNKS_PER_TICK); - if(max_chunk_loads_per_tick < 5) max_chunk_loads_per_tick = 5; - /* Get zoomout processing periond in seconds */ - zoomout_period = configuration.getInteger("zoomoutperiod", DEFAULT_ZOOMOUT_PERIOD); - if(zoomout_period < 5) zoomout_period = 5; - - hashman = new TileHashManager(core.getTilesFolder(), configuration.getBoolean("enabletilehash", true)); - - tileQueue.start(); - } - - void renderFullWorld(DynmapLocation l, DynmapCommandSender sender, String mapname, boolean update) { - DynmapWorld world = getWorld(l.world); - if (world == null) { - sender.sendMessage("Could not render: world '" + l.world + "' not defined in configuration."); - return; - } - String wname = l.world; - FullWorldRenderState rndr; - synchronized(lock) { - rndr = active_renders.get(wname); - if(rndr != null) { - sender.sendMessage(rndr.rendertype + " of world '" + wname + "' already active."); - return; - } - rndr = new FullWorldRenderState(world,l,sender, mapname, update); /* Make new activation record */ - active_renders.put(wname, rndr); /* Add to active table */ - } - /* Schedule first tile to be worked */ - scheduleDelayedJob(rndr, 0); - - if(update) - sender.sendMessage("Update render starting on world '" + wname + "'..."); - else - sender.sendMessage("Full render starting on world '" + wname + "'..."); - } - - void renderWorldRadius(DynmapLocation l, DynmapCommandSender sender, String mapname, int radius) { - DynmapWorld world = getWorld(l.world); - if (world == null) { - sender.sendMessage("Could not render: world '" + l.world + "' not defined in configuration."); - return; - } - String wname = l.world; - FullWorldRenderState rndr; - synchronized(lock) { - rndr = active_renders.get(wname); - if(rndr != null) { - sender.sendMessage(rndr.rendertype + " of world '" + wname + "' already active."); - return; - } - rndr = new FullWorldRenderState(world,l,sender, mapname, radius); /* Make new activation record */ - active_renders.put(wname, rndr); /* Add to active table */ - } - /* Schedule first tile to be worked */ - scheduleDelayedJob(rndr, 0); - sender.sendMessage("Render of " + radius + " block radius starting on world '" + wname + "'..."); - } - - void cancelRender(String w, DynmapCommandSender sender) { - synchronized(lock) { - if(w != null) { - FullWorldRenderState rndr; - rndr = active_renders.get(w); - if(rndr != null) { - rndr.cancelRender(); /* Cancel render */ - if(sender != null) { - sender.sendMessage("Cancelled render for '" + w + "'"); - } - } - } - else { /* Else, cancel all */ - for(String wid : active_renders.keySet()) { - FullWorldRenderState rnd = active_renders.get(wid); - rnd.cancelRender(); - if(sender != null) { - sender.sendMessage("Cancelled render for '" + wid + "'"); - } - } - } - } - } - - void purgeQueue(DynmapCommandSender sender) { - if(tileQueue != null) { - int cnt = 0; - List popped = tileQueue.popAll(); - if(popped != null) { - cnt = popped.size(); - popped.clear(); - } - sender.sendMessage("Purged " + cnt + " tiles from queue"); - } - } - - public boolean activateWorld(DynmapWorld dynmapWorld) { - ConfigurationNode worldConfiguration = core.getWorldConfiguration(dynmapWorld); - if (!worldConfiguration.getBoolean("enabled", false)) { - Log.info("World '" + dynmapWorld.getName() + "' disabled"); - return false; - } - String worldName = dynmapWorld.getName(); - - dynmapWorld.configuration = worldConfiguration; - Log.verboseinfo("Loading maps of world '" + worldName + "'..."); - for(MapType map : worldConfiguration.createInstances("maps", new Class[] { DynmapCore.class }, new Object[] { core })) { - if(map.getName() != null) - dynmapWorld.maps.add(map); - } - Log.info("Loaded " + dynmapWorld.maps.size() + " maps of world '" + worldName + "'."); - - List loclist = worldConfiguration.getNodes("fullrenderlocations"); - dynmapWorld.seedloc = new ArrayList(); - dynmapWorld.servertime = (int)(dynmapWorld.getTime() % 24000); - dynmapWorld.sendposition = worldConfiguration.getBoolean("sendposition", true); - dynmapWorld.sendhealth = worldConfiguration.getBoolean("sendhealth", true); - dynmapWorld.bigworld = worldConfiguration.getBoolean("bigworld", false); - dynmapWorld.setExtraZoomOutLevels(worldConfiguration.getInteger("extrazoomout", 0)); - dynmapWorld.worldtilepath = new File(core.getTilesFolder(), worldName); - if(loclist != null) { - for(ConfigurationNode loc : loclist) { - DynmapLocation lx = new DynmapLocation(worldName, loc.getInteger("x", 0), loc.getInteger("y", 64), loc.getInteger("z", 0)); - dynmapWorld.seedloc.add(lx); - } - } - /* Load visibility limits, if any are defined */ - List vislimits = worldConfiguration.getNodes("visibilitylimits"); - if(vislimits != null) { - dynmapWorld.visibility_limits = new ArrayList(); - for(ConfigurationNode vis : vislimits) { - MapChunkCache.VisibilityLimit lim = new MapChunkCache.VisibilityLimit(); - lim.x0 = vis.getInteger("x0", 0); - lim.x1 = vis.getInteger("x1", 0); - lim.z0 = vis.getInteger("z0", 0); - lim.z1 = vis.getInteger("z1", 0); - dynmapWorld.visibility_limits.add(lim); - /* Also, add a seed location for the middle of each visible area */ - dynmapWorld.seedloc.add(new DynmapLocation(worldName, (lim.x0+lim.x1)/2, 64, (lim.z0+lim.z1)/2)); - } - } - /* Load hidden limits, if any are defined */ - List hidelimits = worldConfiguration.getNodes("hiddenlimits"); - if(hidelimits != null) { - dynmapWorld.hidden_limits = new ArrayList(); - for(ConfigurationNode vis : hidelimits) { - MapChunkCache.VisibilityLimit lim = new MapChunkCache.VisibilityLimit(); - lim.x0 = vis.getInteger("x0", 0); - lim.x1 = vis.getInteger("x1", 0); - lim.z0 = vis.getInteger("z0", 0); - lim.z1 = vis.getInteger("z1", 0); - dynmapWorld.hidden_limits.add(lim); - } - } - String autogen = worldConfiguration.getString("autogenerate-to-visibilitylimits", "none"); - if(autogen.equals("permanent")) { - dynmapWorld.do_autogenerate = AutoGenerateOption.PERMANENT; - } - else if(autogen.equals("map-only")) { - dynmapWorld.do_autogenerate = AutoGenerateOption.FORMAPONLY; - } - else { - dynmapWorld.do_autogenerate = AutoGenerateOption.NONE; - } - if((dynmapWorld.do_autogenerate != AutoGenerateOption.NONE) && (dynmapWorld.visibility_limits == null)) { - Log.info("Warning: Automatic world generation to visible limits option requires that visibitylimits be set - option disabled"); - dynmapWorld.do_autogenerate = AutoGenerateOption.NONE; - } - String hiddenchunkstyle = worldConfiguration.getString("hidestyle", "stone"); - if(hiddenchunkstyle.equals("air")) - dynmapWorld.hiddenchunkstyle = MapChunkCache.HiddenChunkStyle.FILL_AIR; - else if(hiddenchunkstyle.equals("ocean")) - dynmapWorld.hiddenchunkstyle = MapChunkCache.HiddenChunkStyle.FILL_OCEAN; - else - dynmapWorld.hiddenchunkstyle = MapChunkCache.HiddenChunkStyle.FILL_STONE_PLAIN; - - - // TODO: Make this less... weird... - // Insert the world on the same spot as in the configuration. - HashMap indexLookup = new HashMap(); - List nodes = core.configuration.getNodes("worlds"); - for (int i = 0; i < nodes.size(); i++) { - ConfigurationNode node = nodes.get(i); - indexLookup.put(node.getString("name"), i); - } - Integer worldIndex = indexLookup.get(worldName); - if(worldIndex == null) { - worlds.add(dynmapWorld); /* Put at end if no world section */ - } - else { - int insertIndex; - for(insertIndex = 0; insertIndex < worlds.size(); insertIndex++) { - Integer nextWorldIndex = indexLookup.get(worlds.get(insertIndex).getName()); - if (nextWorldIndex == null || worldIndex < nextWorldIndex.intValue()) { - break; - } - } - worlds.add(insertIndex, dynmapWorld); - } - worldsLookup.put(worldName, dynmapWorld); - core.events.trigger("worldactivated", dynmapWorld); - /* Now, restore any pending renders for this world */ - if(saverestorepending) - loadPending(dynmapWorld); - return true; - } - - public void deactivateWorld(String wname) { - Log.warning("World unloading not properly supported"); - } - - private void loadPending(DynmapWorld w) { - String wname = w.getName(); - File f = new File(core.getDataFolder(), wname + ".pending"); - if(f.exists()) { - ConfigurationNode cn = new ConfigurationNode(f); - cn.load(); - /* Get the saved tile definitions */ - List tiles = cn.getNodes("tiles"); - if(tiles != null) { - int cnt = 0; - for(ConfigurationNode tile : tiles) { - MapTile mt = MapTile.restoreTile(w, tile); /* Restore tile, if possible */ - if(mt != null) { - if(invalidateTile(mt)) - cnt++; - } - } - if(cnt > 0) - Log.info("Loaded " + cnt + " pending tile renders for world '" + wname); - } - /* Get saved render job, if any */ - ConfigurationNode job = cn.getNode("job"); - if(job != null) { - try { - FullWorldRenderState j = new FullWorldRenderState(job); - active_renders.put(wname, j); - if(did_start) /* Past initial start */ - scheduleDelayedJob(j, 5000); - - } catch (Exception x) { - Log.info("Unable to restore render job for world '" + wname + "' - map configuration changed"); - } - } - - f.delete(); /* And clean it up */ - } - } - - private void savePending() { - List mt = tileQueue.popAll(); - for(DynmapWorld w : worlds) { - boolean dosave = false; - File f = new File(core.getDataFolder(), w.getName() + ".pending"); - ConfigurationNode saved = new ConfigurationNode(); - ArrayList savedtiles = new ArrayList(); - for(MapTile tile : mt) { - if(tile.getDynmapWorld() != w) continue; - ConfigurationNode tilenode = tile.saveTile(); - if(tilenode != null) { - savedtiles.add(tilenode); - } - } - if(savedtiles.size() > 0) { /* Something to save? */ - saved.put("tiles", savedtiles); - dosave = true; - Log.info("Saved " + savedtiles.size() + " pending tile renders in world '" + w.getName()); - } - FullWorldRenderState job = active_renders.get(w.getName()); - if(job != null) { - saved.put("job", job.saveState()); - dosave = true; - Log.info("Saved active render job in world '" + w.getName()); - } - if(dosave) { - saved.save(f); - Log.info("Saved " + savedtiles.size() + " pending tile renders in world '" + w.getName()); - } - } - } - - public void touch(String wname, int x, int y, int z, String reason) { - TouchEvent evt = new TouchEvent(); - evt.world = wname; - evt.x = x; - evt.y = y; - evt.z = z; - evt.reason = reason; - touch_events.putIfAbsent(evt, reason); - } - - public void touchVolume(String wname, int minx, int miny, int minz, int maxx, int maxy, int maxz, String reason) { - TouchVolumeEvent evt = new TouchVolumeEvent(); - evt.world = wname; - evt.xmin = minx; - evt.xmax = maxx; - evt.ymin = miny; - evt.ymax = maxy; - evt.zmin = minz; - evt.zmax = maxz; - evt.reason = reason; - synchronized(touch_lock) { - touch_volume_events.add(evt); - } - } - - public boolean invalidateTile(MapTile tile) { - return tileQueue.push(tile); - } - - public static boolean scheduleDelayedJob(Runnable job, long delay_in_msec) { - if((mapman != null) && (mapman.render_pool != null)) { - if(delay_in_msec > 0) - mapman.render_pool.schedule(job, delay_in_msec, TimeUnit.MILLISECONDS); - else - mapman.render_pool.execute(job); - return true; - } - else - return false; - } - - public void startRendering() { - render_pool = new DynmapScheduledThreadPoolExecutor(); - tileQueue.start(); - scheduleDelayedJob(new DoZoomOutProcessing(), 60000); - scheduleDelayedJob(new CheckWorldTimes(), 5000); - scheduleDelayedJob(new DoTouchProcessing(), 1000); - /* Resume pending jobs */ - for(FullWorldRenderState job : active_renders.values()) { - scheduleDelayedJob(job, 5000); - Log.info("Resumed render starting on world '" + job.world.getName() + "'..."); - } - did_start = true; - } - - public void stopRendering() { - /* Tell all worlds to cancel any zoom out processing */ - for(DynmapWorld w: worlds) - w.cancelZoomOutFreshen(); - render_pool.shutdown(); - try { - render_pool.awaitTermination(5, TimeUnit.SECONDS); - } catch (InterruptedException ix) { - } - tileQueue.stop(); - mapman = null; - hdmapman = null; - - if(saverestorepending) - savePending(); - if(sscache != null) { - sscache.cleanup(); - sscache = null; - } - did_start = false; - } - - public File getTileFile(MapTile tile) { - File worldTileDirectory = tile.getDynmapWorld().worldtilepath; - if (!worldTileDirectory.isDirectory() && !worldTileDirectory.mkdirs()) { - Log.warning("Could not create directory for tiles ('" + worldTileDirectory + "')."); - } - return new File(worldTileDirectory, tile.getFilename()); - } - - public void pushUpdate(Client.Update update) { - int sz = worlds.size(); - for(int i = 0; i < sz; i++) { - worlds.get(i).updates.pushUpdate(update); - } - } - - public void pushUpdate(DynmapWorld world, Client.Update update) { - pushUpdate(world.getName(), update); - } - - public void pushUpdate(String worldName, Client.Update update) { - DynmapWorld world = getWorld(worldName); - if(world != null) - world.updates.pushUpdate(update); - } - - public Client.Update[] getWorldUpdates(String worldName, long since) { - DynmapWorld world = getWorld(worldName); - if (world == null) - return new Client.Update[0]; - return world.updates.getUpdatedObjects(since); - } - - /** - * Render processor helper - used by code running on render threads to request chunk snapshot cache from server/sync thread - */ - public MapChunkCache createMapChunkCache(DynmapWorld w, List chunks, - boolean blockdata, boolean highesty, boolean biome, boolean rawbiome) { - MapChunkCache c = w.getChunkCache(chunks); - if(w.visibility_limits != null) { - for(MapChunkCache.VisibilityLimit limit: w.visibility_limits) { - c.setVisibleRange(limit); - } - c.setHiddenFillStyle(w.hiddenchunkstyle); - c.setAutoGenerateVisbileRanges(w.do_autogenerate); - } - if(w.hidden_limits != null) { - for(MapChunkCache.VisibilityLimit limit: w.hidden_limits) { - c.setHiddenRange(limit); - } - c.setHiddenFillStyle(w.hiddenchunkstyle); - } - if(c.setChunkDataTypes(blockdata, biome, highesty, rawbiome) == false) - Log.severe("CraftBukkit build does not support biome APIs"); - if(chunks.size() == 0) { /* No chunks to get? */ - return c; - } - - final MapChunkCache cc = c; - - while(!cc.isDoneLoading()) { - synchronized(loadlock) { - long now = System.currentTimeMillis(); - - if(cur_tick != (now/50)) { /* New tick? */ - chunks_in_cur_tick = max_chunk_loads_per_tick; - cur_tick = now/50; - } - } - Future f = core.getServer().callSyncMethod(new Callable() { - public Boolean call() throws Exception { - boolean exhausted; - synchronized(loadlock) { - if(chunks_in_cur_tick > 0) - chunks_in_cur_tick -= cc.loadChunks(chunks_in_cur_tick); - exhausted = (chunks_in_cur_tick == 0); - } - return exhausted; - } - }); - boolean delay; - try { - delay = f.get(); - } catch (Exception ix) { - Log.severe(ix); - return null; - } - if(delay) - try { Thread.sleep(25); } catch (InterruptedException ix) {} - } - return c; - } - /** - * Update map tile statistics - */ - public void updateStatistics(MapTile tile, String prefix, boolean rendered, boolean updated, boolean transparent) { - synchronized(lock) { - String k = tile.getKey(prefix); - MapStats ms = mapstats.get(k); - if(ms == null) { - ms = new MapStats(); - mapstats.put(k, ms); - } - ms.loggedcnt++; - if(rendered) - ms.renderedcnt++; - if(updated) - ms.updatedcnt++; - if(transparent) - ms.transparentcnt++; - } - } - /** - * Print statistics command - */ - public void printStats(DynmapCommandSender sender, String prefix) { - sender.sendMessage("Tile Render Statistics:"); - MapStats tot = new MapStats(); - synchronized(lock) { - for(String k: new TreeSet(mapstats.keySet())) { - if((prefix != null) && !k.startsWith(prefix)) - continue; - MapStats ms = mapstats.get(k); - sender.sendMessage(String.format(" %s: processed=%d, rendered=%d, updated=%d, transparent=%d", - k, ms.loggedcnt, ms.renderedcnt, ms.updatedcnt, ms.transparentcnt)); - tot.loggedcnt += ms.loggedcnt; - tot.renderedcnt += ms.renderedcnt; - tot.updatedcnt += ms.updatedcnt; - tot.transparentcnt += ms.transparentcnt; - } - } - sender.sendMessage(String.format(" TOTALS: processed=%d, rendered=%d, updated=%d, transparent=%d", - tot.loggedcnt, tot.renderedcnt, tot.updatedcnt, tot.transparentcnt)); - sender.sendMessage(String.format(" Triggered update queue size: %d", tileQueue.size())); - String act = ""; - for(String wn : active_renders.keySet()) - act += wn + " "; - sender.sendMessage(String.format(" Active render jobs: %s", act)); - /* Chunk load stats */ - sender.sendMessage("Chunk Loading Statistics:"); - sender.sendMessage(String.format(" Cache hit rate: %.2f%%", sscache.getHitRate())); - int setcnt = chunk_caches_attempted.get(); - sender.sendMessage(String.format(" Chunk sets: created=%d, attempted=%d", chunk_caches_created.get(), chunk_caches_attempted.get())); - int readcnt = chunks_read.get(); - sender.sendMessage(String.format(" Chunk: loaded=%d, attempted=%d", readcnt, chunks_attempted.get())); - double ns = total_loadtime_ns.doubleValue() * 0.000001; /* Convert to milliseconds */ - double chunkloadns = total_chunk_cache_loadtime_ns.doubleValue() * 0.000001; - if(readcnt == 0) readcnt = 1; - if(setcnt == 0) setcnt = 1; - sender.sendMessage(String.format(" Chunk load times: %.2f msec (%.2f msec/chunk)", ns, (ns / readcnt))); - sender.sendMessage(String.format(" Chunk set load times: %.2f msec (%.2f msec/set)", chunkloadns, (chunkloadns / setcnt))); - sender.sendMessage(String.format(" Chunk set delay times: %.2f msec (%.2f msec/set)", chunkloadns-ns, ((chunkloadns-ns) / setcnt))); - sender.sendMessage(String.format(" Chunk set exceptions: %d", total_exceptions.get())); - sender.sendMessage(String.format(" World tick list processing calls: %d", ticklistcalls.get())); - } - /** - * Print trigger statistics command - */ - public void printTriggerStats(DynmapCommandSender sender) { - sender.sendMessage("Render Trigger Statistics:"); - synchronized(lock) { - for(String k: new TreeSet(trigstats.keySet())) { - TriggerStats ts = trigstats.get(k); - sender.sendMessage(" " + k + ": calls=" + ts.callsmade + ", calls-adding-tiles=" + ts.callswithtiles + ", tiles-added=" + ts.tilesqueued); - } - } - } - - /** - * Reset statistics - */ - public void resetStats(DynmapCommandSender sender, String prefix) { - synchronized(lock) { - for(String k : mapstats.keySet()) { - if((prefix != null) && !k.startsWith(prefix)) - continue; - MapStats ms = mapstats.get(k); - ms.loggedcnt = 0; - ms.renderedcnt = 0; - ms.updatedcnt = 0; - ms.transparentcnt = 0; - } - for(String k : trigstats.keySet()) { - TriggerStats ts = trigstats.get(k); - ts.callsmade = 0; - ts.callswithtiles = 0; - ts.tilesqueued = 0; - } - chunk_caches_created.set(0); - chunk_caches_attempted.set(0); - chunks_read.set(0); - chunks_attempted.set(0); - total_loadtime_ns.set(0); - total_chunk_cache_loadtime_ns.set(0); - total_exceptions.set(0); - ticklistcalls.set(0); - } - sscache.resetStats(); - sender.sendMessage("Tile Render Statistics reset"); - } - - public boolean getSwampShading() { - return core.swampshading; - } - - public boolean getWaterBiomeShading() { - return core.waterbiomeshading; - } - - public boolean getFenceJoin() { - return core.fencejoin; - } - - public boolean getBetterGrass() { - return core.bettergrass; - } - - public CompassMode getCompassMode() { - return core.compassmode; - } - - public boolean getHideOres() { - return hideores; - } - /* Map block ID to aliased ID - used to hide ores */ - public int getBlockIDAlias(int id) { - if(!hideores) return id; - switch(id) { - case 14: /* Gold Ore */ - case 15: /* Iron Ore */ - case 16: /* Coal Ore */ - case 21: /* Lapis Lazuli Ore */ - case 56: /* Diamond Ore */ - case 73: /* Redstone ore */ - return 1; /* Stone */ - } - return id; - } - /* - * Pause full/radius render processing - * @param dopause - true to pause, false to unpause - */ - void setPauseFullRadiusRenders(boolean dopause) { - if(dopause != pausefullrenders) { - pausefullrenders = dopause; - Log.info("Full/radius render pause set to " + dopause); - } - } - /* - * Test if full renders are paused - */ - boolean getPauseFullRadiusRenders() { - return pausefullrenders; - } - /* - * Pause update render processing - * @param dopause - true to pause, false to unpause - */ - void setPauseUpdateRenders(boolean dopause) { - if(dopause != pauseupdaterenders) { - pauseupdaterenders = dopause; - Log.info("Update render pause set to " + dopause); - } - } - /* - * Test if update renders are paused - */ - boolean getPauseUpdateRenders() { - return pauseupdaterenders; - } - - public void incExtraTickList() { - ticklistcalls.incrementAndGet(); - } - /* Connect any jobs tied to this player back to the player (resumes output to player) */ - void connectTasksToPlayer(DynmapPlayer p) { - String pn = p.getName(); - for(FullWorldRenderState job : active_renders.values()) { - if(pn.equals(job.player)) { - job.sender = p; - } - } - } - - /** - * Process touch events - */ - private void processTouchEvents() { - ArrayList te = null; - ArrayList tve = null; - - if(touch_events.isEmpty() == false) { - te = new ArrayList(touch_events.keySet()); - for(int i = 0; i < te.size(); i++) { - touch_events.remove(te.get(i)); - } - } - - synchronized(touch_lock) { - if(touch_volume_events.isEmpty() == false) { - tve = new ArrayList(touch_volume_events); - touch_volume_events.clear(); - } - } - DynmapWorld world = null; - String wname = ""; - - /* If any touch events, process them */ - if(te != null) { - for(TouchEvent evt : te) { - int invalidates = 0; - /* If different world, look it up */ - if(evt.world.equals(wname) == false) { - wname = evt.world; - world = getWorld(wname); - } - if(world == null) continue; - for (int i = 0; i < world.maps.size(); i++) { - MapTile[] tiles = world.maps.get(i).getTiles(world, evt.x, evt.y, evt.z); - for (int j = 0; j < tiles.length; j++) { - if(invalidateTile(tiles[j])) - invalidates++; - } - } - if(evt.reason != null) { - synchronized(lock) { - TriggerStats ts = trigstats.get(evt.reason); - if(ts == null) { - ts = new TriggerStats(); - trigstats.put(evt.reason, ts); - } - ts.callsmade++; - if(invalidates > 0) { - ts.callswithtiles++; - ts.tilesqueued += invalidates; - } - } - } - } - te.clear(); /* Clean up set */ - } - - /* If any volume touches */ - if(tve != null) { - for(TouchVolumeEvent evt : tve) { - /* If different world, look it up */ - if(evt.world.equals(wname) == false) { - wname = evt.world; - world = getWorld(wname); - } - if(world == null) continue; - int invalidates = 0; - for (int i = 0; i < world.maps.size(); i++) { - MapTile[] tiles = world.maps.get(i).getTiles(world, evt.xmin, evt.ymin, evt.zmin, evt.xmax, evt.ymax, evt.zmax); - for (int j = 0; j < tiles.length; j++) { - if(invalidateTile(tiles[j])) - invalidates++; - } - } - if(evt.reason != null) { - synchronized(lock) { - TriggerStats ts = trigstats.get(evt.reason); - if(ts == null) { - ts = new TriggerStats(); - trigstats.put(evt.reason, ts); - } - ts.callsmade++; - if(invalidates > 0) { - ts.callswithtiles++; - ts.tilesqueued += invalidates; - } - } - } - } - /* Clean up */ - tve.clear(); - } - } -} diff --git a/src/main/java/org/dynmap/MapTile.java b/src/main/java/org/dynmap/MapTile.java deleted file mode 100644 index 939299bb..00000000 --- a/src/main/java/org/dynmap/MapTile.java +++ /dev/null @@ -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 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; - } -} diff --git a/src/main/java/org/dynmap/MapType.java b/src/main/java/org/dynmap/MapType.java deleted file mode 100644 index e3b4f050..00000000 --- a/src/main/java/org/dynmap/MapType.java +++ /dev/null @@ -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 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 getMapsSharingRender(DynmapWorld w); - /* Get names of maps rendered concurrently with this map type in this world */ - public abstract List 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 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 dirs = new LinkedList(); - 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); - } - } - } - } -} diff --git a/src/main/java/org/dynmap/MarkersComponent.java b/src/main/java/org/dynmap/MarkersComponent.java deleted file mode 100644 index 605aab39..00000000 --- a/src/main/java/org/dynmap/MarkersComponent.java +++ /dev/null @@ -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 */ - } -} diff --git a/src/main/java/org/dynmap/PlayerFaces.java b/src/main/java/org/dynmap/PlayerFaces.java deleted file mode 100644 index d817dac9..00000000 --- a/src/main/java/org/dynmap/PlayerFaces.java +++ /dev/null @@ -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(); - } -} diff --git a/src/main/java/org/dynmap/PlayerList.java b/src/main/java/org/dynmap/PlayerList.java deleted file mode 100644 index 8328e2ac..00000000 --- a/src/main/java/org/dynmap/PlayerList.java +++ /dev/null @@ -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 hiddenPlayerNames = new HashSet(); - 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 getVisiblePlayers(String worldName) { - ArrayList visiblePlayers = new ArrayList(); - 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 getVisiblePlayers() { - return getVisiblePlayers(null); - } - - public List getHiddenPlayers() { - ArrayList hidden = new ArrayList(); - 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; - } -} diff --git a/src/main/java/org/dynmap/SimpleWebChatComponent.java b/src/main/java/org/dynmap/SimpleWebChatComponent.java deleted file mode 100644 index d442a4b4..00000000 --- a/src/main/java/org/dynmap/SimpleWebChatComponent.java +++ /dev/null @@ -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() { - @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() { - @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())); - } - } - }); - } - } -} diff --git a/src/main/java/org/dynmap/TestComponent.java b/src/main/java/org/dynmap/TestComponent.java deleted file mode 100644 index 92ce77cd..00000000 --- a/src/main/java/org/dynmap/TestComponent.java +++ /dev/null @@ -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")); - } - -} diff --git a/src/main/java/org/dynmap/TileHashManager.java b/src/main/java/org/dynmap/TileHashManager.java deleted file mode 100644 index a97bc99f..00000000 --- a/src/main/java/org/dynmap/TileHashManager.java +++ /dev/null @@ -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 tilehash = new LRULinkedHashMap(MAX_CACHED_TILEHASHFILES); - private LinkedList crcworkbufs = new LinkedList(); - private LinkedList crcs = new LinkedList(); - - 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 */ - } - } -} diff --git a/src/main/java/org/dynmap/UpdateQueue.java b/src/main/java/org/dynmap/UpdateQueue.java deleted file mode 100644 index 6196a498..00000000 --- a/src/main/java/org/dynmap/UpdateQueue.java +++ /dev/null @@ -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 updateSet = new HashMap(); - 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 tmpupdates = new ArrayList(); - - 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; - } -} diff --git a/src/main/java/org/dynmap/bukkit/DynmapPlugin.java b/src/main/java/org/dynmap/bukkit/DynmapPlugin.java index 1bb8df5e..f65d0e48 100644 --- a/src/main/java/org/dynmap/bukkit/DynmapPlugin.java +++ b/src/main/java/org/dynmap/bukkit/DynmapPlugin.java @@ -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"); } diff --git a/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java b/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java index 24ebe6f5..079d65af 100644 --- a/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java +++ b/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java @@ -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; diff --git a/src/main/java/org/dynmap/common/BiomeMap.java b/src/main/java/org/dynmap/common/BiomeMap.java deleted file mode 100644 index 86f848a5..00000000 --- a/src/main/java/org/dynmap/common/BiomeMap.java +++ /dev/null @@ -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 -} diff --git a/src/main/java/org/dynmap/common/DynmapChatColor.java b/src/main/java/org/dynmap/common/DynmapChatColor.java deleted file mode 100644 index 220b9b8f..00000000 --- a/src/main/java/org/dynmap/common/DynmapChatColor.java +++ /dev/null @@ -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]", ""); - } -} diff --git a/src/main/java/org/dynmap/common/DynmapCommandSender.java b/src/main/java/org/dynmap/common/DynmapCommandSender.java deleted file mode 100644 index aa0f16cb..00000000 --- a/src/main/java/org/dynmap/common/DynmapCommandSender.java +++ /dev/null @@ -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(); -} diff --git a/src/main/java/org/dynmap/common/DynmapListenerManager.java b/src/main/java/org/dynmap/common/DynmapListenerManager.java deleted file mode 100644 index f74546b5..00000000 --- a/src/main/java/org/dynmap/common/DynmapListenerManager.java +++ /dev/null @@ -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> listeners = new EnumMap>(EventType.class); - - public void addListener(EventType type, EventListener listener) { - ArrayList lst = listeners.get(type); - if(lst == null) { - lst = new ArrayList(); - listeners.put(type, lst); - core.getServer().requestEventNotification(type); - } - lst.add(listener); - } - - public void processWorldEvent(EventType type, DynmapWorld w) { - ArrayList 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 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 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 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 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 l : listeners.values()) - l.clear(); - listeners.clear(); - } -} diff --git a/src/main/java/org/dynmap/common/DynmapPlayer.java b/src/main/java/org/dynmap/common/DynmapPlayer.java deleted file mode 100644 index 6285125f..00000000 --- a/src/main/java/org/dynmap/common/DynmapPlayer.java +++ /dev/null @@ -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(); -} diff --git a/src/main/java/org/dynmap/common/DynmapServerInterface.java b/src/main/java/org/dynmap/common/DynmapServerInterface.java deleted file mode 100644 index e1856228..00000000 --- a/src/main/java/org/dynmap/common/DynmapServerInterface.java +++ /dev/null @@ -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 Future callSyncMethod(Callable 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 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(); -} diff --git a/src/main/java/org/dynmap/debug/Debug.java b/src/main/java/org/dynmap/debug/Debug.java deleted file mode 100644 index d6973e6f..00000000 --- a/src/main/java/org/dynmap/debug/Debug.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.dynmap.debug; - -import java.util.ArrayList; - -public class Debug { - private static ArrayList debuggers = new ArrayList(); - - 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); - } -} diff --git a/src/main/java/org/dynmap/debug/Debugger.java b/src/main/java/org/dynmap/debug/Debugger.java deleted file mode 100644 index 2919e140..00000000 --- a/src/main/java/org/dynmap/debug/Debugger.java +++ /dev/null @@ -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); -} diff --git a/src/main/java/org/dynmap/debug/LogDebugger.java b/src/main/java/org/dynmap/debug/LogDebugger.java deleted file mode 100644 index ce857017..00000000 --- a/src/main/java/org/dynmap/debug/LogDebugger.java +++ /dev/null @@ -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(); - } - -} diff --git a/src/main/java/org/dynmap/debug/NullDebugger.java b/src/main/java/org/dynmap/debug/NullDebugger.java deleted file mode 100644 index 1ccfa5be..00000000 --- a/src/main/java/org/dynmap/debug/NullDebugger.java +++ /dev/null @@ -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) { - } - -} diff --git a/src/main/java/org/dynmap/flat/FlatMap.java b/src/main/java/org/dynmap/flat/FlatMap.java deleted file mode 100644 index 78e413bc..00000000 --- a/src/main/java/org/dynmap/flat/FlatMap.java +++ /dev/null @@ -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 rslt = new ArrayList(); - 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 getRequiredChunks(MapTile tile) { - FlatMapTile t = (FlatMapTile) tile; - int chunksPerTile = t.size / 16; - int sx = t.x * chunksPerTile; - int sz = t.y * chunksPerTile; - - ArrayList result = new ArrayList(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 getMapsSharingRender(DynmapWorld w) { - return Collections.singletonList((MapType)this); - } - - /* Get names of maps rendered concurrently with this map type in this world */ - public List getMapNamesSharingRender(DynmapWorld w) { - return Collections.singletonList(name); - } - - public List baseZoomFileInfo() { - ArrayList s = new ArrayList(); - 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 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); - } -} diff --git a/src/main/java/org/dynmap/hdmap/CaveHDShader.java b/src/main/java/org/dynmap/hdmap/CaveHDShader.java deleted file mode 100644 index cdeb5f83..00000000 --- a/src/main/java/org/dynmap/hdmap/CaveHDShader.java +++ /dev/null @@ -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); - } -} diff --git a/src/main/java/org/dynmap/hdmap/DefaultHDLighting.java b/src/main/java/org/dynmap/hdmap/DefaultHDLighting.java deleted file mode 100644 index 54f182b4..00000000 --- a/src/main/java/org/dynmap/hdmap/DefaultHDLighting.java +++ /dev/null @@ -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()); - } -} diff --git a/src/main/java/org/dynmap/hdmap/DefaultHDShader.java b/src/main/java/org/dynmap/hdmap/DefaultHDShader.java deleted file mode 100644 index f32b6e25..00000000 --- a/src/main/java/org/dynmap/hdmap/DefaultHDShader.java +++ /dev/null @@ -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); - } -} diff --git a/src/main/java/org/dynmap/hdmap/HDBlockModels.java b/src/main/java/org/dynmap/hdmap/HDBlockModels.java deleted file mode 100644 index 3284ed49..00000000 --- a/src/main/java/org/dynmap/hdmap/HDBlockModels.java +++ /dev/null @@ -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 scaledblocks; - private static int linkalg[] = new int[256]; - private static int linkmap[][] = new int[256][]; - - private static HashMap models_by_id_data = new HashMap(); - - 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 scaled_models_by_scale = new HashMap(); - - /** - * 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<(); } - 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 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 modlist = new ArrayList(); - HashMap varvals = new HashMap(); - 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 blkids = new ArrayList(); - 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 blkids = new ArrayList(); - line = line.substring(8); - String[] args = line.split(","); - List map = new ArrayList(); - 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<= 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) { - } - } - } - } -} diff --git a/src/main/java/org/dynmap/hdmap/HDLighting.java b/src/main/java/org/dynmap/hdmap/HDLighting.java deleted file mode 100644 index c8bcfea7..00000000 --- a/src/main/java/org/dynmap/hdmap/HDLighting.java +++ /dev/null @@ -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); -} diff --git a/src/main/java/org/dynmap/hdmap/HDMap.java b/src/main/java/org/dynmap/hdmap/HDMap.java deleted file mode 100644 index eca68fb1..00000000 --- a/src/main/java/org/dynmap/hdmap/HDMap.java +++ /dev/null @@ -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 getRequiredChunks(MapTile tile) { - return perspective.getRequiredChunks(tile); - } - - @Override - public List baseZoomFileInfo() { - ArrayList s = new ArrayList(); - 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 getMapsSharingRender(DynmapWorld w) { - ArrayList maps = new ArrayList(); - 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 getMapNamesSharingRender(DynmapWorld w) { - ArrayList lst = new ArrayList(); - 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); - } - } -} diff --git a/src/main/java/org/dynmap/hdmap/HDMapManager.java b/src/main/java/org/dynmap/hdmap/HDMapManager.java deleted file mode 100644 index 3fa9fefc..00000000 --- a/src/main/java/org/dynmap/hdmap/HDMapManager.java +++ /dev/null @@ -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 shaders = new HashMap(); - public HashMap perspectives = new HashMap(); - public HashMap lightings = new HashMap(); - public HashSet maps = new HashSet(); - public HashMap> maps_by_world_perspective = new HashMap>(); - - 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.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.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.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.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.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.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 shaders = new ArrayList(); - 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 cached_data_flags_by_world_perspective = new HashMap(); - - 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; - } -} diff --git a/src/main/java/org/dynmap/hdmap/HDMapTile.java b/src/main/java/org/dynmap/hdmap/HDMapTile.java deleted file mode 100644 index 2a584d0e..00000000 --- a/src/main/java/org/dynmap/hdmap/HDMapTile.java +++ /dev/null @@ -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 getRequiredChunks() { - return perspective.getRequiredChunks(this); - } - - public MapTile[] getAdjecentTiles() { - return perspective.getAdjecentTiles(this); - } - - public int tileOrdinalX() { return tx; } - public int tileOrdinalY() { return ty; } - -} diff --git a/src/main/java/org/dynmap/hdmap/HDPerspective.java b/src/main/java/org/dynmap/hdmap/HDPerspective.java deleted file mode 100644 index 6813d30f..00000000 --- a/src/main/java/org/dynmap/hdmap/HDPerspective.java +++ /dev/null @@ -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 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); -} diff --git a/src/main/java/org/dynmap/hdmap/HDPerspectiveState.java b/src/main/java/org/dynmap/hdmap/HDPerspectiveState.java deleted file mode 100644 index 3cc1a8fd..00000000 --- a/src/main/java/org/dynmap/hdmap/HDPerspectiveState.java +++ /dev/null @@ -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(); -} diff --git a/src/main/java/org/dynmap/hdmap/HDShader.java b/src/main/java/org/dynmap/hdmap/HDShader.java deleted file mode 100644 index a26c04be..00000000 --- a/src/main/java/org/dynmap/hdmap/HDShader.java +++ /dev/null @@ -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); - -} diff --git a/src/main/java/org/dynmap/hdmap/HDShaderState.java b/src/main/java/org/dynmap/hdmap/HDShaderState.java deleted file mode 100644 index 6cbd55ee..00000000 --- a/src/main/java/org/dynmap/hdmap/HDShaderState.java +++ /dev/null @@ -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(); -} diff --git a/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java b/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java deleted file mode 100644 index 614ef149..00000000 --- a/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java +++ /dev/null @@ -1,1262 +0,0 @@ -package org.dynmap.hdmap; - -import static org.dynmap.JSONUtils.s; - -import org.dynmap.DynmapWorld; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; - -import org.dynmap.Client; -import org.dynmap.Color; -import org.dynmap.ConfigurationNode; -import org.dynmap.DynmapChunk; -import org.dynmap.DynmapCore; -import org.dynmap.DynmapCore.CompassMode; -import org.dynmap.Log; -import org.dynmap.MapManager; -import org.dynmap.MapTile; -import org.dynmap.MapType; -import org.dynmap.MapType.ImageFormat; -import org.dynmap.TileHashManager; -import org.dynmap.debug.Debug; -import org.dynmap.utils.MapIterator.BlockStep; -import org.dynmap.hdmap.TexturePack.BlockTransparency; -import org.dynmap.hdmap.TexturePack.HDTextureMap; -import org.dynmap.utils.DynmapBufferedImage; -import org.dynmap.utils.FileLockManager; -import org.dynmap.utils.MapChunkCache; -import org.dynmap.utils.MapIterator; -import org.dynmap.utils.Matrix3D; -import org.dynmap.utils.Vector3D; -import org.json.simple.JSONObject; - -public class IsoHDPerspective implements HDPerspective { - private String name; - /* View angles */ - public double azimuth; /* Angle in degrees from looking north (0), east (90), south (180), or west (270) */ - public double inclination; /* Angle in degrees from horizontal (0) to vertical (90) */ - public double scale; /* Scale - tile pixel widths per block */ - public double maxheight; - public double minheight; - private boolean fencejoin; - /* Coordinate space for tiles consists of a plane (X, Y), corresponding to the projection of each tile on to the - * plane of the bottom of the world (X positive to the right, Y positive to the top), with Z+ corresponding to the - * height above this plane on a vector towards the viewer). Logically, this makes the parallelogram representing the - * space contributing to the tile have consistent tile-space X,Y coordinate pairs for both the top and bottom faces - * Note that this is a classic right-hand coordinate system, while minecraft's world coordinates are left handed - * (X+ is south, Y+ is up, Z+ is east). - */ - /* Transformation matrix for taking coordinate in world-space (x, y, z) and finding coordinate in tile space (x, y, z) */ - private Matrix3D world_to_map; - private Matrix3D map_to_world; - - /* Scaled models for non-cube blocks */ - private HDBlockModels.HDScaledBlockModels scalemodels; - private int modscale; - - /* dimensions of a map tile */ - public static final int tileWidth = 128; - public static final int tileHeight = 128; - - /* Maximum and minimum inclinations */ - public static final double MAX_INCLINATION = 90.0; - public static final double MIN_INCLINATION = 20.0; - - /* Maximum and minimum scale */ - public static final double MAX_SCALE = 64; - public static final double MIN_SCALE = 1; - - private boolean need_biomedata = false; - private boolean need_rawbiomedata = false; - - private static final int CHEST_BLKTYPEID = 54; - private static final int REDSTONE_BLKTYPEID = 55; - private static final int FENCEGATE_BLKTYPEID = 107; - - private enum ChestData { - SINGLE_WEST, SINGLE_SOUTH, SINGLE_EAST, SINGLE_NORTH, LEFT_WEST, LEFT_SOUTH, LEFT_EAST, LEFT_NORTH, RIGHT_WEST, RIGHT_SOUTH, RIGHT_EAST, RIGHT_NORTH - }; - - /* Orientation lookup for single chest - index bits: occupied blocks NESW */ - private static final ChestData[] SINGLE_LOOKUP = { - ChestData.SINGLE_WEST, ChestData.SINGLE_EAST, ChestData.SINGLE_NORTH, ChestData.SINGLE_NORTH, - ChestData.SINGLE_WEST, ChestData.SINGLE_WEST, ChestData.SINGLE_NORTH, ChestData.SINGLE_NORTH, - ChestData.SINGLE_SOUTH, ChestData.SINGLE_SOUTH, ChestData.SINGLE_WEST, ChestData.SINGLE_EAST, - ChestData.SINGLE_SOUTH, ChestData.SINGLE_SOUTH, ChestData.SINGLE_WEST, ChestData.SINGLE_EAST - }; - - private class OurPerspectiveState implements HDPerspectiveState { - int blocktypeid = 0; - int blockdata = 0; - int blockrenderdata = -1; - int lastblocktypeid = 0; - Vector3D top, bottom; - int px, py; - BlockStep laststep = BlockStep.Y_MINUS; - - BlockStep stepx, stepy, stepz; - /* Raytrace state variables */ - double dx, dy, dz; - int x, y, z; - double dt_dx, dt_dy, dt_dz, t; - int n; - int x_inc, y_inc, z_inc; - double t_next_y, t_next_x, t_next_z; - boolean nonairhit; - /* Subblock tracer state */ - int mx, my, mz; - double xx, yy, zz; - double mdt_dx; - double mdt_dy; - double mdt_dz; - double togo; - double mt_next_x, mt_next_y, mt_next_z; - int subalpha; - double mt; - double mtend; - int mxout, myout, mzout; - - int[] subblock_xyz = new int[3]; - MapIterator mapiter; - boolean isnether; - boolean skiptoair; - int skylevel = -1; - int emitlevel = -1; - - public OurPerspectiveState(MapIterator mi, boolean isnether) { - mapiter = mi; - this.isnether = isnether; - } - private final void updateSemitransparentLight() { - BlockStep [] steps = { BlockStep.Y_PLUS, BlockStep.X_MINUS, BlockStep.X_PLUS, - BlockStep.Z_MINUS, BlockStep.Z_PLUS }; - emitlevel = skylevel = 0; - for(int i = 0; i < steps.length; i++) { - BlockStep s = steps[i]; - mapiter.stepPosition(s); - int v = mapiter.getBlockEmittedLight(); - if(v > emitlevel) emitlevel = v; - v = mapiter.getBlockSkyLight(); - if(v > skylevel) skylevel = v; - mapiter.unstepPosition(s); - } - } - /** - * Update sky and emitted light - */ - private final void updateLightLevel() { - /* Look up transparency for current block */ - BlockTransparency bt = HDTextureMap.getTransparency(blocktypeid); - switch(bt) { - case TRANSPARENT: - skylevel = mapiter.getBlockSkyLight(); - emitlevel = mapiter.getBlockEmittedLight(); - break; - case OPAQUE: - if(HDTextureMap.getTransparency(lastblocktypeid) != BlockTransparency.SEMITRANSPARENT) { - mapiter.unstepPosition(laststep); /* Back up to block we entered on */ - if(mapiter.getY() < 128) { - emitlevel = mapiter.getBlockEmittedLight(); - skylevel = mapiter.getBlockSkyLight(); - } else { - emitlevel = 0; - skylevel = 15; - } - mapiter.stepPosition(laststep); - } - else { - mapiter.unstepPosition(laststep); /* Back up to block we entered on */ - updateSemitransparentLight(); - mapiter.stepPosition(laststep); - } - break; - case SEMITRANSPARENT: - updateSemitransparentLight(); - break; - } - } - /** - * Get sky light level - only available if shader requested it - */ - public final int getSkyLightLevel() { - if(skylevel < 0) { - updateLightLevel(); - } - return skylevel; - } - /** - * Get emitted light level - only available if shader requested it - */ - public final int getEmittedLightLevel() { - if(emitlevel < 0) - updateLightLevel(); - return emitlevel; - } - /** - * Get current block type ID - */ - public final int getBlockTypeID() { return blocktypeid; } - /** - * Get current block data - */ - public final int getBlockData() { return blockdata; } - /** - * Get current block render data - */ - public final int getBlockRenderData() { return blockrenderdata; } - /** - * Get direction of last block step - */ - public final BlockStep getLastBlockStep() { return laststep; } - /** - * Get perspective scale - */ - public final double getScale() { return scale; } - /** - * Get start of current ray, in world coordinates - */ - public final Vector3D getRayStart() { return top; } - /** - * Get end of current ray, in world coordinates - */ - public final Vector3D getRayEnd() { return bottom; } - /** - * Get pixel X coordinate - */ - public final int getPixelX() { return px; } - /** - * Get pixel Y coordinate - */ - public final int getPixelY() { return py; } - /** - * Get map iterator - */ - public final MapIterator getMapIterator() { return mapiter; } - /** - * Return submodel alpha value (-1 if no submodel rendered) - */ - public int getSubmodelAlpha() { - return subalpha; - } - /** - * Initialize raytrace state variables - */ - private void raytrace_init() { - /* Compute total delta on each axis */ - dx = Math.abs(bottom.x - top.x); - dy = Math.abs(bottom.y - top.y); - dz = Math.abs(bottom.z - top.z); - /* Initial block coord */ - x = (int) (Math.floor(top.x)); - y = (int) (Math.floor(top.y)); - z = (int) (Math.floor(top.z)); - /* Compute parametric step (dt) per step on each axis */ - dt_dx = 1.0 / dx; - dt_dy = 1.0 / dy; - dt_dz = 1.0 / dz; - /* Initialize parametric value to 0 (and we're stepping towards 1) */ - t = 0; - /* Compute number of steps and increments for each */ - n = 1; - - /* If perpendicular to X axis */ - if (dx == 0) { - x_inc = 0; - t_next_x = Double.MAX_VALUE; - stepx = BlockStep.X_PLUS; - mxout = modscale; - } - /* If bottom is right of top */ - else if (bottom.x > top.x) { - x_inc = 1; - n += (int) (Math.floor(bottom.x)) - x; - t_next_x = (Math.floor(top.x) + 1 - top.x) * dt_dx; - stepx = BlockStep.X_PLUS; - mxout = modscale; - } - /* Top is right of bottom */ - else { - x_inc = -1; - n += x - (int) (Math.floor(bottom.x)); - t_next_x = (top.x - Math.floor(top.x)) * dt_dx; - stepx = BlockStep.X_MINUS; - mxout = -1; - } - /* If perpendicular to Y axis */ - if (dy == 0) { - y_inc = 0; - t_next_y = Double.MAX_VALUE; - stepy = BlockStep.Y_PLUS; - myout = modscale; - } - /* If bottom is above top */ - else if (bottom.y > top.y) { - y_inc = 1; - n += (int) (Math.floor(bottom.y)) - y; - t_next_y = (Math.floor(top.y) + 1 - top.y) * dt_dy; - stepy = BlockStep.Y_PLUS; - myout = modscale; - } - /* If top is above bottom */ - else { - y_inc = -1; - n += y - (int) (Math.floor(bottom.y)); - t_next_y = (top.y - Math.floor(top.y)) * dt_dy; - stepy = BlockStep.Y_MINUS; - myout = -1; - } - /* If perpendicular to Z axis */ - if (dz == 0) { - z_inc = 0; - t_next_z = Double.MAX_VALUE; - stepz = BlockStep.Z_PLUS; - mzout = modscale; - } - /* If bottom right of top */ - else if (bottom.z > top.z) { - z_inc = 1; - n += (int) (Math.floor(bottom.z)) - z; - t_next_z = (Math.floor(top.z) + 1 - top.z) * dt_dz; - stepz = BlockStep.Z_PLUS; - mzout = modscale; - } - /* If bottom left of top */ - else { - z_inc = -1; - n += z - (int) (Math.floor(bottom.z)); - t_next_z = (top.z - Math.floor(top.z)) * dt_dz; - stepz = BlockStep.Z_MINUS; - mzout = -1; - } - /* Walk through scene */ - laststep = BlockStep.Y_MINUS; /* Last step is down into map */ - nonairhit = false; - skiptoair = isnether; - } - private int generateFenceBlockData(MapIterator mapiter, int blkid) { - int blockdata = 0; - int id; - /* Check north */ - id = mapiter.getBlockTypeIDAt(BlockStep.X_MINUS); - if((id == blkid) || (id == FENCEGATE_BLKTYPEID) || - (fencejoin && (id > 0) && (HDTextureMap.getTransparency(id) == BlockTransparency.OPAQUE))) { /* Fence? */ - blockdata |= 1; - } - /* Look east */ - id = mapiter.getBlockTypeIDAt(BlockStep.Z_MINUS); - if((id == blkid) || (id == FENCEGATE_BLKTYPEID) || - (fencejoin && (id > 0) && (HDTextureMap.getTransparency(id) == BlockTransparency.OPAQUE))) { /* Fence? */ - blockdata |= 2; - } - /* Look south */ - id = mapiter.getBlockTypeIDAt(BlockStep.X_PLUS); - if((id == blkid) || (id == FENCEGATE_BLKTYPEID) || - (fencejoin && (id > 0) && (HDTextureMap.getTransparency(id) == BlockTransparency.OPAQUE))) { /* Fence? */ - blockdata |= 4; - } - /* Look west */ - id = mapiter.getBlockTypeIDAt(BlockStep.Z_PLUS); - if((id == blkid) || (id == FENCEGATE_BLKTYPEID) || - (fencejoin && (id > 0) && (HDTextureMap.getTransparency(id) == BlockTransparency.OPAQUE))) { /* Fence? */ - blockdata |= 8; - } - return blockdata; - } - /** - * Generate chest block to drive model selection: - * 0 = single facing west - * 1 = single facing south - * 2 = single facing east - * 3 = single facing north - * 4 = left side facing west - * 5 = left side facing south - * 6 = left side facing east - * 7 = left side facing north - * 8 = right side facing west - * 9 = right side facing south - * 10 = right side facing east - * 11 = right side facing north - * @param mapiter - * @return - */ - private int generateChestBlockData(MapIterator mapiter) { - ChestData cd = ChestData.SINGLE_WEST; /* Default to single facing west */ - /* Check adjacent block IDs */ - int ids[] = { mapiter.getBlockTypeIDAt(BlockStep.Z_PLUS), /* To west */ - mapiter.getBlockTypeIDAt(BlockStep.X_PLUS), /* To south */ - mapiter.getBlockTypeIDAt(BlockStep.Z_MINUS), /* To east */ - mapiter.getBlockTypeIDAt(BlockStep.X_MINUS) }; /* To north */ - /* First, check if we're a double - see if any adjacent chests */ - if(ids[0] == CHEST_BLKTYPEID) { /* Another to west - assume we face south */ - cd = ChestData.RIGHT_SOUTH; /* We're right side */ - } - else if(ids[1] == CHEST_BLKTYPEID) { /* Another to south - assume west facing */ - cd = ChestData.LEFT_WEST; /* We're left side */ - } - else if(ids[2] == CHEST_BLKTYPEID) { /* Another to east - assume south facing */ - cd = ChestData.LEFT_SOUTH; /* We're left side */ - } - else if(ids[3] == CHEST_BLKTYPEID) { /* Another to north - assume west facing */ - cd = ChestData.RIGHT_WEST; /* We're right side */ - } - else { /* Else, single - build index into lookup table */ - int idx = 0; - for(int i = 0; i < ids.length; i++) { - if((ids[i] != 0) && (HDTextureMap.getTransparency(ids[i]) != BlockTransparency.TRANSPARENT)) { - idx |= (1< 0) && (HDTextureMap.getTransparency(id) == BlockTransparency.OPAQUE))) { - blockdata |= 1; - } - /* Look east */ - id = mapiter.getBlockTypeIDAt(BlockStep.Z_MINUS); - if((id == typeid) || ((id > 0) && (HDTextureMap.getTransparency(id) == BlockTransparency.OPAQUE))) { - blockdata |= 2; - } - /* Look south */ - id = mapiter.getBlockTypeIDAt(BlockStep.X_PLUS); - if((id == typeid) || ((id > 0) && (HDTextureMap.getTransparency(id) == BlockTransparency.OPAQUE))) { - blockdata |= 4; - } - /* Look west */ - id = mapiter.getBlockTypeIDAt(BlockStep.Z_PLUS); - if((id == typeid) || ((id > 0) && (HDTextureMap.getTransparency(id) == BlockTransparency.OPAQUE))) { - blockdata |= 8; - } - return blockdata; - } - private final boolean containsID(int id, int[] linkids) { - for(int i = 0; i < linkids.length; i++) - if(id == linkids[i]) - return true; - return false; - } - private int generateWireBlockData(MapIterator mapiter, int[] linkids) { - int blockdata = 0; - int id; - /* Check north */ - id = mapiter.getBlockTypeIDAt(BlockStep.X_MINUS); - if(containsID(id, linkids)) { - blockdata |= 1; - } - /* Look east */ - id = mapiter.getBlockTypeIDAt(BlockStep.Z_MINUS); - if(containsID(id, linkids)) { - blockdata |= 2; - } - /* Look south */ - id = mapiter.getBlockTypeIDAt(BlockStep.X_PLUS); - if(containsID(id, linkids)) { - blockdata |= 4; - } - /* Look west */ - id = mapiter.getBlockTypeIDAt(BlockStep.Z_PLUS); - if(containsID(id, linkids)) { - blockdata |= 8; - } - return blockdata; - } - - private final boolean handleSubModel(short[] model, HDShaderState[] shaderstate, boolean[] shaderdone) { - boolean firststep = true; - - while(!raytraceSubblock(model, firststep)) { - boolean done = true; - skylevel = emitlevel = -1; - for(int i = 0; i < shaderstate.length; i++) { - if(!shaderdone[i]) - shaderdone[i] = shaderstate[i].processBlock(this); - done = done && shaderdone[i]; - } - /* If all are done, we're out */ - if(done) - return true; - nonairhit = true; - firststep = false; - } - return false; - } - private static final int FENCE_ALGORITHM = 1; - private static final int CHEST_ALGORITHM = 2; - private static final int REDSTONE_ALGORITHM = 3; - private static final int GLASS_IRONFENCE_ALG = 4; - private static final int WIRE_ALGORITHM = 5; - /** - * Process visit of ray to block - */ - private final boolean visit_block(MapIterator mapiter, HDShaderState[] shaderstate, boolean[] shaderdone) { - lastblocktypeid = blocktypeid; - blocktypeid = mapiter.getBlockTypeID(); - if(skiptoair) { /* If skipping until we see air */ - if(blocktypeid == 0) /* If air, we're done */ - skiptoair = false; - } - else if(nonairhit || (blocktypeid != 0)) { - blockdata = mapiter.getBlockData(); - switch(HDBlockModels.getLinkAlgID(blocktypeid)) { - case FENCE_ALGORITHM: /* Fence algorithm */ - blockrenderdata = generateFenceBlockData(mapiter, blocktypeid); - break; - case CHEST_ALGORITHM: - blockrenderdata = generateChestBlockData(mapiter); - break; - case REDSTONE_ALGORITHM: - blockrenderdata = generateRedstoneWireBlockData(mapiter); - break; - case GLASS_IRONFENCE_ALG: - blockrenderdata = generateIronFenceGlassBlockData(mapiter, blocktypeid); - break; - case WIRE_ALGORITHM: - blockrenderdata = generateWireBlockData(mapiter, HDBlockModels.getLinkIDs(blocktypeid)); - break; - case 0: - default: - blockrenderdata = -1; - break; - } - /* Look up to see if block is modelled */ - short[] model = scalemodels.getScaledModel(blocktypeid, blockdata, blockrenderdata); - if(model != null) { - return handleSubModel(model, shaderstate, shaderdone); - } - else { - boolean done = true; - skylevel = emitlevel = -1; - subalpha = -1; - for(int i = 0; i < shaderstate.length; i++) { - if(!shaderdone[i]) - shaderdone[i] = shaderstate[i].processBlock(this); - done = done && shaderdone[i]; - } - /* If all are done, we're out */ - if(done) - return true; - nonairhit = true; - } - } - return false; - } - /** - * Trace ray, based on "Voxel Tranversal along a 3D line" - */ - private void raytrace(MapChunkCache cache, MapIterator mapiter, HDShaderState[] shaderstate, boolean[] shaderdone) { - /* Initialize raytrace state variables */ - raytrace_init(); - - mapiter.initialize(x, y, z); - - for (; n > 0; --n) { - if(visit_block(mapiter, shaderstate, shaderdone)) { - return; - } - /* If Y step is next best */ - if((t_next_y <= t_next_x) && (t_next_y <= t_next_z)) { - y += y_inc; - t = t_next_y; - t_next_y += dt_dy; - laststep = stepy; - mapiter.stepPosition(laststep); - /* If outside 0-127 range */ - if((y & (~0x7F)) != 0) return; - } - /* If X step is next best */ - else if((t_next_x <= t_next_y) && (t_next_x <= t_next_z)) { - x += x_inc; - t = t_next_x; - t_next_x += dt_dx; - laststep = stepx; - mapiter.stepPosition(laststep); - } - /* Else, Z step is next best */ - else { - z += z_inc; - t = t_next_z; - t_next_z += dt_dz; - laststep = stepz; - mapiter.stepPosition(laststep); - } - } - } - - private boolean raytraceSubblock(short[] model, boolean firsttime) { - if(firsttime) { - mt = t + 0.00000001; - xx = top.x + mt *(bottom.x - top.x); - yy = top.y + mt *(bottom.y - top.y); - zz = top.z + mt *(bottom.z - top.z); - mx = (int)((xx - Math.floor(xx)) * modscale); - my = (int)((yy - Math.floor(yy)) * modscale); - mz = (int)((zz - Math.floor(zz)) * modscale); - mdt_dx = dt_dx / modscale; - mdt_dy = dt_dy / modscale; - mdt_dz = dt_dz / modscale; - mt_next_x = t_next_x; - mt_next_y = t_next_y; - mt_next_z = t_next_z; - if(mt_next_x != Double.MAX_VALUE) { - togo = ((t_next_x - t) / mdt_dx); - mt_next_x = mt + (togo - Math.floor(togo)) * mdt_dx; - } - if(mt_next_y != Double.MAX_VALUE) { - togo = ((t_next_y - t) / mdt_dy); - mt_next_y = mt + (togo - Math.floor(togo)) * mdt_dy; - } - if(mt_next_z != Double.MAX_VALUE) { - togo = ((t_next_z - t) / mdt_dz); - mt_next_z = mt + (togo - Math.floor(togo)) * mdt_dz; - } - mtend = Math.min(t_next_x, Math.min(t_next_y, t_next_z)); - } - subalpha = -1; - boolean skip = !firsttime; /* Skip first block on continue */ - while(mt <= mtend) { - if(!skip) { - try { - int blkalpha = model[modscale*modscale*my + modscale*mz + mx]; - if(blkalpha > 0) { - subalpha = blkalpha; - return false; - } - } catch (ArrayIndexOutOfBoundsException aioobx) { /* We're outside the model, so miss */ - return true; - } - } - else { - skip = false; - } - - /* If X step is next best */ - if((mt_next_x <= mt_next_y) && (mt_next_x <= mt_next_z)) { - mx += x_inc; - mt = mt_next_x; - mt_next_x += mdt_dx; - laststep = stepx; - if(mx == mxout) { - return true; - } - } - /* If Y step is next best */ - else if((mt_next_y <= mt_next_x) && (mt_next_y <= mt_next_z)) { - my += y_inc; - mt = mt_next_y; - mt_next_y += mdt_dy; - laststep = stepy; - if(my == myout) { - return true; - } - } - /* Else, Z step is next best */ - else { - mz += z_inc; - mt = mt_next_z; - mt_next_z += mdt_dz; - laststep = stepz; - if(mz == mzout) { - return true; - } - } - } - return true; - } - public final int[] getSubblockCoord() { - if(subalpha < 0) { - double tt = t + 0.0000001; - double xx = top.x + tt * (bottom.x - top.x); - double yy = top.y + tt * (bottom.y - top.y); - double zz = top.z + tt * (bottom.z - top.z); - subblock_xyz[0] = (int)((xx - Math.floor(xx)) * modscale); - subblock_xyz[1] = (int)((yy - Math.floor(yy)) * modscale); - subblock_xyz[2] = (int)((zz - Math.floor(zz)) * modscale); - } - else { - subblock_xyz[0] = mx; - subblock_xyz[1] = my; - subblock_xyz[2] = mz; - } - return subblock_xyz; - } - } - - public IsoHDPerspective(DynmapCore core, ConfigurationNode configuration) { - name = configuration.getString("name", null); - if(name == null) { - Log.severe("Perspective definition missing name - must be defined and unique"); - return; - } - azimuth = configuration.getDouble("azimuth", 135.0); /* Get azimuth (default to classic kzed POV */ - /* Fix azimuth so that we respect new north, if that is requested (newnorth = oldeast) */ - if(MapManager.mapman.getCompassMode() == CompassMode.NEWNORTH) { - azimuth = (azimuth + 90.0); if(azimuth >= 360.0) azimuth = azimuth - 360.0; - } - inclination = configuration.getDouble("inclination", 60.0); - if(inclination > MAX_INCLINATION) inclination = MAX_INCLINATION; - if(inclination < MIN_INCLINATION) inclination = MIN_INCLINATION; - scale = configuration.getDouble("scale", MIN_SCALE); - if(scale < MIN_SCALE) scale = MIN_SCALE; - if(scale > MAX_SCALE) scale = MAX_SCALE; - /* Get max and min height */ - maxheight = configuration.getInteger("maximumheight", 127); - if(maxheight > 127) maxheight = 127; - minheight = configuration.getInteger("minimumheight", 0); - if(minheight < 0) minheight = 0; - /* Fence-to-block-join setting */ - fencejoin = configuration.getBoolean("fence-to-block-join", MapManager.mapman.getFenceJoin()); - - /* Generate transform matrix for world-to-tile coordinate mapping */ - /* First, need to fix basic coordinate mismatches before rotation - we want zero azimuth to have north to top - * (world -X -> tile +Y) and east to right (world -Z to tile +X), with height being up (world +Y -> tile +Z) - */ - Matrix3D transform = new Matrix3D(0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0); - /* Next, rotate world counterclockwise around Z axis by azumuth angle */ - transform.rotateXY(180-azimuth); - /* Next, rotate world by (90-inclination) degrees clockwise around +X axis */ - transform.rotateYZ(90.0-inclination); - /* Finally, shear along Z axis to normalize Z to be height above map plane */ - transform.shearZ(0, Math.tan(Math.toRadians(90.0-inclination))); - /* And scale Z to be same scale as world coordinates, and scale X and Y based on setting */ - transform.scale(scale, scale, Math.sin(Math.toRadians(inclination))); - world_to_map = transform; - /* Now, generate map to world tranform, by doing opposite actions in reverse order */ - transform = new Matrix3D(); - transform.scale(1.0/scale, 1.0/scale, 1/Math.sin(Math.toRadians(inclination))); - transform.shearZ(0, -Math.tan(Math.toRadians(90.0-inclination))); - transform.rotateYZ(-(90.0-inclination)); - transform.rotateXY(-180+azimuth); - Matrix3D coordswap = new Matrix3D(0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0); - transform.multiply(coordswap); - map_to_world = transform; - /* Scaled models for non-cube blocks */ - modscale = (int)Math.ceil(scale); - scalemodels = HDBlockModels.getModelsForScale(modscale);; - } - - @Override - public MapTile[] getTiles(DynmapWorld world, int x, int y, int z) { - HashSet tiles = new HashSet(); - Vector3D block = new Vector3D(); - block.x = x; - block.y = y; - block.z = z; - Vector3D corner = new Vector3D(); - /* Loop through corners of the cube */ - for(int i = 0; i < 2; i++) { - double inity = block.y; - for(int j = 0; j < 2; j++) { - double initz = block.z; - for(int k = 0; k < 2; k++) { - world_to_map.transform(block, corner); /* Get map coordinate of corner */ - addTile(tiles, world, (int)Math.floor(corner.x/tileWidth), (int)Math.floor(corner.y/tileHeight)); - - block.z += 1; - } - block.z = initz; - block.y += 1; - } - block.y = inity; - block.x += 1; - } - return tiles.toArray(new MapTile[tiles.size()]); - } - - @Override - public MapTile[] getTiles(DynmapWorld world, int minx, int miny, int minz, int maxx, int maxy, int maxz) { - HashSet tiles = new HashSet(); - Vector3D blocks[] = new Vector3D[] { new Vector3D(), new Vector3D() }; - blocks[0].x = minx - 1; - blocks[0].y = miny - 1; - blocks[0].z = minz - 1; - blocks[1].x = maxx + 1; - blocks[1].y = maxy + 1; - blocks[1].z = maxz + 1; - - Vector3D corner = new Vector3D(); - Vector3D tcorner = new Vector3D(); - int mintilex = Integer.MAX_VALUE; - int maxtilex = Integer.MIN_VALUE; - int mintiley = Integer.MAX_VALUE; - int maxtiley = Integer.MIN_VALUE; - /* Loop through corners of the prism */ - for(int i = 0; i < 2; i++) { - corner.x = blocks[i].x; - for(int j = 0; j < 2; j++) { - corner.y = blocks[j].y; - for(int k = 0; k < 2; k++) { - corner.z = blocks[k].z; - world_to_map.transform(corner, tcorner); /* Get map coordinate of corner */ - int tx = (int)Math.floor(tcorner.x/tileWidth); - int ty = (int)Math.floor(tcorner.y/tileWidth); - if(mintilex > tx) mintilex = tx; - if(maxtilex < tx) maxtilex = tx; - if(mintiley > ty) mintiley = ty; - if(maxtiley < ty) maxtiley = ty; - } - } - } - /* Now, add the tiles for the ranges - not perfect, but it works (some extra tiles on corners possible) */ - for(int i = mintilex; i <= maxtilex; i++) { - for(int j = mintiley-1; j <= maxtiley; j++) { /* Extra 1 - TODO: figure out why needed... */ - addTile(tiles, world, i, j); - } - } - return tiles.toArray(new MapTile[tiles.size()]); - } - - @Override - public MapTile[] getAdjecentTiles(MapTile tile) { - HDMapTile t = (HDMapTile) tile; - DynmapWorld w = t.getDynmapWorld(); - int x = t.tx; - int y = t.ty; - return new MapTile[] { - new HDMapTile(w, this, x - 1, y - 1), - new HDMapTile(w, this, x + 1, y - 1), - new HDMapTile(w, this, x - 1, y + 1), - new HDMapTile(w, this, x + 1, y + 1), - new HDMapTile(w, this, x, y - 1), - new HDMapTile(w, this, x + 1, y), - new HDMapTile(w, this, x, y + 1), - new HDMapTile(w, this, x - 1, y) }; - } - - public void addTile(HashSet tiles, DynmapWorld world, int tx, int ty) { - tiles.add(new HDMapTile(world, this, tx, ty)); - } - - private static class Rectangle { - double r0x, r0z; /* Coord of corner of rectangle */ - double s1x, s1z; /* Side vector for one edge */ - double s2x, s2z; /* Side vector for other edge */ - public Rectangle(Vector3D v1, Vector3D v2, Vector3D v3) { - r0x = v1.x; - r0z = v1.z; - s1x = v2.x - v1.x; - s1z = v2.z - v1.z; - s2x = v3.x - v1.x; - s2z = v3.z - v1.z; - } - public Rectangle() { - } - public void setSquare(double rx, double rz, double s) { - this.r0x = rx; - this.r0z = rz; - this.s1x = s; - this.s1z = 0; - this.s2x = 0; - this.s2z = s; - } - double getX(int idx) { - return r0x + (((idx & 1) == 0)?0:s1x) + (((idx & 2) != 0)?0:s2x); - } - double getZ(int idx) { - return r0z + (((idx & 1) == 0)?0:s1z) + (((idx & 2) != 0)?0:s2z); - } - /** - * Test for overlap of projection of one vector on to anoter - */ - boolean testoverlap(double rx, double rz, double sx, double sz, Rectangle r) { - double rmin_dot_s0 = Double.MAX_VALUE; - double rmax_dot_s0 = Double.MIN_VALUE; - /* Project each point from rectangle on to vector: find lowest and highest */ - for(int i = 0; i < 4; i++) { - double r_x = r.getX(i) - rx; /* Get relative positon of second vector start to origin */ - double r_z = r.getZ(i) - rz; - double r_dot_s0 = r_x*sx + r_z*sz; /* Projection of start of vector */ - if(r_dot_s0 < rmin_dot_s0) rmin_dot_s0 = r_dot_s0; - if(r_dot_s0 > rmax_dot_s0) rmax_dot_s0 = r_dot_s0; - } - /* Compute dot products */ - double s0_dot_s0 = sx*sx + sz*sz; /* End of our side */ - if((rmax_dot_s0 < 0.0) || (rmin_dot_s0 > s0_dot_s0)) - return false; - else - return true; - } - /** - * Test if two rectangles intersect - * Based on separating axis theorem - */ - boolean testRectangleIntesectsRectangle(Rectangle r) { - /* Test if projection of each edge of one rectangle on to each edge of the other yields overlap */ - if(testoverlap(r0x, r0z, s1x, s1z, r) && testoverlap(r0x, r0z, s2x, s2z, r) && - testoverlap(r0x+s1x, r0z+s1z, s2x, s2z, r) && testoverlap(r0x+s2x, r0z+s2z, s1x, s1z, r) && - r.testoverlap(r.r0x, r.r0z, r.s1x, r.s1z, this) && r.testoverlap(r.r0x, r.r0z, r.s2x, r.s2z, this) && - r.testoverlap(r.r0x+r.s1x, r.r0z+r.s1z, r.s2x, r.s2z, this) && r.testoverlap(r.r0x+r.s2x, r.r0z+r.s2z, r.s1x, r.s1z, this)) { - return true; - } - else { - return false; - } - } - public String toString() { - return "{ " + r0x + "," + r0z + "}x{" + (r0x+s1x) + ","+ + (r0z+s1z) + "}x{" + (r0x+s2x) + "," + (r0z+s2z) + "}"; - } - } - - @Override - public List getRequiredChunks(MapTile tile) { - if (!(tile instanceof HDMapTile)) - return Collections.emptyList(); - - HDMapTile t = (HDMapTile) tile; - int min_chunk_x = Integer.MAX_VALUE; - int max_chunk_x = Integer.MIN_VALUE; - int min_chunk_z = Integer.MAX_VALUE; - int max_chunk_z = Integer.MIN_VALUE; - - /* Make corners for volume: 0 = bottom-lower-left, 1 = top-lower-left, 2=bottom-upper-left, 3=top-upper-left - * 4 = bottom-lower-right, 5 = top-lower-right, 6 = bottom-upper-right, 7 = top-upper-right */ - Vector3D corners[] = new Vector3D[8]; - int[] chunk_x = new int[8]; - int[] chunk_z = new int[8]; - int dx = -1, dy = -1; - for(int x = t.tx, idx = 0; x <= (t.tx+1); x++) { - dy = -1; - for(int y = t.ty; y <= (t.ty+1); y++) { - for(int z = 0; z <= 1; z++) { - corners[idx] = new Vector3D(); - corners[idx].x = x*tileWidth + dx; corners[idx].y = y*tileHeight + dy; corners[idx].z = z*128; - map_to_world.transform(corners[idx]); - /* Compute chunk coordinates of corner */ - chunk_x[idx] = (int)Math.floor(corners[idx].x / 16); - chunk_z[idx] = (int)Math.floor(corners[idx].z / 16); - /* Compute min/max of chunk coordinates */ - if(min_chunk_x > chunk_x[idx]) min_chunk_x = chunk_x[idx]; - if(max_chunk_x < chunk_x[idx]) max_chunk_x = chunk_x[idx]; - if(min_chunk_z > chunk_z[idx]) min_chunk_z = chunk_z[idx]; - if(max_chunk_z < chunk_z[idx]) max_chunk_z = chunk_z[idx]; - idx++; - } - dy = 1; - } - dx = 1; - } - /* Make rectangles of X-Z projection of each side of the tile volume, 0 = top, 1 = bottom, 2 = left, 3 = right, - * 4 = upper, 5 = lower */ - Rectangle rect[] = new Rectangle[6]; - rect[0] = new Rectangle(corners[1], corners[3], corners[5]); - rect[1] = new Rectangle(corners[0], corners[2], corners[4]); - rect[2] = new Rectangle(corners[0], corners[1], corners[2]); - rect[3] = new Rectangle(corners[4], corners[5], corners[6]); - rect[4] = new Rectangle(corners[2], corners[3], corners[6]); - rect[5] = new Rectangle(corners[0], corners[1], corners[4]); - - /* Now, need to walk through the min/max range to see which chunks are actually needed */ - ArrayList chunks = new ArrayList(); - Rectangle chunkrect = new Rectangle(); - int misscnt = 0; - for(int x = min_chunk_x; x <= max_chunk_x; x++) { - for(int z = min_chunk_z; z <= max_chunk_z; z++) { - chunkrect.setSquare(x*16, z*16, 16); - boolean hit = false; - /* Check to see if square of chunk intersects any of our rectangle sides */ - for(int rctidx = 0; (!hit) && (rctidx < rect.length); rctidx++) { - if(chunkrect.testRectangleIntesectsRectangle(rect[rctidx])) { - hit = true; - } - } - if(hit) { - DynmapChunk chunk = new DynmapChunk(x, z); - chunks.add(chunk); - } - else { - misscnt++; - } - } - } - return chunks; - } - - @Override - public boolean render(MapChunkCache cache, HDMapTile tile, String mapname) { - Color rslt = new Color(); - MapIterator mapiter = cache.getIterator(0, 0, 0); - /* Build shader state object for each shader */ - HDShaderState[] shaderstate = MapManager.mapman.hdmapman.getShaderStateForTile(tile, cache, mapiter, mapname); - int numshaders = shaderstate.length; - if(numshaders == 0) - return false; - /* Check if nether world */ - boolean isnether = tile.getDynmapWorld().isNether(); - /* Create buffered image for each */ - DynmapBufferedImage im[] = new DynmapBufferedImage[numshaders]; - DynmapBufferedImage dayim[] = new DynmapBufferedImage[numshaders]; - int[][] argb_buf = new int[numshaders][]; - int[][] day_argb_buf = new int[numshaders][]; - boolean isjpg[] = new boolean[numshaders]; - int bgday[] = new int[numshaders]; - int bgnight[] = new int[numshaders]; - - for(int i = 0; i < numshaders; i++) { - HDLighting lighting = shaderstate[i].getLighting(); - im[i] = DynmapBufferedImage.allocateBufferedImage(tileWidth, tileHeight); - argb_buf[i] = im[i].argb_buf; - if(lighting.isNightAndDayEnabled()) { - dayim[i] = DynmapBufferedImage.allocateBufferedImage(tileWidth, tileHeight); - day_argb_buf[i] = dayim[i].argb_buf; - } - isjpg[i] = shaderstate[i].getMap().getImageFormat() != ImageFormat.FORMAT_PNG; - bgday[i] = shaderstate[i].getMap().getBackgroundARGBDay(); - bgnight[i] = shaderstate[i].getMap().getBackgroundARGBNight(); - } - - /* Create perspective state object */ - OurPerspectiveState ps = new OurPerspectiveState(mapiter, isnether); - - ps.top = new Vector3D(); - ps.bottom = new Vector3D(); - double xbase = tile.tx * tileWidth; - double ybase = tile.ty * tileHeight; - boolean shaderdone[] = new boolean[numshaders]; - boolean rendered[] = new boolean[numshaders]; - - for(int x = 0; x < tileWidth; x++) { - ps.px = x; - for(int y = 0; y < tileHeight; y++) { - ps.top.x = ps.bottom.x = xbase + x + 0.5; /* Start at center of pixel at Y=127.5, bottom at Y=-0.5 */ - ps.top.y = ps.bottom.y = ybase + y + 0.5; - ps.top.z = maxheight + 0.5; ps.bottom.z = minheight - 0.5; - map_to_world.transform(ps.top); /* Transform to world coordinates */ - map_to_world.transform(ps.bottom); - ps.py = y; - for(int i = 0; i < numshaders; i++) { - shaderstate[i].reset(ps); - } - ps.raytrace(cache, mapiter, shaderstate, shaderdone); - for(int i = 0; i < numshaders; i++) { - if(shaderdone[i] == false) { - shaderstate[i].rayFinished(ps); - } - else { - shaderdone[i] = false; - rendered[i] = true; - } - shaderstate[i].getRayColor(rslt, 0); - int c_argb = rslt.getARGB(); - if(c_argb != 0) rendered[i] = true; - if(isjpg[i] && (c_argb == 0)) { - argb_buf[i][(tileHeight-y-1)*tileWidth + x] = bgnight[i]; - } - else { - argb_buf[i][(tileHeight-y-1)*tileWidth + x] = c_argb; - } - if(day_argb_buf[i] != null) { - shaderstate[i].getRayColor(rslt, 1); - c_argb = rslt.getARGB(); - if(isjpg[i] && (c_argb == 0)) { - day_argb_buf[i][(tileHeight-y-1)*tileWidth + x] = bgday[i]; - } - else { - day_argb_buf[i][(tileHeight-y-1)*tileWidth + x] = c_argb; - } - } - } - } - } - - boolean renderone = false; - /* Test to see if we're unchanged from older tile */ - TileHashManager hashman = MapManager.mapman.hashman; - for(int i = 0; i < numshaders; i++) { - long crc = hashman.calculateTileHash(argb_buf[i]); - boolean tile_update = false; - String prefix = shaderstate[i].getMap().getPrefix(); - - MapType.ImageFormat fmt = shaderstate[i].getMap().getImageFormat(); - String fname = tile.getFilename(prefix, fmt); - File f = new File(tile.getDynmapWorld().worldtilepath, fname); - FileLockManager.getWriteLock(f); - try { - if((!f.exists()) || (crc != hashman.getImageHashCode(tile.getKey(prefix), null, tile.tx, tile.ty))) { - /* Wrap buffer as buffered image */ - Debug.debug("saving image " + f.getPath()); - if(!f.getParentFile().exists()) - f.getParentFile().mkdirs(); - try { - FileLockManager.imageIOWrite(im[i].buf_img, fmt, f); - } catch (IOException e) { - Debug.error("Failed to save image: " + f.getPath(), e); - } catch (java.lang.NullPointerException e) { - Debug.error("Failed to save image (NullPointerException): " + f.getPath(), e); - } - MapManager.mapman.pushUpdate(tile.getDynmapWorld(), new Client.Tile(fname)); - hashman.updateHashCode(tile.getKey(prefix), null, tile.tx, tile.ty, crc); - tile.getDynmapWorld().enqueueZoomOutUpdate(f); - tile_update = true; - renderone = true; - } - else { - Debug.debug("skipping image " + f.getPath() + " - hash match"); - } - } finally { - FileLockManager.releaseWriteLock(f); - DynmapBufferedImage.freeBufferedImage(im[i]); - } - MapManager.mapman.updateStatistics(tile, prefix, true, tile_update, !rendered[i]); - /* Handle day image, if needed */ - if(dayim[i] != null) { - fname = tile.getDayFilename(prefix, fmt); - f = new File(tile.getDynmapWorld().worldtilepath, fname); - FileLockManager.getWriteLock(f); - tile_update = false; - try { - if((!f.exists()) || (crc != hashman.getImageHashCode(tile.getKey(prefix), "day", tile.tx, tile.ty))) { - /* Wrap buffer as buffered image */ - Debug.debug("saving image " + f.getPath()); - if(!f.getParentFile().exists()) - f.getParentFile().mkdirs(); - try { - FileLockManager.imageIOWrite(dayim[i].buf_img, fmt, f); - } catch (IOException e) { - Debug.error("Failed to save image: " + f.getPath(), e); - } catch (java.lang.NullPointerException e) { - Debug.error("Failed to save image (NullPointerException): " + f.getPath(), e); - } - MapManager.mapman.pushUpdate(tile.getDynmapWorld(), new Client.Tile(fname)); - hashman.updateHashCode(tile.getKey(prefix), "day", tile.tx, tile.ty, crc); - tile.getDynmapWorld().enqueueZoomOutUpdate(f); - tile_update = true; - renderone = true; - } - else { - Debug.debug("skipping image " + f.getPath() + " - hash match"); - } - } finally { - FileLockManager.releaseWriteLock(f); - DynmapBufferedImage.freeBufferedImage(dayim[i]); - } - MapManager.mapman.updateStatistics(tile, prefix+"_day", true, tile_update, !rendered[i]); - } - } - return renderone; - } - - @Override - public boolean isBiomeDataNeeded() { - return need_biomedata; - } - - @Override - public boolean isRawBiomeDataNeeded() { - return need_rawbiomedata; - } - - public boolean isHightestBlockYDataNeeded() { - return false; - } - - public boolean isBlockTypeDataNeeded() { - return true; - } - - public double getScale() { - return scale; - } - - public int getModelScale() { - return modscale; - } - - @Override - public String getName() { - return name; - } - - private static String[] directions = { "N", "NE", "E", "SE", "S", "SW", "W", "NW" }; - @Override - public void addClientConfiguration(JSONObject mapObject) { - s(mapObject, "perspective", name); - s(mapObject, "azimuth", azimuth); - s(mapObject, "inclination", inclination); - s(mapObject, "scale", scale); - s(mapObject, "worldtomap", world_to_map.toJSON()); - s(mapObject, "maptoworld", map_to_world.toJSON()); - int dir = ((360 + (int)(22.5+azimuth)) / 45) % 8; - if(MapManager.mapman.getCompassMode() != CompassMode.PRE19) - dir = (dir + 6) % 8; - s(mapObject, "compassview", directions[dir]); - - } -} diff --git a/src/main/java/org/dynmap/hdmap/ShadowHDLighting.java b/src/main/java/org/dynmap/hdmap/ShadowHDLighting.java deleted file mode 100644 index f0d0461d..00000000 --- a/src/main/java/org/dynmap/hdmap/ShadowHDLighting.java +++ /dev/null @@ -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); } - -} diff --git a/src/main/java/org/dynmap/hdmap/TexturePack.java b/src/main/java/org/dynmap/hdmap/TexturePack.java deleted file mode 100644 index 7098bb81..00000000 --- a/src/main/java/org/dynmap/hdmap/TexturePack.java +++ /dev/null @@ -1,1783 +0,0 @@ -package org.dynmap.hdmap; - -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.LineNumberReader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import javax.imageio.ImageIO; - -import org.dynmap.Color; -import org.dynmap.ConfigurationNode; -import org.dynmap.DynmapCore; -import org.dynmap.Log; -import org.dynmap.MapManager; -import org.dynmap.common.BiomeMap; -import org.dynmap.utils.DynmapBufferedImage; -import org.dynmap.utils.MapIterator.BlockStep; -import org.dynmap.utils.MapIterator; - -/** - * Loader and processor class for minecraft texture packs - * Texture packs are found in dynmap/texturepacks directory, and either are either ZIP files - * or are directories whose content matches the structure of a zipped texture pack: - * ./terrain.png - main color data (required) - * misc/water.png - still water tile (required)) - * misc/grasscolor.png - tone for grass color, biome sensitive (required) - * misc/foliagecolor.png - tone for leaf color, biome sensitive (required) - * misc/watercolor.png - tone for water color, biome sensitive (required) - * custom_lava_still.png - custom still lava animation (optional) - * custom_lava_flowing.png - custom flowing lava animation (optional) - * custom_water_still.png - custom still water animation (optional) - * custom_water_flowing.png - custom flowing water animation (optional) - */ -public class TexturePack { - /* Loaded texture packs */ - private static HashMap packs = new HashMap(); - - private static final String TERRAIN_PNG = "terrain.png"; - private static final String GRASSCOLOR_PNG = "misc/grasscolor.png"; - private static final String FOLIAGECOLOR_PNG = "misc/foliagecolor.png"; - private static final String WATERCOLOR_PNG = "misc/watercolor.png"; - private static final String WATER_PNG = "misc/water.png"; - private static final String CUSTOMLAVASTILL_PNG = "custom_lava_still.png"; - private static final String CUSTOMLAVAFLOWING_PNG = "custom_lava_flowing.png"; - private static final String CUSTOMWATERSTILL_PNG = "custom_water_still.png"; - private static final String CUSTOMWATERFLOWING_PNG = "custom_water_flowing.png"; - - private static final String STANDARDTP = "standard"; - /* Color modifier codes (x1000 for value in mapping code) */ - private static final int COLORMOD_NONE = 0; - private static final int COLORMOD_GRASSTONED = 1; - private static final int COLORMOD_FOLIAGETONED = 2; - private static final int COLORMOD_WATERTONED = 3; - private static final int COLORMOD_ROT90 = 4; - private static final int COLORMOD_ROT180 = 5; - private static final int COLORMOD_ROT270 = 6; - private static final int COLORMOD_FLIPHORIZ = 7; - private static final int COLORMOD_SHIFTDOWNHALF = 8; - private static final int COLORMOD_SHIFTDOWNHALFANDFLIPHORIZ = 9; - private static final int COLORMOD_INCLINEDTORCH = 10; - private static final int COLORMOD_GRASSSIDE = 11; - private static final int COLORMOD_CLEARINSIDE = 12; - private static final int COLORMOD_PINETONED = 13; - private static final int COLORMOD_BIRCHTONED = 14; - private static final int COLORMOD_LILYTONED = 15; - private static final int COLORMOD_OLD_WATERSHADED = 16; - - /* Special tile index values */ - private static final int BLOCKINDEX_BLANK = -1; - private static final int BLOCKINDEX_GRASS = 0; - private static final int BLOCKINDEX_GRASSMASK = 38; - private static final int BLOCKINDEX_SNOW = 66; - private static final int BLOCKINDEX_SNOWSIDE = 68; - private static final int BLOCKINDEX_PISTONSIDE = 108; - private static final int BLOCKINDEX_GLASSPANETOP = 148; - private static final int BLOCKINDEX_AIRFRAME = 158; - private static final int BLOCKINDEX_REDSTONE_NSEW_TONE = 164; - private static final int BLOCKINDEX_REDSTONE_EW_TONE = 165; - private static final int BLOCKINDEX_EYEOFENDER = 174; - private static final int BLOCKINDEX_REDSTONE_NSEW = 180; - private static final int BLOCKINDEX_REDSTONE_EW = 181; - private static final int BLOCKINDEX_STATIONARYWATER = 257; - private static final int BLOCKINDEX_MOVINGWATER = 258; - private static final int BLOCKINDEX_STATIONARYLAVA = 259; - private static final int BLOCKINDEX_MOVINGLAVA = 260; - private static final int BLOCKINDEX_PISTONEXTSIDE = 261; - private static final int BLOCKINDEX_PISTONSIDE_EXT = 262; - private static final int BLOCKINDEX_PANETOP_X = 263; - private static final int BLOCKINDEX_AIRFRAME_EYE = 264; - private static final int BLOCKINDEX_FIRE = 265; - private static final int MAX_BLOCKINDEX = 265; /* Index of last static tile definition */ - private static final int BLOCKTABLELEN = 1000; /* Leave room for dynmaic tiles */ - - private static int next_dynamic_tile = MAX_BLOCKINDEX+1; - private static class DynamicTileFile { - String filename; - int tilecnt_x, tilecnt_y; /* Number of tiles horizontally and vertically */ - int tile_to_dyntile[]; /* Mapping from tile index in tile file to dynamic ID in global tile table (terrain_argb): 0=unassigned */ - } - private static ArrayList addonfiles = new ArrayList(); - - private static class LoadedImage { - int[] argb; - int width, height; - int trivial_color; - } - - private int[][] terrain_argb; - private int terrain_width, terrain_height; - private int native_scale; - - private int water_toned_op = COLORMOD_WATERTONED; - - private static final int IMG_GRASSCOLOR = 0; - private static final int IMG_FOLIAGECOLOR = 1; - private static final int IMG_WATER = 2; - private static final int IMG_CUSTOMWATERMOVING = 3; - private static final int IMG_CUSTOMWATERSTILL = 4; - private static final int IMG_CUSTOMLAVAMOVING = 5; - private static final int IMG_CUSTOMLAVASTILL = 6; - private static final int IMG_WATERCOLOR = 7; - private static final int IMG_WATERMOVING = 8; - private static final int IMG_LAVA = 9; - private static final int IMG_LAVAMOVING = 10; - private static final int IMG_FIRE = 11; - private static final int IMG_CNT = 12; - /* 0-(IMG_CNT-1) are fixed, IMG_CNT+x is dynamic file x */ - private LoadedImage[] imgs; - - private HashMap scaled_textures; - - public enum BlockTransparency { - OPAQUE, /* Block is opaque - blocks light - lit by light from adjacent blocks */ - TRANSPARENT, /* Block is transparent - passes light - lit by light level in own block */ - SEMITRANSPARENT /* Opaque block that doesn't block all rays (steps, slabs) - use light above for face lighting on opaque blocks */ - } - public static class HDTextureMap { - private int faces[]; /* index in terrain.png of image for each face (indexed by BlockStep.ordinal()) */ - private List blockids; - private int databits; - private BlockTransparency bt; - private boolean userender; - private static HDTextureMap[] texmaps; - private static BlockTransparency transp[]; - private static boolean userenderdata[]; - - private static void initializeTable() { - texmaps = new HDTextureMap[16*BLOCKTABLELEN]; - transp = new BlockTransparency[BLOCKTABLELEN]; - userenderdata = new boolean[BLOCKTABLELEN]; - HDTextureMap blank = new HDTextureMap(); - for(int i = 0; i < texmaps.length; i++) - texmaps[i] = blank; - for(int i = 0; i < transp.length; i++) - transp[i] = BlockTransparency.OPAQUE; - } - - private HDTextureMap() { - blockids = Collections.singletonList(Integer.valueOf(0)); - databits = 0xFFFF; - userender = false; - faces = new int[] { BLOCKINDEX_BLANK, BLOCKINDEX_BLANK, BLOCKINDEX_BLANK, BLOCKINDEX_BLANK, BLOCKINDEX_BLANK, BLOCKINDEX_BLANK }; - - for(int i = 0; i < texmaps.length; i++) { - texmaps[i] = this; - } - - } - - public HDTextureMap(List blockids, int databits, int[] faces, BlockTransparency trans, boolean userender) { - this.faces = faces; - this.blockids = blockids; - this.databits = databits; - this.bt = trans; - this.userender = userender; - } - - public void addToTable() { - /* Add entries to lookup table */ - for(Integer blkid : blockids) { - for(int i = 0; i < 16; i++) { - if((databits & (1 << i)) != 0) { - texmaps[16*blkid + i] = this; - } - } - transp[blkid] = bt; /* Transparency is only blocktype based right now */ - userenderdata[blkid] = userender; /* Ditto for using render data */ - } - } - - public static HDTextureMap getMap(int blkid, int blkdata, int blkrenderdata) { - if(userenderdata[blkid]) - return texmaps[(blkid<<4) + blkrenderdata]; - else - return texmaps[(blkid<<4) + blkdata]; - } - - public static BlockTransparency getTransparency(int blkid) { - return transp[blkid]; - } - - private static void remapTexture(int id, int srcid) { - for(int i = 0; i < 16; i++) { - texmaps[(id<<4)+i] = texmaps[(srcid<<4)+i]; - } - } - - } - /** Get or load texture pack */ - public static TexturePack getTexturePack(DynmapCore core, String tpname) { - TexturePack tp = packs.get(tpname); - if(tp != null) - return tp; - try { - tp = new TexturePack(core, tpname); /* Attempt to load pack */ - packs.put(tpname, tp); - return tp; - } catch (FileNotFoundException fnfx) { - Log.severe("Error loading texture pack '" + tpname + "' - not found"); - } - return null; - } - /** - * Constructor for texture pack, by name - */ - private TexturePack(DynmapCore core, String tpname) throws FileNotFoundException { - ZipFile zf = null; - File texturedir = getTexturePackDirectory(core); - boolean use_generate = HDMapManager.usegeneratedtextures; - if(HDMapManager.biomeshadingfix == false) - water_toned_op = COLORMOD_OLD_WATERSHADED; - - /* Set up for enough files */ - imgs = new LoadedImage[IMG_CNT + addonfiles.size()]; - - /* Generate still and flowing water defaults */ - if(use_generate) { - generateWater(); - generateWaterFlowing(); - generateLava(); - generateLavaFlow(); - } - generateFire(); - - File f = new File(texturedir, tpname); - try { - /* Try to open zip */ - zf = new ZipFile(f); - /* Find and load terrain.png */ - InputStream is; - ZipEntry ze = zf.getEntry(TERRAIN_PNG); /* Try to find terrain.png */ - if(ze == null) { - /* Check for terrain.png under standard texture pack*/ - File ff = new File(texturedir, STANDARDTP + "/" + TERRAIN_PNG); - is = new FileInputStream(ff); - } - else { - is = zf.getInputStream(ze); /* Get input stream for terrain.png */ - } - loadTerrainPNG(is); - is.close(); - /* If not generating water, load it */ - if(!use_generate) { - ze = zf.getEntry(WATER_PNG); - if(ze == null) { - File ff = new File(texturedir, STANDARDTP + "/" + WATER_PNG); - is = new FileInputStream(ff); - } - else { - is = zf.getInputStream(ze); - } - loadImage(is, IMG_WATER); - patchTextureWithImage(IMG_WATER, BLOCKINDEX_STATIONARYWATER); - patchTextureWithImage(IMG_WATER, BLOCKINDEX_MOVINGWATER); - is.close(); - } - else { - patchTextureWithImage(IMG_WATER, BLOCKINDEX_STATIONARYWATER); - patchTextureWithImage(IMG_WATERMOVING, BLOCKINDEX_MOVINGWATER); - patchTextureWithImage(IMG_LAVA, BLOCKINDEX_STATIONARYLAVA); - patchTextureWithImage(IMG_LAVAMOVING, BLOCKINDEX_MOVINGLAVA); - } - patchTextureWithImage(IMG_FIRE, BLOCKINDEX_FIRE); - - /* Try to find and load misc/grasscolor.png */ - ze = zf.getEntry(GRASSCOLOR_PNG); - if(ze == null) { /* Fall back to standard file */ - /* Check for misc/grasscolor.png under standard texture pack*/ - File ff = new File(texturedir, STANDARDTP + "/" + GRASSCOLOR_PNG); - is = new FileInputStream(ff); - } - else { - is = zf.getInputStream(ze); - } - loadBiomeShadingImage(is, IMG_GRASSCOLOR); - is.close(); - /* Try to find and load misc/foliagecolor.png */ - ze = zf.getEntry(FOLIAGECOLOR_PNG); - if(ze == null) { - /* Check for misc/foliagecolor.png under standard texture pack*/ - File ff = new File(texturedir, STANDARDTP + "/" + FOLIAGECOLOR_PNG); - is = new FileInputStream(ff); - } - else { - is = zf.getInputStream(ze); - } - loadBiomeShadingImage(is, IMG_FOLIAGECOLOR); - is.close(); - /* Try to find and load misc/watercolor.png */ - ze = zf.getEntry(WATERCOLOR_PNG); - if(ze == null) { /* Fall back to standard file */ - /* Check for misc/watercolor.png under standard texture pack*/ - File ff = new File(texturedir, STANDARDTP + "/" + WATERCOLOR_PNG); - is = new FileInputStream(ff); - } - else { - is = zf.getInputStream(ze); - } - loadBiomeShadingImage(is, IMG_WATERCOLOR); - is.close(); - - /* Optional files - process if they exist */ - ze = zf.getEntry(CUSTOMLAVAFLOWING_PNG); - if(ze != null) { - is = zf.getInputStream(ze); - loadImage(is, IMG_CUSTOMLAVAMOVING); - patchTextureWithImage(IMG_CUSTOMLAVAMOVING, BLOCKINDEX_MOVINGLAVA); - } - ze = zf.getEntry(CUSTOMLAVASTILL_PNG); - if(ze != null) { - is = zf.getInputStream(ze); - loadImage(is, IMG_CUSTOMLAVASTILL); - patchTextureWithImage(IMG_CUSTOMLAVASTILL, BLOCKINDEX_STATIONARYLAVA); - } - ze = zf.getEntry(CUSTOMWATERFLOWING_PNG); - if(ze != null) { - is = zf.getInputStream(ze); - loadImage(is, IMG_CUSTOMWATERMOVING); - patchTextureWithImage(IMG_CUSTOMWATERMOVING, BLOCKINDEX_MOVINGWATER); - } - ze = zf.getEntry(CUSTOMWATERSTILL_PNG); - if(ze != null) { - is = zf.getInputStream(ze); - loadImage(is, IMG_CUSTOMWATERSTILL); - patchTextureWithImage(IMG_CUSTOMWATERSTILL, BLOCKINDEX_STATIONARYWATER); - } - - /* Loop through dynamic files */ - for(int i = 0; i < addonfiles.size(); i++) { - DynamicTileFile dtf = addonfiles.get(i); - ze = zf.getEntry(dtf.filename); - if(ze == null) { - File ff = new File(texturedir, STANDARDTP + "/" + dtf.filename); - is = new FileInputStream(ff); - } - else { - is = zf.getInputStream(ze); - } - loadDynamicImage(is, i); - is.close(); - } - - zf.close(); - return; - } catch (IOException iox) { - if(zf != null) { - try { zf.close(); } catch (IOException io) {} - } - } - /* Try loading terrain.png from directory of name */ - FileInputStream fis = null; - try { - /* Open and load terrain.png */ - f = new File(texturedir, tpname + "/" + TERRAIN_PNG); - if(!f.canRead()) { - f = new File(texturedir, STANDARDTP + "/" + TERRAIN_PNG); - } - fis = new FileInputStream(f); - loadTerrainPNG(fis); - fis.close(); - - if(use_generate == false) { /* Not using generated - load water */ - /* Check for misc/water.png */ - f = new File(texturedir, tpname + "/" + WATER_PNG); - if(!f.canRead()) { - f = new File(texturedir, STANDARDTP + "/" + WATER_PNG); - } - fis = new FileInputStream(f); - loadImage(fis, IMG_WATER); - patchTextureWithImage(IMG_WATER, BLOCKINDEX_STATIONARYWATER); - patchTextureWithImage(IMG_WATER, BLOCKINDEX_MOVINGWATER); - fis.close(); - } - else { - patchTextureWithImage(IMG_WATER, BLOCKINDEX_STATIONARYWATER); - patchTextureWithImage(IMG_WATERMOVING, BLOCKINDEX_MOVINGWATER); - patchTextureWithImage(IMG_LAVA, BLOCKINDEX_STATIONARYLAVA); - patchTextureWithImage(IMG_LAVAMOVING, BLOCKINDEX_MOVINGLAVA); - } - /* Patch in generated value */ - patchTextureWithImage(IMG_FIRE, BLOCKINDEX_FIRE); - - /* Check for misc/grasscolor.png */ - f = new File(texturedir, tpname + "/" + GRASSCOLOR_PNG); - if(!f.canRead()) { - f = new File(texturedir, STANDARDTP + "/" + GRASSCOLOR_PNG); - } - fis = new FileInputStream(f); - loadBiomeShadingImage(fis, IMG_GRASSCOLOR); - fis.close(); - /* Check for misc/foliagecolor.png */ - f = new File(texturedir, tpname + "/" + FOLIAGECOLOR_PNG); - if(!f.canRead()) { - f = new File(texturedir, STANDARDTP + "/" + FOLIAGECOLOR_PNG); - } - fis = new FileInputStream(f); - loadBiomeShadingImage(fis, IMG_FOLIAGECOLOR); - fis.close(); - /* Check for misc/watercolor.png */ - f = new File(texturedir, tpname + "/" + WATERCOLOR_PNG); - if(!f.canRead()) { - f = new File(texturedir, STANDARDTP + "/" + WATERCOLOR_PNG); - } - fis = new FileInputStream(f); - loadBiomeShadingImage(fis, IMG_WATERCOLOR); - fis.close(); - - /* Optional files - process if they exist */ - f = new File(texturedir, tpname + "/" + CUSTOMLAVAFLOWING_PNG); - if(f.canRead()) { - fis = new FileInputStream(f); - loadImage(fis, IMG_CUSTOMLAVAMOVING); - patchTextureWithImage(IMG_CUSTOMLAVAMOVING, BLOCKINDEX_MOVINGLAVA); - fis.close(); - } - f = new File(texturedir, tpname + "/" + CUSTOMLAVASTILL_PNG); - if(f.canRead()) { - fis = new FileInputStream(f); - loadImage(fis, IMG_CUSTOMLAVASTILL); - patchTextureWithImage(IMG_CUSTOMLAVASTILL, BLOCKINDEX_STATIONARYLAVA); - fis.close(); - } - f = new File(texturedir, tpname + "/" + IMG_CUSTOMWATERMOVING); - if(f.canRead()) { - fis = new FileInputStream(f); - loadImage(fis, IMG_CUSTOMWATERMOVING); - patchTextureWithImage(IMG_CUSTOMWATERMOVING, BLOCKINDEX_MOVINGWATER); - fis.close(); - } - f = new File(texturedir, tpname + "/" + IMG_CUSTOMWATERSTILL); - if(f.canRead()) { - fis = new FileInputStream(f); - loadImage(fis, IMG_CUSTOMWATERSTILL); - patchTextureWithImage(IMG_CUSTOMWATERSTILL, BLOCKINDEX_STATIONARYWATER); - fis.close(); - } - /* Loop through dynamic files */ - for(int i = 0; i < addonfiles.size(); i++) { - DynamicTileFile dtf = addonfiles.get(i); - f = new File(texturedir, tpname + "/" + dtf.filename); - if(!f.canRead()) { - f = new File(texturedir, STANDARDTP + "/" + dtf.filename); - } - fis = new FileInputStream(f); - loadDynamicImage(fis, i); - fis.close(); - } - } catch (IOException iox) { - if(fis != null) { - try { fis.close(); } catch (IOException io) {} - } - Log.info("Cannot process " + f.getPath() + " - " + iox); - - throw new FileNotFoundException(); - } - } - /* Copy texture pack */ - private TexturePack(TexturePack tp) { - this.terrain_argb = new int[tp.terrain_argb.length][]; - System.arraycopy(tp.terrain_argb, 0, this.terrain_argb, 0, this.terrain_argb.length); - this.terrain_width = tp.terrain_width; - this.terrain_height = tp.terrain_height; - this.native_scale = tp.native_scale; - this.water_toned_op = tp.water_toned_op; - - this.imgs = tp.imgs; - } - - /* Load terrain.png */ - private void loadTerrainPNG(InputStream is) throws IOException { - int i, j; - /* Load image */ - ImageIO.setUseCache(false); - BufferedImage img = ImageIO.read(is); - if(img == null) { throw new FileNotFoundException(); } - terrain_width = img.getWidth(); - terrain_height = img.getHeight(); - native_scale = terrain_width / 16; - terrain_argb = new int[BLOCKTABLELEN][]; - for(i = 0; i < 256; i++) { - terrain_argb[i] = new int[native_scale*native_scale]; - img.getRGB((i & 0xF)*native_scale, (i>>4)*native_scale, native_scale, native_scale, terrain_argb[i], 0, native_scale); - } - int[] blank = new int[native_scale*native_scale]; - for(i = 256; i < BLOCKTABLELEN; i++) { - terrain_argb[i] = blank; - } - /* Fallbacks */ - terrain_argb[BLOCKINDEX_STATIONARYLAVA] = terrain_argb[255]; - terrain_argb[BLOCKINDEX_MOVINGLAVA] = terrain_argb[255]; - /* Now, build redstone textures with active wire color (since we're not messing with that) */ - Color tc = new Color(); - for(i = 0; i < native_scale*native_scale; i++) { - if(terrain_argb[BLOCKINDEX_REDSTONE_NSEW_TONE][i] != 0) { - /* Overlay NSEW redstone texture with toned wire color */ - tc.setARGB(terrain_argb[BLOCKINDEX_REDSTONE_NSEW_TONE][i]); - tc.blendColor(0xFFC00000); /* Blend in red */ - terrain_argb[BLOCKINDEX_REDSTONE_NSEW][i] = tc.getARGB(); - } - if(terrain_argb[BLOCKINDEX_REDSTONE_EW_TONE][i] != 0) { - /* Overlay NSEW redstone texture with toned wire color */ - tc.setARGB(terrain_argb[BLOCKINDEX_REDSTONE_EW_TONE][i]); - tc.blendColor(0xFFC00000); /* Blend in red */ - terrain_argb[BLOCKINDEX_REDSTONE_EW][i] = tc.getARGB(); - } - } - /* Build extended piston side texture - take top 1/4 of piston side, use to make piston extension */ - terrain_argb[BLOCKINDEX_PISTONEXTSIDE] = new int[native_scale*native_scale]; - System.arraycopy(terrain_argb[BLOCKINDEX_PISTONSIDE], 0, terrain_argb[BLOCKINDEX_PISTONEXTSIDE], 0, - native_scale * native_scale / 4); - for(i = 0; i < native_scale/4; i++) { - for(j = 0; j < (3*native_scale/4); j++) { - terrain_argb[BLOCKINDEX_PISTONEXTSIDE][native_scale*(native_scale/4 + j) + (3*native_scale/8 + i)] = - terrain_argb[BLOCKINDEX_PISTONSIDE][native_scale*i + j]; - } - } - /* Build piston side while extended (cut off top 1/4, replace with rotated top for extension */ - terrain_argb[BLOCKINDEX_PISTONSIDE_EXT] = new int[native_scale*native_scale]; - System.arraycopy(terrain_argb[BLOCKINDEX_PISTONSIDE], native_scale*native_scale/4, - terrain_argb[BLOCKINDEX_PISTONSIDE_EXT], native_scale*native_scale/4, - 3 * native_scale * native_scale / 4); /* Copy bottom 3/4 */ - for(i = 0; i < native_scale/4; i++) { - for(j = 3*native_scale/4; j < native_scale; j++) { - terrain_argb[BLOCKINDEX_PISTONSIDE_EXT][native_scale*(j - 3*native_scale/4) + (3*native_scale/8 + i)] = - terrain_argb[BLOCKINDEX_PISTONSIDE][native_scale*i + j]; - } - } - /* Build glass pane top in NSEW config (we use model to clip it) */ - terrain_argb[BLOCKINDEX_PANETOP_X] = new int[native_scale*native_scale]; - System.arraycopy(terrain_argb[BLOCKINDEX_GLASSPANETOP], 0, terrain_argb[BLOCKINDEX_PANETOP_X], 0, native_scale*native_scale); - for(i = native_scale*7/16; i < native_scale*9/16; i++) { - for(j = 0; j < native_scale; j++) { - terrain_argb[BLOCKINDEX_PANETOP_X][native_scale*i + j] = terrain_argb[BLOCKINDEX_PANETOP_X][native_scale*j + i]; - } - } - /* Build air frame with eye overlay */ - terrain_argb[BLOCKINDEX_AIRFRAME_EYE] = new int[native_scale*native_scale]; - System.arraycopy(terrain_argb[BLOCKINDEX_AIRFRAME], 0, terrain_argb[BLOCKINDEX_AIRFRAME_EYE], 0, native_scale*native_scale); - for(i = native_scale/4; i < native_scale*3/4; i++) { - for(j = native_scale/4; j < native_scale*3/4; j++) { - terrain_argb[BLOCKINDEX_AIRFRAME_EYE][native_scale*i + j] = terrain_argb[BLOCKINDEX_EYEOFENDER][native_scale*i + j]; - } - } - - img.flush(); - } - - /* Load image into image array */ - private void loadImage(InputStream is, int idx) throws IOException { - /* Load image */ - ImageIO.setUseCache(false); - BufferedImage img = ImageIO.read(is); - if(img == null) { throw new FileNotFoundException(); } - imgs[idx] = new LoadedImage(); - imgs[idx].width = img.getWidth(); - imgs[idx].height = img.getHeight(); - imgs[idx].argb = new int[imgs[idx].width * imgs[idx].height]; - img.getRGB(0, 0, imgs[idx].width, imgs[idx].height, imgs[idx].argb, 0, imgs[idx].width); - img.flush(); - } - - /* Load dynamic texture files, and patch into terrain_argb */ - private void loadDynamicImage(InputStream is, int idx) throws IOException { - loadImage(is, idx+IMG_CNT); /* Load image file */ - DynamicTileFile dtf = addonfiles.get(idx); /* Get tile file definition */ - LoadedImage li = imgs[idx+IMG_CNT]; - int dim = li.width / dtf.tilecnt_x; /* Dimension of each tile */ - int old_argb[] = new int[dim*dim]; - for(int x = 0; x < dtf.tilecnt_x; x++) { - for(int y = 0; y < dtf.tilecnt_y; y++) { - if(dtf.tile_to_dyntile[y*dtf.tilecnt_x + x] > 0) { /* dynamic ID? */ - /* Copy source tile */ - for(int j = 0; j < dim; j++) { - System.arraycopy(li.argb, (y*dim+j)*li.width + (x*dim), old_argb, j*dim, dim); - } - /* Rescale to match rest of terrain PNG */ - int new_argb[] = new int[native_scale*native_scale]; - scaleTerrainPNGSubImage(dim, native_scale, old_argb, new_argb); - terrain_argb[dtf.tile_to_dyntile[y*dtf.tilecnt_x + x]] = new_argb; - } - - } - } - } - /* Load biome shading image into image array */ - private void loadBiomeShadingImage(InputStream is, int idx) throws IOException { - loadImage(is, idx); /* Get image */ - - LoadedImage li = imgs[idx]; - /* Get trivial color for biome-shading image */ - int clr = li.argb[li.height*li.width*3/4 + li.width/2]; - boolean same = true; - for(int j = 0; same && (j < li.height); j++) { - for(int i = 0; same && (i <= j); i++) { - if(li.argb[li.width*j+i] != clr) - same = false; - } - } - /* All the same - no biome lookup needed */ - if(same) { - imgs[idx].argb = null; - li.trivial_color = clr; - } - else { /* Else, calculate color average for lower left quadrant */ - int[] clr_scale = new int[4]; - scaleTerrainPNGSubImage(li.width, 2, li.argb, clr_scale); - li.trivial_color = clr_scale[2]; - } - } - - /* Patch image into texture table */ - private void patchTextureWithImage(int image_idx, int block_idx) { - /* Now, patch in to block table */ - int new_argb[] = new int[native_scale*native_scale]; - scaleTerrainPNGSubImage(imgs[image_idx].width, native_scale, imgs[image_idx].argb, new_argb); - terrain_argb[block_idx] = new_argb; - - } - - /* Get texture pack directory */ - private static File getTexturePackDirectory(DynmapCore core) { - return new File(core.getDataFolder(), "texturepacks"); - } - - /** - * Resample terrain pack for given scale, and return copy using that scale - */ - public TexturePack resampleTexturePack(int scale) { - if(scaled_textures == null) scaled_textures = new HashMap(); - TexturePack stp = scaled_textures.get(scale); - if(stp != null) - return stp; - stp = new TexturePack(this); /* Make copy */ - /* Scale terrain.png, if needed */ - if(stp.native_scale != scale) { - stp.native_scale = scale; - stp.terrain_height = 16*scale; - stp.terrain_width = 16*scale; - scaleTerrainPNG(stp); - } - /* Remember it */ - scaled_textures.put(scale, stp); - return stp; - } - /** - * Scale out terrain_argb into the terrain_argb of the provided destination, matching the scale of that destination - * @param tp - */ - private void scaleTerrainPNG(TexturePack tp) { - tp.terrain_argb = new int[terrain_argb.length][]; - /* Terrain.png is 16x16 array of images : process one at a time */ - for(int idx = 0; idx < terrain_argb.length; idx++) { - tp.terrain_argb[idx] = new int[tp.native_scale*tp.native_scale]; - scaleTerrainPNGSubImage(native_scale, tp.native_scale, terrain_argb[idx], tp.terrain_argb[idx]); - } - /* Special case - some textures are used as masks - need pure alpha (00 or FF) */ - makeAlphaPure(tp.terrain_argb[BLOCKINDEX_GRASSMASK]); /* Grass side mask */ - } - private static void scaleTerrainPNGSubImage(int srcscale, int destscale, int[] src_argb, int[] dest_argb) { - int nativeres = srcscale; - int res = destscale; - Color c = new Color(); - /* Same size, so just copy */ - if(res == nativeres) { - System.arraycopy(src_argb, 0, dest_argb, 0, dest_argb.length); - } - /* If we're scaling larger source pixels into smaller pixels, each destination pixel - * receives input from 1 or 2 source pixels on each axis - */ - 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 + 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 x = 0; x < res; x++, off++) { - int ind_x = offsets[x]; - int wgt_x = weights[x]; - double accum_red = 0; - double accum_green = 0; - double accum_blue = 0; - double accum_alpha = 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; - /* Accumulate */ - c.setARGB(src_argb[(ind_y+yy)*nativeres + ind_x + xx]); - int w = wx * wy; - double a = (double)w * (double)c.getAlpha(); - accum_red += c.getRed() * a; - accum_green += c.getGreen() * a; - accum_blue += c.getBlue() * a; - accum_alpha += a; - } - } - double newalpha = accum_alpha; - if(newalpha == 0.0) newalpha = 1.0; - /* Generate weighted compnents into color */ - c.setRGBA((int)(accum_red / newalpha), (int)(accum_green / newalpha), - (int)(accum_blue / newalpha), (int)(accum_alpha / (nativeres*nativeres))); - dest_argb[(y*res) + x] = c.getARGB(); - } - } - } - 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; - } - } - double accum_red[] = new double[res*res]; - double accum_green[] = new double[res*res]; - double accum_blue[] = new double[res*res]; - double accum_alpha[] = new double[res*res]; - - /* Now, use weights and indices to fill in scaled map */ - for(int y = 0; y < nativeres; y++) { - int ind_y = offsets[y]; - int wgt_y = weights[y]; - for(int x = 0; x < nativeres; x++) { - int ind_x = offsets[x]; - int wgt_x = weights[x]; - c.setARGB(src_argb[(y*nativeres) + 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; - double w = wx * wy; - double a = w * c.getAlpha(); - accum_red[(ind_y+yy)*res + (ind_x+xx)] += c.getRed() * a; - accum_green[(ind_y+yy)*res + (ind_x+xx)] += c.getGreen() * a; - accum_blue[(ind_y+yy)*res + (ind_x+xx)] += c.getBlue() * a; - accum_alpha[(ind_y+yy)*res + (ind_x+xx)] += a; - } - } - } - } - /* Produce normalized scaled values */ - for(int y = 0; y < res; y++) { - for(int x = 0; x < res; x++) { - int off = (y*res) + x; - double aa = accum_alpha[off]; - if(aa == 0.0) aa = 1.0; - c.setRGBA((int)(accum_red[off]/aa), (int)(accum_green[off]/aa), - (int)(accum_blue[off]/aa), (int)(accum_alpha[off] / (nativeres*nativeres))); - dest_argb[y*res + x] = c.getARGB(); - } - } - } - } - public void saveTerrainPNG(File f) throws IOException { - int[] outbuf = new int[256*native_scale*native_scale]; - for(int i = 0; i < 256; i++) { - for(int y = 0; y < native_scale; y++) { - System.arraycopy(terrain_argb[i],native_scale*y,outbuf,((i>>4)*native_scale+y)*terrain_width + (i & 0xF)*native_scale, native_scale); - } - } - BufferedImage img = DynmapBufferedImage.createBufferedImage(outbuf, terrain_width, terrain_height); - ImageIO.setUseCache(false); - ImageIO.write(img, "png", f); - } - - /** - * Load texture pack mappings - */ - public static void loadTextureMapping(File datadir, ConfigurationNode config) { - /* Start clean with texture packs - need to be loaded after mapping */ - packs.clear(); - /* Initialize map with blank map for all entries */ - HDTextureMap.initializeTable(); - /* Load block models */ - InputStream in = TexturePack.class.getResourceAsStream("/texture.txt"); - if(in != null) { - loadTextureFile(in, "texture.txt", config); - if(in != null) { try { in.close(); } catch (IOException x) {} in = null; } - } - else - Log.severe("Error loading texture.txt"); - - File renderdir = new File(datadir, "renderdata"); - String[] files = renderdir.list(); - if(files != null) { - for(String fname : files) { - if(fname.endsWith("-texture.txt")) { - File custom = new File(renderdir, fname); - if(custom.canRead()) { - try { - in = new FileInputStream(custom); - loadTextureFile(in, custom.getPath(), config); - } catch (IOException iox) { - Log.severe("Error loading " + custom.getPath() + " - " + iox); - } finally { - if(in != null) { try { in.close(); } catch (IOException x) {} in = null; } - } - } - } - } - } - } - - private static Integer getIntValue(Map 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); - } - } - - /** - * Translate face ID - in case we've got options to fix it - */ - private static int translateFaceID(int id) { - int f = (id / 1000); - switch(f) { - case COLORMOD_PINETONED: - case COLORMOD_BIRCHTONED: - case COLORMOD_LILYTONED: - if(HDMapManager.biomeshadingfix == false) { - id = (COLORMOD_FOLIAGETONED * 1000) + (id % 1000); - } - break; - case COLORMOD_WATERTONED: - if(HDMapManager.biomeshadingfix == false) { - id = (COLORMOD_OLD_WATERSHADED * 1000) + (id % 1000); - } - break; - } - return id; - } - /** - * Load texture pack mappings from texture.txt file - */ - private static void loadTextureFile(InputStream txtfile, String txtname, ConfigurationNode config) { - LineNumberReader rdr = null; - int cnt = 0; - HashMap filetoidx = new HashMap(); - HashMap varvals = new HashMap(); - - try { - String line; - rdr = new LineNumberReader(new InputStreamReader(txtfile)); - while((line = rdr.readLine()) != null) { - if(line.startsWith("block:")) { - ArrayList blkids = new ArrayList(); - int databits = -1; - int srctxtid = -1; - int faces[] = new int[] { -1, -1, -1, -1, -1, -1 }; - line = line.substring(6); - BlockTransparency trans = BlockTransparency.OPAQUE; - String[] args = line.split(","); - boolean userenderdata = false; - 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(databits < 0) databits = 0; - if(av[1].equals("*")) - databits = 0xFFFF; - else - databits |= (1 << getIntValue(varvals,av[1])); - } - else if(av[0].equals("top") || av[0].equals("y-")) { - faces[BlockStep.Y_MINUS.ordinal()] = Integer.parseInt(av[1]); - } - else if(av[0].equals("bottom") || av[0].equals("y+")) { - faces[BlockStep.Y_PLUS.ordinal()] = Integer.parseInt(av[1]); - } - else if(av[0].equals("north") || av[0].equals("x+")) { - faces[BlockStep.X_PLUS.ordinal()] = Integer.parseInt(av[1]); - } - else if(av[0].equals("south") || av[0].equals("x-")) { - faces[BlockStep.X_MINUS.ordinal()] = Integer.parseInt(av[1]); - } - else if(av[0].equals("west") || av[0].equals("z-")) { - faces[BlockStep.Z_MINUS.ordinal()] = Integer.parseInt(av[1]); - } - else if(av[0].equals("east") || av[0].equals("z+")) { - faces[BlockStep.Z_PLUS.ordinal()] = Integer.parseInt(av[1]); - } - else if(av[0].equals("allfaces")) { - int id = Integer.parseInt(av[1]); - for(int i = 0; i < 6; i++) { - faces[i] = id; - } - } - else if(av[0].equals("allsides")) { - short id = Short.parseShort(av[1]); - faces[BlockStep.X_PLUS.ordinal()] = id; - faces[BlockStep.X_MINUS.ordinal()] = id; - faces[BlockStep.Z_PLUS.ordinal()] = id; - faces[BlockStep.Z_MINUS.ordinal()] = id; - } - else if(av[0].equals("topbottom")) { - faces[BlockStep.Y_MINUS.ordinal()] = - faces[BlockStep.Y_PLUS.ordinal()] = Integer.parseInt(av[1]); - } - else if(av[0].equals("transparency")) { - trans = BlockTransparency.valueOf(av[1]); - if(trans == null) { - trans = BlockTransparency.OPAQUE; - Log.severe("Texture mapping has invalid transparency setting - " + av[1] + " - line " + rdr.getLineNumber() + " of " + txtname); - } - /* If no water lighting fix */ - if((blkids.contains(8) || blkids.contains(9)) && (HDMapManager.waterlightingfix == false)) { - trans = BlockTransparency.TRANSPARENT; /* Treat water as transparent if no fix */ - } - } - else if(av[0].equals("userenderdata")) { - userenderdata = av[1].equals("true"); - } - else if(av[0].equals("txtid")) { - if(filetoidx.containsKey(av[1])) - srctxtid = filetoidx.get(av[1]); - else - Log.severe("Format error - line " + rdr.getLineNumber() + " of " + txtname); - } - } - /* If we have source texture, need to map values to dynamic ids */ - if(srctxtid >= 0) { - for(int i = 0; i < faces.length; i++) { - if(faces[i] < 0) continue; /* Leave invalid IDs alone */ - - int relid = faces[i] % 1000; /* Get relative ID */ - /* Map to assigned ID in global tile table: preserve modifier */ - faces[i] = (faces[i] - relid) + findOrAddDynamicTile(srctxtid, relid); - } - } - /* If no data bits, assume all */ - if(databits < 0) databits = 0xFFFF; - /* If we have everything, build block */ - if(blkids.size() > 0) { - for(int i = 0; i < faces.length; i++) - faces[i] = translateFaceID(faces[i]); - HDTextureMap map = new HDTextureMap(blkids, databits, faces, trans, userenderdata); - map.addToTable(); - cnt++; - } - else { - Log.severe("Texture mapping missing required parameters = line " + rdr.getLineNumber() + " of " + txtname); - } - } - else if(line.startsWith("texturefile:")) { - line = line.substring(line.indexOf(':')+1); - String[] args = line.split(","); - int xdim = 16, ydim = 16; - String fname = null; - String id = null; - for(String arg : args) { - String[] aval = arg.split("="); - if(aval.length < 2) - continue; - if(aval[0].equals("id")) - id = aval[1]; - else if(aval[0].equals("filename")) - fname = aval[1]; - else if(aval[0].equals("xcount")) - xdim = Integer.parseInt(aval[1]); - else if(aval[0].equals("ycount")) - ydim = Integer.parseInt(aval[1]); - } - if((fname != null) && (id != null)) { - /* Register the file */ - int fid = findOrAddDynamicTileFile(fname, xdim, ydim); - filetoidx.put(id, fid); /* Save lookup */ - } - else { - Log.severe("Format error - line " + rdr.getLineNumber() + " of " + txtname); - return; - } - } - 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 + " textures 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 " + txtname); - 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 " + txtname); - return; - } - } - } - } - Log.verboseinfo("Loaded " + cnt + " texture mappings from " + txtname); - } catch (IOException iox) { - Log.severe("Error reading " + txtname + " - " + iox.toString()); - } catch (NumberFormatException nfx) { - Log.severe("Format error - line " + rdr.getLineNumber() + " of " + txtname); - } finally { - if(rdr != null) { - try { - rdr.close(); - rdr = null; - } catch (IOException e) { - } - } - } - - } - - /* Process any ore hiding mappings */ - public static void handleHideOres() { - /* Now, fix mapping if we're hiding any ores */ - if(MapManager.mapman.getHideOres()) { - for(int i = 0; i < 256; i++) { - int id = MapManager.mapman.getBlockIDAlias(i); - if(id != i) { /* New mapping? */ - HDTextureMap.remapTexture(i, id); - } - } - } - } - - private static final int BLOCKID_GRASS = 2; - private static final int BLOCKID_SNOW = 78; - /** - * Read color for given subblock coordinate, with given block id and data and face - */ - public final void readColor(final HDPerspectiveState ps, final MapIterator mapiter, final Color rslt, final int blkid, final int lastblocktype, - TexturePackHDShader.ShaderState ss) { - int blkdata = ps.getBlockData(); - HDTextureMap map = HDTextureMap.getMap(blkid, blkdata, ps.getBlockRenderData()); - BlockStep laststep = ps.getLastBlockStep(); - int textid = map.faces[laststep.ordinal()]; /* Get index of texture source */ - if(textid < 0) { - rslt.setTransparent(); - return; - } - else if(textid < 1000) { /* If simple mapping */ - int[] texture = terrain_argb[textid]; - int[] xyz = ps.getSubblockCoord(); - /* Get texture coordinates (U=horizontal(left=0),V=vertical(top=0)) */ - int u = 0, v = 0; - - switch(laststep) { - case X_MINUS: /* South face: U = East (Z-), V = Down (Y-) */ - u = native_scale-xyz[2]-1; v = native_scale-xyz[1]-1; - break; - case X_PLUS: /* North face: U = West (Z+), V = Down (Y-) */ - u = xyz[2]; v = native_scale-xyz[1]-1; - break; - case Z_MINUS: /* West face: U = South (X+), V = Down (Y-) */ - u = xyz[0]; v = native_scale-xyz[1]-1; - break; - case Z_PLUS: /* East face: U = North (X-), V = Down (Y-) */ - u = native_scale-xyz[0]-1; v = native_scale-xyz[1]-1; - break; - case Y_MINUS: /* U = East(Z-), V = South(X+) */ - case Y_PLUS: - u = native_scale-xyz[2]-1; v = xyz[0]; - break; - } - /* Read color from texture */ - rslt.setARGB(texture[v*native_scale + u]); - return; - } - - /* See if not basic block texture */ - int textop = textid / 1000; - textid = textid % 1000; - - /* If clear-inside op, get out early */ - if(textop == COLORMOD_CLEARINSIDE) { - /* Check if previous block is same block type as we are: surface is transparent if it is */ - if(blkid == lastblocktype) { - rslt.setTransparent(); - return; - } - /* If water block, to watercolor tone op */ - if((blkid == 8) || (blkid == 9)) { - textop = water_toned_op; - } - } - - int[] texture = terrain_argb[textid]; - int[] xyz = ps.getSubblockCoord(); - /* Get texture coordinates (U=horizontal(left=0),V=vertical(top=0)) */ - int u = 0, v = 0, tmp; - - switch(laststep) { - case X_MINUS: /* South face: U = East (Z-), V = Down (Y-) */ - u = native_scale-xyz[2]-1; v = native_scale-xyz[1]-1; - break; - case X_PLUS: /* North face: U = West (Z+), V = Down (Y-) */ - u = xyz[2]; v = native_scale-xyz[1]-1; - break; - case Z_MINUS: /* West face: U = South (X+), V = Down (Y-) */ - u = xyz[0]; v = native_scale-xyz[1]-1; - break; - case Z_PLUS: /* East face: U = North (X-), V = Down (Y-) */ - u = native_scale-xyz[0]-1; v = native_scale-xyz[1]-1; - break; - case Y_MINUS: /* U = East(Z-), V = South(X+) */ - case Y_PLUS: - u = native_scale-xyz[2]-1; v = xyz[0]; - break; - } - /* Handle U-V transorms before fetching color */ - switch(textop) { - case COLORMOD_NONE: - case COLORMOD_GRASSTONED: - case COLORMOD_FOLIAGETONED: - case COLORMOD_WATERTONED: - break; - case COLORMOD_ROT90: - tmp = u; u = native_scale - v - 1; v = tmp; - break; - case COLORMOD_ROT180: - u = native_scale - u - 1; v = native_scale - v - 1; - break; - case COLORMOD_ROT270: - tmp = u; u = v; v = native_scale - tmp - 1; - break; - case COLORMOD_FLIPHORIZ: - u = native_scale - u - 1; - break; - case COLORMOD_SHIFTDOWNHALF: - if(v < native_scale/2) { - rslt.setTransparent(); - return; - } - v -= native_scale/2; - break; - case COLORMOD_SHIFTDOWNHALFANDFLIPHORIZ: - if(v < native_scale/2) { - rslt.setTransparent(); - return; - } - v -= native_scale/2; - u = native_scale - u - 1; - break; - case COLORMOD_INCLINEDTORCH: - if(v >= (3*native_scale/4)) { - rslt.setTransparent(); - return; - } - v += native_scale/4; - if(u < native_scale/2) u = native_scale/2-1; - if(u > native_scale/2) u = native_scale/2; - break; - case COLORMOD_GRASSSIDE: - boolean do_grass_side = false; - boolean do_snow_side = false; - if(ss.do_better_grass) { - mapiter.unstepPosition(laststep); - if(mapiter.getBlockTypeID() == BLOCKID_SNOW) - do_snow_side = true; - if(mapiter.getBlockTypeIDAt(BlockStep.Y_MINUS) == BLOCKID_GRASS) - do_grass_side = true; - mapiter.stepPosition(laststep); - } - - /* Check if snow above block */ - if(mapiter.getBlockTypeIDAt(BlockStep.Y_PLUS) == BLOCKID_SNOW) { - if(do_snow_side) { - texture = terrain_argb[BLOCKINDEX_SNOW]; /* Snow full side block */ - textid = BLOCKINDEX_SNOW; - } - else { - texture = terrain_argb[BLOCKINDEX_SNOWSIDE]; /* Snow block */ - textid = BLOCKINDEX_SNOWSIDE; - } - textop = 0; - } - else { /* Else, check the grass color overlay */ - if(do_grass_side) { - texture = terrain_argb[BLOCKINDEX_GRASS]; /* Grass block */ - textid = BLOCKINDEX_GRASS; - textop = COLORMOD_GRASSTONED; /* Force grass toning */ - } - else { - int ovclr = terrain_argb[BLOCKINDEX_GRASSMASK][v*native_scale+u]; - if((ovclr & 0xFF000000) != 0) { /* Hit? */ - texture = terrain_argb[BLOCKINDEX_GRASSMASK]; /* Use it */ - textop = COLORMOD_GRASSTONED; /* Force grass toning */ - } - } - } - break; - case COLORMOD_CLEARINSIDE: - break; - case COLORMOD_LILYTONED: - /* Rotate texture based on lily orientation function (from renderBlockLilyPad in RenderBlocks.jara in MCP) */ - long l1 = (long)(mapiter.getX() * 0x2fc20f) ^ (long)mapiter.getZ() * 0x6ebfff5L ^ (long)mapiter.getY(); - l1 = l1 * l1 * 0x285b825L + l1 * 11L; - int orientation = (int)(l1 >> 16 & 3L); - switch(orientation) { - case 0: - tmp = u; u = native_scale - v - 1; v = tmp; - break; - case 1: - u = native_scale - u - 1; v = native_scale - v - 1; - break; - case 2: - tmp = u; u = v; v = native_scale - tmp - 1; - break; - case 3: - break; - } - break; - case COLORMOD_OLD_WATERSHADED: - break; - } - /* Read color from texture */ - rslt.setARGB(texture[v*native_scale + u]); - - LoadedImage li = null; - int clrmult = -1; - /* Switch based on texture modifier */ - switch(textop) { - case COLORMOD_GRASSTONED: - li = imgs[IMG_GRASSCOLOR]; - break; - case COLORMOD_FOLIAGETONED: - li = imgs[IMG_FOLIAGECOLOR]; - break; - case COLORMOD_WATERTONED: - if(ss.do_swamp_shading && (mapiter.getBiome() == BiomeMap.SWAMPLAND)) - clrmult = 0xFFE0FF70; - break; - case COLORMOD_BIRCHTONED: - clrmult = 0xFF80a755; /* From ColorizerFoliage.java in MCP */ - break; - case COLORMOD_PINETONED: - clrmult = 0xFF619961; /* From ColorizerFoliage.java in MCP */ - break; - case COLORMOD_LILYTONED: - clrmult = 0xFF208030; /* from BlockLilyPad.java in MCP */ - break; - case COLORMOD_OLD_WATERSHADED: /* Legacy water shading (wrong, but folks used it */ - if(ss.do_water_shading) - li = imgs[IMG_WATERCOLOR]; - break; - } - if(li != null) { - if((li.argb == null) || (!ss.do_biome_shading)) { - clrmult = li.trivial_color; - } - else { - clrmult = biomeLookup(li.argb, li.width, mapiter.getRawBiomeRainfall(), mapiter.getRawBiomeTemperature()); - } - if(ss.do_swamp_shading && (mapiter.getBiome() == BiomeMap.SWAMPLAND)) - clrmult = (clrmult & 0xFF000000) | (((clrmult & 0x00FEFEFE) + 0x4E0E4E) / 2); - } - if((clrmult != -1) && (clrmult != 0)) { - rslt.blendColor(clrmult); - } - } - - private static final int biomeLookup(int[] argb, int width, double rainfall, double temp) { - int w = width-1; - int t = (int)((1.0-temp)*w); - int h = (int)((1.0 - (temp*rainfall))*w); - if(h > w) h = w; - if(t > w) t = w; - return argb[width*h + t]; - } - - private static final void makeAlphaPure(int[] argb) { - for(int i = 0; i < argb.length; i++) { - if((argb[i] & 0xFF000000) != 0) - argb[i] |= 0xFF000000; - } - } - - /** - * Add new dynmaic file definition, or return existing - * - * @param fname - * @param xdim - * @param ydim - * @return dynamic file index - */ - private static int findOrAddDynamicTileFile(String fname, int xdim, int ydim) { - DynamicTileFile f; - /* Find existing, if already there */ - for(int i = 0; i < addonfiles.size(); i++) { - f = addonfiles.get(i); - if(f.filename.equals(fname)) - return i; - } - /* Add new tile file entry */ - f = new DynamicTileFile(); - f.filename = fname; - f.tilecnt_x = xdim; - f.tilecnt_y = ydim; - f.tile_to_dyntile = new int[xdim*ydim]; - addonfiles.add(f); - - return addonfiles.size()-1; - } - /** - * Add or find dynamic tile index of given dynamic tile - * @param dynfile_idx - index of file - * @param tile_id - ID of tile within file - * @return global tile ID - */ - private static int findOrAddDynamicTile(int dynfile_idx, int tile_id) { - DynamicTileFile f = addonfiles.get(dynfile_idx); - if(f == null) { - Log.warning("Invalid add-on file index: " + dynfile_idx); - return 0; - } - if(f.tile_to_dyntile[tile_id] == 0) { /* Not assigned yet? */ - f.tile_to_dyntile[tile_id] = next_dynamic_tile; - next_dynamic_tile++; /* Allocate next ID */ - } - return f.tile_to_dyntile[tile_id]; - } - - /* Based on TextureWaterFX.java in MCP */ - private void generateWater() { - imgs[IMG_WATER] = new LoadedImage(); - imgs[IMG_WATER].width = 16; - imgs[IMG_WATER].height = 16; - imgs[IMG_WATER].argb = new int[256]; - - float[] g = new float[256]; - float[] h = new float[256]; - float[] n = new float[256]; - float[] m = new float[256]; - Color c = new Color(); - Random r = new Random(1234); /* Need to be deterministic */ - int kk; - - for(kk = 0; kk < 200; kk++) { - for(int i = 0; i < 16; i++) - { - for(int k = 0; k < 16; k++) - { - float f = 0.0F; - for(int j1 = i - 1; j1 <= i + 1; j1++) - { - int k1 = j1 & 0xf; - int i2 = k & 0xf; - f += g[k1 + i2 * 16]; - } - - h[i + k * 16] = f / 3.3F + n[i + k * 16] * 0.8F; - } - - } - - for(int j = 0; j < 16; j++) - { - for(int l = 0; l < 16; l++) - { - n[j + l * 16] += m[j + l * 16] * 0.05F; - if(n[j + l * 16] < 0.0F) - { - n[j + l * 16] = 0.0F; - } - m[j + l * 16] -= 0.1F; - if(r.nextDouble() < 0.050000000000000003D) - { - m[j + l * 16] = 0.5F; - } - } - - } - - float af[] = h; - h = g; - g = af; - } - for(int i1 = 0; i1 < 256; i1++) - { - float f1 = g[i1]; - if(f1 > 1.0F) - { - f1 = 1.0F; - } - if(f1 < 0.0F) - { - f1 = 0.0F; - } - float f2 = f1 * f1; - int l1 = (int)(32F + f2 * 32F); - int j2 = (int)(50F + f2 * 64F); - int k2 = 255; - int l2 = (int)(146F + f2 * 50F); - - c.setRGBA(l1, j2, k2, l2); - imgs[IMG_WATER].argb[i1] = c.getARGB(); - } - } - - /* Based on TextureWaterFlowingFX.java in MCP */ - private void generateWaterFlowing() { - - imgs[IMG_WATERMOVING] = new LoadedImage(); - imgs[IMG_WATERMOVING].width = 16; - imgs[IMG_WATERMOVING].height = 16; - imgs[IMG_WATERMOVING].argb = new int[256]; - - float[] g = new float[256]; - float[] h = new float[256]; - float[] n = new float[256]; - float[] m = new float[256]; - Color c = new Color(); - Random r = new Random(1234); /* Need to be deterministic */ - - int kk; - for(kk = 0; kk < 200; kk++) { - for(int i = 0; i < 16; i++) - { - for(int k = 0; k < 16; k++) - { - float f = 0.0F; - for(int j1 = k - 2; j1 <= k; j1++) - { - int k1 = i & 0xf; - int i2 = j1 & 0xf; - f += g[k1 + i2 * 16]; - } - - h[i + k * 16] = f / 3.2F + n[i + k * 16] * 0.8F; - } - - } - - for(int j = 0; j < 16; j++) - { - for(int l = 0; l < 16; l++) - { - n[j + l * 16] += m[j + l * 16] * 0.05F; - if(n[j + l * 16] < 0.0F) - { - n[j + l * 16] = 0.0F; - } - m[j + l * 16] -= 0.3F; - if(r.nextDouble() < 0.20000000000000001D) - { - m[j + l * 16] = 0.5F; - } - } - - } - - float af[] = h; - h = g; - g = af; - } - for(int i1 = 0; i1 < 256; i1++) - { - float f1 = g[i1 - kk * 16 & 0xff]; - if(f1 > 1.0F) - { - f1 = 1.0F; - } - if(f1 < 0.0F) - { - f1 = 0.0F; - } - float f2 = f1 * f1; - int l1 = (int)(32F + f2 * 32F); - int j2 = (int)(50F + f2 * 64F); - int k2 = 255; - int l2 = (int)(146F + f2 * 50F); - - c.setRGBA(l1, j2, k2, l2); - imgs[IMG_WATERMOVING].argb[i1] = c.getARGB(); - } - } - - /* Based on TextureLavaFX.java in MCP */ - private void generateLava() { - imgs[IMG_LAVA] = new LoadedImage(); - imgs[IMG_LAVA].width = 16; - imgs[IMG_LAVA].height = 16; - imgs[IMG_LAVA].argb = new int[256]; - - float[] g = new float[256]; - float[] h = new float[256]; - float[] n = new float[256]; - float[] m = new float[256]; - Color c = new Color(); - Random r = new Random(1234); /* Need to be deterministic */ - - int kk; - for(kk = 0; kk < 200; kk++) { - for(int i = 0; i < 16; i++) - { - for(int j = 0; j < 16; j++) - { - float f = 0.0F; - int l = (int)(Math.sin(((float)j * 3.141593F * 2.0F) / 16F) * 1.2F); - int i1 = (int)(Math.sin(((float)i * 3.141593F * 2.0F) / 16F) * 1.2F); - for(int k1 = i - 1; k1 <= i + 1; k1++) - { - for(int i2 = j - 1; i2 <= j + 1; i2++) - { - int k2 = k1 + l & 0xf; - int i3 = i2 + i1 & 0xf; - f += g[k2 + i3 * 16]; - } - - } - - h[i + j * 16] = f / 10F + ((n[(i + 0 & 0xf) + (j + 0 & 0xf) * 16] + n[(i + 1 & 0xf) + (j + 0 & 0xf) * 16] + n[(i + 1 & 0xf) + (j + 1 & 0xf) * 16] + n[(i + 0 & 0xf) + (j + 1 & 0xf) * 16]) / 4F) * 0.8F; - n[i + j * 16] += m[i + j * 16] * 0.01F; - if(n[i + j * 16] < 0.0F) - { - n[i + j * 16] = 0.0F; - } - m[i + j * 16] -= 0.06F; - if(r.nextDouble() < 0.005D) - { - m[i + j * 16] = 1.5F; - } - } - - } - - float af[] = h; - h = g; - g = af; - } - for(int k = 0; k < 256; k++) - { - float f1 = g[k] * 2.0F; - if(f1 > 1.0F) - { - f1 = 1.0F; - } - if(f1 < 0.0F) - { - f1 = 0.0F; - } - float f2 = f1; - int j1 = (int)(f2 * 100F + 155F); - int l1 = (int)(f2 * f2 * 255F); - int j2 = (int)(f2 * f2 * f2 * f2 * 128F); - - c.setRGBA(j1, l1, j2, 255); - imgs[IMG_LAVA].argb[k] = c.getARGB(); - } - } - - /* Based on TextureLavaFlowFX.java in MCP */ - private void generateLavaFlow() { - imgs[IMG_LAVAMOVING] = new LoadedImage(); - imgs[IMG_LAVAMOVING].width = 16; - imgs[IMG_LAVAMOVING].height = 16; - imgs[IMG_LAVAMOVING].argb = new int[256]; - - float[] g = new float[256]; - float[] h = new float[256]; - float[] n = new float[256]; - float[] m = new float[256]; - Color c = new Color(); - Random r = new Random(1234); /* Need to be deterministic */ - - int kk; - for(kk = 0; kk < 200; kk++) { - for(int i = 0; i < 16; i++) - { - for(int j = 0; j < 16; j++) - { - float f = 0.0F; - int l = (int)(Math.sin(((float)j * 3.141593F * 2.0F) / 16F) * 1.2F); - int i1 = (int)(Math.sin(((float)i * 3.141593F * 2.0F) / 16F) * 1.2F); - for(int k1 = i - 1; k1 <= i + 1; k1++) - { - for(int i2 = j - 1; i2 <= j + 1; i2++) - { - int k2 = k1 + l & 0xf; - int i3 = i2 + i1 & 0xf; - f += g[k2 + i3 * 16]; - } - - } - - h[i + j * 16] = f / 10F + ((n[(i + 0 & 0xf) + (j + 0 & 0xf) * 16] + n[(i + 1 & 0xf) + (j + 0 & 0xf) * 16] + n[(i + 1 & 0xf) + (j + 1 & 0xf) * 16] + n[(i + 0 & 0xf) + (j + 1 & 0xf) * 16]) / 4F) * 0.8F; - n[i + j * 16] += m[i + j * 16] * 0.01F; - if(n[i + j * 16] < 0.0F) - { - n[i + j * 16] = 0.0F; - } - m[i + j * 16] -= 0.06F; - if(r.nextDouble() < 0.005D) - { - m[i + j * 16] = 1.5F; - } - } - - } - - float af[] = h; - h = g; - g = af; - } - for(int k = 0; k < 256; k++) - { - float f1 = g[k - (kk / 3) * 16 & 0xff] * 2.0F; - if(f1 > 1.0F) - { - f1 = 1.0F; - } - if(f1 < 0.0F) - { - f1 = 0.0F; - } - float f2 = f1; - int j1 = (int)(f2 * 100F + 155F); - int l1 = (int)(f2 * f2 * 255F); - int j2 = (int)(f2 * f2 * f2 * f2 * 128F); - - c.setRGBA(j1, l1, j2, 255); - imgs[IMG_LAVAMOVING].argb[k] = c.getARGB(); - } - - } - /* Adapted from TextureFlamesFX.java in MCP */ - private void generateFire() { - imgs[IMG_FIRE] = new LoadedImage(); - imgs[IMG_FIRE].width = 16; - imgs[IMG_FIRE].height = 16; - imgs[IMG_FIRE].argb = new int[256]; - - float[] g = new float[320]; - float[] h = new float[320]; - Random r = new Random(666); - Color cc = new Color(); - - for(int kk = 0; kk < 200; kk++) { - for(int i = 0; i < 16; i++) - { - for(int j = 0; j < 20; j++) - { - int l = 18; - float f1 = g[i + ((j + 1) % 20) * 16] * (float)l; - for(int i1 = i - 1; i1 <= i + 1; i1++) - { - for(int k1 = j; k1 <= j + 1; k1++) - { - int i2 = i1; - int k2 = k1; - if(i2 >= 0 && k2 >= 0 && i2 < 16 && k2 < 20) - { - f1 += g[i2 + k2 * 16]; - } - l++; - } - - } - - h[i + j * 16] = f1 / ((float)l * 1.06F); - if(j >= 19) - { - h[i + j * 16] = (float)(r.nextDouble() * r.nextDouble() * r.nextDouble() * 4D + r.nextDouble() * 0.10000000149011612D + 0.20000000298023224D); - } - } - } - - float af[] = h; - h = g; - g = af; - } - for(int k = 0; k < 256; k++) - { - float f = g[k] * 1.8F; - if(f > 1.0F) - { - f = 1.0F; - } - if(f < 0.0F) - { - f = 0.0F; - } - float f2 = f; - int j1 = (int)(f2 * 155F + 100F); - int l1 = (int)(f2 * f2 * 255F); - int j2 = (int)(f2 * f2 * f2 * f2 * f2 * f2 * f2 * f2 * f2 * f2 * 255F); - int c = 255; - if(f2 < 0.5F) - { - c = 0; - } - f2 = (f2 - 0.5F) * 2.0F; - cc.setRGBA(j1, l1, j2, c); - imgs[IMG_FIRE].argb[k] = cc.getARGB(); - - } - -} - -} diff --git a/src/main/java/org/dynmap/hdmap/TexturePackHDShader.java b/src/main/java/org/dynmap/hdmap/TexturePackHDShader.java deleted file mode 100644 index 827e6a63..00000000 --- a/src/main/java/org/dynmap/hdmap/TexturePackHDShader.java +++ /dev/null @@ -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); - } -} diff --git a/src/main/java/org/dynmap/hdmap/TopoHDShader.java b/src/main/java/org/dynmap/hdmap/TopoHDShader.java deleted file mode 100644 index 0fd6adb2..00000000 --- a/src/main/java/org/dynmap/hdmap/TopoHDShader.java +++ /dev/null @@ -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); - } -} diff --git a/src/main/java/org/dynmap/kzedmap/CaveTileRenderer.java b/src/main/java/org/dynmap/kzedmap/CaveTileRenderer.java deleted file mode 100644 index 1821329b..00000000 --- a/src/main/java/org/dynmap/kzedmap/CaveTileRenderer.java +++ /dev/null @@ -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; - } - } - } -} diff --git a/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java b/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java deleted file mode 100644 index 36875e29..00000000 --- a/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java +++ /dev/null @@ -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 highlightBlocks = new HashSet(); - 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); - } -} diff --git a/src/main/java/org/dynmap/kzedmap/HighlightTileRenderer.java b/src/main/java/org/dynmap/kzedmap/HighlightTileRenderer.java deleted file mode 100644 index 8d66340a..00000000 --- a/src/main/java/org/dynmap/kzedmap/HighlightTileRenderer.java +++ /dev/null @@ -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 highlightBlocks = new HashSet(); - - public HighlightTileRenderer(DynmapCore core, ConfigurationNode configuration) { - super(core, configuration); - List highlight = configuration.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. - ); - } - } - } - } - } - } -} diff --git a/src/main/java/org/dynmap/kzedmap/KzedMap.java b/src/main/java/org/dynmap/kzedmap/KzedMap.java deleted file mode 100644 index bc7e6228..00000000 --- a/src/main/java/org/dynmap/kzedmap/KzedMap.java +++ /dev/null @@ -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 renderers = configuration.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 tiles = new ArrayList(); - - 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 tiles = new ArrayList(); - /* 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> 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 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 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 chunks = new ArrayList(); - - 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(); - } - } - - 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 baseZoomFileInfo() { - ArrayList s = new ArrayList(); - 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 getMapsSharingRender(DynmapWorld w) { - return Collections.singletonList((MapType)this); - } - - /* Get names of maps rendered concurrently with this map type in this world */ - public List getMapNamesSharingRender(DynmapWorld w) { - ArrayList lst = new ArrayList(); - 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); - } - } -} diff --git a/src/main/java/org/dynmap/kzedmap/KzedMapTile.java b/src/main/java/org/dynmap/kzedmap/KzedMapTile.java deleted file mode 100644 index 25329d6e..00000000 --- a/src/main/java/org/dynmap/kzedmap/KzedMapTile.java +++ /dev/null @@ -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 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; } -} diff --git a/src/main/java/org/dynmap/kzedmap/KzedZoomedMapTile.java b/src/main/java/org/dynmap/kzedmap/KzedZoomedMapTile.java deleted file mode 100644 index 413405f8..00000000 --- a/src/main/java/org/dynmap/kzedmap/KzedZoomedMapTile.java +++ /dev/null @@ -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 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; } - -} diff --git a/src/main/java/org/dynmap/kzedmap/MapTileRenderer.java b/src/main/java/org/dynmap/kzedmap/MapTileRenderer.java deleted file mode 100644 index 55722c4d..00000000 --- a/src/main/java/org/dynmap/kzedmap/MapTileRenderer.java +++ /dev/null @@ -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(); -} diff --git a/src/main/java/org/dynmap/markers/impl/AreaMarkerImpl.java b/src/main/java/org/dynmap/markers/impl/AreaMarkerImpl.java deleted file mode 100644 index 95b1189a..00000000 --- a/src/main/java/org/dynmap/markers/impl/AreaMarkerImpl.java +++ /dev/null @@ -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 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(); - 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(); - 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 xx = node.getList("x"); - List 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 getPersistentData() { - if(!ispersistent) /* Nothing if not persistent */ - return null; - HashMap node = new HashMap(); - node.put("label", label); - node.put("markup", markup); - List xx = new ArrayList(); - List zz = new ArrayList(); - 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; - } -} diff --git a/src/main/java/org/dynmap/markers/impl/MarkerAPIImpl.java b/src/main/java/org/dynmap/markers/impl/MarkerAPIImpl.java deleted file mode 100644 index b6f641b9..00000000 --- a/src/main/java/org/dynmap/markers/impl/MarkerAPIImpl.java +++ /dev/null @@ -1,1621 +0,0 @@ -package org.dynmap.markers.impl; - -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; - -import javax.imageio.ImageIO; - -import org.dynmap.ConfigurationNode; -import org.dynmap.DynmapCore; -import org.dynmap.DynmapLocation; -import org.dynmap.DynmapWorld; -import org.dynmap.Event; -import org.dynmap.Log; -import org.dynmap.MapManager; -import org.dynmap.Client.ComponentMessage; -import org.dynmap.common.DynmapCommandSender; -import org.dynmap.common.DynmapPlayer; -import org.dynmap.markers.AreaMarker; -import org.dynmap.markers.Marker; -import org.dynmap.markers.MarkerAPI; -import org.dynmap.markers.MarkerIcon; -import org.dynmap.markers.MarkerIcon.MarkerSize; -import org.dynmap.markers.MarkerSet; -import org.dynmap.web.Json; - -/** - * Implementation class for MarkerAPI - should not be called directly - */ -public class MarkerAPIImpl implements MarkerAPI, Event.Listener { - private File markerpersist; - private File markerpersist_old; - private File markerdir; /* Local store for markers (internal) */ - private File markertiledir; /* Marker directory for web server (under tiles) */ - private HashMap markericons = new HashMap(); - private HashMap markersets = new HashMap(); - private HashMap> pointaccum = new HashMap>(); - private DynmapCore core; - static MarkerAPIImpl api; - - /* Built-in icons */ - private static final String[] builtin_icons = { - "anchor", "bank", "basket", "bed", "beer", "bighouse", "blueflag", "bomb", "bookshelf", "bricks", "bronzemedal", "bronzestar", - "building", "cake", "camera", "cart", "caution", "chest", "church", "coins", "comment", "compass", "construction", - "cross", "cup", "cutlery", "default", "diamond", "dog", "door", "down", "drink", "exclamation", "factory", - "fire", "flower", "gear", "goldmedal", "goldstar", "greenflag", "hammer", "heart", "house", "key", "king", - "left", "lightbulb", "lighthouse", "lock", "minecart", "orangeflag", "pin", "pinkflag", "pirateflag", "pointdown", "pointleft", - "pointright", "pointup", "portal", "purpleflag", "queen", "redflag", "right", "ruby", "scales", "skull", "shield", "sign", - "silvermedal", "silverstar", "star", "sun", "temple", "theater", "tornado", "tower", "tree", "truck", "up", - "walk", "warning", "world", "wrench", "yellowflag", "offlineuser" - }; - - /* Component messages for client updates */ - public static class MarkerComponentMessage extends ComponentMessage { - public String ctype = "markers"; - } - - public static class MarkerUpdated extends MarkerComponentMessage { - public String msg; - public double x, y, z; - public String id; - public String label; - public String icon; - public String set; - public boolean markup; - public String desc; - public String dim; - - public MarkerUpdated(Marker m, boolean deleted) { - this.id = m.getMarkerID(); - this.label = m.getLabel(); - this.x = m.getX(); - this.y = m.getY(); - this.z = m.getZ(); - this.set = m.getMarkerSet().getMarkerSetID(); - this.icon = m.getMarkerIcon().getMarkerIconID(); - this.markup = m.isLabelMarkup(); - this.desc = m.getDescription(); - this.dim = m.getMarkerIcon().getMarkerIconSize().getSize(); - if(deleted) - msg = "markerdeleted"; - else - msg = "markerupdated"; - } - @Override - public boolean equals(Object o) { - if(o instanceof MarkerUpdated) { - MarkerUpdated m = (MarkerUpdated)o; - return m.id.equals(id) && m.set.equals(set); - } - return false; - } - @Override - public int hashCode() { - return id.hashCode() ^ set.hashCode(); - } - - } - - public static class AreaMarkerUpdated extends MarkerComponentMessage { - public String msg; - public double ytop, ybottom; - public double[] x; - public double[] z; - public int weight; - public double opacity; - public String color; - public double fillopacity; - public String fillcolor; - public String id; - public String label; - public String set; - public String desc; - - public AreaMarkerUpdated(AreaMarker m, boolean deleted) { - this.id = m.getMarkerID(); - this.label = m.getLabel(); - this.ytop = m.getTopY(); - this.ybottom = m.getBottomY(); - int cnt = m.getCornerCount(); - x = new double[cnt]; - z = new double[cnt]; - for(int i = 0; i < cnt; i++) { - x[i] = m.getCornerX(i); - z[i] = m.getCornerZ(i); - } - color = String.format("#%06X", m.getLineColor()); - weight = m.getLineWeight(); - opacity = m.getLineOpacity(); - fillcolor = String.format("#%06X", m.getFillColor()); - fillopacity = m.getFillOpacity(); - desc = m.getDescription(); - - this.set = m.getMarkerSet().getMarkerSetID(); - if(deleted) - msg = "areadeleted"; - else - msg = "areaupdated"; - } - @Override - public boolean equals(Object o) { - if(o instanceof AreaMarkerUpdated) { - AreaMarkerUpdated m = (AreaMarkerUpdated)o; - return m.id.equals(id) && m.set.equals(set); - } - return false; - } - @Override - public int hashCode() { - return id.hashCode() ^ set.hashCode(); - } - } - - public static class MarkerSetUpdated extends MarkerComponentMessage { - public String msg; - public String id; - public String label; - public int layerprio; - public int minzoom; - public MarkerSetUpdated(MarkerSet markerset, boolean deleted) { - this.id = markerset.getMarkerSetID(); - this.label = markerset.getMarkerSetLabel(); - this.layerprio = markerset.getLayerPriority(); - this.minzoom = markerset.getMinZoom(); - if(deleted) - msg = "setdeleted"; - else - msg = "setupdated"; - } - @Override - public boolean equals(Object o) { - if(o instanceof MarkerSetUpdated) { - MarkerSetUpdated m = (MarkerSetUpdated)o; - return m.id.equals(id); - } - return false; - } - @Override - public int hashCode() { - return id.hashCode(); - } - } - - private boolean stop = false; - private Set dirty_worlds = new HashSet(); - private boolean dirty_markers = false; - - private class DoFileWrites implements Runnable { - public void run() { - if(stop) - return; - /* Write markers first - drives JSON updates too */ - if(dirty_markers) { - doSaveMarkers(); - dirty_markers = false; - } - /* Process any dirty worlds */ - if(!dirty_worlds.isEmpty()) { - for(String world : dirty_worlds) { - writeMarkersFile(world); - } - dirty_worlds.clear(); - } - core.getServer().scheduleServerTask(this, 20); - } - } - - /** - * Singleton initializer - */ - public static MarkerAPIImpl initializeMarkerAPI(DynmapCore core) { - if(api != null) { - api.cleanup(core); - } - api = new MarkerAPIImpl(); - api.core = core; - /* Initialize persistence file name */ - api.markerpersist = new File(core.getDataFolder(), "markers.yml"); - api.markerpersist_old = new File(core.getDataFolder(), "markers.yml.old"); - /* Fill in default icons and sets, if needed */ - for(int i = 0; i < builtin_icons.length; i++) { - String id = builtin_icons[i]; - api.createBuiltinMarkerIcon(id, id); - } - /* Load persistence */ - api.loadMarkers(); - /* Initialize default marker set, if needed */ - MarkerSet set = api.getMarkerSet(MarkerSet.DEFAULT); - if(set == null) { - set = api.createMarkerSet(MarkerSet.DEFAULT, "Markers", null, true); - } - - /* Build paths for markers */ - api.markerdir = new File(core.getDataFolder(), "markers"); - if(api.markerdir.isDirectory() == false) { - if(api.markerdir.mkdirs() == false) { /* Create directory if needed */ - Log.severe("Error creating markers directory - " + api.markerdir.getPath()); - } - } - api.markertiledir = new File(core.getTilesFolder(), "_markers_"); - if(api.markertiledir.isDirectory() == false) { - if(api.markertiledir.mkdirs() == false) { /* Create directory if needed */ - Log.severe("Error creating markers directory - " + api.markertiledir.getPath()); - } - } - /* Now publish marker files to the tiles directory */ - for(MarkerIcon ico : api.getMarkerIcons()) { - api.publishMarkerIcon(ico); - } - /* Freshen files */ - api.freshenMarkerFiles(); - /* Add listener so we update marker files for other worlds as they become active */ - core.events.addListener("worldactivated", api); - - api.scheduleWriteJob(); /* Start write job */ - - return api; - } - - private void scheduleWriteJob() { - core.getServer().scheduleServerTask(new DoFileWrites(), 20); - } - - /** - * Cleanup - */ - public void cleanup(DynmapCore plugin) { - plugin.events.removeListener("worldactivated", api); - - stop = true; - if(dirty_markers) { - doSaveMarkers(); - dirty_markers = false; - } - - for(MarkerIconImpl icn : markericons.values()) - icn.cleanup(); - markericons.clear(); - for(MarkerSetImpl set : markersets.values()) - set.cleanup(); - markersets.clear(); - } - - private MarkerIcon createBuiltinMarkerIcon(String id, String label) { - if(markericons.containsKey(id)) return null; /* Exists? */ - MarkerIconImpl ico = new MarkerIconImpl(id, label, true); - markericons.put(id, ico); /* Add to set */ - return ico; - } - - void publishMarkerIcon(MarkerIcon ico) { - byte[] buf = new byte[512]; - InputStream in = null; - File infile = new File(markerdir, ico.getMarkerIconID() + ".png"); /* Get source file name */ - File outfile = new File(markertiledir, ico.getMarkerIconID() + ".png"); /* Destination */ - BufferedImage im = null; - OutputStream out = null; - - try { - out = new FileOutputStream(outfile); - } catch (IOException iox) { - Log.severe("Cannot write marker to tilespath - " + outfile.getPath()); - return; - } - if(ico.isBuiltIn()) { - in = getClass().getResourceAsStream("/markers/" + ico.getMarkerIconID() + ".png"); - } - else if(infile.canRead()) { /* If it exists and is readable */ - try { - im = ImageIO.read(infile); - } catch (IOException e) { - } catch (IndexOutOfBoundsException e) { - } - if(im != null) { - MarkerIconImpl icon = (MarkerIconImpl)ico; - int w = im.getWidth(); /* Get width */ - if(w <= 8) { /* Small size? */ - icon.setMarkerIconSize(MarkerSize.MARKER_8x8); - } - else if(w > 16) { - icon.setMarkerIconSize(MarkerSize.MARKER_32x32); - } - else { - icon.setMarkerIconSize(MarkerSize.MARKER_16x16); - } - im.flush(); - } - - try { - in = new FileInputStream(infile); - } catch (IOException iox) { - Log.severe("Error opening marker " + infile.getPath() + " - " + iox); - } - } - if(in == null) { /* Not found, use default marker */ - in = getClass().getResourceAsStream("/markers/marker.png"); - if(in == null) - return; - } - /* Copy to destination */ - try { - int len; - while((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - } catch (IOException iox) { - Log.severe("Error writing marker to tilespath - " + outfile.getPath()); - } finally { - if(in != null) try { in.close(); } catch (IOException x){} - if(out != null) try { out.close(); } catch (IOException x){} - } - } - - @Override - public Set getMarkerSets() { - return new HashSet(markersets.values()); - } - - @Override - public MarkerSet getMarkerSet(String id) { - return markersets.get(id); - } - - @Override - public MarkerSet createMarkerSet(String id, String lbl, Set iconlimit, boolean persistent) { - if(markersets.containsKey(id)) return null; /* Exists? */ - - MarkerSetImpl set = new MarkerSetImpl(id, lbl, iconlimit, persistent); - - markersets.put(id, set); /* Add to list */ - if(persistent) { - saveMarkers(); - } - markerSetUpdated(set, MarkerUpdate.CREATED); /* Notify update */ - - return set; - } - - @Override - public Set getMarkerIcons() { - return new HashSet(markericons.values()); - } - - @Override - public MarkerIcon getMarkerIcon(String id) { - return markericons.get(id); - } - - boolean loadMarkerIconStream(String id, InputStream in) { - /* Copy icon resource into marker directory */ - File f = new File(markerdir, id + ".png"); - FileOutputStream fos = null; - try { - byte[] buf = new byte[512]; - int len; - fos = new FileOutputStream(f); - while((len = in.read(buf)) > 0) { - fos.write(buf, 0, len); - } - } catch (IOException iox) { - Log.severe("Error copying marker - " + f.getPath()); - return false; - } finally { - if(fos != null) try { fos.close(); } catch (IOException x) {} - } - return true; - } - @Override - public MarkerIcon createMarkerIcon(String id, String label, InputStream marker_png) { - if(markericons.containsKey(id)) return null; /* Exists? */ - MarkerIconImpl ico = new MarkerIconImpl(id, label, false); - /* Copy icon resource into marker directory */ - if(!loadMarkerIconStream(id, marker_png)) - return null; - markericons.put(id, ico); /* Add to set */ - - /* Publish the marker */ - publishMarkerIcon(ico); - - saveMarkers(); /* Save results */ - - return ico; - } - - static MarkerIconImpl getMarkerIconImpl(String id) { - if(api != null) { - return api.markericons.get(id); - } - return null; - } - - /** - * Save persistence for markers - */ - static void saveMarkers() { - if(api != null) { - api.dirty_markers = true; - } - } - private void doSaveMarkers() { - if(api != null) { - ConfigurationNode conf = new ConfigurationNode(api.markerpersist); /* Make configuration object */ - /* First, save icon definitions */ - HashMap icons = new HashMap(); - for(String id : api.markericons.keySet()) { - MarkerIconImpl ico = api.markericons.get(id); - Map dat = ico.getPersistentData(); - if(dat != null) { - icons.put(id, dat); - } - } - conf.put("icons", icons); - /* Then, save persistent sets */ - HashMap sets = new HashMap(); - for(String id : api.markersets.keySet()) { - MarkerSetImpl set = api.markersets.get(id); - if(set.isMarkerSetPersistent()) { - Map dat = set.getPersistentData(); - if(dat != null) { - sets.put(id, dat); - } - } - } - conf.put("sets", sets); - /* And shift old file file out */ - if(api.markerpersist_old.exists()) api.markerpersist_old.delete(); - if(api.markerpersist.exists()) api.markerpersist.renameTo(api.markerpersist_old); - /* And write it out */ - if(!conf.save()) - Log.severe("Error writing markers - " + api.markerpersist.getPath()); - /* Refresh JSON files */ - api.freshenMarkerFiles(); - } - } - - private void freshenMarkerFiles() { - if(MapManager.mapman != null) { - for(DynmapWorld w : MapManager.mapman.worlds) { - dirty_worlds.add(w.getName()); - } - } - } - - /** - * Load persistence - */ - private boolean loadMarkers() { - ConfigurationNode conf = new ConfigurationNode(api.markerpersist); /* Make configuration object */ - conf.load(); /* Load persistence */ - /* Get icons */ - - ConfigurationNode icons = conf.getNode("icons"); - if(icons == null) return false; - for(String id : icons.keySet()) { - MarkerIconImpl ico = new MarkerIconImpl(id); - if(ico.loadPersistentData(icons.getNode(id))) { - markericons.put(id, ico); - } - } - /* Get marker sets */ - ConfigurationNode sets = conf.getNode("sets"); - if(sets != null) { - for(String id: sets.keySet()) { - MarkerSetImpl set = new MarkerSetImpl(id); - if(set.loadPersistentData(sets.getNode(id))) { - markersets.put(id, set); - } - } - } - - return true; - } - - enum MarkerUpdate { CREATED, UPDATED, DELETED }; - - /** - * Signal marker update - * @param marker - updated marker - * @param update - type of update - */ - static void markerUpdated(MarkerImpl marker, MarkerUpdate update) { - /* Freshen marker file for the world for this marker */ - if(api != null) - api.dirty_worlds.add(marker.getWorld()); - /* Enqueue client update */ - if(MapManager.mapman != null) - MapManager.mapman.pushUpdate(marker.getWorld(), new MarkerUpdated(marker, update == MarkerUpdate.DELETED)); - } - /** - * Signal area marker update - * @param marker - updated marker - * @param update - type of update - */ - static void areaMarkerUpdated(AreaMarkerImpl marker, MarkerUpdate update) { - /* Freshen marker file for the world for this marker */ - if(api != null) - api.dirty_worlds.add(marker.getWorld()); - /* Enqueue client update */ - if(MapManager.mapman != null) - MapManager.mapman.pushUpdate(marker.getWorld(), new AreaMarkerUpdated(marker, update == MarkerUpdate.DELETED)); - } - /** - * Signal marker set update - * @param markerset - updated marker set - * @param update - type of update - */ - static void markerSetUpdated(MarkerSetImpl markerset, MarkerUpdate update) { - /* Freshen all marker files */ - if(api != null) - api.freshenMarkerFiles(); - /* Enqueue client update */ - if(MapManager.mapman != null) - MapManager.mapman.pushUpdate(new MarkerSetUpdated(markerset, update == MarkerUpdate.DELETED)); - } - - /** - * Remove marker set - */ - static void removeMarkerSet(MarkerSetImpl markerset) { - if(api != null) { - api.markersets.remove(markerset.getMarkerSetID()); /* Remove set from list */ - if(markerset.isMarkerSetPersistent()) { /* If persistent */ - MarkerAPIImpl.saveMarkers(); /* Drive save */ - } - markerSetUpdated(markerset, MarkerUpdate.DELETED); /* Signal delete of set */ - } - } - - private static boolean processAreaArgs(DynmapCommandSender sender, AreaMarker marker, Map parms) { - String val = null; - try { - double ytop = marker.getTopY(); - double ybottom = marker.getBottomY(); - int scolor = marker.getLineColor(); - int fcolor = marker.getFillColor(); - double sopacity = marker.getLineOpacity(); - double fopacity = marker.getFillOpacity(); - int sweight = marker.getLineWeight(); - - val = parms.get(ARG_STROKECOLOR); - if(val != null) - scolor = Integer.parseInt(val, 16); - val = parms.get(ARG_FILLCOLOR); - if(val != null) - fcolor = Integer.parseInt(val, 16); - val = parms.get(ARG_STROKEOPACITY); - if(val != null) - sopacity = Double.parseDouble(val); - val = parms.get(ARG_FILLOPACITY); - if(val != null) - fopacity = Double.parseDouble(val); - val = parms.get(ARG_STROKEWEIGHT); - if(val != null) - sweight = Integer.parseInt(val); - val = parms.get(ARG_YTOP); - if(val != null) - ytop = Double.parseDouble(val); - val = parms.get(ARG_YBOTTOM); - if(val != null) - ybottom = Double.parseDouble(val); - marker.setLineStyle(sweight, sopacity, scolor); - marker.setFillStyle(fopacity, fcolor); - if(ytop >= ybottom) - marker.setRangeY(ytop, ybottom); - else - marker.setRangeY(ybottom, ytop); - } catch (NumberFormatException nfx) { - sender.sendMessage("Invalid parameter format: " + val); - return false; - } - return true; - } - - private static final Set commands = new HashSet(Arrays.asList(new String[] { - "add", "movehere", "update", "delete", "list", "icons", "addset", "updateset", "deleteset", "listsets", "addicon", "updateicon", - "deleteicon", "addcorner", "clearcorners", "addarea", "listareas", "deletearea", "updatearea" - })); - private static final String ARG_LABEL = "label"; - private static final String ARG_ID = "id"; - private static final String ARG_NEWLABEL = "newlabel"; - private static final String ARG_FILE = "file"; - private static final String ARG_HIDE = "hide"; - private static final String ARG_ICON = "icon"; - private static final String ARG_SET = "set"; - private static final String ARG_PRIO = "prio"; - private static final String ARG_MINZOOM = "minzoom"; - private static final String ARG_STROKEWEIGHT = "weight"; - private static final String ARG_STROKECOLOR = "color"; - private static final String ARG_STROKEOPACITY = "opacity"; - private static final String ARG_FILLCOLOR = "fillcolor"; - private static final String ARG_FILLOPACITY = "fillopacity"; - private static final String ARG_YTOP = "ytop"; - private static final String ARG_YBOTTOM = "ybottom"; - - /* Parse argument strings : handle 'attrib:value' and quoted strings */ - private static Map parseArgs(String[] args, DynmapCommandSender snd) { - HashMap rslt = new HashMap(); - /* Build command line, so we can parse our way - make sure there is trailing space */ - String cmdline = ""; - for(int i = 1; i < args.length; i++) { - cmdline += args[i] + " "; - } - boolean inquote = false; - StringBuilder sb = new StringBuilder(); - String varid = null; - for(int i = 0; i < cmdline.length(); i++) { - char c = cmdline.charAt(i); - if(inquote) { /* If in quote, accumulate until end or another quote */ - if(c == '\"') { /* End quote */ - inquote = false; - if(varid == null) { /* No varid? */ - rslt.put(ARG_LABEL, sb.toString()); - } - else { - rslt.put(varid, sb.toString()); - varid = null; - } - sb.setLength(0); - } - else { - sb.append(c); - } - } - else if(c == '\"') { /* Start of quote? */ - inquote = true; - } - else if(c == ':') { /* var:value */ - varid = sb.toString(); /* Save variable ID */ - sb.setLength(0); - } - else if(c == ' ') { /* Ending space? */ - if(varid == null) { /* No varid? */ - if(sb.length() > 0) { - rslt.put(ARG_LABEL, sb.toString()); - } - } - else { - rslt.put(varid, sb.toString()); - varid = null; - } - sb.setLength(0); - } - else { - sb.append(c); - } - } - if(inquote) { /* If still in quote, syntax error */ - snd.sendMessage("Error: unclosed doublequote"); - return null; - } - return rslt; - } - - - - public static boolean onCommand(DynmapCore plugin, DynmapCommandSender sender, String cmd, String commandLabel, String[] args) { - String id, setid, file, label, newlabel, iconid, prio, minzoom; - - if(api == null) { - sender.sendMessage("Markers component is not enabled."); - return false; - } - if(args.length == 0) - return false; - DynmapPlayer player = null; - if (sender instanceof DynmapPlayer) - player = (DynmapPlayer) sender; - /* Check if valid command */ - String c = args[0]; - if (!commands.contains(c)) { - return false; - } - /* Process commands */ - if(c.equals("add") && api.core.checkPlayerPermission(sender, "marker.add")) { - if(player == null) { - sender.sendMessage("Command can only be used by player"); - } - else if(args.length > 1) { - /* Parse arguements */ - Map parms = parseArgs(args, sender); - if(parms == null) return true; - iconid = parms.get(ARG_ICON); - setid = parms.get(ARG_SET); - id = parms.get(ARG_ID); - label = parms.get(ARG_LABEL); - - DynmapLocation loc = player.getLocation(); - /* Fill in defaults for missing parameters */ - if(iconid == null) { - iconid = MarkerIcon.DEFAULT; - } - if(setid == null) { - setid = MarkerSet.DEFAULT; - } - /* Add new marker */ - MarkerSet set = api.getMarkerSet(setid); - if(set == null) { - sender.sendMessage("Error: invalid set - " + setid); - return true; - } - MarkerIcon ico = api.getMarkerIcon(iconid); - if(ico == null) { - sender.sendMessage("Error: invalid icon - " + iconid); - return true; - } - Marker m = set.createMarker(id, label, - loc.world, loc.x, loc.y, loc.z, ico, true); - if(m == null) { - sender.sendMessage("Error creating marker"); - } - else { - sender.sendMessage("Added marker id:'" + m.getMarkerID() + "' (" + m.getLabel() + ") to set '" + set.getMarkerSetID() + "'"); - } - } - else { - sender.sendMessage("Marker label required"); - } - } - /* Update position of bookmark - must have ID parameter */ - else if(c.equals("movehere") && plugin.checkPlayerPermission(sender, "marker.movehere")) { - if(player == null) { - sender.sendMessage("Command can only be used by player"); - } - else if(args.length > 1) { - /* Parse arguements */ - Map parms = parseArgs(args, sender); - if(parms == null) return true; - id = parms.get(ARG_ID); - label = parms.get(ARG_LABEL); - setid = parms.get(ARG_SET); - if((id == null) && (label == null)) { - sender.sendMessage("