diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3576d9a54..59265620a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,7 +19,7 @@ jobs: strategy: fail-fast: false matrix: - platform: [core, spigot] + platform: [core, spigot, spigot26] steps: - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5 with: @@ -28,6 +28,14 @@ jobs: with: distribution: temurin java-version: '21' + - uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 + if: matrix.platform == 'spigot26' + with: + distribution: temurin + java-version: '25' + - name: Build and inspect Minecraft 26 candidate + if: matrix.platform == 'spigot26' + run: bash gradlew-minecraft26 verifySpigotJar --no-daemon --console=plain - name: Test shared core if: matrix.platform == 'core' run: bash gradlew -PdynmapPlatform=core :DynmapCore:test --no-daemon --console=plain @@ -44,4 +52,8 @@ jobs: path: | DynmapCore/build/reports/tests/ DynmapCore/build/test-results/ + bukkit-helper-26-2/build/reports/tests/ + bukkit-helper-26-2/build/test-results/ + spigot/build/reports/tests/ + spigot/build/test-results/ build/reports/acecore/ diff --git a/DynmapCore/build.gradle b/DynmapCore/build.gradle index d5955eebf..f1640b81f 100644 --- a/DynmapCore/build.gradle +++ b/DynmapCore/build.gradle @@ -8,7 +8,10 @@ eclipse { } } -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' +} dependencies { implementation project(':DynmapCoreAPI') @@ -68,8 +71,8 @@ shadowJar { include(dependency('com.googlecode.json-simple:json-simple:')) include(dependency('org.yaml:snakeyaml:')) include(dependency('com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:')) - include(dependency('javax.servlet::')) - include(dependency('org.eclipse.jetty::')) + include(dependency('javax.servlet:.*:.*')) + include(dependency('org.eclipse.jetty:.*:.*')) include(dependency('org.eclipse.jetty.orbit:javax.servlet:')) include(dependency('org.postgresql:postgresql:')) include(dependency('io.github.linktosriram.s3lite:core:')) @@ -77,8 +80,8 @@ shadowJar { include(dependency('io.github.linktosriram.s3lite:http-client-url-connection:')) include(dependency('io.github.linktosriram.s3lite:http-client-spi:')) include(dependency('io.github.linktosriram.s3lite:util:')) - include(dependency('jakarta.xml.bind::')) - include(dependency('com.sun.xml.bind::')) + include(dependency('jakarta.xml.bind:.*:.*')) + include(dependency('com.sun.xml.bind:.*:.*')) include(dependency(':DynmapCoreAPI')) exclude("META-INF/maven/**") exclude("META-INF/services/**") diff --git a/DynmapCore/src/main/java/org/dynmap/hdmap/renderer/CopperGolemStatueRenderer.java b/DynmapCore/src/main/java/org/dynmap/hdmap/renderer/CopperGolemStatueRenderer.java new file mode 100644 index 000000000..a8fd1f4f7 --- /dev/null +++ b/DynmapCore/src/main/java/org/dynmap/hdmap/renderer/CopperGolemStatueRenderer.java @@ -0,0 +1,86 @@ +package org.dynmap.hdmap.renderer; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; +import java.util.Map; +import org.dynmap.Log; +import org.dynmap.renderer.CustomRenderer; +import org.dynmap.renderer.DynmapBlockState; +import org.dynmap.renderer.MapDataContext; +import org.dynmap.renderer.RenderPatch; +import org.dynmap.renderer.RenderPatchFactory; +import org.dynmap.renderer.RenderPatchFactory.SideVisible; + +/** Block-state-only statue mesh, including the antenna above the owning block. */ +public class CopperGolemStatueRenderer extends CustomRenderer { + private static final String[] POSES = {"standing", "sitting", "running", "star"}; + private static final String[] FACINGS = {"north", "east", "south", "west"}; + private final RenderPatch[][] meshes = new RenderPatch[16][]; + + @Override + public boolean initializeRenderer(RenderPatchFactory factory, String name, BitSet states, Map parameters) { + if (!super.initializeRenderer(factory, name, states, parameters)) return false; + List> lists = new ArrayList<>(); + for (int i = 0; i < meshes.length; i++) lists.add(new ArrayList()); + try (BufferedReader reader = new BufferedReader(new InputStreamReader( + CopperGolemStatueRenderer.class.getResourceAsStream("/copper-golem-statue.csv"), StandardCharsets.UTF_8))) { + String line; + while ((line = reader.readLine()) != null) { + if (line.startsWith("#") || line.isEmpty()) continue; + String[] fields = line.split(","); + int pose = indexOf(POSES, fields[0]); + int texture = Integer.parseInt(fields[1]); + double width = Double.parseDouble(fields[2]) / 16; + double height = Double.parseDouble(fields[3]) / 16; + SideVisible side = "1".equals(fields[4]) ? SideVisible.BOTTOM : SideVisible.TOP; + double[] points = new double[9]; + for (int i = 0; i < points.length; i++) points[i] = Double.parseDouble(fields[i + 5]); + for (int facing = 0; facing < 4; facing++) { + double[] rotated = rotate(points, facing); + RenderPatch patch = factory.getPatch(rotated[0], rotated[1], rotated[2], + rotated[3], rotated[4], rotated[5], rotated[6], rotated[7], rotated[8], + 0, width, 0, height, side, texture); + if (patch == null) throw new IOException("Invalid statue patch: " + line); + lists.get(pose * 4 + facing).add(patch); + } + } + for (int i = 0; i < meshes.length; i++) meshes[i] = lists.get(i).toArray(new RenderPatch[0]); + return true; + } catch (IOException | RuntimeException error) { + Log.severe("Cannot load copper golem statue model", error); + return false; + } + } + + private static int indexOf(String[] values, String value) { + for (int i = 0; i < values.length; i++) if (values[i].equals(value)) return i; + throw new IllegalArgumentException("Unknown statue state: " + value); + } + + private static double[] rotate(double[] source, int facing) { + double[] result = source.clone(); + for (int i = 0; i < result.length; i += 3) { + double x = source[i] - 0.5, z = source[i + 2] - 0.5; + for (int n = 0; n < facing; n++) { double oldX = x; x = -z; z = oldX; } + result[i] = x + 0.5; + result[i + 2] = z + 0.5; + } + return result; + } + + RenderPatch[] meshFor(DynmapBlockState state) { + int pose = 0, facing = 0; + for (int i = 0; i < POSES.length; i++) if (state.isStateMatch("copper_golem_pose", POSES[i])) pose = i; + for (int i = 0; i < FACINGS.length; i++) if (state.isStateMatch("facing", FACINGS[i])) facing = i; + return meshes[pose * 4 + facing]; + } + + @Override public RenderPatch[] getRenderPatchList(MapDataContext context) { return meshFor(context.getBlockType()); } + @Override public int getMaximumTextureCount() { return 65; } + @Override public boolean isOnlyBlockStateSensitive() { return true; } +} diff --git a/DynmapCore/src/main/java/org/dynmap/utils/PatchDefinition.java b/DynmapCore/src/main/java/org/dynmap/utils/PatchDefinition.java index f26587159..f36ced88b 100644 --- a/DynmapCore/src/main/java/org/dynmap/utils/PatchDefinition.java +++ b/DynmapCore/src/main/java/org/dynmap/utils/PatchDefinition.java @@ -232,25 +232,25 @@ public boolean validate() { boolean good = true; // Compute visible corners to see if we're inside cube (u.x = xu-x0, v.x = xv-x0) double xx0 = x0 + u.x * umin + v.x * vmin; - double xx1 = x0 + u.x * vmin + v.x * vmax; - double xx2 = x0 + u.x * umax + v.x * vmin; - double xx3 = x0 + u.x * vmax + v.x * vmax; + double xx1 = x0 + u.x * umin + v.x * vmax; + double xx2 = x0 + u.x * umax + v.x * vminatumax; + double xx3 = x0 + u.x * umax + v.x * vmaxatumax; if (outOfRange(xx0) || outOfRange(xx1) || outOfRange(xx2) || outOfRange(xx3)) { Log.verboseinfo(String.format("Invalid visible range xu=[%f:%f], xv=[%f:%f]", xx0, xx2, xx1, xx3)); good = false; } double yy0 = y0 + u.y * umin + v.y * vmin; - double yy1 = y0 + u.y * vmin + v.y * vmax; - double yy2 = y0 + u.y * umax + v.y * vmin; - double yy3 = y0 + u.y * vmax + v.y * vmax; + double yy1 = y0 + u.y * umin + v.y * vmax; + double yy2 = y0 + u.y * umax + v.y * vminatumax; + double yy3 = y0 + u.y * umax + v.y * vmaxatumax; if (outOfRange(yy0) || outOfRange(yy1) || outOfRange(yy2) || outOfRange(yy3)) { Log.verboseinfo(String.format("Invalid visible range yu=[%f:%f], yv=[%f:%f]", yy0, yy2, yy1, yy3)); good = false; } double zz0 = z0 + u.z * umin + v.z * vmin; - double zz1 = z0 + u.z * vmin + v.z * vmax; - double zz2 = z0 + u.z * umax + v.z * vmin; - double zz3 = z0 + u.z * vmax + v.z * vmax; + double zz1 = z0 + u.z * umin + v.z * vmax; + double zz2 = z0 + u.z * umax + v.z * vminatumax; + double zz3 = z0 + u.z * umax + v.z * vmaxatumax; if (outOfRange(zz0) || outOfRange(zz1) || outOfRange(zz2) || outOfRange(zz3)) { Log.verboseinfo(String.format("Invalid visible range zu=[%f:%f], zv=[%f:%f]", zz0, zz2, zz1, zz3)); good = false; diff --git a/DynmapCore/src/main/resources/copper-golem-statue.csv b/DynmapCore/src/main/resources/copper-golem-statue.csv new file mode 100644 index 000000000..9af6f9957 --- /dev/null +++ b/DynmapCore/src/main/resources/copper-golem-statue.csv @@ -0,0 +1,230 @@ +# Minecraft 26.2 copper golem statue geometry; client SHA1 2dc72797acbc1b63fc16a11c4ac393605f453754 +# pose,texture,width,height,flipped,origin xyz,U endpoint xyz,V endpoint xyz (north; blocks) +standing,0,8,6,0,0.750000000,0.687500000,0.312500000,-0.250000000,0.687500000,0.312500000,0.750000000,0.687500000,1.312500000 +standing,1,8,6,1,0.750000000,0.312500000,0.312500000,-0.250000000,0.312500000,0.312500000,0.750000000,0.312500000,1.312500000 +standing,2,6,6,0,0.750000000,0.312500000,0.687500000,0.750000000,0.312500000,-0.312500000,0.750000000,1.312500000,0.687500000 +standing,3,8,6,0,0.750000000,0.312500000,0.312500000,-0.250000000,0.312500000,0.312500000,0.750000000,1.312500000,0.312500000 +standing,4,6,6,0,0.250000000,0.312500000,0.312500000,0.250000000,0.312500000,1.312500000,0.250000000,1.312500000,0.312500000 +standing,5,8,6,0,0.250000000,0.312500000,0.687500000,1.250000000,0.312500000,0.687500000,0.250000000,1.312500000,0.687500000 +standing,6,8,10,0,0.750937500,1.000937500,0.186562500,-0.252812500,1.000937500,0.186562500,0.750937500,1.000937500,1.189562500 +standing,7,8,10,1,0.750937500,0.686562500,0.186562500,-0.252812500,0.686562500,0.186562500,0.750937500,0.686562500,1.189562500 +standing,8,10,5,0,0.750937500,0.686562500,0.813437500,0.750937500,0.686562500,-0.189562500,0.750937500,1.692562500,0.813437500 +standing,9,8,5,0,0.750937500,0.686562500,0.186562500,-0.252812500,0.686562500,0.186562500,0.750937500,1.692562500,0.186562500 +standing,10,10,5,0,0.249062500,0.686562500,0.186562500,0.249062500,0.686562500,1.189562500,0.249062500,1.692562500,0.186562500 +standing,11,8,5,0,0.249062500,0.686562500,0.813437500,1.252812500,0.686562500,0.813437500,0.249062500,1.692562500,0.813437500 +standing,12,2,2,0,0.562500000,0.812500000,0.125000000,-0.437500000,0.812500000,0.125000000,0.562500000,0.812500000,1.125000000 +standing,13,2,2,1,0.562500000,0.625000000,0.125000000,-0.437500000,0.625000000,0.125000000,0.562500000,0.625000000,1.125000000 +standing,14,2,3,0,0.562500000,0.625000000,0.250000000,0.562500000,0.625000000,-0.750000000,0.562500000,1.625000000,0.250000000 +standing,15,2,3,0,0.562500000,0.625000000,0.125000000,-0.437500000,0.625000000,0.125000000,0.562500000,1.625000000,0.125000000 +standing,16,2,3,0,0.437500000,0.625000000,0.125000000,0.437500000,0.625000000,1.125000000,0.437500000,1.625000000,0.125000000 +standing,17,2,3,0,0.437500000,0.625000000,0.250000000,1.437500000,0.625000000,0.250000000,0.437500000,1.625000000,0.250000000 +standing,18,2,2,0,0.561562500,1.249062500,0.438437500,-0.423437500,1.249062500,0.438437500,0.561562500,1.249062500,1.423437500 +standing,19,2,2,1,0.561562500,1.000937500,0.438437500,-0.423437500,1.000937500,0.438437500,0.561562500,1.000937500,1.423437500 +standing,20,2,4,0,0.561562500,1.000937500,0.561562500,0.561562500,1.000937500,-0.423437500,0.561562500,1.993437500,0.561562500 +standing,21,2,4,0,0.561562500,1.000937500,0.438437500,-0.423437500,1.000937500,0.438437500,0.561562500,1.993437500,0.438437500 +standing,22,2,4,0,0.438437500,1.000937500,0.438437500,0.438437500,1.000937500,1.423437500,0.438437500,1.993437500,0.438437500 +standing,23,2,4,0,0.438437500,1.000937500,0.561562500,1.423437500,1.000937500,0.561562500,0.438437500,1.993437500,0.561562500 +standing,24,4,4,0,0.624062500,1.499062500,0.375937500,-0.368437500,1.499062500,0.375937500,0.624062500,1.499062500,1.368437500 +standing,25,4,4,1,0.624062500,1.250937500,0.375937500,-0.368437500,1.250937500,0.375937500,0.624062500,1.250937500,1.368437500 +standing,26,4,4,0,0.624062500,1.250937500,0.624062500,0.624062500,1.250937500,-0.368437500,0.624062500,2.243437500,0.624062500 +standing,27,4,4,0,0.624062500,1.250937500,0.375937500,-0.368437500,1.250937500,0.375937500,0.624062500,2.243437500,0.375937500 +standing,28,4,4,0,0.375937500,1.250937500,0.375937500,0.375937500,1.250937500,1.368437500,0.375937500,2.243437500,0.375937500 +standing,29,4,4,0,0.375937500,1.250937500,0.624062500,1.368437500,1.250937500,0.624062500,0.375937500,2.243437500,0.624062500 +standing,30,3,4,0,0.937500000,0.750000000,0.375000000,-0.062500000,0.750000000,0.375000000,0.937500000,0.750000000,1.375000000 +standing,31,3,4,1,0.937500000,0.125000000,0.375000000,-0.062500000,0.125000000,0.375000000,0.937500000,0.125000000,1.375000000 +standing,32,4,10,0,0.937500000,0.125000000,0.625000000,0.937500000,0.125000000,-0.375000000,0.937500000,1.125000000,0.625000000 +standing,33,3,10,0,0.937500000,0.125000000,0.375000000,-0.062500000,0.125000000,0.375000000,0.937500000,1.125000000,0.375000000 +standing,34,4,10,0,0.750000000,0.125000000,0.375000000,0.750000000,0.125000000,1.375000000,0.750000000,1.125000000,0.375000000 +standing,35,3,10,0,0.750000000,0.125000000,0.625000000,1.750000000,0.125000000,0.625000000,0.750000000,1.125000000,0.625000000 +standing,36,3,4,0,0.250000000,0.750000000,0.375000000,-0.750000000,0.750000000,0.375000000,0.250000000,0.750000000,1.375000000 +standing,37,3,4,1,0.250000000,0.125000000,0.375000000,-0.750000000,0.125000000,0.375000000,0.250000000,0.125000000,1.375000000 +standing,38,4,10,0,0.250000000,0.125000000,0.625000000,0.250000000,0.125000000,-0.375000000,0.250000000,1.125000000,0.625000000 +standing,39,3,10,0,0.250000000,0.125000000,0.375000000,-0.750000000,0.125000000,0.375000000,0.250000000,1.125000000,0.375000000 +standing,40,4,10,0,0.062500000,0.125000000,0.375000000,0.062500000,0.125000000,1.375000000,0.062500000,1.125000000,0.375000000 +standing,41,3,10,0,0.062500000,0.125000000,0.625000000,1.062500000,0.125000000,0.625000000,0.062500000,1.125000000,0.625000000 +standing,42,4,4,0,0.750000000,0.312500000,0.375000000,-0.250000000,0.312500000,0.375000000,0.750000000,0.312500000,1.375000000 +standing,43,4,4,1,0.750000000,0.000000000,0.375000000,-0.250000000,0.000000000,0.375000000,0.750000000,0.000000000,1.375000000 +standing,44,4,5,0,0.750000000,0.000000000,0.625000000,0.750000000,0.000000000,-0.375000000,0.750000000,1.000000000,0.625000000 +standing,45,4,5,0,0.750000000,0.000000000,0.375000000,-0.250000000,0.000000000,0.375000000,0.750000000,1.000000000,0.375000000 +standing,46,4,5,0,0.500000000,0.000000000,0.375000000,0.500000000,0.000000000,1.375000000,0.500000000,1.000000000,0.375000000 +standing,47,4,5,0,0.500000000,0.000000000,0.625000000,1.500000000,0.000000000,0.625000000,0.500000000,1.000000000,0.625000000 +standing,48,4,4,0,0.500000000,0.312500000,0.375000000,-0.500000000,0.312500000,0.375000000,0.500000000,0.312500000,1.375000000 +standing,49,4,4,1,0.500000000,0.000000000,0.375000000,-0.500000000,0.000000000,0.375000000,0.500000000,0.000000000,1.375000000 +standing,50,4,5,0,0.500000000,0.000000000,0.625000000,0.500000000,0.000000000,-0.375000000,0.500000000,1.000000000,0.625000000 +standing,51,4,5,0,0.500000000,0.000000000,0.375000000,-0.500000000,0.000000000,0.375000000,0.500000000,1.000000000,0.375000000 +standing,52,4,5,0,0.250000000,0.000000000,0.375000000,0.250000000,0.000000000,1.375000000,0.250000000,1.000000000,0.375000000 +standing,53,4,5,0,0.250000000,0.000000000,0.625000000,1.250000000,0.000000000,0.625000000,0.250000000,1.000000000,0.625000000 +sitting,54,6,6,0,0.687500000,0.437500000,0.362500000,-0.312500000,0.437500000,0.362500000,0.687500000,0.437500000,1.362500000 +sitting,55,6,6,1,0.687500000,0.375000000,0.362500000,-0.312500000,0.375000000,0.362500000,0.687500000,0.375000000,1.362500000 +sitting,56,6,1,0,0.687500000,0.375000000,0.737500000,0.687500000,0.375000000,-0.262500000,0.687500000,1.375000000,0.737500000 +sitting,57,6,1,0,0.687500000,0.375000000,0.362500000,-0.312500000,0.375000000,0.362500000,0.687500000,1.375000000,0.362500000 +sitting,58,6,1,0,0.312500000,0.375000000,0.362500000,0.312500000,0.375000000,1.362500000,0.312500000,1.375000000,0.362500000 +sitting,59,6,1,0,0.312500000,0.375000000,0.737500000,1.312500000,0.375000000,0.737500000,0.312500000,1.375000000,0.737500000 +sitting,0,8,6,0,0.750000000,0.375000000,0.425000000,-0.250000000,0.375000000,0.425000000,0.750000000,0.375000000,1.425000000 +sitting,1,8,6,1,0.750000000,0.000000000,0.425000000,-0.250000000,0.000000000,0.425000000,0.750000000,0.000000000,1.425000000 +sitting,2,6,6,0,0.750000000,0.000000000,0.800000000,0.750000000,0.000000000,-0.200000000,0.750000000,1.000000000,0.800000000 +sitting,3,8,6,0,0.750000000,0.000000000,0.425000000,-0.250000000,0.000000000,0.425000000,0.750000000,1.000000000,0.425000000 +sitting,4,6,6,0,0.250000000,0.000000000,0.425000000,0.250000000,0.000000000,1.425000000,0.250000000,1.000000000,0.425000000 +sitting,5,8,6,0,0.250000000,0.000000000,0.800000000,1.250000000,0.000000000,0.800000000,0.250000000,1.000000000,0.800000000 +sitting,60,8,3,0,0.249998623,0.062501837,0.237500000,1.249998623,0.062494490,0.237500000,0.249998623,0.062501837,1.237500000 +sitting,61,8,3,1,0.250001377,0.437501837,0.237500000,1.250001377,0.437494490,0.237500000,0.250001377,0.437501837,1.237500000 +sitting,62,3,6,0,0.250001377,0.437501837,0.425000000,0.250001377,0.437501837,-0.575000000,0.249994031,-0.562498163,0.425000000 +sitting,3,8,6,0,0.250001377,0.437501837,0.237500000,1.250001377,0.437494490,0.237500000,0.249994031,-0.562498163,0.237500000 +sitting,63,3,6,0,0.750001377,0.437498163,0.237500000,0.750001377,0.437498163,1.237500000,0.749994031,-0.562501837,0.237500000 +sitting,64,8,6,0,0.750001377,0.437498163,0.425000000,-0.249998623,0.437505510,0.425000000,0.749994031,-0.562501837,0.425000000 +sitting,18,2,2,0,0.561562500,0.999062500,0.427500000,-0.423437500,0.999062500,0.427500000,0.561562500,0.999062500,1.412500000 +sitting,19,2,2,1,0.561562500,0.750937500,0.427500000,-0.423437500,0.750937500,0.427500000,0.561562500,0.750937500,1.412500000 +sitting,20,2,4,0,0.561562500,0.750937500,0.550625000,0.561562500,0.750937500,-0.434375000,0.561562500,1.743437500,0.550625000 +sitting,21,2,4,0,0.561562500,0.750937500,0.427500000,-0.423437500,0.750937500,0.427500000,0.561562500,1.743437500,0.427500000 +sitting,22,2,4,0,0.438437500,0.750937500,0.427500000,0.438437500,0.750937500,1.412500000,0.438437500,1.743437500,0.427500000 +sitting,23,2,4,0,0.438437500,0.750937500,0.550625000,1.423437500,0.750937500,0.550625000,0.438437500,1.743437500,0.550625000 +sitting,24,4,4,0,0.624062500,1.249062500,0.365000000,-0.368437500,1.249062500,0.365000000,0.624062500,1.249062500,1.357500000 +sitting,25,4,4,1,0.624062500,1.000937500,0.365000000,-0.368437500,1.000937500,0.365000000,0.624062500,1.000937500,1.357500000 +sitting,26,4,4,0,0.624062500,1.000937500,0.613125000,0.624062500,1.000937500,-0.379375000,0.624062500,1.993437500,0.613125000 +sitting,27,4,4,0,0.624062500,1.000937500,0.365000000,-0.368437500,1.000937500,0.365000000,0.624062500,1.993437500,0.365000000 +sitting,28,4,4,0,0.375937500,1.000937500,0.365000000,0.375937500,1.000937500,1.357500000,0.375937500,1.993437500,0.365000000 +sitting,29,4,4,0,0.375937500,1.000937500,0.613125000,1.368437500,1.000937500,0.613125000,0.375937500,1.993437500,0.613125000 +sitting,6,8,10,0,0.750000000,0.750000000,0.175000000,-0.250000000,0.750000000,0.175000000,0.750000000,0.750000000,1.175000000 +sitting,7,8,10,1,0.750000000,0.437500000,0.175000000,-0.250000000,0.437500000,0.175000000,0.750000000,0.437500000,1.175000000 +sitting,8,10,5,0,0.750000000,0.437500000,0.800000000,0.750000000,0.437500000,-0.200000000,0.750000000,1.437500000,0.800000000 +sitting,9,8,5,0,0.750000000,0.437500000,0.175000000,-0.250000000,0.437500000,0.175000000,0.750000000,1.437500000,0.175000000 +sitting,10,10,5,0,0.250000000,0.437500000,0.175000000,0.250000000,0.437500000,1.175000000,0.250000000,1.437500000,0.175000000 +sitting,11,8,5,0,0.250000000,0.437500000,0.800000000,1.250000000,0.437500000,0.800000000,0.250000000,1.437500000,0.800000000 +sitting,12,2,2,0,0.562500000,0.562500000,0.112500000,-0.437500000,0.562500000,0.112500000,0.562500000,0.562500000,1.112500000 +sitting,13,2,2,1,0.562500000,0.375000000,0.112500000,-0.437500000,0.375000000,0.112500000,0.562500000,0.375000000,1.112500000 +sitting,14,2,3,0,0.562500000,0.375000000,0.237500000,0.562500000,0.375000000,-0.762500000,0.562500000,1.375000000,0.237500000 +sitting,15,2,3,0,0.562500000,0.375000000,0.112500000,-0.437500000,0.375000000,0.112500000,0.562500000,1.375000000,0.112500000 +sitting,16,2,3,0,0.437500000,0.375000000,0.112500000,0.437500000,0.375000000,1.112500000,0.437500000,1.375000000,0.112500000 +sitting,17,2,3,0,0.437500000,0.375000000,0.237500000,1.437500000,0.375000000,0.237500000,0.437500000,1.375000000,0.237500000 +sitting,30,3,4,0,0.942187500,0.657013281,0.474632813,-0.057812500,0.657013281,0.474632813,0.942187500,0.083408370,1.293764918 +sitting,31,3,4,1,0.942187500,0.145055715,0.116129743,-0.057812500,0.145055715,0.116129743,0.942187500,-0.428549196,0.935261848 +sitting,32,4,10,0,0.942187500,0.001654488,0.320912770,0.942187500,0.575259399,-0.498219336,0.942187500,0.820786593,0.894517681 +sitting,33,3,10,0,0.942187500,0.145055715,0.116129743,-0.057812500,0.145055715,0.116129743,0.942187500,0.964187821,0.689734654 +sitting,34,4,10,0,0.754687500,0.145055715,0.116129743,0.754687500,-0.428549196,0.935261848,0.754687500,0.964187821,0.689734654 +sitting,35,3,10,0,0.754687500,0.001654488,0.320912770,1.754687500,0.001654488,0.320912770,0.754687500,0.820786593,0.894517681 +sitting,36,3,4,0,0.245312500,0.657019450,0.474627856,-0.754687500,0.657019450,0.474627856,0.245312500,0.083414539,1.293759961 +sitting,37,3,4,1,0.245312500,0.145061884,0.116124786,-0.754687500,0.145061884,0.116124786,0.245312500,-0.428543027,0.935256892 +sitting,38,4,10,0,0.245312500,0.001660656,0.320907813,0.245312500,0.575265568,-0.498224293,0.245312500,0.820792762,0.894512724 +sitting,39,3,10,0,0.245312500,0.145061884,0.116124786,-0.754687500,0.145061884,0.116124786,0.245312500,0.964193989,0.689729697 +sitting,40,4,10,0,0.057812500,0.145061884,0.116124786,0.057812500,-0.428543027,0.935256892,0.057812500,0.964193989,0.689729697 +sitting,41,3,10,0,0.057812500,0.001660656,0.320907813,1.057812500,0.001660656,0.320907813,0.057812500,0.820792762,0.894512724 +sitting,42,4,4,0,0.753125000,0.250000224,0.376562500,-0.246875000,0.250000224,0.376562500,0.753125000,-0.749999776,0.376558827 +sitting,43,4,4,1,0.753125000,0.250001372,0.064062500,-0.246875000,0.250001372,0.064062500,0.753125000,-0.749998628,0.064058827 +sitting,44,4,5,0,0.753125000,0.000001372,0.064061582,0.753125000,1.000001372,0.064065255,0.753125000,-0.000002301,1.064061582 +sitting,45,4,5,0,0.753125000,0.250001372,0.064062500,-0.246875000,0.250001372,0.064062500,0.753125000,0.249997699,1.064062500 +sitting,46,4,5,0,0.503125000,0.250001372,0.064062500,0.503125000,-0.749998628,0.064058827,0.503125000,0.249997699,1.064062500 +sitting,47,4,5,0,0.503125000,0.000001372,0.064061582,1.503125000,0.000001372,0.064061582,0.503125000,-0.000002301,1.064061582 +sitting,48,4,4,0,0.496875000,0.250000224,0.376562500,-0.503125000,0.250000224,0.376562500,0.496875000,-0.749999776,0.376558827 +sitting,49,4,4,1,0.496875000,0.250001372,0.064062500,-0.503125000,0.250001372,0.064062500,0.496875000,-0.749998628,0.064058827 +sitting,50,4,5,0,0.496875000,0.000001372,0.064061582,0.496875000,1.000001372,0.064065255,0.496875000,-0.000002301,1.064061582 +sitting,51,4,5,0,0.496875000,0.250001372,0.064062500,-0.503125000,0.250001372,0.064062500,0.496875000,0.249997699,1.064062500 +sitting,52,4,5,0,0.246875000,0.250001372,0.064062500,0.246875000,-0.749998628,0.064058827,0.246875000,0.249997699,1.064062500 +sitting,53,4,5,0,0.246875000,0.000001372,0.064061582,1.246875000,0.000001372,0.064061582,0.246875000,-0.000002301,1.064061582 +running,0,8,6,0,0.774041478,0.638966528,0.279069214,-0.222905433,0.716786170,0.285469170,0.789722890,0.758217150,1.271809554 +running,1,8,6,1,0.745357166,0.267787862,0.324109287,-0.251589745,0.345607504,0.330509243,0.761038578,0.387038484,1.316849627 +running,2,6,6,0,0.751237695,0.312506846,0.696386914,0.735556283,0.193256223,-0.296353426,0.827729195,1.302316621,0.576280053 +running,3,8,6,0,0.745357166,0.267787862,0.324109287,-0.251589745,0.345607504,0.330509243,0.821848665,1.257597638,0.204002426 +running,4,6,6,0,0.246883710,0.306697683,0.327309265,0.262565123,0.425948305,1.320049605,0.323375209,1.296507459,0.207202404 +running,5,8,6,0,0.252764240,0.351416667,0.699586892,1.249711151,0.273597025,0.693186936,0.329255739,1.341226442,0.579480031 +running,6,8,10,0,0.772750000,0.981250000,0.075000000,-0.227250000,0.981250000,0.075000000,0.772750000,0.981250000,1.075000000 +running,7,8,10,1,0.772750000,0.668750000,0.075000000,-0.227250000,0.668750000,0.075000000,0.772750000,0.668750000,1.075000000 +running,8,10,5,0,0.772750000,0.668750000,0.700000000,0.772750000,0.668750000,-0.300000000,0.772750000,1.668750000,0.700000000 +running,9,8,5,0,0.772750000,0.668750000,0.075000000,-0.227250000,0.668750000,0.075000000,0.772750000,1.668750000,0.075000000 +running,10,10,5,0,0.272750000,0.668750000,0.075000000,0.272750000,0.668750000,1.075000000,0.272750000,1.668750000,0.075000000 +running,11,8,5,0,0.272750000,0.668750000,0.700000000,1.272750000,0.668750000,0.700000000,0.272750000,1.668750000,0.700000000 +running,12,2,2,0,0.586500000,0.793750000,0.012500000,-0.413500000,0.793750000,0.012500000,0.586500000,0.793750000,1.012500000 +running,13,2,2,1,0.586500000,0.606250000,0.012500000,-0.413500000,0.606250000,0.012500000,0.586500000,0.606250000,1.012500000 +running,14,2,3,0,0.586500000,0.606250000,0.137500000,0.586500000,0.606250000,-0.862500000,0.586500000,1.606250000,0.137500000 +running,15,2,3,0,0.586500000,0.606250000,0.012500000,-0.413500000,0.606250000,0.012500000,0.586500000,1.606250000,0.012500000 +running,16,2,3,0,0.461500000,0.606250000,0.012500000,0.461500000,0.606250000,1.012500000,0.461500000,1.606250000,0.012500000 +running,17,2,3,0,0.461500000,0.606250000,0.137500000,1.461500000,0.606250000,0.137500000,0.461500000,1.606250000,0.137500000 +running,18,2,2,0,0.585562500,1.230312500,0.325937500,-0.399437500,1.230312500,0.325937500,0.585562500,1.230312500,1.310937500 +running,19,2,2,1,0.585562500,0.982187500,0.325937500,-0.399437500,0.982187500,0.325937500,0.585562500,0.982187500,1.310937500 +running,20,2,4,0,0.585562500,0.982187500,0.449062500,0.585562500,0.982187500,-0.535937500,0.585562500,1.974687500,0.449062500 +running,21,2,4,0,0.585562500,0.982187500,0.325937500,-0.399437500,0.982187500,0.325937500,0.585562500,1.974687500,0.325937500 +running,22,2,4,0,0.462437500,0.982187500,0.325937500,0.462437500,0.982187500,1.310937500,0.462437500,1.974687500,0.325937500 +running,23,2,4,0,0.462437500,0.982187500,0.449062500,1.447437500,0.982187500,0.449062500,0.462437500,1.974687500,0.449062500 +running,24,4,4,0,0.646812500,1.480312500,0.263437500,-0.345687500,1.480312500,0.263437500,0.646812500,1.480312500,1.255937500 +running,25,4,4,1,0.646812500,1.232187500,0.263437500,-0.345687500,1.232187500,0.263437500,0.646812500,1.232187500,1.255937500 +running,26,4,4,0,0.646812500,1.232187500,0.511562500,0.646812500,1.232187500,-0.480937500,0.646812500,2.224687500,0.511562500 +running,27,4,4,0,0.646812500,1.232187500,0.263437500,-0.345687500,1.232187500,0.263437500,0.646812500,2.224687500,0.263437500 +running,28,4,4,0,0.398687500,1.232187500,0.263437500,0.398687500,1.232187500,1.255937500,0.398687500,2.224687500,0.263437500 +running,29,4,4,0,0.398687500,1.232187500,0.511562500,1.391187500,1.232187500,0.511562500,0.398687500,2.224687500,0.511562500 +running,30,3,4,0,0.963500000,0.632949072,0.271870843,-0.036500000,0.632949072,0.271870843,0.963500000,1.476359688,0.809140358 +running,31,3,4,1,0.963500000,0.297155624,0.799002478,-0.036500000,0.297155624,0.799002478,0.963500000,1.140566241,1.336271993 +running,32,4,10,0,0.963500000,0.508008278,0.933319857,0.963500000,-0.335402338,0.396050341,0.963500000,1.045277794,0.089909240 +running,33,3,10,0,0.963500000,0.297155624,0.799002478,-0.036500000,0.297155624,0.799002478,0.963500000,0.834425140,-0.044408138 +running,34,4,10,0,0.776000000,0.297155624,0.799002478,0.776000000,1.140566241,1.336271993,0.776000000,0.834425140,-0.044408138 +running,35,3,10,0,0.776000000,0.508008278,0.933319857,1.776000000,0.508008278,0.933319857,0.776000000,1.045277794,0.089909240 +running,36,3,4,0,0.273547399,0.827430334,0.472300927,-0.724015424,0.872251029,0.525775409,0.273582912,0.061361352,1.115059290 +running,37,3,4,1,0.229938638,0.426684243,-0.005324288,-0.767624185,0.471504937,0.048150194,0.229974151,-0.339384739,0.637434075 +running,38,4,10,0,0.229947516,0.235166997,0.155365303,0.229912003,1.001235980,-0.487393060,0.299721534,0.876360743,0.919565647 +running,39,3,10,0,0.229938638,0.426684243,-0.005324288,-0.767624185,0.471504937,0.048150194,0.299712656,1.067877989,0.758876056 +running,40,4,10,0,0.042895608,0.435088123,0.004702177,0.042931122,-0.330980859,0.647460540,0.112669626,1.076281869,0.768902522 +running,41,3,10,0,0.042904487,0.243570878,0.165391768,1.040467309,0.198750183,0.111917286,0.112678505,0.884764624,0.929592113 +running,42,4,4,0,0.742000000,0.368705580,0.404749860,-0.258000000,0.368705580,0.404749860,0.742000000,-0.397361601,1.047510371 +running,43,4,4,1,0.742000000,0.167842920,0.165353866,-0.258000000,0.167842920,0.165353866,0.742000000,-0.598224260,0.808114377 +running,44,4,5,0,0.742000000,-0.023673875,0.326043994,0.742000000,0.742393306,-0.316716517,0.742000000,0.619086636,1.092111175 +running,45,4,5,0,0.742000000,0.167842920,0.165353866,-0.258000000,0.167842920,0.165353866,0.742000000,0.810603431,0.931421047 +running,46,4,5,0,0.492000000,0.167842920,0.165353866,0.492000000,-0.598224260,0.808114377,0.492000000,0.810603431,0.931421047 +running,47,4,5,0,0.492000000,-0.023673875,0.326043994,1.492000000,-0.023673875,0.326043994,0.492000000,0.619086636,1.092111175 +running,48,4,4,0,0.509500000,0.228530899,0.407192389,-0.490500000,0.228530899,0.407192389,0.509500000,0.935638979,1.114297872 +running,49,4,4,1,0.509500000,0.007560436,0.628163664,-0.490500000,0.007560436,0.628163664,0.509500000,0.714668516,1.335269147 +running,50,4,5,0,0.509500000,0.184337456,0.804940035,0.509500000,-0.522770624,0.097834552,0.509500000,0.891442938,0.097831955 +running,51,4,5,0,0.509500000,0.007560436,0.628163664,-0.490500000,0.007560436,0.628163664,0.509500000,0.714665919,-0.078944416 +running,52,4,5,0,0.259500000,0.007560436,0.628163664,0.259500000,0.714668516,1.335269147,0.259500000,0.714665919,-0.078944416 +running,53,4,5,0,0.259500000,0.184337456,0.804940035,1.259500000,0.184337456,0.804940035,0.259500000,0.891442938,0.097831955 +star,0,8,6,0,0.750000000,0.687500000,0.312500000,-0.250000000,0.687500000,0.312500000,0.750000000,0.687500000,1.312500000 +star,1,8,6,1,0.750000000,0.312500000,0.312500000,-0.250000000,0.312500000,0.312500000,0.750000000,0.312500000,1.312500000 +star,2,6,6,0,0.750000000,0.312500000,0.687500000,0.750000000,0.312500000,-0.312500000,0.750000000,1.312500000,0.687500000 +star,3,8,6,0,0.750000000,0.312500000,0.312500000,-0.250000000,0.312500000,0.312500000,0.750000000,1.312500000,0.312500000 +star,4,6,6,0,0.250000000,0.312500000,0.312500000,0.250000000,0.312500000,1.312500000,0.250000000,1.312500000,0.312500000 +star,5,8,6,0,0.250000000,0.312500000,0.687500000,1.250000000,0.312500000,0.687500000,0.250000000,1.312500000,0.687500000 +star,6,8,10,0,0.750000000,1.000000000,0.187500000,-0.250000000,1.000000000,0.187500000,0.750000000,1.000000000,1.187500000 +star,7,8,10,1,0.750000000,0.687500000,0.187500000,-0.250000000,0.687500000,0.187500000,0.750000000,0.687500000,1.187500000 +star,8,10,5,0,0.750000000,0.687500000,0.812500000,0.750000000,0.687500000,-0.187500000,0.750000000,1.687500000,0.812500000 +star,9,8,5,0,0.750000000,0.687500000,0.187500000,-0.250000000,0.687500000,0.187500000,0.750000000,1.687500000,0.187500000 +star,10,10,5,0,0.250000000,0.687500000,0.187500000,0.250000000,0.687500000,1.187500000,0.250000000,1.687500000,0.187500000 +star,11,8,5,0,0.250000000,0.687500000,0.812500000,1.250000000,0.687500000,0.812500000,0.250000000,1.687500000,0.812500000 +star,12,2,2,0,0.562500000,0.812500000,0.125000000,-0.437500000,0.812500000,0.125000000,0.562500000,0.812500000,1.125000000 +star,13,2,2,1,0.562500000,0.625000000,0.125000000,-0.437500000,0.625000000,0.125000000,0.562500000,0.625000000,1.125000000 +star,14,2,3,0,0.562500000,0.625000000,0.250000000,0.562500000,0.625000000,-0.750000000,0.562500000,1.625000000,0.250000000 +star,15,2,3,0,0.562500000,0.625000000,0.125000000,-0.437500000,0.625000000,0.125000000,0.562500000,1.625000000,0.125000000 +star,16,2,3,0,0.437500000,0.625000000,0.125000000,0.437500000,0.625000000,1.125000000,0.437500000,1.625000000,0.125000000 +star,17,2,3,0,0.437500000,0.625000000,0.250000000,1.437500000,0.625000000,0.250000000,0.437500000,1.625000000,0.250000000 +star,18,2,2,0,0.561562500,1.249062500,0.438437500,-0.423437500,1.249062500,0.438437500,0.561562500,1.249062500,1.423437500 +star,19,2,2,1,0.561562500,1.000937500,0.438437500,-0.423437500,1.000937500,0.438437500,0.561562500,1.000937500,1.423437500 +star,20,2,4,0,0.561562500,1.000937500,0.561562500,0.561562500,1.000937500,-0.423437500,0.561562500,1.993437500,0.561562500 +star,21,2,4,0,0.561562500,1.000937500,0.438437500,-0.423437500,1.000937500,0.438437500,0.561562500,1.993437500,0.438437500 +star,22,2,4,0,0.438437500,1.000937500,0.438437500,0.438437500,1.000937500,1.423437500,0.438437500,1.993437500,0.438437500 +star,23,2,4,0,0.438437500,1.000937500,0.561562500,1.423437500,1.000937500,0.561562500,0.438437500,1.993437500,0.561562500 +star,24,4,4,0,0.624062500,1.499062500,0.375937500,-0.368437500,1.499062500,0.375937500,0.624062500,1.499062500,1.368437500 +star,25,4,4,1,0.624062500,1.250937500,0.375937500,-0.368437500,1.250937500,0.375937500,0.624062500,1.250937500,1.368437500 +star,26,4,4,0,0.624062500,1.250937500,0.624062500,0.624062500,1.250937500,-0.368437500,0.624062500,2.243437500,0.624062500 +star,27,4,4,0,0.624062500,1.250937500,0.375937500,-0.368437500,1.250937500,0.375937500,0.624062500,2.243437500,0.375937500 +star,28,4,4,0,0.375937500,1.250937500,0.375937500,0.375937500,1.250937500,1.368437500,0.375937500,2.243437500,0.375937500 +star,29,4,4,0,0.375937500,1.250937500,0.624062500,1.368437500,1.250937500,0.624062500,0.375937500,2.243437500,0.624062500 +star,30,3,4,0,0.361782378,0.606202569,0.375000000,0.703838063,-0.333477115,0.375000000,0.361782378,0.606202569,1.375000000 +star,31,3,4,1,0.949082181,0.819987372,0.375000000,1.291137866,-0.119692312,0.375000000,0.949082181,0.819987372,1.375000000 +star,32,4,10,0,0.949082181,0.819987372,0.625000000,0.949082181,0.819987372,-0.375000000,0.009402497,0.477931687,0.625000000 +star,33,3,10,0,0.949082181,0.819987372,0.375000000,1.291137866,-0.119692312,0.375000000,0.009402497,0.477931687,0.375000000 +star,34,4,10,0,1.013217622,0.643797431,0.375000000,1.013217622,0.643797431,1.375000000,0.073537938,0.301741746,0.375000000 +star,35,3,10,0,1.013217622,0.643797431,0.625000000,0.671161937,1.583477115,0.625000000,0.073537938,0.301741746,0.625000000 +star,36,3,4,0,0.574082181,0.430012628,0.375000000,0.916137866,1.369692312,0.375000000,0.574082181,0.430012628,1.375000000 +star,37,3,4,1,-0.013217622,0.643797431,0.375000000,0.328838063,1.583477115,0.375000000,-0.013217622,0.643797431,1.375000000 +star,38,4,10,0,-0.013217622,0.643797431,0.625000000,-0.013217622,0.643797431,-0.375000000,0.926462062,0.301741746,0.625000000 +star,39,3,10,0,-0.013217622,0.643797431,0.375000000,0.328838063,1.583477115,0.375000000,0.926462062,0.301741746,0.375000000 +star,40,4,10,0,0.050917819,0.819987372,0.375000000,0.050917819,0.819987372,1.375000000,0.990597503,0.477931687,0.375000000 +star,41,3,10,0,0.050917819,0.819987372,0.625000000,-0.291137866,-0.119692312,0.625000000,0.990597503,0.477931687,0.625000000 +star,42,4,4,0,0.745925140,0.370778340,0.375625000,-0.220000528,0.111958704,0.375625000,0.745925140,0.370778340,1.375625000 +star,43,4,4,1,0.826806277,0.068926569,0.375625000,-0.139119391,-0.189893067,0.375625000,0.826806277,0.068926569,1.375625000 +star,44,4,5,0,0.826806277,0.068926569,0.625625000,0.826806277,0.068926569,-0.374375000,0.567986640,1.034852237,0.625625000 +star,45,4,5,0,0.826806277,0.068926569,0.375625000,-0.139119391,-0.189893067,0.375625000,0.567986640,1.034852237,0.375625000 +star,46,4,5,0,0.585324860,0.004221660,0.375625000,0.585324860,0.004221660,1.375625000,0.326505223,0.970147328,0.375625000 +star,47,4,5,0,0.585324860,0.004221660,0.625625000,1.551250528,0.263041296,0.625625000,0.326505223,0.970147328,0.625625000 +star,48,4,4,0,0.495556277,0.306073431,0.375000000,-0.470369391,0.564893067,0.375000000,0.495556277,0.306073431,1.375000000 +star,49,4,4,1,0.414675140,0.004221660,0.375000000,-0.551250528,0.263041296,0.375000000,0.414675140,0.004221660,1.375000000 +star,50,4,5,0,0.414675140,0.004221660,0.625000000,0.414675140,0.004221660,-0.375000000,0.673494777,0.970147328,0.625000000 +star,51,4,5,0,0.414675140,0.004221660,0.375000000,-0.551250528,0.263041296,0.375000000,0.673494777,0.970147328,0.375000000 +star,52,4,5,0,0.173193723,0.068926569,0.375000000,0.173193723,0.068926569,1.375000000,0.432013360,1.034852237,0.375000000 +star,53,4,5,0,0.173193723,0.068926569,0.625000000,1.139119391,-0.189893067,0.625000000,0.432013360,1.034852237,0.625000000 diff --git a/DynmapCore/src/main/resources/models_1.txt b/DynmapCore/src/main/resources/models_1.txt index 5292b2438..60a3e523b 100644 --- a/DynmapCore/src/main/resources/models_1.txt +++ b/DynmapCore/src/main/resources/models_1.txt @@ -881,6 +881,7 @@ patchblock:id=tall_seagrass,id=seagrass,patch0=VertX075,patch1=VertX075@90,patch # Brown mushroom # Red mushroom patchblock:id=dandelion,id=poppy,id=blue_orchid,id=allium,id=azure_bluet,id=red_tulip,id=orange_tulip,id=white_tulip,id=pink_tulip,id=oxeye_daisy,id=brown_mushroom,id=red_mushroom,patch0=VertX1Z0ToX0Z1,patch1=VertX1Z0ToX0Z1@90 +[26.1-]patchblock:id=golden_dandelion,patch0=VertX1Z0ToX0Z1,patch1=VertX1Z0ToX0Z1@90 # Sunflower modellist:id=%sunflower,state=half:upper,box=0.800000/0.000000/8.000000/false:15.200000/8.000000/8.000000/0.000000/45.000000/0.000000/8.000000/8.000000/8.000000:n/0/0.000000/8.000000/16.000000/16.000000:s/0/0.000000/8.000000/16.000000/16.000000,box=8.000000/0.000000/0.800000/false:8.000000/8.000000/15.200000/0.000000/45.000000/0.000000/8.000000/8.000000/8.000000:w/0/0.000000/8.000000/16.000000/16.000000:e/0/0.000000/8.000000/16.000000/16.000000,box=9.600000/-1.000000/1.000000/false:9.600000/15.000000/15.000000/0.000000/0.000000/22.500000/8.000000/8.000000/8.000000:w/1/0.000000/0.000000/16.000000/16.000000:e/2/0.000000/0.000000/16.000000/16.000000 @@ -1036,6 +1037,7 @@ patchblock:id=potted_dark_oak_sapling,patch0=FlowerPotTop,patch1=FlowerPotBottom patchblock:id=potted_fern,patch0=FlowerPotTop,patch1=FlowerPotBottom,patch2=FlowerPotSide,patch3=FlowerPotSide@90,patch4=FlowerPotSide@180,patch5=FlowerPotSide@270,patch6=FlowerPotDirt,patch7=FlowerPotFlower,patch8=FlowerPotFlower@90 # Flower pot with dandelion patchblock:id=potted_dandelion,patch0=FlowerPotTop,patch1=FlowerPotBottom,patch2=FlowerPotSide,patch3=FlowerPotSide@90,patch4=FlowerPotSide@180,patch5=FlowerPotSide@270,patch6=FlowerPotDirt,patch7=FlowerPotFlower,patch8=FlowerPotFlower@90 +[26.1-]patchblock:id=potted_golden_dandelion,patch0=FlowerPotTop,patch1=FlowerPotBottom,patch2=FlowerPotSide,patch3=FlowerPotSide@90,patch4=FlowerPotSide@180,patch5=FlowerPotSide@270,patch6=FlowerPotDirt,patch7=FlowerPotFlower,patch8=FlowerPotFlower@90 # Flower pot with poppy patchblock:id=potted_poppy,patch0=FlowerPotTop,patch1=FlowerPotBottom,patch2=FlowerPotSide,patch3=FlowerPotSide@90,patch4=FlowerPotSide@180,patch5=FlowerPotSide@270,patch6=FlowerPotDirt,patch7=FlowerPotFlower,patch8=FlowerPotFlower@90 # Flower pot with blue orchid @@ -1637,7 +1639,7 @@ patchblock:id=bubble_column [1.14-]patchblock:id=campfire,data=24,data=25,data=26,data=27 [1.14-]patchrotate:id=campfire,data=8,roty=90 # Campfire (unlit) (unlit log, lit log, fire) -[1-14-]modellist:id=campfire,data=12,data=13,data=14,data=15,box=1/0/0:5/4/16:n/0/0/4/4/8:e/0/0/1/16/5:s/0/0/4/4/8:w/0/16/0/0/4:u90/0/0/0/16/4:d90/0/0/0/16/4,box=0/3/11:16/7/15:n/0/16/0/0/4:e/0/0/4/4/8:s/0/0/0/16/4:w/0/0/4/4/8:u180/0/0/0/16/4:d/0/0/0/16/4,box=11/0/0:15/4/16:n/0/0/4/4/8:e/0/0/0/16/4:s/0/0/4/4/8:w/0/16/1/0/5:u90/0/0/0/16/4:d90/0/0/0/16/4,box=0/3/1:16/7/5:n/0/0/0/16/4:e/0/0/4/4/8:s/0/16/0/0/4:w/0/0/4/4/8:u180/0/0/0/16/4:d/0/0/0/16/4,box=5/0/0:11/1/16:n/0/0/15/6/16:s/0/10/15/16/16:u90/0/0/8/16/14:d90/0/0/8/16/14 +[1.14-]modellist:id=campfire,data=12,data=13,data=14,data=15,box=1/0/0:5/4/16:n/0/0/4/4/8:e/0/0/1/16/5:s/0/0/4/4/8:w/0/16/0/0/4:u90/0/0/0/16/4:d90/0/0/0/16/4,box=0/3/11:16/7/15:n/0/16/0/0/4:e/0/0/4/4/8:s/0/0/0/16/4:w/0/0/4/4/8:u180/0/0/0/16/4:d/0/0/0/16/4,box=11/0/0:15/4/16:n/0/0/4/4/8:e/0/0/0/16/4:s/0/0/4/4/8:w/0/16/1/0/5:u90/0/0/0/16/4:d90/0/0/0/16/4,box=0/3/1:16/7/5:n/0/0/0/16/4:e/0/0/4/4/8:s/0/16/0/0/4:w/0/0/4/4/8:u180/0/0/0/16/4:d/0/0/0/16/4,box=5/0/0:11/1/16:n/0/0/15/6/16:s/0/10/15/16/16:u90/0/0/8/16/14:d90/0/0/8/16/14 [1.14-]patchblock:id=campfire,data=4,data=5,data=6,data=7 [1.14-]patchrotate:id=campfire,data=12,roty=180 [1.14-]patchblock:id=campfire,data=20,data=21,data=22,data=23 @@ -1893,6 +1895,7 @@ patchblock:id=bubble_column [1.17-]boxblock:id=moss_carpet,ymax=0.0625 # Pointed dripstone [1.17-]patchblock:id=pointed_dripstone,patch0=VertX1Z0ToX0Z1,patch1=VertX1Z0ToX0Z1@90 +[26.2-]patchblock:id=sulfur_spike,patch0=VertX1Z0ToX0Z1,patch1=VertX1Z0ToX0Z1@90 # Candle [1.17-]modellist:id=%candle,state=candles:1/lit:true,box=7.000000/0.000000/7.000000:9.000000/6.000000/9.000000:n/0/0.000000/8.000000/2.000000/14.000000:e/0/0.000000/8.000000/2.000000/14.000000:w/0/0.000000/8.000000/2.000000/14.000000:d/0/0.000000/14.000000/2.000000/16.000000:u/0/0.000000/6.000000/2.000000/8.000000:s/0/0.000000/8.000000/2.000000/14.000000,box=7.500000/6.000000/8.000000:8.500000/7.000000/8.000000/0.000000/45.000000/0.000000/8.000000/6.000000/8.000000:n/0/0.000000/5.000000/1.000000/6.000000:s/0/0.000000/5.000000/1.000000/6.000000,box=7.500000/6.000000/8.000000:8.500000/7.000000/8.000000/0.000000/-45.000000/0.000000/8.000000/6.000000/8.000000:n/0/0.000000/5.000000/1.000000/6.000000:s/0/0.000000/5.000000/1.000000/6.000000 [1.17-]modellist:id=%candle,state=candles:1/lit:false,box=7.000000/0.000000/7.000000:9.000000/6.000000/9.000000:n/0/0.000000/8.000000/2.000000/14.000000:e/0/0.000000/8.000000/2.000000/14.000000:w/0/0.000000/8.000000/2.000000/14.000000:d/0/0.000000/14.000000/2.000000/16.000000:u/0/0.000000/6.000000/2.000000/8.000000:s/0/0.000000/8.000000/2.000000/14.000000,box=7.500000/6.000000/8.000000:8.500000/7.000000/8.000000/0.000000/45.000000/0.000000/8.000000/6.000000/8.000000:n/0/0.000000/5.000000/1.000000/6.000000:s/0/0.000000/5.000000/1.000000/6.000000,box=7.500000/6.000000/8.000000:8.500000/7.000000/8.000000/0.000000/-45.000000/0.000000/8.000000/6.000000/8.000000:n/0/0.000000/5.000000/1.000000/6.000000:s/0/0.000000/5.000000/1.000000/6.000000 @@ -3455,6 +3458,30 @@ modellist:id=%dropper,state=facing:down,box=0.000000/0.000000/0.000000:16.000000 [1.20.3-]modellist:id=%tuff_brick_slab,state=type:top,box=0.000000/8.000000/0.000000:16.000000/16.000000/16.000000:n/0/0.000000/0.000000/16.000000/8.000000:w/0/0.000000/0.000000/16.000000/8.000000:e/0/0.000000/0.000000/16.000000/8.000000:s/0/0.000000/0.000000/16.000000/8.000000:u/0/0.000000/0.000000/16.000000/16.000000:d/0/0.000000/0.000000/16.000000/16.000000 [1.20.3-]modellist:id=%tuff_brick_slab,state=type:bottom,box=0.000000/0.000000/0.000000:16.000000/8.000000/16.000000:n/0/0.000000/8.000000/16.000000/16.000000:w/0/0.000000/8.000000/16.000000/16.000000:e/0/0.000000/8.000000/16.000000/16.000000:s/0/0.000000/8.000000/16.000000/16.000000:u/0/0.000000/0.000000/16.000000/16.000000:d/0/0.000000/0.000000/16.000000/16.000000 [1.20.3-]customblock:id=%tuff_brick_wall,class=org.dynmap.hdmap.renderer.FenceWallBlockStateRenderer,type=tallwall +[26.2-]customblock:id=%sulfur_stairs,class=org.dynmap.hdmap.renderer.StairStateRenderer +[26.2-]modellist:id=%sulfur_slab,state=type:top,box=0.000000/8.000000/0.000000:16.000000/16.000000/16.000000:n/0/0.000000/0.000000/16.000000/8.000000:w/0/0.000000/0.000000/16.000000/8.000000:e/0/0.000000/0.000000/16.000000/8.000000:s/0/0.000000/0.000000/16.000000/8.000000:u/0/0.000000/0.000000/16.000000/16.000000:d/0/0.000000/0.000000/16.000000/16.000000 +[26.2-]modellist:id=%sulfur_slab,state=type:bottom,box=0.000000/0.000000/0.000000:16.000000/8.000000/16.000000:n/0/0.000000/8.000000/16.000000/16.000000:w/0/0.000000/8.000000/16.000000/16.000000:e/0/0.000000/8.000000/16.000000/16.000000:s/0/0.000000/8.000000/16.000000/16.000000:u/0/0.000000/0.000000/16.000000/16.000000:d/0/0.000000/0.000000/16.000000/16.000000 +[26.2-]customblock:id=%sulfur_wall,class=org.dynmap.hdmap.renderer.FenceWallBlockStateRenderer,type=tallwall +[26.2-]customblock:id=%sulfur_brick_stairs,class=org.dynmap.hdmap.renderer.StairStateRenderer +[26.2-]modellist:id=%sulfur_brick_slab,state=type:top,box=0.000000/8.000000/0.000000:16.000000/16.000000/16.000000:n/0/0.000000/0.000000/16.000000/8.000000:w/0/0.000000/0.000000/16.000000/8.000000:e/0/0.000000/0.000000/16.000000/8.000000:s/0/0.000000/0.000000/16.000000/8.000000:u/0/0.000000/0.000000/16.000000/16.000000:d/0/0.000000/0.000000/16.000000/16.000000 +[26.2-]modellist:id=%sulfur_brick_slab,state=type:bottom,box=0.000000/0.000000/0.000000:16.000000/8.000000/16.000000:n/0/0.000000/8.000000/16.000000/16.000000:w/0/0.000000/8.000000/16.000000/16.000000:e/0/0.000000/8.000000/16.000000/16.000000:s/0/0.000000/8.000000/16.000000/16.000000:u/0/0.000000/0.000000/16.000000/16.000000:d/0/0.000000/0.000000/16.000000/16.000000 +[26.2-]customblock:id=%sulfur_brick_wall,class=org.dynmap.hdmap.renderer.FenceWallBlockStateRenderer,type=tallwall +[26.2-]customblock:id=%polished_sulfur_stairs,class=org.dynmap.hdmap.renderer.StairStateRenderer +[26.2-]modellist:id=%polished_sulfur_slab,state=type:top,box=0.000000/8.000000/0.000000:16.000000/16.000000/16.000000:n/0/0.000000/0.000000/16.000000/8.000000:w/0/0.000000/0.000000/16.000000/8.000000:e/0/0.000000/0.000000/16.000000/8.000000:s/0/0.000000/0.000000/16.000000/8.000000:u/0/0.000000/0.000000/16.000000/16.000000:d/0/0.000000/0.000000/16.000000/16.000000 +[26.2-]modellist:id=%polished_sulfur_slab,state=type:bottom,box=0.000000/0.000000/0.000000:16.000000/8.000000/16.000000:n/0/0.000000/8.000000/16.000000/16.000000:w/0/0.000000/8.000000/16.000000/16.000000:e/0/0.000000/8.000000/16.000000/16.000000:s/0/0.000000/8.000000/16.000000/16.000000:u/0/0.000000/0.000000/16.000000/16.000000:d/0/0.000000/0.000000/16.000000/16.000000 +[26.2-]customblock:id=%polished_sulfur_wall,class=org.dynmap.hdmap.renderer.FenceWallBlockStateRenderer,type=tallwall +[26.2-]customblock:id=%cinnabar_stairs,class=org.dynmap.hdmap.renderer.StairStateRenderer +[26.2-]modellist:id=%cinnabar_slab,state=type:top,box=0.000000/8.000000/0.000000:16.000000/16.000000/16.000000:n/0/0.000000/0.000000/16.000000/8.000000:w/0/0.000000/0.000000/16.000000/8.000000:e/0/0.000000/0.000000/16.000000/8.000000:s/0/0.000000/0.000000/16.000000/8.000000:u/0/0.000000/0.000000/16.000000/16.000000:d/0/0.000000/0.000000/16.000000/16.000000 +[26.2-]modellist:id=%cinnabar_slab,state=type:bottom,box=0.000000/0.000000/0.000000:16.000000/8.000000/16.000000:n/0/0.000000/8.000000/16.000000/16.000000:w/0/0.000000/8.000000/16.000000/16.000000:e/0/0.000000/8.000000/16.000000/16.000000:s/0/0.000000/8.000000/16.000000/16.000000:u/0/0.000000/0.000000/16.000000/16.000000:d/0/0.000000/0.000000/16.000000/16.000000 +[26.2-]customblock:id=%cinnabar_wall,class=org.dynmap.hdmap.renderer.FenceWallBlockStateRenderer,type=tallwall +[26.2-]customblock:id=%cinnabar_brick_stairs,class=org.dynmap.hdmap.renderer.StairStateRenderer +[26.2-]modellist:id=%cinnabar_brick_slab,state=type:top,box=0.000000/8.000000/0.000000:16.000000/16.000000/16.000000:n/0/0.000000/0.000000/16.000000/8.000000:w/0/0.000000/0.000000/16.000000/8.000000:e/0/0.000000/0.000000/16.000000/8.000000:s/0/0.000000/0.000000/16.000000/8.000000:u/0/0.000000/0.000000/16.000000/16.000000:d/0/0.000000/0.000000/16.000000/16.000000 +[26.2-]modellist:id=%cinnabar_brick_slab,state=type:bottom,box=0.000000/0.000000/0.000000:16.000000/8.000000/16.000000:n/0/0.000000/8.000000/16.000000/16.000000:w/0/0.000000/8.000000/16.000000/16.000000:e/0/0.000000/8.000000/16.000000/16.000000:s/0/0.000000/8.000000/16.000000/16.000000:u/0/0.000000/0.000000/16.000000/16.000000:d/0/0.000000/0.000000/16.000000/16.000000 +[26.2-]customblock:id=%cinnabar_brick_wall,class=org.dynmap.hdmap.renderer.FenceWallBlockStateRenderer,type=tallwall +[26.2-]customblock:id=%polished_cinnabar_stairs,class=org.dynmap.hdmap.renderer.StairStateRenderer +[26.2-]modellist:id=%polished_cinnabar_slab,state=type:top,box=0.000000/8.000000/0.000000:16.000000/16.000000/16.000000:n/0/0.000000/0.000000/16.000000/8.000000:w/0/0.000000/0.000000/16.000000/8.000000:e/0/0.000000/0.000000/16.000000/8.000000:s/0/0.000000/0.000000/16.000000/8.000000:u/0/0.000000/0.000000/16.000000/16.000000:d/0/0.000000/0.000000/16.000000/16.000000 +[26.2-]modellist:id=%polished_cinnabar_slab,state=type:bottom,box=0.000000/0.000000/0.000000:16.000000/8.000000/16.000000:n/0/0.000000/8.000000/16.000000/16.000000:w/0/0.000000/8.000000/16.000000/16.000000:e/0/0.000000/8.000000/16.000000/16.000000:s/0/0.000000/8.000000/16.000000/16.000000:u/0/0.000000/0.000000/16.000000/16.000000:d/0/0.000000/0.000000/16.000000/16.000000 +[26.2-]customblock:id=%polished_cinnabar_wall,class=org.dynmap.hdmap.renderer.FenceWallBlockStateRenderer,type=tallwall [1.20.3-]customblock:id=%copper_door,id=%exposed_copper_door,id=%oxidized_copper_door,id=%weathered_copper_door,class=org.dynmap.hdmap.renderer.DoorStateRenderer [1.20.3-]customblock:id=%waxed_copper_door,id=%waxed_exposed_copper_door,id=%waxed_oxidized_copper_door,id=%waxed_weathered_copper_door,class=org.dynmap.hdmap.renderer.DoorStateRenderer @@ -4730,3 +4757,5 @@ modellist:id=%dropper,state=facing:down,box=0.000000/0.000000/0.000000:16.000000 # Copper chests [1.21.9-]customblock:id=copper_chest,id=exposed_copper_chest,id=weathered_copper_chest,id=oxidized_copper_chest,id=waxed_copper_chest,id=waxed_exposed_copper_chest,id=waxed_weathered_copper_chest,id=waxed_oxidized_copper_chest,class=org.dynmap.hdmap.renderer.ChestStateRenderer,doublechest=true + +[26.2-]customblock:id=%copper_golem_statue,id=%exposed_copper_golem_statue,id=%weathered_copper_golem_statue,id=%oxidized_copper_golem_statue,id=%waxed_copper_golem_statue,id=%waxed_exposed_copper_golem_statue,id=%waxed_weathered_copper_golem_statue,id=%waxed_oxidized_copper_golem_statue,class=org.dynmap.hdmap.renderer.CopperGolemStatueRenderer diff --git a/DynmapCore/src/main/resources/texture_1.txt b/DynmapCore/src/main/resources/texture_1.txt index 730baa859..cad51165d 100644 --- a/DynmapCore/src/main/resources/texture_1.txt +++ b/DynmapCore/src/main/resources/texture_1.txt @@ -4547,6 +4547,26 @@ block:id=%melon_stem,patch0=0:melon_stem,blockcolor=foliagebiome,transparency=TR [1.20.3-]texture:id=exposed_copper_grate,filename=assets/minecraft/textures/block/exposed_copper_grate.png,xcount=1,ycount=1 [1.20.3-]texture:id=weathered_copper_grate,filename=assets/minecraft/textures/block/weathered_copper_grate.png,xcount=1,ycount=1 [1.20.3-]texture:id=oxidized_copper_grate,filename=assets/minecraft/textures/block/oxidized_copper_grate.png,xcount=1,ycount=1 +[26.2-]texture:id=sulfur,filename=assets/minecraft/textures/block/sulfur.png,xcount=1,ycount=1 +[26.2-]texture:id=sulfur_bricks,filename=assets/minecraft/textures/block/sulfur_bricks.png,xcount=1,ycount=1 +[26.2-]texture:id=chiseled_sulfur,filename=assets/minecraft/textures/block/chiseled_sulfur.png,xcount=1,ycount=1 +[26.2-]texture:id=polished_sulfur,filename=assets/minecraft/textures/block/polished_sulfur.png,xcount=1,ycount=1 +[26.2-]texture:id=potent_sulfur,filename=assets/minecraft/textures/block/potent_sulfur.png,xcount=1,ycount=1 +[26.2-]texture:id=cinnabar,filename=assets/minecraft/textures/block/cinnabar.png,xcount=1,ycount=1 +[26.2-]texture:id=cinnabar_bricks,filename=assets/minecraft/textures/block/cinnabar_bricks.png,xcount=1,ycount=1 +[26.2-]texture:id=chiseled_cinnabar,filename=assets/minecraft/textures/block/chiseled_cinnabar.png,xcount=1,ycount=1 +[26.2-]texture:id=polished_cinnabar,filename=assets/minecraft/textures/block/polished_cinnabar.png,xcount=1,ycount=1 +[26.2-]texture:id=golden_dandelion,filename=assets/minecraft/textures/block/golden_dandelion.png,xcount=1,ycount=1 +[26.2-]texture:id=sulfur_spike_up_base,filename=assets/minecraft/textures/block/sulfur_spike_up_base.png,xcount=1,ycount=1 +[26.2-]texture:id=sulfur_spike_down_base,filename=assets/minecraft/textures/block/sulfur_spike_down_base.png,xcount=1,ycount=1 +[26.2-]texture:id=sulfur_spike_up_frustum,filename=assets/minecraft/textures/block/sulfur_spike_up_frustum.png,xcount=1,ycount=1 +[26.2-]texture:id=sulfur_spike_down_frustum,filename=assets/minecraft/textures/block/sulfur_spike_down_frustum.png,xcount=1,ycount=1 +[26.2-]texture:id=sulfur_spike_up_middle,filename=assets/minecraft/textures/block/sulfur_spike_up_middle.png,xcount=1,ycount=1 +[26.2-]texture:id=sulfur_spike_down_middle,filename=assets/minecraft/textures/block/sulfur_spike_down_middle.png,xcount=1,ycount=1 +[26.2-]texture:id=sulfur_spike_up_tip,filename=assets/minecraft/textures/block/sulfur_spike_up_tip.png,xcount=1,ycount=1 +[26.2-]texture:id=sulfur_spike_down_tip,filename=assets/minecraft/textures/block/sulfur_spike_down_tip.png,xcount=1,ycount=1 +[26.2-]texture:id=sulfur_spike_up_tip_merge,filename=assets/minecraft/textures/block/sulfur_spike_up_tip_merge.png,xcount=1,ycount=1 +[26.2-]texture:id=sulfur_spike_down_tip_merge,filename=assets/minecraft/textures/block/sulfur_spike_down_tip_merge.png,xcount=1,ycount=1 [1.20.3-]block:id=%suspicious_gravel,state=dusted:0,patch0=0:suspicious_gravel_0,patch1=0:suspicious_gravel_0,patch2=0:suspicious_gravel_0,patch3=0:suspicious_gravel_0,patch4=0:suspicious_gravel_0,patch5=0:suspicious_gravel_0,stdrot=true [1.20.3-]block:id=%suspicious_gravel,state=dusted:1,patch0=0:suspicious_gravel_1,patch1=0:suspicious_gravel_1,patch2=0:suspicious_gravel_1,patch3=0:suspicious_gravel_1,patch4=0:suspicious_gravel_1,patch5=0:suspicious_gravel_1,stdrot=true [1.20.3-]block:id=%suspicious_gravel,state=dusted:2,patch0=0:suspicious_gravel_2,patch1=0:suspicious_gravel_2,patch2=0:suspicious_gravel_2,patch3=0:suspicious_gravel_2,patch4=0:suspicious_gravel_2,patch5=0:suspicious_gravel_2,stdrot=true @@ -4571,6 +4591,57 @@ block:id=%melon_stem,patch0=0:melon_stem,blockcolor=foliagebiome,transparency=TR [1.20.3-]block:id=%tuff_brick_stairs,patch0-2=0:tuff_bricks,transparency=SEMITRANSPARENT,stdrot=true [1.20.3-]block:id=%tuff_brick_wall,patch0-2=0:tuff_bricks,transparency=SEMITRANSPARENT,stdrot=true [1.20.3-]block:id=%chiseled_tuff_bricks,patch0-5=0:chiseled_tuff_bricks,stdrot=true +[26.2-]block:id=%sulfur,patch0-5=0:sulfur,stdrot=true +[26.2-]block:id=%sulfur_slab,state=type:top,patch0=0:sulfur,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%sulfur_slab,state=type:bottom,patch0=0:sulfur,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%sulfur_slab,state=type:double,patch0-5=0:sulfur,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%sulfur_stairs,patch0-2=0:sulfur,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%sulfur_wall,patch0-2=0:sulfur,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%sulfur_bricks,patch0-5=0:sulfur_bricks,stdrot=true +[26.2-]block:id=%sulfur_brick_slab,state=type:top,patch0=0:sulfur_bricks,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%sulfur_brick_slab,state=type:bottom,patch0=0:sulfur_bricks,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%sulfur_brick_slab,state=type:double,patch0-5=0:sulfur_bricks,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%sulfur_brick_stairs,patch0-2=0:sulfur_bricks,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%sulfur_brick_wall,patch0-2=0:sulfur_bricks,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%chiseled_sulfur,patch0-5=0:chiseled_sulfur,stdrot=true +[26.2-]block:id=%polished_sulfur,patch0-5=0:polished_sulfur,stdrot=true +[26.2-]block:id=%polished_sulfur_slab,state=type:top,patch0=0:polished_sulfur,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%polished_sulfur_slab,state=type:bottom,patch0=0:polished_sulfur,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%polished_sulfur_slab,state=type:double,patch0-5=0:polished_sulfur,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%polished_sulfur_stairs,patch0-2=0:polished_sulfur,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%polished_sulfur_wall,patch0-2=0:polished_sulfur,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%potent_sulfur,patch0-5=0:potent_sulfur,stdrot=true +[26.2-]block:id=%cinnabar,patch0-5=0:cinnabar,stdrot=true +[26.2-]block:id=%cinnabar_slab,state=type:top,patch0=0:cinnabar,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%cinnabar_slab,state=type:bottom,patch0=0:cinnabar,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%cinnabar_slab,state=type:double,patch0-5=0:cinnabar,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%cinnabar_stairs,patch0-2=0:cinnabar,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%cinnabar_wall,patch0-2=0:cinnabar,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%cinnabar_bricks,patch0-5=0:cinnabar_bricks,stdrot=true +[26.2-]block:id=%cinnabar_brick_slab,state=type:top,patch0=0:cinnabar_bricks,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%cinnabar_brick_slab,state=type:bottom,patch0=0:cinnabar_bricks,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%cinnabar_brick_slab,state=type:double,patch0-5=0:cinnabar_bricks,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%cinnabar_brick_stairs,patch0-2=0:cinnabar_bricks,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%cinnabar_brick_wall,patch0-2=0:cinnabar_bricks,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%chiseled_cinnabar,patch0-5=0:chiseled_cinnabar,stdrot=true +[26.2-]block:id=%polished_cinnabar,patch0-5=0:polished_cinnabar,stdrot=true +[26.2-]block:id=%polished_cinnabar_slab,state=type:top,patch0=0:polished_cinnabar,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%polished_cinnabar_slab,state=type:bottom,patch0=0:polished_cinnabar,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%polished_cinnabar_slab,state=type:double,patch0-5=0:polished_cinnabar,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%polished_cinnabar_stairs,patch0-2=0:polished_cinnabar,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=%polished_cinnabar_wall,patch0-2=0:polished_cinnabar,transparency=SEMITRANSPARENT,stdrot=true +[26.2-]block:id=golden_dandelion,patch0-1=0:golden_dandelion,transparency=TRANSPARENT +[26.2-]block:id=potted_golden_dandelion,patch0-5=0:flower_pot,patch6=0:dirt,patch7-8=0:golden_dandelion,transparency=TRANSPARENT +[26.2-]block:id=%sulfur_spike,state=thickness:base/vertical_direction:up,patch0-1=0:sulfur_spike_up_base,transparency=TRANSPARENT +[26.2-]block:id=%sulfur_spike,state=thickness:base/vertical_direction:down,patch0-1=0:sulfur_spike_down_base,transparency=TRANSPARENT +[26.2-]block:id=%sulfur_spike,state=thickness:frustum/vertical_direction:up,patch0-1=0:sulfur_spike_up_frustum,transparency=TRANSPARENT +[26.2-]block:id=%sulfur_spike,state=thickness:frustum/vertical_direction:down,patch0-1=0:sulfur_spike_down_frustum,transparency=TRANSPARENT +[26.2-]block:id=%sulfur_spike,state=thickness:middle/vertical_direction:up,patch0-1=0:sulfur_spike_up_middle,transparency=TRANSPARENT +[26.2-]block:id=%sulfur_spike,state=thickness:middle/vertical_direction:down,patch0-1=0:sulfur_spike_down_middle,transparency=TRANSPARENT +[26.2-]block:id=%sulfur_spike,state=thickness:tip/vertical_direction:up,patch0-1=0:sulfur_spike_up_tip,transparency=TRANSPARENT +[26.2-]block:id=%sulfur_spike,state=thickness:tip/vertical_direction:down,patch0-1=0:sulfur_spike_down_tip,transparency=TRANSPARENT +[26.2-]block:id=%sulfur_spike,state=thickness:tip_merge/vertical_direction:up,patch0-1=0:sulfur_spike_up_tip_merge,transparency=TRANSPARENT +[26.2-]block:id=%sulfur_spike,state=thickness:tip_merge/vertical_direction:down,patch0-1=0:sulfur_spike_down_tip_merge,transparency=TRANSPARENT [1.20.3-]block:id=%oxidized_chiseled_copper,patch0-5=0:oxidized_chiseled_copper,stdrot=true [1.20.3-]block:id=%weathered_chiseled_copper,patch0-5=0:weathered_chiseled_copper,stdrot=true [1.20.3-]block:id=%exposed_chiseled_copper,patch0-5=0:exposed_chiseled_copper,stdrot=true @@ -4984,12 +5055,25 @@ block:id=%melon_stem,patch0=0:melon_stem,blockcolor=foliagebiome,transparency=TR [1.21.4-]texture:id=creaking_heart_top,filename=assets/minecraft/textures/block/creaking_heart_top.png,xcount=1,ycount=1 [1.21.4-]texture:id=creaking_heart_active,filename=assets/minecraft/textures/block/creaking_heart_active.png,xcount=1,ycount=1 [1.21.4-]texture:id=creaking_heart,filename=assets/minecraft/textures/block/creaking_heart.png,xcount=1,ycount=1 +[26.2-]texture:id=creaking_heart_top_awake,filename=assets/minecraft/textures/block/creaking_heart_top_awake.png,xcount=1,ycount=1 +[26.2-]texture:id=creaking_heart_awake,filename=assets/minecraft/textures/block/creaking_heart_awake.png,xcount=1,ycount=1 +[26.2-]texture:id=creaking_heart_top_dormant,filename=assets/minecraft/textures/block/creaking_heart_top_dormant.png,xcount=1,ycount=1 +[26.2-]texture:id=creaking_heart_dormant,filename=assets/minecraft/textures/block/creaking_heart_dormant.png,xcount=1,ycount=1 [1.21.4-]block:id=%creaking_heart,state=axis:x/active:false,patch0=0:creaking_heart_top,patch1=6000:creaking_heart,patch2=6000:creaking_heart,patch3=0:creaking_heart_top,patch4=6000:creaking_heart,patch5=6000:creaking_heart,stdrot=true [1.21.4-]block:id=%creaking_heart,state=axis:y/active:false,patch0=0:creaking_heart,patch1=0:creaking_heart_top,patch2=0:creaking_heart,patch3=0:creaking_heart,patch4=0:creaking_heart_top,patch5=0:creaking_heart,stdrot=true [1.21.4-]block:id=%creaking_heart,state=axis:z/active:false,patch0=6000:creaking_heart,patch1=0:creaking_heart,patch2=0:creaking_heart_top,patch3=6000:creaking_heart,patch4=0:creaking_heart,patch5=0:creaking_heart_top,stdrot=true [1.21.4-]block:id=%creaking_heart,state=axis:x/active:true,patch0=0:creaking_heart_top_active,patch1=6000:creaking_heart_active,patch2=6000:creaking_heart_active,patch3=0:creaking_heart_top_active,patch4=6000:creaking_heart_active,patch5=6000:creaking_heart_active,stdrot=true [1.21.4-]block:id=%creaking_heart,state=axis:y/active:true,patch0=0:creaking_heart_active,patch1=0:creaking_heart_top_active,patch2=0:creaking_heart_active,patch3=0:creaking_heart_active,patch4=0:creaking_heart_top_active,patch5=0:creaking_heart_active,stdrot=true [1.21.4-]block:id=%creaking_heart,state=axis:z/active:true,patch0=6000:creaking_heart_active,patch1=0:creaking_heart_active,patch2=0:creaking_heart_top_active,patch3=6000:creaking_heart_active,patch4=0:creaking_heart_active,patch5=0:creaking_heart_top_active,stdrot=true +[26.2-]block:id=%creaking_heart,state=axis:x/creaking_heart_state:uprooted,patch0=0:creaking_heart_top,patch1=6000:creaking_heart,patch2=6000:creaking_heart,patch3=0:creaking_heart_top,patch4=6000:creaking_heart,patch5=6000:creaking_heart,stdrot=true +[26.2-]block:id=%creaking_heart,state=axis:y/creaking_heart_state:uprooted,patch0=0:creaking_heart,patch1=0:creaking_heart_top,patch2=0:creaking_heart,patch3=0:creaking_heart,patch4=0:creaking_heart_top,patch5=0:creaking_heart,stdrot=true +[26.2-]block:id=%creaking_heart,state=axis:z/creaking_heart_state:uprooted,patch0=6000:creaking_heart,patch1=0:creaking_heart,patch2=0:creaking_heart_top,patch3=6000:creaking_heart,patch4=0:creaking_heart,patch5=0:creaking_heart_top,stdrot=true +[26.2-]block:id=%creaking_heart,state=axis:x/creaking_heart_state:awake,patch0=0:creaking_heart_top_awake,patch1=6000:creaking_heart_awake,patch2=6000:creaking_heart_awake,patch3=0:creaking_heart_top_awake,patch4=6000:creaking_heart_awake,patch5=6000:creaking_heart_awake,stdrot=true +[26.2-]block:id=%creaking_heart,state=axis:y/creaking_heart_state:awake,patch0=0:creaking_heart_awake,patch1=0:creaking_heart_top_awake,patch2=0:creaking_heart_awake,patch3=0:creaking_heart_awake,patch4=0:creaking_heart_top_awake,patch5=0:creaking_heart_awake,stdrot=true +[26.2-]block:id=%creaking_heart,state=axis:z/creaking_heart_state:awake,patch0=6000:creaking_heart_awake,patch1=0:creaking_heart_awake,patch2=0:creaking_heart_top_awake,patch3=6000:creaking_heart_awake,patch4=0:creaking_heart_awake,patch5=0:creaking_heart_top_awake,stdrot=true +[26.2-]block:id=%creaking_heart,state=axis:x/creaking_heart_state:dormant,patch0=0:creaking_heart_top_dormant,patch1=6000:creaking_heart_dormant,patch2=6000:creaking_heart_dormant,patch3=0:creaking_heart_top_dormant,patch4=6000:creaking_heart_dormant,patch5=6000:creaking_heart_dormant,stdrot=true +[26.2-]block:id=%creaking_heart,state=axis:y/creaking_heart_state:dormant,patch0=0:creaking_heart_dormant,patch1=0:creaking_heart_top_dormant,patch2=0:creaking_heart_dormant,patch3=0:creaking_heart_dormant,patch4=0:creaking_heart_top_dormant,patch5=0:creaking_heart_dormant,stdrot=true +[26.2-]block:id=%creaking_heart,state=axis:z/creaking_heart_state:dormant,patch0=6000:creaking_heart_dormant,patch1=0:creaking_heart_dormant,patch2=0:creaking_heart_top_dormant,patch3=6000:creaking_heart_dormant,patch4=0:creaking_heart_dormant,patch5=0:creaking_heart_top_dormant,stdrot=true #All the resin stuff [1.21.4-]texture:id=resin_bricks,filename=assets/minecraft/textures/block/resin_bricks.png,xcount=1,ycount=1 [1.21.4-]texture:id=chiseled_resin_bricks,filename=assets/minecraft/textures/block/chiseled_resin_bricks.png,xcount=1,ycount=1 @@ -6096,4 +6180,12 @@ block:id=%melon_stem,patch0=0:melon_stem,blockcolor=foliagebiome,transparency=TR [1.21.9-]texturefile:id=oxidized_copper_chest,filename=assets/minecraft/textures/entity/chest/copper_oxidized.png,format=CHEST [1.21.9-]texturefile:id=bigooxidizedcopperchest,filename=assets/minecraft/textures/entity/chest/copper_oxidized_double.png,format=BIGCHEST -[1.21.9-]block:id=oxidized_copper_chest,id=waxed_oxidized_copper_chest,data=*,patch0=0:oxidized_copper_chest,patch1=1:oxidized_copper_chest,patch2=2:oxidized_copper_chest,patch3=3:oxidized_copper_chest,patch4=4:oxidized_copper_chest,patch5=5:oxidized_copper_chest,patch6=0:bigooxidizedcopperchest,patch7=1:bigooxidizedcopperchest,patch8=2:bigooxidizedcopperchest,patch9=3:bigooxidizedcopperchest,patch10=4:bigooxidizedcopperchest,patch11=5:bigooxidizedcopperchest,patch12=6:bigooxidizedcopperchest,patch13=7:bigooxidizedcopperchest,patch14=8:bigooxidizedcopperchest,patch15=9:bigooxidizedcopperchest \ No newline at end of file +[1.21.9-]block:id=oxidized_copper_chest,id=waxed_oxidized_copper_chest,data=*,patch0=0:oxidized_copper_chest,patch1=1:oxidized_copper_chest,patch2=2:oxidized_copper_chest,patch3=3:oxidized_copper_chest,patch4=4:oxidized_copper_chest,patch5=5:oxidized_copper_chest,patch6=0:bigooxidizedcopperchest,patch7=1:bigooxidizedcopperchest,patch8=2:bigooxidizedcopperchest,patch9=3:bigooxidizedcopperchest,patch10=4:bigooxidizedcopperchest,patch11=5:bigooxidizedcopperchest,patch12=6:bigooxidizedcopperchest,patch13=7:bigooxidizedcopperchest,patch14=8:bigooxidizedcopperchest,patch15=9:bigooxidizedcopperchest +[26.2-]texturefile:id=copper_golem,filename=assets/minecraft/textures/entity/copper_golem/copper_golem.png,format=CUSTOM,xcount=4,ycount=4,tile0=6:15/8:6/0:10,tile1=14:15/8:6/0:10,tile2=0:21/6:6/0:10,tile3=6:21/8:6/0:10,tile4=14:21/6:6/0:10,tile5=20:21/8:6/0:10,tile6=10:0/8:10/0:6,tile7=18:0/8:10/0:6,tile8=0:10/10:5/0:11,tile9=10:10/8:5/0:11,tile10=18:10/10:5/0:11,tile11=28:10/8:5/0:11,tile12=58:0/2:2/0:14,tile13=60:0/2:2/0:14,tile14=56:2/2:3/0:13,tile15=58:2/2:3/0:13,tile16=60:2/2:3/0:13,tile17=62:2/2:3/0:13,tile18=39:8/2:2/0:14,tile19=41:8/2:2/0:14,tile20=37:10/2:4/0:12,tile21=39:10/2:4/0:12,tile22=41:10/2:4/0:12,tile23=43:10/2:4/0:12,tile24=41:0/4:4/0:12,tile25=45:0/4:4/0:12,tile26=37:4/4:4/0:12,tile27=41:4/4:4/0:12,tile28=45:4/4:4/0:12,tile29=49:4/4:4/0:12,tile30=40:16/3:4/0:12,tile31=43:16/3:4/0:12,tile32=36:20/4:10/0:6,tile33=40:20/3:10/0:6,tile34=43:20/4:10/0:6,tile35=47:20/3:10/0:6,tile36=54:16/3:4/0:12,tile37=57:16/3:4/0:12,tile38=50:20/4:10/0:6,tile39=54:20/3:10/0:6,tile40=57:20/4:10/0:6,tile41=61:20/3:10/0:6,tile42=4:27/4:4/0:12,tile43=8:27/4:4/0:12,tile44=0:31/4:5/0:11,tile45=4:31/4:5/0:11,tile46=8:31/4:5/0:11,tile47=12:31/4:5/0:11,tile48=20:27/4:4/0:12,tile49=24:27/4:4/0:12,tile50=16:31/4:5/0:11,tile51=20:31/4:5/0:11,tile52=24:31/4:5/0:11,tile53=28:31/4:5/0:11,tile54=9:19/6:6/0:10,tile55=15:19/6:6/0:10,tile56=3:25/6:1/0:15,tile57=9:25/6:1/0:15,tile58=15:25/6:1/0:15,tile59=21:25/6:1/0:15,tile60=6:18/8:3/0:13,tile61=14:18/8:3/0:13,tile62=3:21/3:6/0:10,tile63=14:21/3:6/0:10,tile64=17:21/8:6/0:10 +[26.2-]block:id=%copper_golem_statue,id=%waxed_copper_golem_statue,transparency=TRANSPARENT,stdrot=true,patch0=0:copper_golem,patch1=1:copper_golem,patch2=2:copper_golem,patch3=3:copper_golem,patch4=4:copper_golem,patch5=5:copper_golem,patch6=6:copper_golem,patch7=7:copper_golem,patch8=8:copper_golem,patch9=9:copper_golem,patch10=10:copper_golem,patch11=11:copper_golem,patch12=12:copper_golem,patch13=13:copper_golem,patch14=14:copper_golem,patch15=15:copper_golem,patch16=16:copper_golem,patch17=17:copper_golem,patch18=18:copper_golem,patch19=19:copper_golem,patch20=20:copper_golem,patch21=21:copper_golem,patch22=22:copper_golem,patch23=23:copper_golem,patch24=24:copper_golem,patch25=25:copper_golem,patch26=26:copper_golem,patch27=27:copper_golem,patch28=28:copper_golem,patch29=29:copper_golem,patch30=30:copper_golem,patch31=31:copper_golem,patch32=32:copper_golem,patch33=33:copper_golem,patch34=34:copper_golem,patch35=35:copper_golem,patch36=36:copper_golem,patch37=37:copper_golem,patch38=38:copper_golem,patch39=39:copper_golem,patch40=40:copper_golem,patch41=41:copper_golem,patch42=42:copper_golem,patch43=43:copper_golem,patch44=44:copper_golem,patch45=45:copper_golem,patch46=46:copper_golem,patch47=47:copper_golem,patch48=48:copper_golem,patch49=49:copper_golem,patch50=50:copper_golem,patch51=51:copper_golem,patch52=52:copper_golem,patch53=53:copper_golem,patch54=54:copper_golem,patch55=55:copper_golem,patch56=56:copper_golem,patch57=57:copper_golem,patch58=58:copper_golem,patch59=59:copper_golem,patch60=60:copper_golem,patch61=61:copper_golem,patch62=62:copper_golem,patch63=63:copper_golem,patch64=64:copper_golem +[26.2-]texturefile:id=copper_golem_exposed,filename=assets/minecraft/textures/entity/copper_golem/copper_golem_exposed.png,format=CUSTOM,xcount=4,ycount=4,tile0=6:15/8:6/0:10,tile1=14:15/8:6/0:10,tile2=0:21/6:6/0:10,tile3=6:21/8:6/0:10,tile4=14:21/6:6/0:10,tile5=20:21/8:6/0:10,tile6=10:0/8:10/0:6,tile7=18:0/8:10/0:6,tile8=0:10/10:5/0:11,tile9=10:10/8:5/0:11,tile10=18:10/10:5/0:11,tile11=28:10/8:5/0:11,tile12=58:0/2:2/0:14,tile13=60:0/2:2/0:14,tile14=56:2/2:3/0:13,tile15=58:2/2:3/0:13,tile16=60:2/2:3/0:13,tile17=62:2/2:3/0:13,tile18=39:8/2:2/0:14,tile19=41:8/2:2/0:14,tile20=37:10/2:4/0:12,tile21=39:10/2:4/0:12,tile22=41:10/2:4/0:12,tile23=43:10/2:4/0:12,tile24=41:0/4:4/0:12,tile25=45:0/4:4/0:12,tile26=37:4/4:4/0:12,tile27=41:4/4:4/0:12,tile28=45:4/4:4/0:12,tile29=49:4/4:4/0:12,tile30=40:16/3:4/0:12,tile31=43:16/3:4/0:12,tile32=36:20/4:10/0:6,tile33=40:20/3:10/0:6,tile34=43:20/4:10/0:6,tile35=47:20/3:10/0:6,tile36=54:16/3:4/0:12,tile37=57:16/3:4/0:12,tile38=50:20/4:10/0:6,tile39=54:20/3:10/0:6,tile40=57:20/4:10/0:6,tile41=61:20/3:10/0:6,tile42=4:27/4:4/0:12,tile43=8:27/4:4/0:12,tile44=0:31/4:5/0:11,tile45=4:31/4:5/0:11,tile46=8:31/4:5/0:11,tile47=12:31/4:5/0:11,tile48=20:27/4:4/0:12,tile49=24:27/4:4/0:12,tile50=16:31/4:5/0:11,tile51=20:31/4:5/0:11,tile52=24:31/4:5/0:11,tile53=28:31/4:5/0:11,tile54=9:19/6:6/0:10,tile55=15:19/6:6/0:10,tile56=3:25/6:1/0:15,tile57=9:25/6:1/0:15,tile58=15:25/6:1/0:15,tile59=21:25/6:1/0:15,tile60=6:18/8:3/0:13,tile61=14:18/8:3/0:13,tile62=3:21/3:6/0:10,tile63=14:21/3:6/0:10,tile64=17:21/8:6/0:10 +[26.2-]block:id=%exposed_copper_golem_statue,id=%waxed_exposed_copper_golem_statue,transparency=TRANSPARENT,stdrot=true,patch0=0:copper_golem_exposed,patch1=1:copper_golem_exposed,patch2=2:copper_golem_exposed,patch3=3:copper_golem_exposed,patch4=4:copper_golem_exposed,patch5=5:copper_golem_exposed,patch6=6:copper_golem_exposed,patch7=7:copper_golem_exposed,patch8=8:copper_golem_exposed,patch9=9:copper_golem_exposed,patch10=10:copper_golem_exposed,patch11=11:copper_golem_exposed,patch12=12:copper_golem_exposed,patch13=13:copper_golem_exposed,patch14=14:copper_golem_exposed,patch15=15:copper_golem_exposed,patch16=16:copper_golem_exposed,patch17=17:copper_golem_exposed,patch18=18:copper_golem_exposed,patch19=19:copper_golem_exposed,patch20=20:copper_golem_exposed,patch21=21:copper_golem_exposed,patch22=22:copper_golem_exposed,patch23=23:copper_golem_exposed,patch24=24:copper_golem_exposed,patch25=25:copper_golem_exposed,patch26=26:copper_golem_exposed,patch27=27:copper_golem_exposed,patch28=28:copper_golem_exposed,patch29=29:copper_golem_exposed,patch30=30:copper_golem_exposed,patch31=31:copper_golem_exposed,patch32=32:copper_golem_exposed,patch33=33:copper_golem_exposed,patch34=34:copper_golem_exposed,patch35=35:copper_golem_exposed,patch36=36:copper_golem_exposed,patch37=37:copper_golem_exposed,patch38=38:copper_golem_exposed,patch39=39:copper_golem_exposed,patch40=40:copper_golem_exposed,patch41=41:copper_golem_exposed,patch42=42:copper_golem_exposed,patch43=43:copper_golem_exposed,patch44=44:copper_golem_exposed,patch45=45:copper_golem_exposed,patch46=46:copper_golem_exposed,patch47=47:copper_golem_exposed,patch48=48:copper_golem_exposed,patch49=49:copper_golem_exposed,patch50=50:copper_golem_exposed,patch51=51:copper_golem_exposed,patch52=52:copper_golem_exposed,patch53=53:copper_golem_exposed,patch54=54:copper_golem_exposed,patch55=55:copper_golem_exposed,patch56=56:copper_golem_exposed,patch57=57:copper_golem_exposed,patch58=58:copper_golem_exposed,patch59=59:copper_golem_exposed,patch60=60:copper_golem_exposed,patch61=61:copper_golem_exposed,patch62=62:copper_golem_exposed,patch63=63:copper_golem_exposed,patch64=64:copper_golem_exposed +[26.2-]texturefile:id=copper_golem_weathered,filename=assets/minecraft/textures/entity/copper_golem/copper_golem_weathered.png,format=CUSTOM,xcount=4,ycount=4,tile0=6:15/8:6/0:10,tile1=14:15/8:6/0:10,tile2=0:21/6:6/0:10,tile3=6:21/8:6/0:10,tile4=14:21/6:6/0:10,tile5=20:21/8:6/0:10,tile6=10:0/8:10/0:6,tile7=18:0/8:10/0:6,tile8=0:10/10:5/0:11,tile9=10:10/8:5/0:11,tile10=18:10/10:5/0:11,tile11=28:10/8:5/0:11,tile12=58:0/2:2/0:14,tile13=60:0/2:2/0:14,tile14=56:2/2:3/0:13,tile15=58:2/2:3/0:13,tile16=60:2/2:3/0:13,tile17=62:2/2:3/0:13,tile18=39:8/2:2/0:14,tile19=41:8/2:2/0:14,tile20=37:10/2:4/0:12,tile21=39:10/2:4/0:12,tile22=41:10/2:4/0:12,tile23=43:10/2:4/0:12,tile24=41:0/4:4/0:12,tile25=45:0/4:4/0:12,tile26=37:4/4:4/0:12,tile27=41:4/4:4/0:12,tile28=45:4/4:4/0:12,tile29=49:4/4:4/0:12,tile30=40:16/3:4/0:12,tile31=43:16/3:4/0:12,tile32=36:20/4:10/0:6,tile33=40:20/3:10/0:6,tile34=43:20/4:10/0:6,tile35=47:20/3:10/0:6,tile36=54:16/3:4/0:12,tile37=57:16/3:4/0:12,tile38=50:20/4:10/0:6,tile39=54:20/3:10/0:6,tile40=57:20/4:10/0:6,tile41=61:20/3:10/0:6,tile42=4:27/4:4/0:12,tile43=8:27/4:4/0:12,tile44=0:31/4:5/0:11,tile45=4:31/4:5/0:11,tile46=8:31/4:5/0:11,tile47=12:31/4:5/0:11,tile48=20:27/4:4/0:12,tile49=24:27/4:4/0:12,tile50=16:31/4:5/0:11,tile51=20:31/4:5/0:11,tile52=24:31/4:5/0:11,tile53=28:31/4:5/0:11,tile54=9:19/6:6/0:10,tile55=15:19/6:6/0:10,tile56=3:25/6:1/0:15,tile57=9:25/6:1/0:15,tile58=15:25/6:1/0:15,tile59=21:25/6:1/0:15,tile60=6:18/8:3/0:13,tile61=14:18/8:3/0:13,tile62=3:21/3:6/0:10,tile63=14:21/3:6/0:10,tile64=17:21/8:6/0:10 +[26.2-]block:id=%weathered_copper_golem_statue,id=%waxed_weathered_copper_golem_statue,transparency=TRANSPARENT,stdrot=true,patch0=0:copper_golem_weathered,patch1=1:copper_golem_weathered,patch2=2:copper_golem_weathered,patch3=3:copper_golem_weathered,patch4=4:copper_golem_weathered,patch5=5:copper_golem_weathered,patch6=6:copper_golem_weathered,patch7=7:copper_golem_weathered,patch8=8:copper_golem_weathered,patch9=9:copper_golem_weathered,patch10=10:copper_golem_weathered,patch11=11:copper_golem_weathered,patch12=12:copper_golem_weathered,patch13=13:copper_golem_weathered,patch14=14:copper_golem_weathered,patch15=15:copper_golem_weathered,patch16=16:copper_golem_weathered,patch17=17:copper_golem_weathered,patch18=18:copper_golem_weathered,patch19=19:copper_golem_weathered,patch20=20:copper_golem_weathered,patch21=21:copper_golem_weathered,patch22=22:copper_golem_weathered,patch23=23:copper_golem_weathered,patch24=24:copper_golem_weathered,patch25=25:copper_golem_weathered,patch26=26:copper_golem_weathered,patch27=27:copper_golem_weathered,patch28=28:copper_golem_weathered,patch29=29:copper_golem_weathered,patch30=30:copper_golem_weathered,patch31=31:copper_golem_weathered,patch32=32:copper_golem_weathered,patch33=33:copper_golem_weathered,patch34=34:copper_golem_weathered,patch35=35:copper_golem_weathered,patch36=36:copper_golem_weathered,patch37=37:copper_golem_weathered,patch38=38:copper_golem_weathered,patch39=39:copper_golem_weathered,patch40=40:copper_golem_weathered,patch41=41:copper_golem_weathered,patch42=42:copper_golem_weathered,patch43=43:copper_golem_weathered,patch44=44:copper_golem_weathered,patch45=45:copper_golem_weathered,patch46=46:copper_golem_weathered,patch47=47:copper_golem_weathered,patch48=48:copper_golem_weathered,patch49=49:copper_golem_weathered,patch50=50:copper_golem_weathered,patch51=51:copper_golem_weathered,patch52=52:copper_golem_weathered,patch53=53:copper_golem_weathered,patch54=54:copper_golem_weathered,patch55=55:copper_golem_weathered,patch56=56:copper_golem_weathered,patch57=57:copper_golem_weathered,patch58=58:copper_golem_weathered,patch59=59:copper_golem_weathered,patch60=60:copper_golem_weathered,patch61=61:copper_golem_weathered,patch62=62:copper_golem_weathered,patch63=63:copper_golem_weathered,patch64=64:copper_golem_weathered +[26.2-]texturefile:id=copper_golem_oxidized,filename=assets/minecraft/textures/entity/copper_golem/copper_golem_oxidized.png,format=CUSTOM,xcount=4,ycount=4,tile0=6:15/8:6/0:10,tile1=14:15/8:6/0:10,tile2=0:21/6:6/0:10,tile3=6:21/8:6/0:10,tile4=14:21/6:6/0:10,tile5=20:21/8:6/0:10,tile6=10:0/8:10/0:6,tile7=18:0/8:10/0:6,tile8=0:10/10:5/0:11,tile9=10:10/8:5/0:11,tile10=18:10/10:5/0:11,tile11=28:10/8:5/0:11,tile12=58:0/2:2/0:14,tile13=60:0/2:2/0:14,tile14=56:2/2:3/0:13,tile15=58:2/2:3/0:13,tile16=60:2/2:3/0:13,tile17=62:2/2:3/0:13,tile18=39:8/2:2/0:14,tile19=41:8/2:2/0:14,tile20=37:10/2:4/0:12,tile21=39:10/2:4/0:12,tile22=41:10/2:4/0:12,tile23=43:10/2:4/0:12,tile24=41:0/4:4/0:12,tile25=45:0/4:4/0:12,tile26=37:4/4:4/0:12,tile27=41:4/4:4/0:12,tile28=45:4/4:4/0:12,tile29=49:4/4:4/0:12,tile30=40:16/3:4/0:12,tile31=43:16/3:4/0:12,tile32=36:20/4:10/0:6,tile33=40:20/3:10/0:6,tile34=43:20/4:10/0:6,tile35=47:20/3:10/0:6,tile36=54:16/3:4/0:12,tile37=57:16/3:4/0:12,tile38=50:20/4:10/0:6,tile39=54:20/3:10/0:6,tile40=57:20/4:10/0:6,tile41=61:20/3:10/0:6,tile42=4:27/4:4/0:12,tile43=8:27/4:4/0:12,tile44=0:31/4:5/0:11,tile45=4:31/4:5/0:11,tile46=8:31/4:5/0:11,tile47=12:31/4:5/0:11,tile48=20:27/4:4/0:12,tile49=24:27/4:4/0:12,tile50=16:31/4:5/0:11,tile51=20:31/4:5/0:11,tile52=24:31/4:5/0:11,tile53=28:31/4:5/0:11,tile54=9:19/6:6/0:10,tile55=15:19/6:6/0:10,tile56=3:25/6:1/0:15,tile57=9:25/6:1/0:15,tile58=15:25/6:1/0:15,tile59=21:25/6:1/0:15,tile60=6:18/8:3/0:13,tile61=14:18/8:3/0:13,tile62=3:21/3:6/0:10,tile63=14:21/3:6/0:10,tile64=17:21/8:6/0:10 +[26.2-]block:id=%oxidized_copper_golem_statue,id=%waxed_oxidized_copper_golem_statue,transparency=TRANSPARENT,stdrot=true,patch0=0:copper_golem_oxidized,patch1=1:copper_golem_oxidized,patch2=2:copper_golem_oxidized,patch3=3:copper_golem_oxidized,patch4=4:copper_golem_oxidized,patch5=5:copper_golem_oxidized,patch6=6:copper_golem_oxidized,patch7=7:copper_golem_oxidized,patch8=8:copper_golem_oxidized,patch9=9:copper_golem_oxidized,patch10=10:copper_golem_oxidized,patch11=11:copper_golem_oxidized,patch12=12:copper_golem_oxidized,patch13=13:copper_golem_oxidized,patch14=14:copper_golem_oxidized,patch15=15:copper_golem_oxidized,patch16=16:copper_golem_oxidized,patch17=17:copper_golem_oxidized,patch18=18:copper_golem_oxidized,patch19=19:copper_golem_oxidized,patch20=20:copper_golem_oxidized,patch21=21:copper_golem_oxidized,patch22=22:copper_golem_oxidized,patch23=23:copper_golem_oxidized,patch24=24:copper_golem_oxidized,patch25=25:copper_golem_oxidized,patch26=26:copper_golem_oxidized,patch27=27:copper_golem_oxidized,patch28=28:copper_golem_oxidized,patch29=29:copper_golem_oxidized,patch30=30:copper_golem_oxidized,patch31=31:copper_golem_oxidized,patch32=32:copper_golem_oxidized,patch33=33:copper_golem_oxidized,patch34=34:copper_golem_oxidized,patch35=35:copper_golem_oxidized,patch36=36:copper_golem_oxidized,patch37=37:copper_golem_oxidized,patch38=38:copper_golem_oxidized,patch39=39:copper_golem_oxidized,patch40=40:copper_golem_oxidized,patch41=41:copper_golem_oxidized,patch42=42:copper_golem_oxidized,patch43=43:copper_golem_oxidized,patch44=44:copper_golem_oxidized,patch45=45:copper_golem_oxidized,patch46=46:copper_golem_oxidized,patch47=47:copper_golem_oxidized,patch48=48:copper_golem_oxidized,patch49=49:copper_golem_oxidized,patch50=50:copper_golem_oxidized,patch51=51:copper_golem_oxidized,patch52=52:copper_golem_oxidized,patch53=53:copper_golem_oxidized,patch54=54:copper_golem_oxidized,patch55=55:copper_golem_oxidized,patch56=56:copper_golem_oxidized,patch57=57:copper_golem_oxidized,patch58=58:copper_golem_oxidized,patch59=59:copper_golem_oxidized,patch60=60:copper_golem_oxidized,patch61=61:copper_golem_oxidized,patch62=62:copper_golem_oxidized,patch63=63:copper_golem_oxidized,patch64=64:copper_golem_oxidized diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/chiseled_cinnabar.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/chiseled_cinnabar.png new file mode 100644 index 000000000..e3c3f0ce8 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/chiseled_cinnabar.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/chiseled_sulfur.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/chiseled_sulfur.png new file mode 100644 index 000000000..1eadf2526 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/chiseled_sulfur.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/cinnabar.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/cinnabar.png new file mode 100644 index 000000000..c983786a4 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/cinnabar.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/cinnabar_bricks.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/cinnabar_bricks.png new file mode 100644 index 000000000..4e242d993 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/cinnabar_bricks.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/golden_dandelion.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/golden_dandelion.png new file mode 100644 index 000000000..69b6aa292 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/golden_dandelion.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/polished_cinnabar.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/polished_cinnabar.png new file mode 100644 index 000000000..c198d8eef Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/polished_cinnabar.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/polished_sulfur.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/polished_sulfur.png new file mode 100644 index 000000000..03a07cad9 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/polished_sulfur.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/potent_sulfur.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/potent_sulfur.png new file mode 100644 index 000000000..efafaff04 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/potent_sulfur.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur.png new file mode 100644 index 000000000..4edbb8c9f Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_bricks.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_bricks.png new file mode 100644 index 000000000..f37084854 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_bricks.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_base.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_base.png new file mode 100644 index 000000000..0b04a5316 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_base.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_frustum.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_frustum.png new file mode 100644 index 000000000..8d62485ae Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_frustum.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_middle.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_middle.png new file mode 100644 index 000000000..8ef4ac825 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_middle.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_tip.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_tip.png new file mode 100644 index 000000000..53eaa22d7 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_tip.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_tip_merge.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_tip_merge.png new file mode 100644 index 000000000..acd2b98e6 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_tip_merge.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_base.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_base.png new file mode 100644 index 000000000..0c793bb5d Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_base.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_frustum.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_frustum.png new file mode 100644 index 000000000..f669921e5 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_frustum.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_middle.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_middle.png new file mode 100644 index 000000000..d71213429 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_middle.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_tip.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_tip.png new file mode 100644 index 000000000..637d8dd7c Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_tip.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_tip_merge.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_tip_merge.png new file mode 100644 index 000000000..053a25335 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_tip_merge.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem.png new file mode 100644 index 000000000..eff34ff8f Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem_exposed.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem_exposed.png new file mode 100644 index 000000000..54aecd5af Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem_exposed.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem_oxidized.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem_oxidized.png new file mode 100644 index 000000000..d4130fd9c Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem_oxidized.png differ diff --git a/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem_weathered.png b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem_weathered.png new file mode 100644 index 000000000..96e41bac7 Binary files /dev/null and b/DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem_weathered.png differ diff --git a/DynmapCore/src/test/java/org/dynmap/hdmap/renderer/CopperGolemStatueRendererTest.java b/DynmapCore/src/test/java/org/dynmap/hdmap/renderer/CopperGolemStatueRendererTest.java new file mode 100644 index 000000000..42156356d --- /dev/null +++ b/DynmapCore/src/test/java/org/dynmap/hdmap/renderer/CopperGolemStatueRendererTest.java @@ -0,0 +1,51 @@ +package org.dynmap.hdmap.renderer; + +import java.util.BitSet; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import org.dynmap.renderer.DynmapBlockState; +import org.dynmap.renderer.RenderPatch; +import org.dynmap.utils.PatchDefinition; +import org.dynmap.utils.PatchDefinitionFactory; +import org.junit.Test; +import static org.junit.Assert.*; + +public class CopperGolemStatueRendererTest { + @Test public void allStatueStatesHaveDetailedMeshesAndWaterDoesNotChangeGeometry() { + Set shapes = new HashSet<>(); + int checked = 0; + for (String wax : new String[]{"", "waxed_"}) for (String oxidation : new String[]{"", "exposed_", "weathered_", "oxidized_"}) { + String name = "minecraft:" + wax + oxidation + "copper_golem_statue"; + CopperGolemStatueRenderer renderer = new CopperGolemStatueRenderer(); + assertTrue(renderer.initializeRenderer(new PatchDefinitionFactory(), name, new BitSet(), Collections.emptyMap())); + for (String pose : new String[]{"standing", "sitting", "running", "star"}) for (String facing : new String[]{"north", "east", "south", "west"}) { + RenderPatch[] dry = null; + for (boolean water : new boolean[]{false, true}) { + DynmapBlockState state = new DynmapBlockState(null, 0, name, + "waterlogged=" + water + ",copper_golem_pose=" + pose + ",facing=" + facing, "COPPER"); + RenderPatch[] patches = renderer.meshFor(state); + assertEquals(pose.equals("sitting") ? 66 : 54, patches.length); + StringBuilder shape = new StringBuilder(); + double maxY = 0; + for (RenderPatch patch : patches) { + assertNotNull(patch); + PatchDefinition p = (PatchDefinition) patch; + assertTrue(p.validate()); + assertTrue(p.textureindex >= 0 && p.textureindex < renderer.getMaximumTextureCount()); + assertTrue(p.umax > 0 && p.umax <= 1 && p.vmax > 0 && p.vmax <= 1); + for (double u : new double[]{0, p.umax}) for (double v : new double[]{0, p.vmax}) + maxY = Math.max(maxY, p.y0 + (p.yu-p.y0)*u + (p.yv-p.y0)*v); + shape.append(p.toString()); + } + assertTrue("Antenna is not truncated", maxY > 1.1 && maxY < 1.6); + if (dry == null) dry = patches; else assertSame(dry, patches); + shapes.add(shape.toString()); + checked++; + } + } + } + assertEquals(256, checked); + assertEquals("Four distinct poses in each of four directions", 16, shapes.size()); + } +} diff --git a/DynmapCore/src/test/java/org/dynmap/utils/PatchDefinitionTest.java b/DynmapCore/src/test/java/org/dynmap/utils/PatchDefinitionTest.java new file mode 100644 index 000000000..0763e691b --- /dev/null +++ b/DynmapCore/src/test/java/org/dynmap/utils/PatchDefinitionTest.java @@ -0,0 +1,18 @@ +package org.dynmap.utils; + +import org.dynmap.renderer.RenderPatchFactory.SideVisible; +import org.junit.Test; +import static org.junit.Assert.*; + +public class PatchDefinitionTest { + @Test public void visibleCornersUseIndependentUvBounds() { + PatchDefinitionFactory factory = new PatchDefinitionFactory(); + // Only a quarter of the long U vector is visible; using vmax as U rejects it incorrectly. + assertNotNull(factory.getPatch(0, 0, 0, 8, 0, 0, 0, 1, 0, 0, .25, 0, 1, SideVisible.TOP, 0)); + } + @Test public void trapezoidBoundsAtUmaxAreChecked() { + PatchDefinitionFactory factory = new PatchDefinitionFactory(); + assertNull(factory.getPatch(0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 1, 0, 0, .25, 1, SideVisible.TOP, 0)); + assertNotNull(factory.getPatch(0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 1, 0, 0, .25, .5, SideVisible.TOP, 0)); + } +} diff --git a/DynmapCoreAPI/build.gradle b/DynmapCoreAPI/build.gradle index 93f716856..93d0d0cbd 100644 --- a/DynmapCoreAPI/build.gradle +++ b/DynmapCoreAPI/build.gradle @@ -6,7 +6,10 @@ eclipse { name = "Dynmap(DynmapCoreAPI)" } } -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' +} description = "DynmapCoreAPI" diff --git a/build-minecraft26.gradle b/build-minecraft26.gradle new file mode 100644 index 000000000..a4bf4a5bd --- /dev/null +++ b/build-minecraft26.gradle @@ -0,0 +1,7 @@ +plugins { + id 'com.gradleup.shadow' version '9.6.0' + id 'java' + id 'maven-publish' +} +ext.shadowPluginId = 'com.gradleup.shadow' +apply from: 'gradle/common.gradle' \ No newline at end of file diff --git a/build.gradle b/build.gradle index e6a54132e..691ecda83 100644 --- a/build.gradle +++ b/build.gradle @@ -18,74 +18,5 @@ plugins { id 'maven-publish' } -apply plugin: 'eclipse' - -eclipse { - project { - name = "Dynmap" - } -} - -allprojects { - repositories { - if (providers.gradleProperty('useMavenLocal').isPresent()) { mavenLocal() } - mavenCentral() - maven { url "https://repo.mikeprimm.com" } - maven { url 'https://libraries.minecraft.net/' } - maven { url "https://oss.sonatype.org/content/repositories/releases" } - maven { url "https://oss.sonatype.org/content/repositories/snapshots" } - maven { url "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" } - maven { url "https://repo.codemc.org/repository/maven-public/" } - } - - apply plugin: 'java' - - group = 'us.dynmap' - version = '3.9-SNAPSHOT' - -} - -class Globals { - String buildNumber -} -def gitOutput = { List arguments -> - def output = new ByteArrayOutputStream() - exec { commandLine(['git'] + arguments); standardOutput = output } - output.toString('UTF-8').trim() -} -def sourceRevision = gitOutput(['rev-parse', 'HEAD']) -def sourceDirty = !gitOutput(['status', '--porcelain', '--untracked-files=normal']).isEmpty() -ext { - acecoreRevision = sourceRevision - acecoreDirty = sourceDirty - globals = new Globals(buildNumber: 'acecore-' + sourceRevision.take(12) + (sourceDirty ? '-dirty' : '')) -} - -subprojects { - apply plugin: "io.github.goooler.shadow" - apply plugin: 'java' - apply plugin: 'maven-publish' - - sourceCompatibility = 1.8 - targetCompatibility = 1.8 - tasks.withType(JavaCompile) { - options.encoding = 'UTF-8' - } - tasks.withType(ProcessResources).configureEach { - inputs.property('acecoreBuildNumber', rootProject.ext.globals.buildNumber) - inputs.property('dynmapVersion', project.version.toString()) - } - tasks.withType(AbstractArchiveTask).configureEach { - preserveFileTimestamps = false - reproducibleFileOrder = true - } -} - -apply from: 'gradle/acecore-verification.gradle' - -clean { - delete "target" -} - -task setupCIWorkspace { -} +ext.shadowPluginId = 'io.github.goooler.shadow' +apply from: 'gradle/common.gradle' diff --git a/bukkit-helper-113-2/build.gradle b/bukkit-helper-113-2/build.gradle index c15ea7a28..f8e60a2cd 100644 --- a/bukkit-helper-113-2/build.gradle +++ b/bukkit-helper-113-2/build.gradle @@ -8,7 +8,10 @@ eclipse { description = 'bukkit-helper-1.13.2' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-114-1/build.gradle b/bukkit-helper-114-1/build.gradle index 2b3f7f249..3f95a4976 100644 --- a/bukkit-helper-114-1/build.gradle +++ b/bukkit-helper-114-1/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.14.1' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-115/build.gradle b/bukkit-helper-115/build.gradle index 1cafc4a33..8895e71dd 100644 --- a/bukkit-helper-115/build.gradle +++ b/bukkit-helper-115/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.15' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-116-2/build.gradle b/bukkit-helper-116-2/build.gradle index 8f6102507..bfa9ca188 100644 --- a/bukkit-helper-116-2/build.gradle +++ b/bukkit-helper-116-2/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.16.2' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-116-3/build.gradle b/bukkit-helper-116-3/build.gradle index 9a7dcf191..ad9160296 100644 --- a/bukkit-helper-116-3/build.gradle +++ b/bukkit-helper-116-3/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.16.3' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-116-4/build.gradle b/bukkit-helper-116-4/build.gradle index 6a0df89ba..ebaf5f71e 100644 --- a/bukkit-helper-116-4/build.gradle +++ b/bukkit-helper-116-4/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.16.4' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-116/build.gradle b/bukkit-helper-116/build.gradle index c3e81f899..40ffcd4f9 100644 --- a/bukkit-helper-116/build.gradle +++ b/bukkit-helper-116/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.16' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-117/build.gradle b/bukkit-helper-117/build.gradle index fc862dffb..639c2bb0d 100644 --- a/bukkit-helper-117/build.gradle +++ b/bukkit-helper-117/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.17' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(16) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(16) + targetCompatibility = JavaVersion.toVersion(16) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-118-2/build.gradle b/bukkit-helper-118-2/build.gradle index cc86d1431..cd18766c1 100644 --- a/bukkit-helper-118-2/build.gradle +++ b/bukkit-helper-118-2/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.18.2' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-118/build.gradle b/bukkit-helper-118/build.gradle index f7093a23d..bcd5bc783 100644 --- a/bukkit-helper-118/build.gradle +++ b/bukkit-helper-118/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.18' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-119-3/build.gradle b/bukkit-helper-119-3/build.gradle index 8a0525d12..a890bd1fe 100644 --- a/bukkit-helper-119-3/build.gradle +++ b/bukkit-helper-119-3/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.19.3' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-119-4/build.gradle b/bukkit-helper-119-4/build.gradle index 1f7a9179f..d4c3e2820 100644 --- a/bukkit-helper-119-4/build.gradle +++ b/bukkit-helper-119-4/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.19.4' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-119/build.gradle b/bukkit-helper-119/build.gradle index 4061ec3db..e1be8f5e1 100644 --- a/bukkit-helper-119/build.gradle +++ b/bukkit-helper-119/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.19' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-120-2/build.gradle b/bukkit-helper-120-2/build.gradle index 6cca6f432..332951ae0 100644 --- a/bukkit-helper-120-2/build.gradle +++ b/bukkit-helper-120-2/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.20.2' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-120-4/build.gradle b/bukkit-helper-120-4/build.gradle index 33dc9cf40..619e94b11 100644 --- a/bukkit-helper-120-4/build.gradle +++ b/bukkit-helper-120-4/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.20.4' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-120-5/build.gradle b/bukkit-helper-120-5/build.gradle index 15448e084..1861f748a 100644 --- a/bukkit-helper-120-5/build.gradle +++ b/bukkit-helper-120-5/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.20.5' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-120/build.gradle b/bukkit-helper-120/build.gradle index a32246715..21caa5b28 100644 --- a/bukkit-helper-120/build.gradle +++ b/bukkit-helper-120/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.20' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-121-10/build.gradle b/bukkit-helper-121-10/build.gradle index 59fff7240..16d26f81d 100644 --- a/bukkit-helper-121-10/build.gradle +++ b/bukkit-helper-121-10/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.21.10' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-121-11/build.gradle b/bukkit-helper-121-11/build.gradle index 5a8ccc1f0..78f2ff255 100644 --- a/bukkit-helper-121-11/build.gradle +++ b/bukkit-helper-121-11/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.21.11' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-121-3/build.gradle b/bukkit-helper-121-3/build.gradle index 47b4464ac..781ef803e 100644 --- a/bukkit-helper-121-3/build.gradle +++ b/bukkit-helper-121-3/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.21.3' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-121-4/build.gradle b/bukkit-helper-121-4/build.gradle index 863066193..701cfb4a4 100644 --- a/bukkit-helper-121-4/build.gradle +++ b/bukkit-helper-121-4/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.21.4' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-121-5/build.gradle b/bukkit-helper-121-5/build.gradle index 0b5680747..86a626cf5 100644 --- a/bukkit-helper-121-5/build.gradle +++ b/bukkit-helper-121-5/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.21.5' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-121-6/build.gradle b/bukkit-helper-121-6/build.gradle index e4aa9c39a..5264fb760 100644 --- a/bukkit-helper-121-6/build.gradle +++ b/bukkit-helper-121-6/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.21.7' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-121/build.gradle b/bukkit-helper-121/build.gradle index 6d8ecf422..d08c11c39 100644 --- a/bukkit-helper-121/build.gradle +++ b/bukkit-helper-121/build.gradle @@ -6,7 +6,10 @@ eclipse { description = 'bukkit-helper-1.21' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaLanguageVersion.of(17) // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = JavaVersion.toVersion(17) + targetCompatibility = JavaVersion.toVersion(17) +} dependencies { implementation project(':bukkit-helper') diff --git a/bukkit-helper-26-2/.gitignore b/bukkit-helper-26-2/.gitignore new file mode 100644 index 000000000..7c9cf9c2a --- /dev/null +++ b/bukkit-helper-26-2/.gitignore @@ -0,0 +1,2 @@ +/build/ +/.gradle/ diff --git a/bukkit-helper-26-2/build.gradle b/bukkit-helper-26-2/build.gradle new file mode 100644 index 000000000..538d4eb61 --- /dev/null +++ b/bukkit-helper-26-2/build.gradle @@ -0,0 +1,42 @@ +plugins { + id 'io.papermc.paperweight.userdev' version '2.0.0-beta.21' +} + +eclipse { + project { + name = "Dynmap(Spigot-26.2)" + } +} + +description = 'bukkit-helper-26.2' + +// Paper 26.2 requires JDK 25 to compile against - use a real Gradle toolchain (rather than just a +// sourceCompatibility flag) so this module can be built with JDK 25 regardless of what JDK is +// running the Gradle daemon itself (root project still targets JDK 8 elsewhere). +java { + sourceCompatibility = JavaVersion.VERSION_25 + targetCompatibility = JavaVersion.VERSION_25 + toolchain { + languageVersion = JavaLanguageVersion.of(25) + } +} + +// Resolve this Paper-only module without walking the legacy Spigot repositories first. +repositories.clear() +repositories { + mavenCentral() + maven { url 'https://repo.papermc.io/repository/maven-public/' } + maven { url 'https://repo.mikeprimm.com' } +} + +dependencies { + implementation project(':bukkit-helper') + implementation project(':dynmap-api') + implementation project(path: ':DynmapCore', configuration: 'shadow') + // Minecraft ships unobfuscated as of 26.1+, so there is no more "spigot mappings" reobf jar + // (org.spigotmc:spigot / org.spigotmc:spigot-api) to depend on for NMS access - paperweight-userdev's + // dev bundle supplies the full compile classpath (Paper/Bukkit API + real Mojang-mapped net.minecraft.* + // classes) by itself, so no separate paper-api dependency is needed (or resolvable) here. + paperweight.paperDevBundle('26.2.build.105-stable') + testImplementation 'junit:junit:4.13.2' +} diff --git a/bukkit-helper-26-2/src/main/java/org/dynmap/bukkit/helper/v26_2/BukkitVersionHelperSpigot26_2.java b/bukkit-helper-26-2/src/main/java/org/dynmap/bukkit/helper/v26_2/BukkitVersionHelperSpigot26_2.java new file mode 100644 index 000000000..27a69e649 --- /dev/null +++ b/bukkit-helper-26-2/src/main/java/org/dynmap/bukkit/helper/v26_2/BukkitVersionHelperSpigot26_2.java @@ -0,0 +1,441 @@ +package org.dynmap.bukkit.helper.v26_2; + +import org.bukkit.*; +import org.bukkit.craftbukkit.CraftChunk; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.dynmap.DynmapChunk; +import org.dynmap.Log; +import org.dynmap.bukkit.helper.BukkitMaterial; +import org.dynmap.bukkit.helper.BukkitVersionHelper; +import org.dynmap.bukkit.helper.BukkitWorld; +import org.dynmap.bukkit.helper.BukkitVersionHelperGeneric.TexturesPayload; +import org.dynmap.renderer.DynmapBlockState; +import org.dynmap.utils.MapChunkCache; +import org.dynmap.utils.Polygon; + +import com.google.common.collect.Iterables; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; + +import net.minecraft.core.IdMapper; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.core.Registry; +import net.minecraft.nbt.ByteArrayTag; +import net.minecraft.nbt.ByteTag; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.DoubleTag; +import net.minecraft.nbt.FloatTag; +import net.minecraft.nbt.IntArrayTag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.LongTag; +import net.minecraft.nbt.ShortTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.resources.Identifier; +import net.minecraft.nbt.Tag; +import net.minecraft.server.MinecraftServer; +import net.minecraft.tags.BlockTags; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.LiquidBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.status.ChunkStatus; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collection; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + + +/** + * Helper for isolation of bukkit version specific issues + * + * NOTE: As of Minecraft 26.1+, Mojang ships the server unobfuscated, so there is no more + * "Spigot mappings" reobfuscated layer (the versioned org.bukkit.craftbukkit.vX_Y_RZ packages + * and single/double-letter obfuscated method names seen in earlier bukkit-helper-* modules). + * This class is written directly against the real (Mojang-mapped) net.minecraft.* names, + * derived from bukkit-helper-121-11's obfuscated calls using that module's own inline + * "// RealClass.realMethod" comments as the translation key. Acecore validation and the + * pinned upstream source are documented in docs/minecraft26-validation.md. + */ +public class BukkitVersionHelperSpigot26_2 extends BukkitVersionHelper { + + @Override + public String getBlockStateSignature(org.bukkit.block.Block block) { + return block.getBlockData().getAsString(); + } + + @Override + public boolean isUnsafeAsync() { + return false; + } + + /** + * Get block short name list + */ + @Override + public String[] getBlockNames() { + String[] names = new String[BuiltInRegistries.BLOCK.size()]; + for (Block block : BuiltInRegistries.BLOCK) { + names[BuiltInRegistries.BLOCK.getId(block)] = BuiltInRegistries.BLOCK.getKey(block).toString(); + } + return names; + } + + private static Registry reg = null; + + private static Registry getBiomeReg() { + if (reg == null) { + reg = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME); + } + return reg; + } + + private Object[] biomelist; + /** + * Get list of defined biomebase objects + */ + @Override + public Object[] getBiomeBaseList() { + if (biomelist == null) { + biomelist = new Biome[256]; + Iterator iter = getBiomeReg().iterator(); + while (iter.hasNext()) { + Biome b = iter.next(); + int bidx = getBiomeReg().getId(b); + if (bidx >= biomelist.length) { + biomelist = Arrays.copyOf(biomelist, bidx + biomelist.length); + } + biomelist[bidx] = b; + } + } + return biomelist; + } + + /** Get ID from biomebase */ + @Override + public int getBiomeBaseID(Object bb) { + return getBiomeReg().getId((Biome)bb); + } + + public static IdentityHashMap dataToState; + + /** + * Initialize block states (org.dynmap.blockstate.DynmapBlockState) + */ + @Override + public void initializeBlockStates() { + dataToState = new IdentityHashMap(); + HashMap lastBlockState = new HashMap(); + IdMapper bsids = Block.BLOCK_STATE_REGISTRY; + Block baseb = null; + Iterator iter = bsids.iterator(); + ArrayList names = new ArrayList(); + + // Loop through block data states + DynmapBlockState.Builder bld = new DynmapBlockState.Builder(); + while (iter.hasNext()) { + BlockState bd = iter.next(); + Block b = bd.getBlock(); + Identifier id = BuiltInRegistries.BLOCK.getKey(b); + String bname = id.toString(); + DynmapBlockState lastbs = lastBlockState.get(bname); // See if we have seen this one + int idx = 0; + if (lastbs != null) { // Yes + idx = lastbs.getStateCount(); // Get number of states so far, since this is next + } + // Build state name + String sb = ""; + String fname = bd.toString(); + int off1 = fname.indexOf('['); + if (off1 >= 0) { + int off2 = fname.indexOf(']'); + sb = fname.substring(off1+1, off2); + } + int lightAtten = bd.getLightDampening(); + //Log.info("statename=" + bname + "[" + sb + "], lightAtten=" + lightAtten); + // Fill in base attributes + bld.setBaseState(lastbs).setStateIndex(idx).setBlockName(bname).setStateName(sb).setAttenuatesLight(lightAtten); + if (bd.isSolid()) { bld.setSolid(); } + if (bd.isAir()) { bld.setAir(); } + if (bd.is(BlockTags.OVERWORLD_NATURAL_LOGS)) { bld.setLog(); } + if (bd.is(BlockTags.LEAVES)) { bld.setLeaves(); } + if (!bd.getFluidState().isEmpty() && !(bd.getBlock() instanceof LiquidBlock)) { // Test if fluid type for block is not empty + bld.setWaterlogged(); + //Log.info("statename=" + bname + "[" + sb + "] = waterlogged"); + } + DynmapBlockState dbs = bld.build(); // Build state + + dataToState.put(bd, dbs); + lastBlockState.put(bname, (lastbs == null) ? dbs : lastbs); + Log.verboseinfo("blk=" + bname + ", idx=" + idx + ", state=" + sb + ", waterlogged=" + dbs.isWaterlogged()); + } + } + /** + * Create chunk cache for given chunks of given world + * @param dw - world + * @param chunks - chunk list + * @return cache + */ + @Override + public MapChunkCache getChunkCache(BukkitWorld dw, List chunks) { + MapChunkCache26_2 c = new MapChunkCache26_2(gencache); + c.setChunks(dw, chunks); + return c; + } + + /** + * Get biome base water multiplier + */ + @Override + public int getBiomeBaseWaterMult(Object bb) { + Biome biome = (Biome) bb; + return biome.getWaterColor(); + } + + /** Get temperature from biomebase */ + @Override + public float getBiomeBaseTemperature(Object bb) { + return ((Biome)bb).getBaseTemperature(); + } + + /** Get humidity from biomebase */ + @Override + public float getBiomeBaseHumidity(Object bb) { + return ((Biome)bb).climateSettings.downfall(); + } + + @Override + public Polygon getWorldBorder(World world) { + Polygon p = null; + WorldBorder wb = world.getWorldBorder(); + if (wb != null) { + Location c = wb.getCenter(); + double size = wb.getSize(); + if ((size > 1) && (size < 1E7)) { + size = size / 2; + p = new Polygon(); + p.addVertex(c.getX()-size, c.getZ()-size); + p.addVertex(c.getX()+size, c.getZ()-size); + p.addVertex(c.getX()+size, c.getZ()+size); + p.addVertex(c.getX()-size, c.getZ()+size); + } + } + return p; + } + // Send title/subtitle to user + public void sendTitleText(Player p, String title, String subtitle, int fadeInTicks, int stayTicks, int fadeOutTIcks) { + if (p != null) { + p.sendTitle(title, subtitle, fadeInTicks, stayTicks, fadeOutTIcks); + } + } + + /** + * Get material map by block ID + */ + @Override + public BukkitMaterial[] getMaterialList() { + return new BukkitMaterial[4096]; // Not used + } + + @Override + public void unloadChunkNoSave(World w, Chunk c, int cx, int cz) { + Log.severe("unloadChunkNoSave not implemented"); + } + + private String[] biomenames; + @Override + public String[] getBiomeNames() { + if (biomenames == null) { + biomenames = new String[256]; + Iterator iter = getBiomeReg().iterator(); + while (iter.hasNext()) { + Biome b = iter.next(); + int bidx = getBiomeReg().getId(b); + if (bidx >= biomenames.length) { + biomenames = Arrays.copyOf(biomenames, bidx + biomenames.length); + } + biomenames[bidx] = b.toString(); + } + } + return biomenames; + } + + @Override + public String getStateStringByCombinedId(int blkid, int meta) { + Log.severe("getStateStringByCombinedId not implemented"); + return null; + } + @Override + /** Get ID string from biomebase */ + public String getBiomeBaseIDString(Object bb) { + return getBiomeReg().getKey((Biome)bb).getPath(); + } + @Override + public String getBiomeBaseResourceLocsation(Object bb) { + return getBiomeReg().getKey((Biome)bb).toString(); + } + + @Override + public Object getUnloadQueue(World world) { + Log.warning("getUnloadQueue not implemented yet"); + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isInUnloadQueue(Object unloadqueue, int x, int z) { + Log.warning("isInUnloadQueue not implemented yet"); + // TODO Auto-generated method stub + return false; + } + + @Override + public Object[] getBiomeBaseFromSnapshot(ChunkSnapshot css) { + Log.warning("getBiomeBaseFromSnapshot not implemented yet"); + // TODO Auto-generated method stub + return new Object[256]; + } + + @Override + public long getInhabitedTicks(Chunk c) { + return ((CraftChunk)c).getHandle(ChunkStatus.FULL).getInhabitedTime(); + } + + @Override + public Map getTileEntitiesForChunk(Chunk c) { + return ((CraftChunk)c).getHandle(ChunkStatus.FULL).blockEntities; + } + + @Override + public int getTileEntityX(Object te) { + BlockEntity tileent = (BlockEntity) te; + return tileent.getBlockPos().getX(); + } + + @Override + public int getTileEntityY(Object te) { + BlockEntity tileent = (BlockEntity) te; + return tileent.getBlockPos().getY(); + } + + @Override + public int getTileEntityZ(Object te) { + BlockEntity tileent = (BlockEntity) te; + return tileent.getBlockPos().getZ(); + } + + @Override + public Object readTileEntityNBT(Object te, World w) { + BlockEntity tileent = (BlockEntity) te; + CraftWorld cw = (CraftWorld) w; + return tileent.saveCustomOnly(cw.getHandle().registryAccess()); + } + + @Override + public Object getFieldValue(Object nbt, String field) { + CompoundTag rec = (CompoundTag) nbt; + Tag val = rec.get(field); + if(val == null) return null; + if(val instanceof ByteTag) { + return ((ByteTag)val).byteValue(); + } + else if(val instanceof ShortTag) { + return ((ShortTag)val).shortValue(); + } + else if(val instanceof IntTag) { + return ((IntTag)val).intValue(); + } + else if(val instanceof LongTag) { + return ((LongTag)val).longValue(); + } + else if(val instanceof FloatTag) { + return ((FloatTag)val).floatValue(); + } + else if(val instanceof DoubleTag) { + return ((DoubleTag)val).doubleValue(); + } + else if(val instanceof ByteArrayTag) { + return ((ByteArrayTag)val).getAsByteArray(); + } + else if(val instanceof StringTag) { + return ((StringTag)val).value(); + } + else if(val instanceof IntArrayTag) { + return ((IntArrayTag)val).getAsIntArray(); + } + return null; + } + + @Override + public Player[] getOnlinePlayers() { + Collection p = Bukkit.getServer().getOnlinePlayers(); + return p.toArray(new Player[0]); + } + + @Override + public double getHealth(Player p) { + return p.getHealth(); + } + + private static final Gson gson = new GsonBuilder().create(); + + /** + * Get skin URL for player + * @param player + */ + @Override + public String getSkinURL(Player player) { + String url = null; + CraftPlayer cp = (CraftPlayer)player; + GameProfile profile = cp.getProfile(); + if (profile != null) { + PropertyMap pm = profile.properties(); + if (pm != null) { + Collection txt = pm.get("textures"); + Property textureProperty = Iterables.getFirst(pm.get("textures"), null); + if (textureProperty != null) { + String val = textureProperty.value(); + if (val != null) { + TexturesPayload result = null; + try { + String json = new String(Base64.getDecoder().decode(val), StandardCharsets.UTF_8); + result = gson.fromJson(json, TexturesPayload.class); + } catch (JsonParseException e) { + } catch (IllegalArgumentException x) { + Log.warning("Malformed response from skin URL check"); + } + if ((result != null) && (result.textures != null) && (result.textures.containsKey("SKIN"))) { + url = result.textures.get("SKIN").url; + } + } + } + } + } + return url; + } + // Get minY for world + @Override + public int getWorldMinY(World w) { + CraftWorld cw = (CraftWorld) w; + return cw.getMinHeight(); + } + @Override + public boolean useGenericCache() { + return true; + } + +} diff --git a/bukkit-helper-26-2/src/main/java/org/dynmap/bukkit/helper/v26_2/MapChunkCache26_2.java b/bukkit-helper-26-2/src/main/java/org/dynmap/bukkit/helper/v26_2/MapChunkCache26_2.java new file mode 100644 index 000000000..2caf4deae --- /dev/null +++ b/bukkit-helper-26-2/src/main/java/org/dynmap/bukkit/helper/v26_2/MapChunkCache26_2.java @@ -0,0 +1,111 @@ +package org.dynmap.bukkit.helper.v26_2; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeSpecialEffects; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.storage.SerializableChunkData; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.dynmap.DynmapChunk; +import org.dynmap.bukkit.helper.BukkitWorld; +import org.dynmap.common.BiomeMap; +import org.dynmap.common.chunk.GenericChunk; +import org.dynmap.common.chunk.GenericChunkCache; +import org.dynmap.common.chunk.GenericMapChunkCache; + +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; + +/** + * Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread + * + * See the header note in BukkitVersionHelperSpigot26_2 - this is a direct translation of + * bukkit-helper-121-11's obfuscated (Spigot-mapped) calls to their real Mojang names, since + * Minecraft 26.1+ ships unobfuscated and there is no more reobfuscated "spigot" jar to target. + */ +public class MapChunkCache26_2 extends GenericMapChunkCache { + private World w; + /** + * Construct empty cache + */ + public MapChunkCache26_2(GenericChunkCache cc) { + super(cc); + } + + @Override + protected Supplier getLoadedChunkAsync(DynmapChunk chunk) { + CompletableFuture> chunkData = CompletableFuture.supplyAsync(() -> { + CraftWorld cw = (CraftWorld) w; + LevelChunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z); + if (c == null) { + return Optional.empty(); + } + return Optional.of(SerializableChunkData.copyOf(cw.getHandle(), c)); + }, ((CraftServer) Bukkit.getServer()).getServer()); + return () -> chunkData.join().map(SerializableChunkData::write).map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(null); + } + + protected GenericChunk getLoadedChunk(DynmapChunk chunk) { + CraftWorld cw = (CraftWorld) w; + if (!cw.isChunkLoaded(chunk.x, chunk.z)) return null; + // LevelChunk.loaded is private with no public getter in 26.2 - getChunkIfLoaded() + // returning non-null already implies the chunk is loaded, so no extra check is needed. + LevelChunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z); + if (c == null) return null; + SerializableChunkData chunkData = SerializableChunkData.copyOf(cw.getHandle(), c); + CompoundTag nbt = chunkData.write(); + return nbt != null ? parseChunkFromNBT(new NBT.NBTCompound(nbt)) : null; + } + + @Override + protected Supplier loadChunkAsync(DynmapChunk chunk) { + CraftWorld cw = (CraftWorld) w; + CompletableFuture> genericChunk = cw.getHandle().getChunkSource().chunkMap.read(new ChunkPos(chunk.x, chunk.z)); + return () -> genericChunk.join().map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(null); + } + + protected GenericChunk loadChunk(DynmapChunk chunk) { + CraftWorld cw = (CraftWorld) w; + CompoundTag nbt = null; + ChunkPos cc = new ChunkPos(chunk.x, chunk.z); + GenericChunk gc = null; + try { // BUGBUG - convert this all to asyn properly, since now native async + nbt = cw.getHandle() + .getChunkSource() + .chunkMap + .read(cc) + .join().get(); + } catch (CancellationException cx) { + } catch (NoSuchElementException snex) { + } + if (nbt != null) { + gc = parseChunkFromNBT(new NBT.NBTCompound(nbt)); + } + return gc; + } + + public void setChunks(BukkitWorld dw, List chunks) { + this.w = dw.getWorld(); + super.setChunks(dw, chunks); + } + + @Override + public int getFoliageColor(BiomeMap bm, int[] colormap, int x, int z) { + return bm.getBiomeObject().map(Biome::getSpecialEffects).flatMap(BiomeSpecialEffects::foliageColorOverride).orElse(colormap[bm.biomeLookup()]); + } + + @Override + public int getGrassColor(BiomeMap bm, int[] colormap, int x, int z) { + BiomeSpecialEffects fog = bm.getBiomeObject().map(Biome::getSpecialEffects).orElse(null); + if (fog == null) return colormap[bm.biomeLookup()]; + return fog.grassColorModifier().modifyColor(x, z, fog.grassColorOverride().orElse(colormap[bm.biomeLookup()])); + } +} diff --git a/bukkit-helper-26-2/src/main/java/org/dynmap/bukkit/helper/v26_2/NBT.java b/bukkit-helper-26-2/src/main/java/org/dynmap/bukkit/helper/v26_2/NBT.java new file mode 100644 index 000000000..1cb79ad36 --- /dev/null +++ b/bukkit-helper-26-2/src/main/java/org/dynmap/bukkit/helper/v26_2/NBT.java @@ -0,0 +1,145 @@ +package org.dynmap.bukkit.helper.v26_2; + +import org.dynmap.common.chunk.GenericBitStorage; +import org.dynmap.common.chunk.GenericNBTCompound; +import org.dynmap.common.chunk.GenericNBTList; + +import java.util.Optional; +import java.util.Set; +import net.minecraft.nbt.Tag; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.util.SimpleBitStorage; + +public class NBT { + + public static class NBTCompound implements GenericNBTCompound { + private final CompoundTag obj; + public NBTCompound(CompoundTag t) { + this.obj = t; + } + @Override + public Set getAllKeys() { + return obj.keySet(); + } + @Override + public boolean contains(String s) { + return obj.contains(s); + } + @Override + public boolean contains(String s, int i) { + // Like contains, but with an extra constraint on type + Tag base = obj.get(s); + if (base == null) + return false; + byte type = base.getId(); + if (type == i) + return true; + else if (i != TAG_ANY_NUMERIC) + return false; + return type == TAG_BYTE || type == TAG_SHORT || type == TAG_INT || type == TAG_LONG || type == TAG_FLOAT + || type == TAG_DOUBLE; + } + @Override + public byte getByte(String s) { + return obj.getByteOr(s, (byte)0); + } + @Override + public short getShort(String s) { + return obj.getShortOr(s, (short)0); + } + @Override + public int getInt(String s) { + return obj.getIntOr(s, 0); + } + @Override + public long getLong(String s) { + return obj.getLongOr(s, 0L); + } + @Override + public float getFloat(String s) { + return obj.getFloatOr(s, 0.0f); + } + @Override + public double getDouble(String s) { + return obj.getDoubleOr(s, 0.0); + } + @Override + public String getString(String s) { + return obj.getStringOr(s, ""); + } + @Override + public byte[] getByteArray(String s) { + Optional byteArr = obj.getByteArray(s); + return byteArr.orElseGet(() -> new byte[0]); + } + @Override + public int[] getIntArray(String s) { + Optional intArr = obj.getIntArray(s); + return intArr.orElseGet(() -> new int[0]); + } + @Override + public long[] getLongArray(String s) { + Optional longArr = obj.getLongArray(s); + return longArr.orElseGet(() -> new long[0]); + } + @Override + public GenericNBTCompound getCompound(String s) { + return new NBTCompound(obj.getCompoundOrEmpty(s)); + } + @Override + public GenericNBTList getList(String s, int i) { + // i argument used to be used to constrain list type, but nbt lists no longer have types as of 1.21.5 + return new NBTList(obj.getListOrEmpty(s)); + } + @Override + public boolean getBoolean(String s) { + return getByte(s) != 0; + } + @Override + public String getAsString(String s) { + Tag t = obj.get(s); + return (t != null) ? t.asString().orElseGet(() -> "") : ""; + } + @Override + public GenericBitStorage makeBitStorage(int bits, int count, long[] data) { + return new OurBitStorage(bits, count, data); + } + public String toString() { + return obj.toString(); + } + } + + public static class NBTList implements GenericNBTList { + private final ListTag obj; + public NBTList(ListTag t) { + obj = t; + } + @Override + public int size() { + return obj.size(); + } + @Override + public String getString(int idx) { + return obj.getStringOr(idx, ""); + } + @Override + public GenericNBTCompound getCompound(int idx) { + return new NBTCompound(obj.getCompoundOrEmpty(idx)); + } + public String toString() { + return obj.toString(); + } + } + + public static class OurBitStorage implements GenericBitStorage { + private final SimpleBitStorage bs; + public OurBitStorage(int bits, int count, long[] data) { + bs = new SimpleBitStorage(bits, count, data); + } + @Override + public int get(int idx) { + return bs.get(idx); + } + } +} diff --git a/bukkit-helper-26-2/src/test/java/org/dynmap/bukkit/helper/v26_2/NBTTest.java b/bukkit-helper-26-2/src/test/java/org/dynmap/bukkit/helper/v26_2/NBTTest.java new file mode 100644 index 000000000..347789fe3 --- /dev/null +++ b/bukkit-helper-26-2/src/test/java/org/dynmap/bukkit/helper/v26_2/NBTTest.java @@ -0,0 +1,78 @@ +package org.dynmap.bukkit.helper.v26_2; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.StringTag; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class NBTTest { + @Test + public void preservesNumericTypesAndMissingDefaults() { + CompoundTag tag = new CompoundTag(); + tag.putByte("b", (byte) 1); + tag.putShort("s", (short) 32000); + tag.putInt("i", -123456); + tag.putLong("l", 1234567890123L); + tag.putFloat("f", 0.25F); + tag.putDouble("d", 0.125); + NBT.NBTCompound nbt = new NBT.NBTCompound(tag); + assertTrue(nbt.getBoolean("b")); + assertEquals(32000, nbt.getShort("s")); + assertEquals(-123456, nbt.getInt("i")); + assertEquals(1234567890123L, nbt.getLong("l")); + assertEquals(0.25F, nbt.getFloat("f"), 0); + assertEquals(0.125, nbt.getDouble("d"), 0); + assertTrue(nbt.contains("i", 99)); + assertFalse(nbt.contains("i", 8)); + assertFalse(nbt.contains("missing", 99)); + assertEquals(0, nbt.getInt("missing")); + assertFalse(nbt.getBoolean("missing")); + } + + @Test + public void preservesChunkPaletteAndNestedCompounds() { + CompoundTag state = new CompoundTag(); + state.putString("Name", "minecraft:sulfur_stairs"); + CompoundTag properties = new CompoundTag(); + properties.putString("facing", "east"); + state.put("Properties", properties); + ListTag palette = new ListTag(); + palette.add(state); + CompoundTag chunk = new CompoundTag(); + chunk.put("palette", palette); + NBT.NBTCompound nbt = new NBT.NBTCompound(chunk); + assertEquals(1, nbt.getList("palette", 10).size()); + assertEquals("minecraft:sulfur_stairs", nbt.getList("palette", 10).getCompound(0).getString("Name")); + assertEquals("east", nbt.getList("palette", 10).getCompound(0).getCompound("Properties").getString("facing")); + assertEquals(0, nbt.getList("missing", 10).size()); + assertEquals("", nbt.getCompound("missing").getString("Name")); + } + + @Test + public void preservesArraysAndStringLists() { + CompoundTag tag = new CompoundTag(); + tag.putByteArray("b", new byte[] {1, -1}); + tag.putIntArray("i", new int[] {0, Integer.MAX_VALUE}); + tag.putLongArray("l", new long[] {Long.MIN_VALUE, 7}); + ListTag list = new ListTag(); + list.add(StringTag.valueOf("minecraft:plains")); + tag.put("biomes", list); + NBT.NBTCompound nbt = new NBT.NBTCompound(tag); + assertArrayEquals(new byte[] {1, -1}, nbt.getByteArray("b")); + assertArrayEquals(new int[] {0, Integer.MAX_VALUE}, nbt.getIntArray("i")); + assertArrayEquals(new long[] {Long.MIN_VALUE, 7}, nbt.getLongArray("l")); + assertEquals("minecraft:plains", nbt.getList("biomes", 8).getString(0)); + assertArrayEquals(new long[0], nbt.getLongArray("missing")); + } + + @Test + public void decodesPackedStatesAcrossLongBoundary() { + // Five-bit palette entries use 12 values per long, with four padding bits. + long[] data = new long[2]; + for (int i = 0; i < 20; i++) { data[i / 12] |= (long) i << ((i % 12) * 5); } + NBT.OurBitStorage storage = new NBT.OurBitStorage(5, 20, data); + for (int i = 0; i < 20; i++) { assertEquals(i, storage.get(i)); } + } +} diff --git a/bukkit-helper/build.gradle b/bukkit-helper/build.gradle index 9263aef69..ab4d954f8 100644 --- a/bukkit-helper/build.gradle +++ b/bukkit-helper/build.gradle @@ -8,7 +8,10 @@ eclipse { description = 'bukkit-helper' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' +} dependencies { implementation project(':dynmap-api') diff --git a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java index b85f6acaa..bc0019352 100644 --- a/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java +++ b/bukkit-helper/src/main/java/org/dynmap/bukkit/helper/BukkitVersionHelper.java @@ -18,6 +18,9 @@ * Helper for isolation of bukkit version specific issues */ public abstract class BukkitVersionHelper { + /** Modern state detail, when available; null preserves legacy ID/data change checks. */ + public String getBlockStateSignature(org.bukkit.block.Block block) { return null; } + public static BukkitVersionHelper helper = null; public static GenericChunkCache gencache; @@ -227,4 +230,4 @@ public void sendTitleText(Player p, String title, String subtitle, int fadeInTic public boolean useGenericCache() { return false; } -} \ No newline at end of file +} diff --git a/docs/minecraft26-validation.md b/docs/minecraft26-validation.md new file mode 100644 index 000000000..18f0de6a9 --- /dev/null +++ b/docs/minecraft26-validation.md @@ -0,0 +1,104 @@ +# Minecraft 26.2 候補 + +Issue #2 の対象は Paper / Spigot 26.2 の隔離検証用候補です。自動本番反映や一般向けJAR配布は行いません。 +R2マーカー修正 (#1) はこの差分に含めず、ビルド基盤 (#3) を前提にします。 + +## 上流と採否 + +- 上流PR: https://github.com/webbukkit/dynmap/pull/4271 (取得時は未マージ) +- 取得head: `f87c4dda5b7feea9ff60d68f96475d73d3eafd91` +- 採用元ソース: `46ba070e03267d942ff542371a91c6ca67e37c0e` +- 基点: `93b454efb8802dc7406d6873434f2aeec5c636f4` + +新helper、NBT/チャンク読み取り、ブロックモデル・テクスチャのソースを取り込みました。 +上流PRの `Plugin/*.jar`、Fabricの新プラットフォーム、Forgeビルドの削除・移動、 +作業用指示ファイルは取り込みません。Apache-2.0と既存の著作権・商標表示を維持し、 +取り込んだPNGは上流PRのMinecraft用標準テクスチャ資材です。 +銅ゴーレム像用に追加した4枚は、下記SHA-1の公式クライアントから取得した標準テクスチャです。 +ソースの公開とバイナリの一般配布は別に判断します。 + +Acecoreでは以下を調整しています。 + +- バージョン判定は26.2に限定し、旧サーバーの既存fallbackを維持。 + `(MC: ...)` がない版表記ではBukkit API版を読み、共有コアが1.0.0と誤認するのを防ぐ。 +- dev-bundleの動的指定を `26.2.build.105-stable` に固定。 +- Java 25 / Gradle 9.5.1 / Shadow 9.6.0 / paperweight 2.0.0-beta.21 は候補用。 + 元のGradle 8.14 / Shadow 8.1.7は既存ビルド用に維持。 +- 共通ビルド処理は `gradle/common.gradle` に集約。Java DSLは両Gradleで使える形式へ変更。 +- helperだけJava 25、共有コア・既存helperのコンパイルとコアテストはJava 21を使用。 + 共有コア/APIのJava 8ターゲットは維持。 +- Shadowのgroupだけの指定を明示的な正規表現に直し、Jetty/Servlet等の脱落を検査。 +- ブロック名リストで単一状態ブロックを飛ばし、複数状態を重複登録する上流helperの処理を、 + ブロックレジストリIDと名前の対応へ修正。 +- スキン応答のエラー時に元の応答本文をログへ出さない。 +- NBTの数値・欠損値、配列、チャンクパレット、long境界のビット展開をテスト。 + 旧Paper/新版Paper/パッチ版/不明形式の版判定もテスト。 +- 銅ゴーレム像の立方体による暫定表示を廃止。4ポーズ・4方向・8種類の酸化/ワックス状態と水没状態に対応。 + 公式26.2クライアント(SHA-1 `2dc72797acbc1b63fc16a11c4ac393605f453754`)の + CopperGolemModel / CopperGolemStatueBlockRendererの形状・UV・変換を照合した数値データを使用。 + 64pxのエンティティテクスチャを面ごとに切り出し、アンテナを含めて描画します。 +- パッチの可視範囲検査でUの代わりにVを使っていた計算を修正。台形の端点も検査します。 +- 像への右クリック後に実際のブロック状態が変わった場合だけ再描画。 + 26.2では旧Materialのdata値への変換を使わず、旧helperのID/data比較は維持。 +- golden dandelionと鉢植えのモデルを26.1以降に限定し、旧版で存在しないブロックのエラーを防止。 + +## ビルド + +JDK 21と25の両方をインストールし、候補用wrapperはJAVA_HOMEを25にします。 +Gradleが21を検出しない場合は `-Porg.gradle.java.installations.paths=` を追加します。 + +```sh +# Minecraft 26候補: JAVA_HOME=JDK25 +bash gradlew-minecraft26 verifySpigotJar --no-daemon +# 既存向け: JAVA_HOME=JDK21 +bash gradlew -PdynmapPlatform=spigot verifySpigotJar --no-daemon +``` + +Windowsではそれぞれ `gradlew-minecraft26.bat` / `gradlew.bat` を使います。 +候補出力は `target/Dynmap-3.9-SNAPSHOT-spigot-mc26.jar`、版番号には `-mc26` を付けます。 +既存向けの `*-spigot.jar` と区別してください。監査記録は検証のたびに上書きされるため、 +複数プロファイルの証拠を保存するときはCIのように別worktree/jobを使います。 + +## 稼働検証の確認項目 + +既存設定やR2資格情報を持ち込まず、localhost限定・新規ワールド・ファイル保存で検証します。 +Paper 26.2 build 105 / Java 25を主対象とし、旧Paperは既存向けJARの回帰検証対象です。 + +1. Dynmap有効化とJetty起動。未対応platform、Class/Method欠落、NBT例外がないこと。 +2. sulfur/cinnabar全系列、上下/二重slab、階段の向き、wall、sulfur spike、 + golden dandelionと鉢植え、creaking heart各状態、既存の石・ガラス・水・葉を描画。 +3. surface/flat、部分更新、ズーム画像、ブラウザ表示を確認。 +4. 同じ入力で旧Paper向けビルドの起動・レンダー・マーカーを確認。 +5. テストサーバーを正常停止し、ソース版・JAR SHA-256・ログを記録。 + +銅ゴーレム像は256状態のメッシュを単体検査し、同じ256状態を実サーバーにも配置します。 +通常の設置・破壊・ポーズ変更の検証方法は [隔離操作試験](../validation/minecraft26/README.md) を参照してください。 +Fabric/Forge 26.2の新規対応は、今回選択したPaper/Spigot用ソースの取り込み範囲に含みません。 +既存ローダーへの影響は、元のモジュールを保持した標準ビルドと共有コアのテストで確認します。 +本番へ進める際は [運用手順](acecore-maintenance.md) のバックアップと個別承認に従います。 + +## 2026-09-09の実行結果 + +実行JARのソースは `18eed07ec78585a42cfd60242df6053ca1c360c7`。 +後続変更は検証プラグイン・記録・旧Forgeの依存取得先の登録順です。候補JARの実装変更はありません。 + +| 対象 | 検証結果 | +| --- | --- | +| Paper 26.2 build 105 / Java 25 | 256状態の像、surface全描画と更新全体の完了、flat、zoom、HTTP成功 | +| Spigot 26.2 (8db49a2 / efaae75) / Java 25 | 同じ256状態と描画・更新試験成功、ブラウザで形状・色・水没表示を確認 | +| 両26.2サーバーの通常更新 | 設置16件で対象タイル変更、破壊16件で元のSHA-256へ復元、右クリックのポーズ変更で再変更 | +| Paper 1.21.8 / Java 21 | 起動、WorldGuard合成領域マーカー、既存16種類・状態のsurface/flat、HTTP成功 | +| 候補ビルド | コア96、NBT4、版判定4の計104テスト、同梱クラス・版・SHA-256検査成功 | +| 既存向けビルド | コア96、版判定4の計100テスト、同梱検査成功 | + +通常更新の試験は各操作間にDynmapの描画コマンドを実行していません。 +最終ログにERROR/SEVERE、Class/Method欠落、対象の描画例外がないことを検査し、各サーバーを終了コード0で停止しました。 +先行試験のタイムアウト・検証プラグインのAPI差・重複配置は修正後に再実行しています。 + +| JAR | SHA-256 | +| --- | --- | +| `Dynmap-3.9-SNAPSHOT-spigot-mc26.jar` | `f41cc98770102cb800f4f06a6515bd818e31c8d63250be2afd5046c5dbb04f40` | +| `Dynmap-3.9-SNAPSHOT-spigot.jar` | `24f27932ac795164fd9f8bea28bb1fe02b0e06d00494c888b263ad83caf7c0db` | + +このソースのCI: https://github.com/acecore-systems/dynmap/actions/runs/34243308356 (core / spigot / spigot26成功)。 +Spigotは公式BuildToolsの26.2定義からローカルビルドしました。サーバーJARの一般配布はしていません。 diff --git a/dynmap-api/build.gradle b/dynmap-api/build.gradle index fe9231737..5c106eb24 100644 --- a/dynmap-api/build.gradle +++ b/dynmap-api/build.gradle @@ -8,7 +8,10 @@ eclipse { description = "dynmap-api" -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' +} dependencies { compileOnly group: 'org.bukkit', name: 'bukkit', version:'1.7.10-R0.1-SNAPSHOT' diff --git a/gradle/acecore-verification.gradle b/gradle/acecore-verification.gradle index a31d34cd7..3a74a7432 100644 --- a/gradle/acecore-verification.gradle +++ b/gradle/acecore-verification.gradle @@ -14,11 +14,21 @@ def sha256 = { File file -> if (findProject(':spigot') != null) { tasks.register('verifySpigotJar') { - dependsOn ':spigot:shadowJar', ':DynmapCore:test' + dependsOn ':spigot:shadowJar', ':DynmapCore:test', ':spigot:test' + if (findProject(':bukkit-helper-26-2') != null) { + dependsOn ':bukkit-helper-26-2:test' + } doLast { File jar = project(':spigot').tasks.named('shadowJar').get().archiveFile.get().asFile String expectedVersion = "${project.version}-${globals.buildNumber}" new ZipFile(jar).withCloseable { zip -> + if (zip.entries().any { it.name.startsWith('net/minecraft/') || it.name.startsWith('org/bukkit/craftbukkit/') }) { + throw new GradleException('Server implementation classes must not be bundled') + } + if (findProject(':bukkit-helper-26-2') != null && + zip.getEntry('org/dynmap/bukkit/helper/v26_2/BukkitVersionHelperSpigot26_2.class') == null) { + throw new GradleException('Minecraft 26 helper is missing') + } [ 'org/dynmap/bukkit/DynmapPlugin.class', 'org/dynmap/DynmapCore.class', diff --git a/gradle/common.gradle b/gradle/common.gradle new file mode 100644 index 000000000..af049235e --- /dev/null +++ b/gradle/common.gradle @@ -0,0 +1,79 @@ +apply plugin: 'eclipse' + +eclipse { + project { + name = "Dynmap" + } +} + +allprojects { + repositories { + if (providers.gradleProperty('useMavenLocal').isPresent()) { mavenLocal() } + // ForgeGradle resolves userdev modules while applying its plugin, before it + // finishes adding repositories. Register its existing source up front. + if (project.name.startsWith('forge-')) { maven { url 'https://maven.minecraftforge.net/' } } + mavenCentral() + maven { url "https://repo.mikeprimm.com" } + maven { url 'https://libraries.minecraft.net/' } + maven { url "https://oss.sonatype.org/content/repositories/releases" } + maven { url "https://oss.sonatype.org/content/repositories/snapshots" } + maven { url "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" } + maven { url "https://repo.codemc.org/repository/maven-public/" } + } + + apply plugin: 'java' + + group = 'us.dynmap' + version = '3.9-SNAPSHOT' + +} + +class Globals { + String buildNumber +} +def gitOutput = { List arguments -> + providers.exec { commandLine(['git'] + arguments) }.standardOutput.asText.get().trim() +} +def sourceRevision = gitOutput(['rev-parse', 'HEAD']) +def sourceDirty = !gitOutput(['status', '--porcelain', '--untracked-files=normal']).isEmpty() +ext { + acecoreRevision = sourceRevision + acecoreDirty = sourceDirty + globals = new Globals(buildNumber: 'acecore-' + sourceRevision.take(12) + + (providers.gradleProperty('dynmapPlatform').getOrElse('all') == 'spigot26' ? '-mc26' : '') + + (sourceDirty ? '-dirty' : '')) +} + +subprojects { + apply plugin: rootProject.ext.shadowPluginId + apply plugin: 'java' + apply plugin: 'maven-publish' + + java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + if (rootProject.ext.shadowPluginId == 'com.gradleup.shadow') { + toolchain { languageVersion = JavaLanguageVersion.of(21) } + } + } + tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' + } + tasks.withType(ProcessResources).configureEach { + inputs.property('acecoreBuildNumber', rootProject.ext.globals.buildNumber) + inputs.property('dynmapVersion', project.version.toString()) + } + tasks.withType(AbstractArchiveTask).configureEach { + preserveFileTimestamps = false + reproducibleFileOrder = true + } +} + +apply from: 'gradle/acecore-verification.gradle' + +clean { + delete "target" +} + +task setupCIWorkspace { +} diff --git a/gradle/minecraft26/gradle-wrapper.jar b/gradle/minecraft26/gradle-wrapper.jar new file mode 100644 index 000000000..e6441136f Binary files /dev/null and b/gradle/minecraft26/gradle-wrapper.jar differ diff --git a/gradle/minecraft26/gradle-wrapper.properties b/gradle/minecraft26/gradle-wrapper.properties new file mode 100644 index 000000000..ff3a87e06 --- /dev/null +++ b/gradle/minecraft26/gradle-wrapper.properties @@ -0,0 +1,8 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionSha256Sum=bafc141b619ad6350fd975fc903156dd5c151998cc8b058e8c1044ab5f7b031f diff --git a/gradlew-minecraft26 b/gradlew-minecraft26 new file mode 100644 index 000000000..502cd7706 --- /dev/null +++ b/gradlew-minecraft26 @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/minecraft26/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain -PdynmapPlatform=spigot26 \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew-minecraft26.bat b/gradlew-minecraft26.bat new file mode 100644 index 000000000..9a95f3ade --- /dev/null +++ b/gradlew-minecraft26.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\minecraft26\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain -PdynmapPlatform=spigot26 %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle index 2c538ca46..1a8369b1c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,7 +2,7 @@ pluginManagement { repositories { gradlePluginPortal() maven { url "https://maven.fabricmc.net/" } - maven { url "https://papermc.io/repo/repository/maven-public/" } + maven { url "https://repo.papermc.io/repository/maven-public/" } } } @@ -10,9 +10,16 @@ rootProject.name = 'dynmap-common' // Focused builds avoid configuring unrelated mod loaders; the default keeps upstream scope. def platform = providers.gradleProperty('dynmapPlatform').getOrElse('all') -if (!(platform in ['all', 'core', 'spigot'])) { +if (!(platform in ['all', 'core', 'spigot', 'spigot26'])) { throw new GradleException("Unknown dynmapPlatform: ${platform}") } +if (platform == 'spigot26') { + if (GradleVersion.current() < GradleVersion.version('9.5.1') || !JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_25)) { + throw new GradleException('spigot26 requires the Minecraft 26 wrapper and JDK 25 or newer') + } + rootProject.buildFileName = 'build-minecraft26.gradle' + include ':bukkit-helper-26-2' +} def modules = [ 'spigot', 'bukkit-helper-113-2', @@ -66,5 +73,5 @@ def modules = [ ] modules.findAll { name -> platform == 'all' || name in ['DynmapCore', 'DynmapCoreAPI'] || - (platform == 'spigot' && (name in ['spigot', 'dynmap-api'] || name.startsWith('bukkit-helper'))) + (platform in ['spigot', 'spigot26'] && (name in ['spigot', 'dynmap-api'] || name.startsWith('bukkit-helper'))) }.each { name -> include ':' + name } diff --git a/spigot/build.gradle b/spigot/build.gradle index 9fa548e1d..b18363ae3 100644 --- a/spigot/build.gradle +++ b/spigot/build.gradle @@ -16,9 +16,18 @@ repositories { } } -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +java { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' + // Helpers are selected through reflection for the running server's Java version. + disableAutoTargetJvm() +} dependencies { + testImplementation 'junit:junit:4.13.2' + if (findProject(':bukkit-helper-26-2') != null) { + implementation(project(':bukkit-helper-26-2')) { transitive = false } + } implementation('org.bukkit:bukkit:1.10.2-R0.1-SNAPSHOT') { transitive = false } compileOnly('com.nijikokun.bukkit:Permissions:3.1.6') { transitive = false } compileOnly('me.lucko.luckperms:luckperms-api:4.3') { transitive = false } @@ -128,7 +137,11 @@ jar { shadowJar { dependencies { - include(dependency('org.bstats::')) + include(dependency('org.bstats:bstats-bukkit:.*')) + include(dependency('org.bstats:bstats-base:.*')) + if (findProject(':bukkit-helper-26-2') != null) { + include(dependency(':bukkit-helper-26-2')) + } include(dependency(':dynmap-api')) include(dependency(":DynmapCore")) include(dependency(':bukkit-helper')) @@ -160,11 +173,11 @@ shadowJar { relocate('org.bstats', 'org.dynmap.bstats') destinationDirectory = file '../target' archiveBaseName = "Dynmap" - archiveClassifier = 'spigot' + archiveClassifier = findProject(':bukkit-helper-26-2') != null ? 'spigot-mc26' : 'spigot' } shadowJar.doLast { task -> - ant.checksum file: task.archivePath + ant.checksum file: task.archiveFile.get().asFile } artifacts { diff --git a/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java b/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java index 48c8b4fe1..8c190a543 100644 --- a/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java +++ b/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java @@ -52,6 +52,8 @@ import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerBedLeaveEvent; import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.server.PluginEnableEvent; @@ -211,6 +213,7 @@ private static class BlockToCheck { Location loc; int typeid; byte data; + String stateSignature; String trigger; }; private LinkedList blocks_to_check = null; @@ -921,13 +924,7 @@ public void onEnable() { /* Get MC version */ String bukkitver = getServer().getVersion(); - String mcver = "1.0.0"; - int idx = bukkitver.indexOf("(MC: "); - if(idx > 0) { - mcver = bukkitver.substring(idx+5); - idx = mcver.indexOf(")"); - if(idx > 0) mcver = mcver.substring(0, idx); - } + String mcver = MinecraftVersion.fromServer(bukkitver, getServer().getBukkitVersion()); // Initialize block states helper.initializeBlockStates(); @@ -1302,7 +1299,8 @@ public void run() { /* Avoid stationary and moving water churn */ if(bt == 9) bt = 8; if(btt.typeid == 9) btt.typeid = 8; - if((bt != btt.typeid) || (btt.data != w.getBlockAt(loc).getData())) { + if((bt != btt.typeid) || (btt.stateSignature == null && btt.data != w.getBlockAt(loc).getData()) || + (btt.stateSignature != null && !btt.stateSignature.equals(helper.getBlockStateSignature(w.getBlockAt(loc))))) { String wn = getWorld(w).getName(); invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), btt.trigger); @@ -1326,7 +1324,8 @@ private void checkBlock(Block b, String trigger) { BlockToCheck btt = new BlockToCheck(); btt.loc = b.getLocation(); btt.typeid = getBlockIdFromBlock(b); - btt.data = b.getData(); + btt.stateSignature = helper.getBlockStateSignature(b); + btt.data = btt.stateSignature == null ? b.getData() : 0; btt.trigger = trigger; blocks_to_check_accum.add(btt); /* Add to accumulator */ btth.startIfNeeded(); @@ -1384,6 +1383,16 @@ private void registerEvents() { if(onplace) { Listener placelistener = new Listener() { + @EventHandler(priority=EventPriority.MONITOR) + public void onStatueInteract(PlayerInteractEvent event) { + Block block = event.getClickedBlock(); + if (event.getAction() == Action.RIGHT_CLICK_BLOCK && block != null && + event.useInteractedBlock() != org.bukkit.event.Event.Result.DENY && + block.getType().name().endsWith("COPPER_GOLEM_STATUE")) { + // Interaction fires before the new pose/oxidation/wax state is applied. + checkBlock(block, "blockplace"); + } + } @EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true) public void onBlockPlace(BlockPlaceEvent event) { Location loc = event.getBlock().getLocation(); diff --git a/spigot/src/main/java/org/dynmap/bukkit/Helper.java b/spigot/src/main/java/org/dynmap/bukkit/Helper.java index 26cc72e7f..aa7085ecc 100644 --- a/spigot/src/main/java/org/dynmap/bukkit/Helper.java +++ b/spigot/src/main/java/org/dynmap/bukkit/Helper.java @@ -40,6 +40,9 @@ else if(Bukkit.getServer().getClass().getName().contains("GlowServer")) { Log.info("Loading Glowstone support"); BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.BukkitVersionHelperGlowstone"); } + else if (MinecraftVersion.fromServer(v, Bukkit.getBukkitVersion()).equals("26.2")) { + BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.v26_2.BukkitVersionHelperSpigot26_2"); + } else if (v.contains("(MC: 1.21)") || v.contains("(MC: 1.21.1)")) { BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.v121.BukkitVersionHelperSpigot121"); } diff --git a/spigot/src/main/java/org/dynmap/bukkit/MinecraftVersion.java b/spigot/src/main/java/org/dynmap/bukkit/MinecraftVersion.java new file mode 100644 index 000000000..1ea0b9211 --- /dev/null +++ b/spigot/src/main/java/org/dynmap/bukkit/MinecraftVersion.java @@ -0,0 +1,18 @@ +package org.dynmap.bukkit; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +final class MinecraftVersion { + private static final Pattern LEGACY = Pattern.compile("\\(MC: ([0-9]+(?:\\.[0-9]+){1,2})\\)"); + private static final Pattern API = Pattern.compile("^([0-9]+(?:\\.[0-9]+){1,2})(?:-|$)"); + + private MinecraftVersion() { } + + static String fromServer(String serverVersion, String bukkitVersion) { + Matcher legacy = LEGACY.matcher(serverVersion); + if (legacy.find()) { return legacy.group(1); } + Matcher api = API.matcher(bukkitVersion); + return api.find() ? api.group(1) : "1.0.0"; + } +} diff --git a/spigot/src/test/java/org/dynmap/bukkit/MinecraftVersionTest.java b/spigot/src/test/java/org/dynmap/bukkit/MinecraftVersionTest.java new file mode 100644 index 000000000..48f28c4e8 --- /dev/null +++ b/spigot/src/test/java/org/dynmap/bukkit/MinecraftVersionTest.java @@ -0,0 +1,28 @@ +package org.dynmap.bukkit; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; + +public class MinecraftVersionTest { + @Test + public void readsLegacyPaperVersion() { + assertEquals("1.21.8", MinecraftVersion.fromServer("1.21.8-60-abcdef (MC: 1.21.8)", "1.21.8-R0.1-SNAPSHOT")); + } + + @Test + public void readsNewPaperVersionWithoutMcSuffix() { + assertEquals("26.2", MinecraftVersion.fromServer("26.2-105-abcdef", "26.2-R0.1-SNAPSHOT")); + } + + @Test + public void acceptsVersionAtStartAndKeepsPatchNumber() { + assertEquals("1.20.1", MinecraftVersion.fromServer("(MC: 1.20.1)", "unknown")); + assertEquals("26.2.1", MinecraftVersion.fromServer("custom", "26.2.1-R0.1-SNAPSHOT")); + } + + @Test + public void doesNotTreatServerBuildNumberAsMinecraftVersion() { + assertEquals("1.0.0", MinecraftVersion.fromServer("git-custom-12345", "unknown")); + assertEquals("1.0.0", MinecraftVersion.fromServer("26.20-105", "26.2evil")); + } +} diff --git a/validation/minecraft26/README.md b/validation/minecraft26/README.md new file mode 100644 index 000000000..a3ce8fd9b --- /dev/null +++ b/validation/minecraft26/README.md @@ -0,0 +1,42 @@ +# 26.2の隔離操作試験 + +`ValidationPlugin.java` は検証専用です。本番JARには含めません。 +localhost限定・合成ワールドのPaper/Spigot 26.2で、コンソールからだけ実行します。 +水没サンプル同士が干渉しないよう水流を止め、時刻とランダムティックも固定します。 + +試験用ServerPlayerが通常の `ServerPlayerGameMode.useItemOn` / `destroyBlock` を呼びます。 +Bukkitイベントの直接注入やDynmapの描画API呼び出しは行いません。 +クライアントのログイン・パケット通信・マウス操作自体はこの試験の対象ではありません。 + +## ビルド + +JDK 25で候補の `verifySpigotJar` を実行してから、同じ作業ディレクトリで次を実行します。 +JDK 21を自動検出しない環境は通常の候補ビルドと同じtoolchainパラメーターを追加してください。 + +```sh +bash gradlew-minecraft26 -I validation/minecraft26/classpath.init.gradle :bukkit-helper-26-2:validationClasspath +mkdir -p build/validation/minecraft26/classes +javac -cp "$(cat build/validation/minecraft26/classpath.txt)" -d build/validation/minecraft26/classes validation/minecraft26/ValidationPlugin.java +cp validation/minecraft26/plugin.yml build/validation/minecraft26/classes/ +jar --create --file build/validation/minecraft26/validation.jar -C build/validation/minecraft26/classes . +``` + +Windowsはwrapperを `.bat` にし、クラスパスを `Get-Content -Raw` で渡します。 + +## 入力と判定 + +ワールドのY=0に白い床を作り、X/Z=4..7のY=1を空けておきます。 +X=12,Y=1,Z=12には `copper_golem_statue[copper_golem_pose=standing,facing=north,waterlogged=false]` を置きます。 +先にsurfaceを描画し、更新が落ち着いてから次の各操作を個別に実行します。 + +1. `dynmapvalidate place`: ダイヤモンドブロックを16個設置し、未キャンセルのBlockPlaceEvent 16件を検査。 +2. `dynmapvalidate break`: 16個を破壊し、未キャンセルのBlockBreakEvent 16件を検査。 +3. `dynmapvalidate pose`: 像を右クリックする通常処理でポーズが変わることを検査。 + +各操作間に描画コマンドを挟まず、対象のsurface通常タイルのSHA-256を比較します。 +設置で変更、破壊で設置前へ復元、ポーズ変更で再変更されることを確認します。 +zoomタイルや離れたタイルの変更だけを合格にしないでください。 +大量のサンプル変更直後は通常更新のキューも処理されるため、対象範囲をvisibilitylimitsで限定します。 + +別途fullrender/updaterenderの完了行、flat、zoom、HTTP、実際のブラウザ表示を確認します。 +試験後は `stop` で正常終了し、使用した候補の版・SHA-256とログを保存します。 diff --git a/validation/minecraft26/ValidationPlugin.java b/validation/minecraft26/ValidationPlugin.java new file mode 100644 index 000000000..b9e849a4b --- /dev/null +++ b/validation/minecraft26/ValidationPlugin.java @@ -0,0 +1,88 @@ +import java.util.UUID; +import com.mojang.authlib.GameProfile; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.PacketFlow; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ClientInformation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.CommonListenerCookie; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.GameType; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import org.bukkit.command.*; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.event.*; +import org.bukkit.event.block.*; +import org.bukkit.plugin.java.JavaPlugin; + +public class ValidationPlugin extends JavaPlugin implements Listener { + private ServerPlayer player; + private int places, breaks; + public void onEnable() { + getServer().getPluginManager().registerEvents(this, this); + org.bukkit.World world = getServer().getWorlds().get(0); + world.setTime(6000); + // Spigot registers vanilla commands after plugin enablement. + getServer().getScheduler().runTask(this, () -> { + setRule("advance_time", "false"); + setRule("random_tick_speed", "0"); + }); + } + private void setRule(String name, String value) { + // GameRule is a class in Paper and an interface in Spigot 26.2. + // Use the shared vanilla command instead of linking either API representation. + if (!getServer().dispatchCommand(getServer().getConsoleSender(), "minecraft:gamerule minecraft:" + name + " " + value)) + throw new IllegalStateException("Cannot set game rule " + name); + } + // Keep waterlogged samples independent; flowing water would obscure adjacent dry samples. + @EventHandler public void fluid(BlockFromToEvent event) { event.setCancelled(true); } + @EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true) + public void placed(BlockPlaceEvent event) { if (event.getPlayer().getName().equals("DynmapValidator")) places++; } + @EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true) + public void broken(BlockBreakEvent event) { if (event.getPlayer().getName().equals("DynmapValidator")) breaks++; } + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof ConsoleCommandSender)) return false; + try { + ServerLevel level = ((CraftWorld)getServer().getWorlds().get(0)).getHandle(); + if (player == null) { + MinecraftServer server = ((CraftServer)getServer()).getServer(); + GameProfile profile = new GameProfile(UUID.nameUUIDFromBytes("OfflinePlayer:DynmapValidator".getBytes(java.nio.charset.StandardCharsets.UTF_8)), "DynmapValidator"); + player = new ServerPlayer(server, level, profile, ClientInformation.createDefault()); + player.connection = new ServerGamePacketListenerImpl(server, new Connection(PacketFlow.SERVERBOUND), player, CommonListenerCookie.createInitial(profile, false)); + player.gameMode.changeGameModeForPlayer(GameType.CREATIVE); + player.setPos(6, 2, 2); + } + if (args[0].equals("pose")) { + String old = level.getWorld().getBlockAt(12,1,12).getBlockData().getAsString(); + player.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY); + player.gameMode.useItemOn(player, level, ItemStack.EMPTY, InteractionHand.MAIN_HAND, + new BlockHitResult(new Vec3(12.5,1.5,12), Direction.NORTH, new BlockPos(12,1,12), false)); + String changed = level.getWorld().getBlockAt(12,1,12).getBlockData().getAsString(); + if (old.equals(changed)) throw new IllegalStateException("Pose did not change"); + getLogger().info("VALIDATION pose " + changed); + return true; + } + int before = args[0].equals("place") ? places : breaks; + for (int x=4; x<8; x++) for (int z=4; z<8; z++) { + if (args[0].equals("place")) { + ItemStack stack = new ItemStack(Items.DIAMOND_BLOCK, 64); + player.setItemInHand(InteractionHand.MAIN_HAND, stack); + player.gameMode.useItemOn(player, level, stack, InteractionHand.MAIN_HAND, + new BlockHitResult(new Vec3(x+.5, 1, z+.5), Direction.UP, new BlockPos(x, 0, z), false)); + } else player.gameMode.destroyBlock(new BlockPos(x,1,z)); + } + int events = (args[0].equals("place") ? places : breaks) - before; + if (events != 16) throw new IllegalStateException("Expected 16 events, got " + events); + getLogger().info("VALIDATION " + args[0] + " events=" + events); + } catch (Throwable error) { getLogger().log(java.util.logging.Level.SEVERE,"VALIDATION FAILED",error); } + return true; + } +} diff --git a/validation/minecraft26/classpath.init.gradle b/validation/minecraft26/classpath.init.gradle new file mode 100644 index 000000000..1b8886e38 --- /dev/null +++ b/validation/minecraft26/classpath.init.gradle @@ -0,0 +1,9 @@ +gradle.projectsEvaluated { + rootProject.project(':bukkit-helper-26-2').tasks.register('validationClasspath') { + doLast { + def output = rootProject.file('build/validation/minecraft26/classpath.txt') + output.parentFile.mkdirs() + output.text = rootProject.project(':bukkit-helper-26-2').sourceSets.main.compileClasspath.asPath + } + } +} diff --git a/validation/minecraft26/plugin.yml b/validation/minecraft26/plugin.yml new file mode 100644 index 000000000..3852dd0df --- /dev/null +++ b/validation/minecraft26/plugin.yml @@ -0,0 +1,9 @@ +name: DynmapValidation +version: '1' +main: ValidationPlugin +api-version: '26.2' +load: POSTWORLD +depend: [dynmap] +commands: + dynmapvalidate: + description: Isolated console-only rendering validation