From 734a687045d7208c834409aac4adff474350e279 Mon Sep 17 00:00:00 2001 From: Gui <51219838+gui-ace@users.noreply.github.com> Date: Tue, 8 Sep 2026 22:32:22 +0900 Subject: [PATCH 1/7] =?UTF-8?q?Paper=2026.2=E5=80=99=E8=A3=9C=E3=81=A8?= =?UTF-8?q?=E7=8B=AC=E7=AB=8B=E3=81=97=E3=81=9FJava=2025=E3=83=93=E3=83=AB?= =?UTF-8?q?=E3=83=89=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 12 +- DynmapCore/build.gradle | 13 +- DynmapCore/src/main/resources/models_1.txt | 30 +- DynmapCore/src/main/resources/texture_1.txt | 88 ++++ .../textures/block/chiseled_cinnabar.png | Bin 0 -> 240 bytes .../textures/block/chiseled_sulfur.png | Bin 0 -> 215 bytes .../minecraft/textures/block/cinnabar.png | Bin 0 -> 223 bytes .../textures/block/cinnabar_bricks.png | Bin 0 -> 244 bytes .../textures/block/golden_dandelion.png | Bin 0 -> 160 bytes .../textures/block/polished_cinnabar.png | Bin 0 -> 239 bytes .../textures/block/polished_sulfur.png | Bin 0 -> 210 bytes .../textures/block/potent_sulfur.png | Bin 0 -> 203 bytes .../minecraft/textures/block/sulfur.png | Bin 0 -> 184 bytes .../textures/block/sulfur_bricks.png | Bin 0 -> 209 bytes .../textures/block/sulfur_spike_down_base.png | Bin 0 -> 200 bytes .../block/sulfur_spike_down_frustum.png | Bin 0 -> 194 bytes .../block/sulfur_spike_down_middle.png | Bin 0 -> 194 bytes .../textures/block/sulfur_spike_down_tip.png | Bin 0 -> 165 bytes .../block/sulfur_spike_down_tip_merge.png | Bin 0 -> 174 bytes .../textures/block/sulfur_spike_up_base.png | Bin 0 -> 211 bytes .../block/sulfur_spike_up_frustum.png | Bin 0 -> 192 bytes .../textures/block/sulfur_spike_up_middle.png | Bin 0 -> 196 bytes .../textures/block/sulfur_spike_up_tip.png | Bin 0 -> 162 bytes .../block/sulfur_spike_up_tip_merge.png | Bin 0 -> 175 bytes DynmapCoreAPI/build.gradle | 5 +- build-minecraft26.gradle | 7 + build.gradle | 73 +-- bukkit-helper-113-2/build.gradle | 5 +- bukkit-helper-114-1/build.gradle | 5 +- bukkit-helper-115/build.gradle | 5 +- bukkit-helper-116-2/build.gradle | 5 +- bukkit-helper-116-3/build.gradle | 5 +- bukkit-helper-116-4/build.gradle | 5 +- bukkit-helper-116/build.gradle | 5 +- bukkit-helper-117/build.gradle | 5 +- bukkit-helper-118-2/build.gradle | 5 +- bukkit-helper-118/build.gradle | 5 +- bukkit-helper-119-3/build.gradle | 5 +- bukkit-helper-119-4/build.gradle | 5 +- bukkit-helper-119/build.gradle | 5 +- bukkit-helper-120-2/build.gradle | 5 +- bukkit-helper-120-4/build.gradle | 5 +- bukkit-helper-120-5/build.gradle | 5 +- bukkit-helper-120/build.gradle | 5 +- bukkit-helper-121-10/build.gradle | 5 +- bukkit-helper-121-11/build.gradle | 5 +- bukkit-helper-121-3/build.gradle | 5 +- bukkit-helper-121-4/build.gradle | 5 +- bukkit-helper-121-5/build.gradle | 5 +- bukkit-helper-121-6/build.gradle | 5 +- bukkit-helper-121/build.gradle | 5 +- bukkit-helper-26-2/.gitignore | 2 + bukkit-helper-26-2/build.gradle | 42 ++ .../v26_2/BukkitVersionHelperSpigot26_2.java | 436 ++++++++++++++++++ .../helper/v26_2/MapChunkCache26_2.java | 111 +++++ .../org/dynmap/bukkit/helper/v26_2/NBT.java | 145 ++++++ .../dynmap/bukkit/helper/v26_2/NBTTest.java | 78 ++++ bukkit-helper/build.gradle | 5 +- docs/minecraft26-validation.md | 66 +++ dynmap-api/build.gradle | 5 +- gradle/acecore-verification.gradle | 10 + gradle/common.gradle | 76 +++ gradle/minecraft26/gradle-wrapper.jar | Bin 0 -> 43453 bytes gradle/minecraft26/gradle-wrapper.properties | 8 + gradlew-minecraft26 | 249 ++++++++++ gradlew-minecraft26.bat | 92 ++++ settings.gradle | 13 +- spigot/build.gradle | 20 +- .../main/java/org/dynmap/bukkit/Helper.java | 3 + 69 files changed, 1596 insertions(+), 113 deletions(-) create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/chiseled_cinnabar.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/chiseled_sulfur.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/cinnabar.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/cinnabar_bricks.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/golden_dandelion.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/polished_cinnabar.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/polished_sulfur.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/potent_sulfur.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_bricks.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_base.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_frustum.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_middle.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_tip.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_down_tip_merge.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_base.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_frustum.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_middle.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_tip.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/block/sulfur_spike_up_tip_merge.png create mode 100644 build-minecraft26.gradle create mode 100644 bukkit-helper-26-2/.gitignore create mode 100644 bukkit-helper-26-2/build.gradle create mode 100644 bukkit-helper-26-2/src/main/java/org/dynmap/bukkit/helper/v26_2/BukkitVersionHelperSpigot26_2.java create mode 100644 bukkit-helper-26-2/src/main/java/org/dynmap/bukkit/helper/v26_2/MapChunkCache26_2.java create mode 100644 bukkit-helper-26-2/src/main/java/org/dynmap/bukkit/helper/v26_2/NBT.java create mode 100644 bukkit-helper-26-2/src/test/java/org/dynmap/bukkit/helper/v26_2/NBTTest.java create mode 100644 docs/minecraft26-validation.md create mode 100644 gradle/common.gradle create mode 100644 gradle/minecraft26/gradle-wrapper.jar create mode 100644 gradle/minecraft26/gradle-wrapper.properties create mode 100644 gradlew-minecraft26 create mode 100644 gradlew-minecraft26.bat diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3576d9a54..cf07b4bc0 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,6 @@ jobs: path: | DynmapCore/build/reports/tests/ DynmapCore/build/test-results/ + bukkit-helper-26-2/build/reports/tests/ + bukkit-helper-26-2/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/resources/models_1.txt b/DynmapCore/src/main/resources/models_1.txt index 5292b2438..56aa28627 100644 --- a/DynmapCore/src/main/resources/models_1.txt +++ b/DynmapCore/src/main/resources/models_1.txt @@ -880,7 +880,7 @@ patchblock:id=tall_seagrass,id=seagrass,patch0=VertX075,patch1=VertX075@90,patch # Oxeye daisy # 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 +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,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 +1036,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 +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 +1638,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 +1894,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 +3457,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 diff --git a/DynmapCore/src/main/resources/texture_1.txt b/DynmapCore/src/main/resources/texture_1.txt index 730baa859..7133a7e7a 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,61 @@ 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=%copper_golem_statue,id=%waxed_copper_golem_statue,allfaces=0:copper_block,stdrot=true +[26.2-]block:id=%exposed_copper_golem_statue,id=%waxed_exposed_copper_golem_statue,allfaces=0:exposed_copper,stdrot=true +[26.2-]block:id=%weathered_copper_golem_statue,id=%waxed_weathered_copper_golem_statue,allfaces=0:weathered_copper,stdrot=true +[26.2-]block:id=%oxidized_copper_golem_statue,id=%waxed_oxidized_copper_golem_statue,allfaces=0:oxidized_copper,stdrot=true +[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 +5059,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 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 0000000000000000000000000000000000000000..e3c3f0ce8e0d2981958a0207dc8cf086d5fdc03c GIT binary patch literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!dVo)eYk`V-gTDR_|A5ubj>~K; z=a?Dv8|d`gS9t(79Hm?WNm1*oOP)5S5Q;+E+tPa$VR4(5x~Qa;Gn z{Qs<0rj^fp)#1;d8-8vNEmvC}yM9_&$f376o|%s$h1n)h{MEFy)7CdG79O?s*!6fl zkLT-}D=a2%Z(7UuPuMa&%0{&MzR{a6hgi7|sO}Konc_d;)U}u;w~`fBTJLo}9=fsk me&OMY{&#l8fg2*~KQLYrU}5(>+MWP(4}+(xpUXO@geCy$SXpTR literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..1eadf25261d5738afc489d755a1a70ff1f5806b2 GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!T!2rA>)m@r=g(yvI~a3hOZ=|Y z(YqH!&ad}h*%`QYO5o&tpMAf}6M!m9JY5_^DsHhJY;;@4IrkOy%Eg9)5F`4`)nXQrw@>zU2zv!tFN$&nwJwInt49eDL(ynm*3y z+vXSgPM98cqWD&4oFS**r`oj8{pUT-?eh6Q?dztKkFLvj*ljFlTvyM!z&h4AtPbRK N22WQ%mvv4FO#peKSY!YI literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..c983786a4900d304401d57f379f6fa17d90b46c8 GIT binary patch literal 223 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Vt`MG>ojktR!6HmJDWluzxt4n zrih6CjO=6i`IBNJ*QTee3JuOVIR6Mxaiyn=V@Sm<)`N|V%?1pI4VJe~{PDk8{bCcF z!_MhiDvsZO#@*mP11g0CcL0^IR~fK-)p~Z7O=}0 zf3N(Od%E=Sh2?L}f8TL0S`aH*?XPg~EQ4i7(F{k&2el_Tx4dF||NeU%Q|sB^?1xlY VCHdofe*zuB;OXk;vd$@?2>_t5Rqp@* literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..4e242d993fa6d8e2aabd1d854fe833dda2e50c20 GIT binary patch literal 244 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Zh%jSYpb@_(U{mR(P2CM1Lg&K zt#)=?;O@N4#&VXUUB8{h95aJf3zL2WodOm06j{XsvXhSjH8y#=IEGZ*Vm-*{$7CSD za^U7_RgISa`-7QPX5F)#e78ApY4`p$x{o5VZdqr$_emT)cW=(omtkAOwh1ZwX|9dm9BZUDm+zk)7GHr*WIJt_RZnjZyl_&)6MTyX=IVd ryIGUu%a0lF_*hfJ{KgTe~DWM4f(`;Jr literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..69b6aa292ddeaba85d9c5f37811380c6e8351760 GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa3-AeX1=9ciKl}D$(yMpjZ%(`3 zUL?FJMR1}EXQ>8Lh!AJlxu|lW3dWKkzhDN3XE)M-90N}m$B>F!$qQr*v>YTCofMd5 zx%4dKAuj(`uR_0uOS!B86EkH46u-?35bWdR;o)KUS;Nk#RJ;Ua6@#a%pUXO@geCwT C4>EiJ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..c198d8eef46154a984cfdef28ab3a69597caa5e7 GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!dVo)e>l`zKWj2jo!ld6o$9XDuI#5fqr;B4q#VykwM?Pjljw3b>Ws}qX z{lC{1@|87Fr{m)viDVZJH&MHUk{=&D1lU(6+?W6TjuXSo(5aS{R-$FQ*C_XV z-?utsYsIPsw>%Cc$*g^|Ij5M5;jTN=d?wc~_b%S+_UK%7W(l8rgVcuad5O|F@0)Ee lK2Q36jTEqYV literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..03a07cad9ca20d40df86d14867281d7f7bf40dc1 GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!bbwEY>+S`SyH-aZ*%E*3V9fb* z8F%j$&9C>LobR)CO5oYTXFNbB>Ar-e+4;~a`GT>o0*!g6^Z~xojJto2q!DZ@e zxA=v>wqAAmWmwQ+^{uf&M!PPi+|rX>nxT~2cFppx?<6Ue%+)uI{5D0;3G4aFIcZCl zR;=F^-N`9)SL}VUC8=}I>%VRDkAJQB{x0X<-U7$8{kIsd$eTY62@tZ*)BxJf;OXk; Jvd$@?2>=2HRUrTX literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..efafaff040cdcc074b961097be360a5a899dfb5c GIT binary patch literal 203 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^4e$wZy>uz%)vLsN_p+{EPdk4) z{`BF9!<&6sRK5rS6%=~9IEGZ*Vm-K#_pkvE!$E#cy$75sk}o+c8x zEwpaPW;7eWQJ<|Y|Mg0q`2DccXVNDb?MZme|IA8AomdKI;Vst0OM^? A&j0`b literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..4edbb8c9f7f69e4ea9a5b5d6be67ac399b1752d3 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!P=HT}>!HorhxW&xKaus|TIu2` zp<5TEPV!n=29!w}EnR_|rKeR=5|_R{de)V7D3`<}1ec3Q65e`UA%U0DsUiM5M0+P1Ho ivHAN8z4P<*^6ll_nbiFGt8V};WAJqKb6Mw<&;$T`pGgq_ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f3708485405416b110a53977d0c3d8037d053cf1 GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!bbwEY>+S`SyH-aZ*%E*3V9fb* z8F%j$&9C=gJ0);(zRwliPp^Q=3O!vMLn>~$_Ma3y;=sWi{Yc_df5qt=!MFMOK2A`0 zJ!$I0hbx($u=9#;Q)W3O;5@Th{KA#(X=^SmIb!LdV8J`*>FdKK<>wDu7yQkaQ_{T| zynbt8OO9`ALEFLGyZ#(V+IYzBpd~{Io5vjqo;N(N?f)y-uXAJ$;qR5%3bdTT)78&q Iol`;+0F@|IMgRZ+ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..0b04a5316b38feb9942d83b1987c30c913a2c7f9 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!P=HT}E0Df=CU@`7n5_#^7f%VD z+UU2?B=#Lpl(8hpFPOpM*^M+HC&kmnF{I)a>%qoEDF*=-!?TY6dD;KFy;9!B_2$jl zoaUb<7q*@hN_}Oy-#Bw~;-jqo&3}GAdKq{0gm1^Ee|C8 vZ^C+!ANxOiyb|;K=ch^s;p0lT%>FSSzu_ctsl15~Xdi>8tDnm{r-UW|UnEec literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..8d62485aee7f106efe4a82b1a9b4d926c58fe20f GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!P=HT}E0Es0Aa(D~n5$=Ur#AX6 zo)S9!iD@WMl(8hpFPOpM*^M+HC(hHwF{I*_Z=WMyg9FEr8Pk6LpYCh2t|;4?*|>Sq zgc57x?H!Zey;Ek``!m*2XUXiH?yO7C?orF)n|wsS;@zdYmW^s(IszBv^gCYpl05Z^ oLDoMzopr09!jrSpWb4 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..8ef4ac825daf5fbcc1efa15296350fe90628fcad GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!P=HT}E0Es0Aa(D~n5$=Ur#AX6 zo)S9!iD@WMl(8hpFPOpM*^M+HC(hHwF{I*_Z=WOA5eJ^bZb6^^>+9#d47jh<^rpBk zjLEwC-^P%#XF{!?SOWs@MSC}|_BcBC^AfMJ^`Ar5gmWzjF}Cs3JYCz6+RC$CHSv3C n)RLNM!SP9vhtAbax8t{GD`5P3$3j;bXcL2{tDnm{r-UW|08d3M literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..53eaa22d731fbb07714d8574ee8e9d6ecd990ec2 GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!P=HT}E0Df=CU@`7n5_#^r#AX6 zo)UV{^7sp&C}T;GUoeBivm0qZj-#iGV@SoVwcUn%4F)_%9u3^~OB literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..acd2b98e6e266c2324f0487d4169f0888da1d1d0 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!P=HT}E0Df=CU@`7n5_#^r#AX6 zo)UV{^7sp&C}T;GUoeBivm0qZj+dv4V@SoV*j`5=21AZR954Rw-?O>hZ}rZZj2HP; zR%XcxvBwKHKjdPT6ZI&cF88M7HIqf~jlI&BjJzL6G6pF(EH5~w`&PVZ^C!l6VGN%e T6s}eQO=a+O^>bP0l+XkK1voi} literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..0c793bb5d872e74404de6b5093da629f626205ef GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^3h)VW1=3f~yQ~<@us{ z;os^fd?8yh*;lFLb6aG8+SIuCtem|<_lsKv9Z$;Nil_TseNtSkHe2uhZ0C^Ze(s`G zs%8n!_wF@>Y^vH>(Ye$1shawBiR=g8GWut1vCMIOV}GblxOmERjr%~W89ZJ6T-G@y GGywpvg;9n8 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f669921e56817e972649efbbb52ba37b426574ae GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!P=HT}E0Es0Aa(D~n5$=Ur#AX6 zo)S9!iD@WMl(8hpFPOpM*^M+HC&tsoF{I*_Z=WY0izCmWCfR@gp9c0OBu0&0TE1?6^_ytY@i?FLNDqY}^@U my}S4MqDKAat!+zg&y+v%o^e5FfSn-F9tKZWKbLh*2~7aN8As0m literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d712134294890221c122fd5e1e29f53299667a52 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!P=HT}E0Es0Aa(D~n5$=Ur#AX6 zo)S9!iD@WMl(8hpFPOpM*^M+HC&AOjF{I*F?D;^h0}dR_fyRr!?=M=o+i7KeWx|nF zPOOvOtt=0ilCsVr#6v%$?x)U~la7JTR{AW9G&UEVwF_99HX%1u)%d=)!;E#e!dNFq q1up&)!zlDLm?`BK(~2i{zZtkTFn*Po=fn=Qi^0>?&t;ucLK6TAAw%{6 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..637d8dd7c683923f4537b0879ed2b39df0d1f7f5 GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!P=HT}E0Df=CU@`7n5_#^r#AX6 zo)UV{^7sp&C}T;GUoeBivm0qZj-98AV@SoVwLOM>4F&>-U;TLZKR%5qw)=?7wusK_ z{f&FsZP-4pUeEG7V2{U|l>xiAJFltgXgr|eX2kHKb|-_;ONOm`cTA24n#ADg>gTe~ HDWM4fWXw5- literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..053a25335d60555c33a80a1f4746b7ed2019756f GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Xn;?ME0Df=CU@`7n5_#^FI`HR z+UU1|K?x@L-p$v zFAIOY4=)`hV>e|pTu?a>_Rqa+K9k2x2FvQndKR8vw@+AYca+IdeOe%M!v4w91y>ja UXRfz83N(|!)78&qol`;+0QUkrcK`qY literal 0 HcmV?d00001 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..4ba66dc8d --- /dev/null +++ b/bukkit-helper-26-2/src/main/java/org/dynmap/bukkit/helper/v26_2/BukkitVersionHelperSpigot26_2.java @@ -0,0 +1,436 @@ +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 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/docs/minecraft26-validation.md b/docs/minecraft26-validation.md new file mode 100644 index 000000000..9696d3241 --- /dev/null +++ b/docs/minecraft26-validation.md @@ -0,0 +1,66 @@ +# Minecraft 26.2 候補 + +Issue #2 の対象は Paper 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用標準テクスチャ資材と同じものです。 +ソースの公開とバイナリの一般配布は別に判断します。 + +Acecoreでは以下を調整しています。 + +- バージョン判定は26.2に限定し、旧サーバーの既存fallbackを維持。 +- 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境界のビット展開をテスト。 + +## ビルド + +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・ログを記録。 + +候補の起動だけでは26.2の全ブロック・全状態への対応完了とはしません。 +上流PRのcopper golem statueは銅色の立方体による暫定表示です。実モデルへの忠実性は未達です。 +Spigot 26.2、Fabric/Forge 26.2、全旧バージョン、一般プレイヤー操作の網羅試験は別途必要です。 +本番へ進める際は [運用手順](acecore-maintenance.md) のバックアップと個別承認に従います。 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..e334ea365 100644 --- a/gradle/acecore-verification.gradle +++ b/gradle/acecore-verification.gradle @@ -15,10 +15,20 @@ def sha256 = { File file -> if (findProject(':spigot') != null) { tasks.register('verifySpigotJar') { dependsOn ':spigot:shadowJar', ':DynmapCore: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..4d3dcf7ed --- /dev/null +++ b/gradle/common.gradle @@ -0,0 +1,76 @@ +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 -> + 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 0000000000000000000000000000000000000000..e6441136f3d4ba8a0da8d277868979cfbc8ad796 GIT binary patch literal 43453 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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
NnX)EH+Nua)3Y(c z&{(nX_ht=QbJ%DzAya}!&uNu!4V0xI)QE$SY__m)SAKcN0P(&JcoK*Lxr@P zY&P=}&B3*UWNlc|&$Oh{BEqwK2+N2U$4WB7Fd|aIal`FGANUa9E-O)!gV`((ZGCc$ zBJA|FFrlg~9OBp#f7aHodCe{6= zay$6vN~zj1ddMZ9gQ4p32(7wD?(dE>KA2;SOzXRmPBiBc6g`eOsy+pVcHu=;Yd8@{ zSGgXf@%sKKQz~;!J;|2fC@emm#^_rnO0esEn^QxXgJYd`#FPWOUU5b;9eMAF zZhfiZb|gk8aJIw*YLp4!*(=3l8Cp{(%p?ho22*vN9+5NLV0TTazNY$B5L6UKUrd$n zjbX%#m7&F#U?QNOBXkiiWB*_tk+H?N3`vg;1F-I+83{M2!8<^nydGr5XX}tC!10&e z7D36bLaB56WrjL&HiiMVtpff|K%|*{t*ltt^5ood{FOG0<>k&1h95qPio)2`eL${YAGIx(b4VN*~nKn6E~SIQUuRH zQ+5zP6jfnP$S0iJ@~t!Ai3o`X7biohli;E zT#yXyl{bojG@-TGZzpdVDXhbmF%F9+-^YSIv|MT1l3j zrxOFq>gd2%U}?6}8mIj?M zc077Zc9fq(-)4+gXv?Az26IO6eV`RAJz8e3)SC7~>%rlzDwySVx*q$ygTR5kW2ds- z!HBgcq0KON9*8Ff$X0wOq$`T7ml(@TF)VeoF}x1OttjuVHn3~sHrMB++}f7f9H%@f z=|kP_?#+fve@{0MlbkC9tyvQ_R?lRdRJ@$qcB(8*jyMyeME5ns6ypVI1Xm*Zr{DuS zZ!1)rQfa89c~;l~VkCiHI|PCBd`S*2RLNQM8!g9L6?n`^evQNEwfO@&JJRme+uopQX0%Jo zgd5G&#&{nX{o?TQwQvF1<^Cg3?2co;_06=~Hcb6~4XWpNFL!WU{+CK;>gH%|BLOh7@!hsa(>pNDAmpcuVO-?;Bic17R}^|6@8DahH)G z!EmhsfunLL|3b=M0MeK2vqZ|OqUqS8npxwge$w-4pFVXFq$_EKrZY?BuP@Az@(k`L z`ViQBSk`y+YwRT;&W| z2e3UfkCo^uTA4}Qmmtqs+nk#gNr2W4 zTH%hhErhB)pkXR{B!q5P3-OM+M;qu~f>}IjtF%>w{~K-0*jPVLl?Chz&zIdxp}bjx zStp&Iufr58FTQ36AHU)0+CmvaOpKF;W@sMTFpJ`j;3d)J_$tNQI^c<^1o<49Z(~K> z;EZTBaVT%14(bFw2ob@?JLQ2@(1pCdg3S%E4*dJ}dA*v}_a4_P(a`cHnBFJxNobAv zf&Zl-Yt*lhn-wjZsq<9v-IsXxAxMZ58C@e0!rzhJ+D@9^3~?~yllY^s$?&oNwyH!#~6x4gUrfxplCvK#!f z$viuszW>MFEcFL?>ux*((!L$;R?xc*myjRIjgnQX79@UPD$6Dz0jutM@7h_pq z0Zr)#O<^y_K6jfY^X%A-ip>P%3saX{!v;fxT-*0C_j4=UMH+Xth(XVkVGiiKE#f)q z%Jp=JT)uy{&}Iq2E*xr4YsJ5>w^=#-mRZ4vPXpI6q~1aFwi+lQcimO45V-JXP;>(Q zo={U`{=_JF`EQj87Wf}{Qy35s8r1*9Mxg({CvOt}?Vh9d&(}iI-quvs-rm~P;eRA@ zG5?1HO}puruc@S{YNAF3vmUc2B4!k*yi))<5BQmvd3tr}cIs#9)*AX>t`=~{f#Uz0 z0&Nk!7sSZwJe}=)-R^$0{yeS!V`Dh7w{w5rZ9ir!Z7Cd7dwZcK;BT#V0bzTt>;@Cl z#|#A!-IL6CZ@eHH!CG>OO8!%G8&8t4)Ro@}USB*k>oEUo0LsljsJ-%5Mo^MJF2I8- z#v7a5VdJ-Cd%(a+y6QwTmi+?f8Nxtm{g-+WGL>t;s#epv7ug>inqimZCVm!uT5Pf6 ziEgQt7^%xJf#!aPWbuC_3Nxfb&CFbQy!(8ANpkWLI4oSnH?Q3f?0k1t$3d+lkQs{~(>06l&v|MpcFsyAv zin6N!-;pggosR*vV=DO(#+}4ps|5$`udE%Kdmp?G7B#y%H`R|i8skKOd9Xzx8xgR$>Zo2R2Ytktq^w#ul4uicxW#{ zFjG_RNlBroV_n;a7U(KIpcp*{M~e~@>Q#Av90Jc5v%0c>egEdY4v3%|K1XvB{O_8G zkTWLC>OZKf;XguMH2-Pw{BKbFzaY;4v2seZV0>^7Q~d4O=AwaPhP3h|!hw5aqOtT@ z!SNz}$of**Bl3TK209@F=Tn1+mgZa8yh(Png%Zd6Mt}^NSjy)etQrF zme*llAW=N_8R*O~d2!apJnF%(JcN??=`$qs3Y+~xs>L9x`0^NIn!8mMRFA_tg`etw z3k{9JAjnl@ygIiJcNHTy02GMAvBVqEss&t2<2mnw!; zU`J)0>lWiqVqo|ex7!+@0i>B~BSU1A_0w#Ee+2pJx0BFiZ7RDHEvE*ptc9md(B{&+ zKE>TM)+Pd>HEmdJao7U@S>nL(qq*A)#eLOuIfAS@j`_sK0UEY6OAJJ-kOrHG zjHx`g!9j*_jRcJ%>CE9K2MVf?BUZKFHY?EpV6ai7sET-tqk=nDFh-(65rhjtlKEY% z@G&cQ<5BKatfdA1FKuB=i>CCC5(|9TMW%K~GbA4}80I5%B}(gck#Wlq@$nO3%@QP_ z8nvPkJFa|znk>V92cA!K1rKtr)skHEJD;k8P|R8RkCq1Rh^&}Evwa4BUJz2f!2=MH zo4j8Y$YL2313}H~F7@J7mh>u%556Hw0VUOz-Un@ZASCL)y8}4XXS`t1AC*^>PLwIc zUQok5PFS=*#)Z!3JZN&eZ6ZDP^-c@StY*t20JhCnbMxXf=LK#;`4KHEqMZ-Ly9KsS zI2VUJGY&PmdbM+iT)zek)#Qc#_i4uH43 z@T5SZBrhNCiK~~esjsO9!qBpaWK<`>!-`b71Y5ReXQ4AJU~T2Njri1CEp5oKw;Lnm)-Y@Z3sEY}XIgSy%xo=uek(kAAH5MsV$V3uTUsoTzxp_rF=tx zV07vlJNKtJhCu`b}*#m&5LV4TAE&%KtHViDAdv#c^x`J7bg z&N;#I2GkF@SIGht6p-V}`!F_~lCXjl1BdTLIjD2hH$J^YFN`7f{Q?OHPFEM$65^!u zNwkelo*5+$ZT|oQ%o%;rBX$+?xhvjb)SHgNHE_yP%wYkkvXHS{Bf$OiKJ5d1gI0j< zF6N}Aq=(WDo(J{e-uOecxPD>XZ@|u-tgTR<972`q8;&ZD!cep^@B5CaqFz|oU!iFj zU0;6fQX&~15E53EW&w1s9gQQ~Zk16X%6 zjG`j0yq}4deX2?Tr(03kg>C(!7a|b9qFI?jcE^Y>-VhudI@&LI6Qa}WQ>4H_!UVyF z((cm&!3gmq@;BD#5P~0;_2qgZhtJS|>WdtjY=q zLnHH~Fm!cxw|Z?Vw8*~?I$g#9j&uvgm7vPr#&iZgPP~v~BI4jOv;*OQ?jYJtzO<^y z7-#C={r7CO810!^s(MT!@@Vz_SVU)7VBi(e1%1rvS!?PTa}Uv`J!EP3s6Y!xUgM^8 z4f!fq<3Wer_#;u!5ECZ|^c1{|q_lh3m^9|nsMR1#Qm|?4Yp5~|er2?W^7~cl;_r4WSme_o68J9p03~Hc%X#VcX!xAu%1`R!dfGJCp zV*&m47>s^%Ib0~-2f$6oSgn3jg8m%UA;ArcdcRyM5;}|r;)?a^D*lel5C`V5G=c~k zy*w_&BfySOxE!(~PI$*dwG><+-%KT5p?whOUMA*k<9*gi#T{h3DAxzAPxN&Xws8o9Cp*`PA5>d9*Z-ynV# z9yY*1WR^D8|C%I@vo+d8r^pjJ$>eo|j>XiLWvTWLl(^;JHCsoPgem6PvegHb-OTf| zvTgsHSa;BkbG=(NgPO|CZu9gUCGr$8*EoH2_Z#^BnxF0yM~t`|9ws_xZ8X8iZYqh! zAh;HXJ)3P&)Q0(&F>!LN0g#bdbis-cQxyGn9Qgh`q+~49Fqd2epikEUw9caM%V6WgP)532RMRW}8gNS%V%Hx7apSz}tn@bQy!<=lbhmAH=FsMD?leawbnP5BWM0 z5{)@EEIYMu5;u)!+HQWhQ;D3_Cm_NADNeb-f56}<{41aYq8p4=93d=-=q0Yx#knGYfXVt z+kMxlus}t2T5FEyCN~!}90O_X@@PQpuy;kuGz@bWft%diBTx?d)_xWd_-(!LmVrh**oKg!1CNF&LX4{*j|) zIvjCR0I2UUuuEXh<9}oT_zT#jOrJAHNLFT~Ilh9hGJPI1<5`C-WA{tUYlyMeoy!+U zhA#=p!u1R7DNg9u4|QfED-2TuKI}>p#2P9--z;Bbf4Op*;Q9LCbO&aL2i<0O$ByoI z!9;Ght733FC>Pz>$_mw(F`zU?`m@>gE`9_p*=7o=7av`-&ifU(^)UU`Kg3Kw`h9-1 z6`e6+im=|m2v`pN(2dE%%n8YyQz;#3Q-|x`91z?gj68cMrHl}C25|6(_dIGk*8cA3 zRHB|Nwv{@sP4W+YZM)VKI>RlB`n=Oj~Rzx~M+Khz$N$45rLn6k1nvvD^&HtsMA4`s=MmuOJID@$s8Ph4E zAmSV^+s-z8cfv~Yd(40Sh4JG#F~aB>WFoX7ykaOr3JaJ&Lb49=B8Vk-SQT9%7TYhv z?-Pprt{|=Y5ZQ1?od|A<_IJU93|l4oAfBm?3-wk{O<8ea+`}u%(kub(LFo2zFtd?4 zwpN|2mBNywv+d^y_8#<$r>*5+$wRTCygFLcrwT(qc^n&@9r+}Kd_u@Ithz(6Qb4}A zWo_HdBj#V$VE#l6pD0a=NfB0l^6W^g`vm^sta>Tly?$E&{F?TTX~DsKF~poFfmN%2 z4x`Dc{u{Lkqz&y!33;X}weD}&;7p>xiI&ZUb1H9iD25a(gI|`|;G^NwJPv=1S5e)j z;U;`?n}jnY6rA{V^ zxTd{bK)Gi^odL3l989DQlN+Zs39Xe&otGeY(b5>rlIqfc7Ap4}EC?j<{M=hlH{1+d zw|c}}yx88_xQr`{98Z!d^FNH77=u(p-L{W6RvIn40f-BldeF-YD>p6#)(Qzf)lfZj z?3wAMtPPp>vMehkT`3gToPd%|D8~4`5WK{`#+}{L{jRUMt zrFz+O$C7y8$M&E4@+p+oV5c%uYzbqd2Y%SSgYy#xh4G3hQv>V*BnuKQhBa#=oZB~w{azUB+q%bRe_R^ z>fHBilnRTUfaJ201czL8^~Ix#+qOHSO)A|xWLqOxB$dT2W~)e-r9;bm=;p;RjYahB z*1hegN(VKK+ztr~h1}YP@6cfj{e#|sS`;3tJhIJK=tVJ-*h-5y9n*&cYCSdg#EHE# zSIx=r#qOaLJoVVf6v;(okg6?*L_55atl^W(gm^yjR?$GplNP>BZsBYEf_>wM0Lc;T zhf&gpzOWNxS>m+mN92N0{;4uw`P+9^*|-1~$uXpggj4- z^SFc4`uzj2OwdEVT@}Q`(^EcQ_5(ZtXTql*yGzdS&vrS_w>~~ra|Nb5abwf}Y!uq6R5f&6g2ge~2p(%c< z@O)cz%%rr4*cRJ5f`n@lvHNk@lE1a*96Kw6lJ~B-XfJW%?&-y?;E&?1AacU@`N`!O z6}V>8^%RZ7SQnZ-z$(jsX`amu*5Fj8g!3RTRwK^`2_QHe;_2y_n|6gSaGyPmI#kA0sYV<_qOZc#-2BO%hX)f$s-Z3xlI!ub z^;3ru11DA`4heAu%}HIXo&ctujzE2!6DIGE{?Zs>2}J+p&C$rc7gJC35gxhflorvsb%sGOxpuWhF)dL_&7&Z99=5M0b~Qa;Mo!j&Ti_kXW!86N%n= zSC@6Lw>UQ__F&+&Rzv?gscwAz8IP!n63>SP)^62(HK98nGjLY2*e^OwOq`3O|C92? z;TVhZ2SK%9AGW4ZavTB9?)mUbOoF`V7S=XM;#3EUpR+^oHtdV!GK^nXzCu>tpR|89 zdD{fnvCaN^^LL%amZ^}-E+214g&^56rpdc@yv0b<3}Ys?)f|fXN4oHf$six)-@<;W&&_kj z-B}M5U*1sb4)77aR=@%I?|Wkn-QJVuA96an25;~!gq(g1@O-5VGo7y&E_srxL6ZfS z*R%$gR}dyONgju*D&?geiSj7SZ@ftyA|}(*Y4KbvU!YLsi1EDQQCnb+-cM=K1io78o!v*);o<XwjaQH%)uIP&Zm?)Nfbfn;jIr z)d#!$gOe3QHp}2NBak@yYv3m(CPKkwI|{;d=gi552u?xj9ObCU^DJFQp4t4e1tPzM zvsRIGZ6VF+{6PvqsplMZWhz10YwS={?`~O0Ec$`-!klNUYtzWA^f9m7tkEzCy<_nS z=&<(awFeZvt51>@o_~>PLs05CY)$;}Oo$VDO)?l-{CS1Co=nxjqben*O1BR>#9`0^ zkwk^k-wcLCLGh|XLjdWv0_Hg54B&OzCE^3NCP}~OajK-LuRW53CkV~Su0U>zN%yQP zH8UH#W5P3-!ToO-2k&)}nFe`t+mdqCxxAHgcifup^gKpMObbox9LFK;LP3}0dP-UW z?Zo*^nrQ6*$FtZ(>kLCc2LY*|{!dUn$^RW~m9leoF|@Jy|M5p-G~j%+P0_#orRKf8 zvuu5<*XO!B?1E}-*SY~MOa$6c%2cM+xa8}_8x*aVn~57v&W(0mqN1W`5a7*VN{SUH zXz98DDyCnX2EPl-`Lesf`=AQT%YSDb`$%;(jUTrNen$NPJrlpPDP}prI>Ml!r6bCT;mjsg@X^#&<}CGf0JtR{Ecwd&)2zuhr#nqdgHj+g2n}GK9CHuwO zk>oZxy{vcOL)$8-}L^iVfJHAGfwN$prHjYV0ju}8%jWquw>}_W6j~m<}Jf!G?~r5&Rx)!9JNX!ts#SGe2HzobV5); zpj@&`cNcO&q+%*<%D7za|?m5qlmFK$=MJ_iv{aRs+BGVrs)98BlN^nMr{V_fcl_;jkzRju+c-y?gqBC_@J0dFLq-D9@VN&-`R9U;nv$Hg?>$oe4N&Ht$V_(JR3TG^! zzJsbQbi zFE6-{#9{G{+Z}ww!ycl*7rRdmU#_&|DqPfX3CR1I{Kk;bHwF6jh0opI`UV2W{*|nn zf_Y@%wW6APb&9RrbEN=PQRBEpM(N1w`81s=(xQj6 z-eO0k9=Al|>Ej|Mw&G`%q8e$2xVz1v4DXAi8G};R$y)ww638Y=9y$ZYFDM$}vzusg zUf+~BPX>(SjA|tgaFZr_e0{)+z9i6G#lgt=F_n$d=beAt0Sa0a7>z-?vcjl3e+W}+ z1&9=|vC=$co}-Zh*%3588G?v&U7%N1Qf-wNWJ)(v`iO5KHSkC5&g7CrKu8V}uQGcfcz zmBz#Lbqwqy#Z~UzHgOQ;Q-rPxrRNvl(&u6ts4~0=KkeS;zqURz%!-ERppmd%0v>iRlEf+H$yl{_8TMJzo0 z>n)`On|7=WQdsqhXI?#V{>+~}qt-cQbokEbgwV3QvSP7&hK4R{Z{aGHVS3;+h{|Hz z6$Js}_AJr383c_+6sNR|$qu6dqHXQTc6?(XWPCVZv=)D#6_;D_8P-=zOGEN5&?~8S zl5jQ?NL$c%O)*bOohdNwGIKM#jSAC?BVY={@A#c9GmX0=T(0G}xs`-%f3r=m6-cpK z!%waekyAvm9C3%>sixdZj+I(wQlbB4wv9xKI*T13DYG^T%}zZYJ|0$Oj^YtY+d$V$ zAVudSc-)FMl|54n=N{BnZTM|!>=bhaja?o7s+v1*U$!v!qQ%`T-6fBvmdPbVmro&d zk07TOp*KuxRUSTLRrBj{mjsnF8`d}rMViY8j`jo~Hp$fkv9F_g(jUo#Arp;Xw0M$~ zRIN!B22~$kx;QYmOkos@%|5k)!QypDMVe}1M9tZfkpXKGOxvKXB!=lo`p?|R1l=tA zp(1}c6T3Fwj_CPJwVsYtgeRKg?9?}%oRq0F+r+kdB=bFUdVDRPa;E~~>2$w}>O>v=?|e>#(-Lyx?nbg=ckJ#5U6;RT zNvHhXk$P}m9wSvFyU3}=7!y?Y z=fg$PbV8d7g25&-jOcs{%}wTDKm>!Vk);&rr;O1nvO0VrU&Q?TtYVU=ir`te8SLlS zKSNmV=+vF|ATGg`4$N1uS|n??f}C_4Sz!f|4Ly8#yTW-FBfvS48Tef|-46C(wEO_%pPhUC5$-~Y?!0vFZ^Gu`x=m7X99_?C-`|h zfmMM&Y@zdfitA@KPw4Mc(YHcY1)3*1xvW9V-r4n-9ZuBpFcf{yz+SR{ zo$ZSU_|fgwF~aakGr(9Be`~A|3)B=9`$M-TWKipq-NqRDRQc}ABo*s_5kV%doIX7LRLRau_gd@Rd_aLFXGSU+U?uAqh z8qusWWcvgQ&wu{|sRXmv?sl=xc<$6AR$+cl& zFNh5q1~kffG{3lDUdvEZu5c(aAG~+64FxdlfwY^*;JSS|m~CJusvi-!$XR`6@XtY2 znDHSz7}_Bx7zGq-^5{stTRy|I@N=>*y$zz>m^}^{d&~h;0kYiq8<^Wq7Dz0w31ShO^~LUfW6rfitR0(=3;Uue`Y%y@ex#eKPOW zO~V?)M#AeHB2kovn1v=n^D?2{2jhIQd9t|_Q+c|ZFaWt+r&#yrOu-!4pXAJuxM+Cx z*H&>eZ0v8Y`t}8{TV6smOj=__gFC=eah)mZt9gwz>>W$!>b3O;Rm^Ig*POZP8Rl0f zT~o=Nu1J|lO>}xX&#P58%Yl z83`HRs5#32Qm9mdCrMlV|NKNC+Z~ z9OB8xk5HJ>gBLi+m@(pvpw)1(OaVJKs*$Ou#@Knd#bk+V@y;YXT?)4eP9E5{J%KGtYinNYJUH9PU3A}66c>Xn zZ{Bn0<;8$WCOAL$^NqTjwM?5d=RHgw3!72WRo0c;+houoUA@HWLZM;^U$&sycWrFd zE7ekt9;kb0`lps{>R(}YnXlyGY}5pPd9zBpgXeJTY_jwaJGSJQC#-KJqmh-;ad&F- z-Y)E>!&`Rz!HtCz>%yOJ|v(u7P*I$jqEY3}(Z-orn4 zlI?CYKNl`6I){#2P1h)y(6?i;^z`N3bxTV%wNvQW+eu|x=kbj~s8rhCR*0H=iGkSj zk23lr9kr|p7#qKL=UjgO`@UnvzU)`&fI>1Qs7ubq{@+lK{hH* zvl6eSb9%yngRn^T<;jG1SVa)eA>T^XX=yUS@NCKpk?ovCW1D@!=@kn;l_BrG;hOTC z6K&H{<8K#dI(A+zw-MWxS+~{g$tI7|SfP$EYKxA}LlVO^sT#Oby^grkdZ^^lA}uEF zBSj$weBJG{+Bh@Yffzsw=HyChS(dtLE3i*}Zj@~!_T-Ay7z=B)+*~3|?w`Zd)Co2t zC&4DyB!o&YgSw+fJn6`sn$e)29`kUwAc+1MND7YjV%lO;H2}fNy>hD#=gT ze+-aFNpyKIoXY~Vq-}OWPBe?Rfu^{ps8>Xy%42r@RV#*QV~P83jdlFNgkPN=T|Kt7 zV*M`Rh*30&AWlb$;ae130e@}Tqi3zx2^JQHpM>j$6x`#{mu%tZlwx9Gj@Hc92IuY* zarmT|*d0E~vt6<+r?W^UW0&#U&)8B6+1+;k^2|FWBRP9?C4Rk)HAh&=AS8FS|NQaZ z2j!iZ)nbEyg4ZTp-zHwVlfLC~tXIrv(xrP8PAtR{*c;T24ycA-;auWsya-!kF~CWZ zw_uZ|%urXgUbc@x=L=_g@QJ@m#5beS@6W195Hn7>_}z@Xt{DIEA`A&V82bc^#!q8$ zFh?z_Vn|ozJ;NPd^5uu(9tspo8t%&-U9Ckay-s@DnM*R5rtu|4)~e)`z0P-sy?)kc zs_k&J@0&0!q4~%cKL)2l;N*T&0;mqX5T{Qy60%JtKTQZ-xb%KOcgqwJmb%MOOKk7N zgq})R_6**{8A|6H?fO+2`#QU)p$Ei2&nbj6TpLSIT^D$|`TcSeh+)}VMb}LmvZ{O| ze*1IdCt3+yhdYVxcM)Q_V0bIXLgr6~%JS<<&dxIgfL=Vnx4YHuU@I34JXA|+$_S3~ zy~X#gO_X!cSs^XM{yzDGNM>?v(+sF#<0;AH^YrE8smx<36bUsHbN#y57K8WEu(`qHvQ6cAZPo=J5C(lSmUCZ57Rj6cx!e^rfaI5%w}unz}4 zoX=nt)FVNV%QDJH`o!u9olLD4O5fl)xp+#RloZlaA92o3x4->?rB4`gS$;WO{R;Z3>cG3IgFX2EA?PK^M}@%1%A;?f6}s&CV$cIyEr#q5;yHdNZ9h{| z-=dX+a5elJoDo?Eq&Og!nN6A)5yYpnGEp}?=!C-V)(*~z-+?kY1Q7qs#Rsy%hu_60rdbB+QQNr?S1 z?;xtjUv|*E3}HmuNyB9aFL5H~3Ho0UsmuMZELp1a#CA1g`P{-mT?BchuLEtK}!QZ=3AWakRu~?f9V~3F;TV`5%9Pcs_$gq&CcU}r8gOO zC2&SWPsSG{&o-LIGTBqp6SLQZPvYKp$$7L4WRRZ0BR$Kf0I0SCFkqveCp@f)o8W)! z$%7D1R`&j7W9Q9CGus_)b%+B#J2G;l*FLz#s$hw{BHS~WNLODV#(!u_2Pe&tMsq={ zdm7>_WecWF#D=?eMjLj=-_z`aHMZ=3_-&E8;ibPmM}61i6J3is*=dKf%HC>=xbj4$ zS|Q-hWQ8T5mWde6h@;mS+?k=89?1FU<%qH9B(l&O>k|u_aD|DY*@~(`_pb|B#rJ&g zR0(~(68fpUPz6TdS@4JT5MOPrqDh5_H(eX1$P2SQrkvN8sTxwV>l0)Qq z0pzTuvtEAKRDkKGhhv^jk%|HQ1DdF%5oKq5BS>szk-CIke{%js?~%@$uaN3^Uz6Wf z_iyx{bZ(;9y4X&>LPV=L=d+A}7I4GkK0c1Xts{rrW1Q7apHf-))`BgC^0^F(>At1* za@e7{lq%yAkn*NH8Q1{@{lKhRg*^TfGvv!Sn*ed*x@6>M%aaqySxR|oNadYt1mpUZ z6H(rupHYf&Z z29$5g#|0MX#aR6TZ$@eGxxABRKakDYtD%5BmKp;HbG_ZbT+=81E&=XRk6m_3t9PvD zr5Cqy(v?gHcYvYvXkNH@S#Po~q(_7MOuCAB8G$a9BC##gw^5mW16cML=T=ERL7wsk zzNEayTG?mtB=x*wc@ifBCJ|irFVMOvH)AFRW8WE~U()QT=HBCe@s$dA9O!@`zAAT) zaOZ7l6vyR+Nk_OOF!ZlZmjoImKh)dxFbbR~z(cMhfeX1l7S_`;h|v3gI}n9$sSQ>+3@AFAy9=B_y$)q;Wdl|C-X|VV3w8 z2S#>|5dGA8^9%Bu&fhmVRrTX>Z7{~3V&0UpJNEl0=N32euvDGCJ>#6dUSi&PxFW*s zS`}TB>?}H(T2lxBJ!V#2taV;q%zd6fOr=SGHpoSG*4PDaiG0pdb5`jelVipkEk%FV zThLc@Hc_AL1#D&T4D=w@UezYNJ%0=f3iVRuVL5H?eeZM}4W*bomebEU@e2d`M<~uW zf#Bugwf`VezG|^Qbt6R_=U0}|=k;mIIakz99*>FrsQR{0aQRP6ko?5<7bkDN8evZ& zB@_KqQG?ErKL=1*ZM9_5?Pq%lcS4uLSzN(Mr5=t6xHLS~Ym`UgM@D&VNu8e?_=nSFtF$u@hpPSmI4Vo_t&v?>$~K4y(O~Rb*(MFy_igM7 z*~yYUyR6yQgzWnWMUgDov!!g=lInM+=lOmOk4L`O?{i&qxy&D*_qorRbDwj6?)!ef z#JLd7F6Z2I$S0iYI={rZNk*<{HtIl^mx=h>Cim*04K4+Z4IJtd*-)%6XV2(MCscPiw_a+y*?BKbTS@BZ3AUao^%Zi#PhoY9Vib4N>SE%4>=Jco0v zH_Miey{E;FkdlZSq)e<{`+S3W=*ttvD#hB8w=|2aV*D=yOV}(&p%0LbEWH$&@$X3x~CiF-?ejQ*N+-M zc8zT@3iwkdRT2t(XS`d7`tJQAjRmKAhiw{WOqpuvFp`i@Q@!KMhwKgsA}%@sw8Xo5Y=F zhRJZg)O4uqNWj?V&&vth*H#je6T}}p_<>!Dr#89q@uSjWv~JuW(>FqoJ5^ho0%K?E z9?x_Q;kmcsQ@5=}z@tdljMSt9-Z3xn$k)kEjK|qXS>EfuDmu(Z8|(W?gY6-l z@R_#M8=vxKMAoi&PwnaIYw2COJM@atcgfr=zK1bvjW?9B`-+Voe$Q+H$j!1$Tjn+* z&LY<%)L@;zhnJlB^Og6I&BOR-m?{IW;tyYC%FZ!&Z>kGjHJ6cqM-F z&19n+e1=9AH1VrVeHrIzqlC`w9=*zfmrerF?JMzO&|Mmv;!4DKc(sp+jy^Dx?(8>1 zH&yS_4yL7m&GWX~mdfgH*AB4{CKo;+egw=PrvkTaoBU+P-4u?E|&!c z)DKc;>$$B6u*Zr1SjUh2)FeuWLWHl5TH(UHWkf zLs>7px!c5n;rbe^lO@qlYLzlDVp(z?6rPZel=YB)Uv&n!2{+Mb$-vQl=xKw( zve&>xYx+jW_NJh!FV||r?;hdP*jOXYcLCp>DOtJ?2S^)DkM{{Eb zS$!L$e_o0(^}n3tA1R3-$SNvgBq;DOEo}fNc|tB%%#g4RA3{|euq)p+xd3I8^4E&m zFrD%}nvG^HUAIKe9_{tXB;tl|G<%>yk6R;8L2)KUJw4yHJXUOPM>(-+jxq4R;z8H#>rnJy*)8N+$wA$^F zN+H*3t)eFEgxLw+Nw3};4WV$qj&_D`%ADV2%r zJCPCo%{=z7;`F98(us5JnT(G@sKTZ^;2FVitXyLe-S5(hV&Ium+1pIUB(CZ#h|g)u zSLJJ<@HgrDiA-}V_6B^x1>c9B6%~847JkQ!^KLZ2skm;q*edo;UA)~?SghG8;QbHh z_6M;ouo_1rq9=x$<`Y@EA{C%6-pEV}B(1#sDoe_e1s3^Y>n#1Sw;N|}8D|s|VPd+g z-_$QhCz`vLxxrVMx3ape1xu3*wjx=yKSlM~nFgkNWb4?DDr*!?U)L_VeffF<+!j|b zZ$Wn2$TDv3C3V@BHpSgv3JUif8%hk%OsGZ=OxH@8&4`bbf$`aAMchl^qN>Eyu3JH} z9-S!x8-s4fE=lad%Pkp8hAs~u?|uRnL48O|;*DEU! zuS0{cpk%1E0nc__2%;apFsTm0bKtd&A0~S3Cj^?72-*Owk3V!ZG*PswDfS~}2<8le z5+W^`Y(&R)yVF*tU_s!XMcJS`;(Tr`J0%>p=Z&InR%D3@KEzzI+-2)HK zuoNZ&o=wUC&+*?ofPb0a(E6(<2Amd6%uSu_^-<1?hsxs~0K5^f(LsGqgEF^+0_H=uNk9S0bb!|O8d?m5gQjUKevPaO+*VfSn^2892K~%crWM8+6 z25@V?Y@J<9w%@NXh-2!}SK_(X)O4AM1-WTg>sj1{lj5@=q&dxE^9xng1_z9w9DK>| z6Iybcd0e zyi;Ew!KBRIfGPGytQ6}z}MeXCfLY0?9%RiyagSp_D1?N&c{ zyo>VbJ4Gy`@Fv+5cKgUgs~na$>BV{*em7PU3%lloy_aEovR+J7TfQKh8BJXyL6|P8un-Jnq(ghd!_HEOh$zlv2$~y3krgeH;9zC}V3f`uDtW(%mT#944DQa~^8ZI+zAUu4U(j0YcDfKR$bK#gvn_{JZ>|gZ5+)u?T$w7Q%F^;!Wk?G z(le7r!ufT*cxS}PR6hIVtXa)i`d$-_1KkyBU>qmgz-=T};uxx&sKgv48akIWQ89F{ z0XiY?WM^~;|T8zBOr zs#zuOONzH?svv*jokd5SK8wG>+yMC)LYL|vLqm^PMHcT=`}V$=nIRHe2?h)8WQa6O zPAU}d`1y(>kZiP~Gr=mtJLMu`i<2CspL|q2DqAgAD^7*$xzM`PU4^ga`ilE134XBQ z99P(LhHU@7qvl9Yzg$M`+dlS=x^(m-_3t|h>S}E0bcFMn=C|KamQ)=w2^e)35p`zY zRV8X?d;s^>Cof2SPR&nP3E+-LCkS0J$H!eh8~k0qo$}00b=7!H_I2O+Ro@3O$nPdm ztmbOO^B+IHzQ5w>@@@J4cKw5&^_w6s!s=H%&byAbUtczPQ7}wfTqxxtQNfn*u73Qw zGuWsrky_ajPx-5`R<)6xHf>C(oqGf_Fw|-U*GfS?xLML$kv;h_pZ@Kk$y0X(S+K80 z6^|z)*`5VUkawg}=z`S;VhZhxyDfrE0$(PMurAxl~<>lfZa>JZ288ULK7D` zl9|#L^JL}Y$j*j`0-K6kH#?bRmg#5L3iB4Z)%iF@SqT+Lp|{i`m%R-|ZE94Np7Pa5 zCqC^V3}B(FR340pmF*qaa}M}+h6}mqE~7Sh!9bDv9YRT|>vBNAqv09zXHMlcuhKD| zcjjA(b*XCIwJ33?CB!+;{)vX@9xns_b-VO{i0y?}{!sdXj1GM8+$#v>W7nw;+O_9B z_{4L;C6ol?(?W0<6taGEn1^uG=?Q3i29sE`RfYCaV$3DKc_;?HsL?D_fSYg}SuO5U zOB_f4^vZ_x%o`5|C@9C5+o=mFy@au{s)sKw!UgC&L35aH(sgDxRE2De%(%OT=VUdN ziVLEmdOvJ&5*tCMKRyXctCwQu_RH%;m*$YK&m;jtbdH#Ak~13T1^f89tn`A%QEHWs~jnY~E}p_Z$XC z=?YXLCkzVSK+Id`xZYTegb@W8_baLt-Fq`Tv|=)JPbFsKRm)4UW;yT+J`<)%#ue9DPOkje)YF2fsCilK9MIIK>p*`fkoD5nGfmLwt)!KOT+> zOFq*VZktDDyM3P5UOg`~XL#cbzC}eL%qMB=Q5$d89MKuN#$6|4gx_Jt0Gfn8w&q}%lq4QU%6#jT*MRT% zrLz~C8FYKHawn-EQWN1B75O&quS+Z81(zN)G>~vN8VwC+e+y(`>HcxC{MrJ;H1Z4k zZWuv$w_F0-Ub%MVcpIc){4PGL^I7M{>;hS?;eH!;gmcOE66z3;Z1Phqo(t zVP(Hg6q#0gIKgsg7L7WE!{Y#1nI(45tx2{$34dDd#!Z0NIyrm)HOn5W#7;f4pQci# zDW!FI(g4e668kI9{2+mLwB+=#9bfqgX%!B34V-$wwSN(_cm*^{y0jQtv*4}eO^sOV z*9xoNvX)c9isB}Tgx&ZRjp3kwhTVK?r9;n!x>^XYT z@Q^7zp{rkIs{2mUSE^2!Gf6$6;j~&4=-0cSJJDizZp6LTe8b45;{AKM%v99}{{FfC zz709%u0mC=1KXTo(=TqmZQ;c?$M3z(!xah>aywrj40sc2y3rKFw4jCq+Y+u=CH@_V zxz|qeTwa>+<|H%8Dz5u>ZI5MmjTFwXS-Fv!TDd*`>3{krWoNVx$<133`(ftS?ZPyY z&4@ah^3^i`vL$BZa>O|Nt?ucewzsF)0zX3qmM^|waXr=T0pfIb0*$AwU=?Ipl|1Y; z*Pk6{C-p4MY;j@IJ|DW>QHZQJcp;Z~?8(Q+Kk3^0qJ}SCk^*n4W zu9ZFwLHUx-$6xvaQ)SUQcYd6fF8&x)V`1bIuX@>{mE$b|Yd(qomn3;bPwnDUc0F=; zh*6_((%bqAYQWQ~odER?h>1mkL4kpb3s7`0m@rDKGU*oyF)$j~Ffd4fXV$?`f~rHf zB%Y)@5SXZvfwm10RY5X?TEo)PK_`L6qgBp=#>fO49$D zDq8Ozj0q6213tV5Qq=;fZ0$|KroY{Dz=l@lU^J)?Ko@ti20TRplXzphBi>XGx4bou zEWrkNjz0t5j!_ke{g5I#PUlEU$Km8g8TE|XK=MkU@PT4T><2OVamoK;wJ}3X0L$vX zgd7gNa359*nc)R-0!`2X@FOTB`+oETOPc=ubp5R)VQgY+5BTZZJ2?9QwnO=dnulIUF3gFn;BODC2)65)HeVd%t86sL7Rv^Y+nbn+&l z6BAJY(ETvwI)Ts$aiE8rht4KD*qNyE{8{x6R|%akbTBzw;2+6Echkt+W+`u^XX z_z&x%n '} + 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..30dbf61e5 100644 --- a/spigot/build.gradle +++ b/spigot/build.gradle @@ -16,9 +16,17 @@ 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 { + 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 +136,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 +172,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/Helper.java b/spigot/src/main/java/org/dynmap/bukkit/Helper.java index 26cc72e7f..0d1adeede 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 (v.contains("(MC: 26.2)") || Bukkit.getBukkitVersion().split("-")[0].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"); } From 416fda1c2cc28feb92ec8e00c92bdb40717b3d50 Mon Sep 17 00:00:00 2001 From: Gui <51219838+gui-ace@users.noreply.github.com> Date: Tue, 8 Sep 2026 22:36:48 +0900 Subject: [PATCH 2/7] =?UTF-8?q?=E6=96=B0=E3=81=97=E3=81=84Paper=E7=89=88?= =?UTF-8?q?=E8=A1=A8=E8=A8=98=E3=82=92=E5=85=B1=E6=9C=89=E3=82=B3=E3=82=A2?= =?UTF-8?q?=E3=81=A7=E3=82=82=E6=AD=A3=E3=81=97=E3=81=8F=E5=88=A4=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 2 ++ docs/minecraft26-validation.md | 2 ++ gradle/acecore-verification.gradle | 2 +- spigot/build.gradle | 1 + .../java/org/dynmap/bukkit/DynmapPlugin.java | 8 +----- .../main/java/org/dynmap/bukkit/Helper.java | 2 +- .../org/dynmap/bukkit/MinecraftVersion.java | 18 ++++++++++++ .../dynmap/bukkit/MinecraftVersionTest.java | 28 +++++++++++++++++++ 8 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 spigot/src/main/java/org/dynmap/bukkit/MinecraftVersion.java create mode 100644 spigot/src/test/java/org/dynmap/bukkit/MinecraftVersionTest.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cf07b4bc0..59265620a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,4 +54,6 @@ jobs: 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/docs/minecraft26-validation.md b/docs/minecraft26-validation.md index 9696d3241..1bdfe1072 100644 --- a/docs/minecraft26-validation.md +++ b/docs/minecraft26-validation.md @@ -19,6 +19,7 @@ R2マーカー修正 (#1) はこの差分に含めず、ビルド基盤 (#3) を 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は既存ビルド用に維持。 @@ -30,6 +31,7 @@ Acecoreでは以下を調整しています。 ブロックレジストリIDと名前の対応へ修正。 - スキン応答のエラー時に元の応答本文をログへ出さない。 - NBTの数値・欠損値、配列、チャンクパレット、long境界のビット展開をテスト。 + 旧Paper/新版Paper/パッチ版/不明形式の版判定もテスト。 ## ビルド diff --git a/gradle/acecore-verification.gradle b/gradle/acecore-verification.gradle index e334ea365..3a74a7432 100644 --- a/gradle/acecore-verification.gradle +++ b/gradle/acecore-verification.gradle @@ -14,7 +14,7 @@ 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' } diff --git a/spigot/build.gradle b/spigot/build.gradle index 30dbf61e5..b18363ae3 100644 --- a/spigot/build.gradle +++ b/spigot/build.gradle @@ -24,6 +24,7 @@ java { } dependencies { + testImplementation 'junit:junit:4.13.2' if (findProject(':bukkit-helper-26-2') != null) { implementation(project(':bukkit-helper-26-2')) { transitive = false } } diff --git a/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java b/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java index 48c8b4fe1..63e0025a8 100644 --- a/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java +++ b/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java @@ -921,13 +921,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(); diff --git a/spigot/src/main/java/org/dynmap/bukkit/Helper.java b/spigot/src/main/java/org/dynmap/bukkit/Helper.java index 0d1adeede..aa7085ecc 100644 --- a/spigot/src/main/java/org/dynmap/bukkit/Helper.java +++ b/spigot/src/main/java/org/dynmap/bukkit/Helper.java @@ -40,7 +40,7 @@ else if(Bukkit.getServer().getClass().getName().contains("GlowServer")) { Log.info("Loading Glowstone support"); BukkitVersionHelper.helper = loadVersionHelper("org.dynmap.bukkit.helper.BukkitVersionHelperGlowstone"); } - else if (v.contains("(MC: 26.2)") || Bukkit.getBukkitVersion().split("-")[0].equals("26.2")) { + 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)")) { 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")); + } +} From b35dfecae8ab878411a953a6def001c9a361cff8 Mon Sep 17 00:00:00 2001 From: Gui <51219838+gui-ace@users.noreply.github.com> Date: Tue, 8 Sep 2026 23:18:30 +0900 Subject: [PATCH 3/7] =?UTF-8?q?=E9=8A=85=E3=82=B4=E3=83=BC=E3=83=AC?= =?UTF-8?q?=E3=83=A0=E5=83=8F=E3=81=AE=E5=85=A8=E3=83=9D=E3=83=BC=E3=82=BA?= =?UTF-8?q?=E3=81=A8=E6=96=B9=E5=90=91=E3=82=92=E6=8F=8F=E7=94=BB=E3=81=97?= =?UTF-8?q?=E3=83=91=E3=83=83=E3=83=81=E7=AF=84=E5=9B=B2=E6=A4=9C=E6=9F=BB?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../renderer/CopperGolemStatueRenderer.java | 86 +++++++ .../org/dynmap/utils/PatchDefinition.java | 18 +- .../main/resources/copper-golem-statue.csv | 230 ++++++++++++++++++ DynmapCore/src/main/resources/models_1.txt | 2 + DynmapCore/src/main/resources/texture_1.txt | 14 +- .../entity/copper_golem/copper_golem.png | Bin 0 -> 648 bytes .../copper_golem/copper_golem_exposed.png | Bin 0 -> 659 bytes .../copper_golem/copper_golem_oxidized.png | Bin 0 -> 647 bytes .../copper_golem/copper_golem_weathered.png | Bin 0 -> 684 bytes .../CopperGolemStatueRendererTest.java | 51 ++++ .../org/dynmap/utils/PatchDefinitionTest.java | 18 ++ 11 files changed, 405 insertions(+), 14 deletions(-) create mode 100644 DynmapCore/src/main/java/org/dynmap/hdmap/renderer/CopperGolemStatueRenderer.java create mode 100644 DynmapCore/src/main/resources/copper-golem-statue.csv create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem_exposed.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem_oxidized.png create mode 100644 DynmapCore/src/main/resources/texturepacks/standard/assets/minecraft/textures/entity/copper_golem/copper_golem_weathered.png create mode 100644 DynmapCore/src/test/java/org/dynmap/hdmap/renderer/CopperGolemStatueRendererTest.java create mode 100644 DynmapCore/src/test/java/org/dynmap/utils/PatchDefinitionTest.java 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..b7ef6d78f --- /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,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 56aa28627..8c350f634 100644 --- a/DynmapCore/src/main/resources/models_1.txt +++ b/DynmapCore/src/main/resources/models_1.txt @@ -4756,3 +4756,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 7133a7e7a..cad51165d 100644 --- a/DynmapCore/src/main/resources/texture_1.txt +++ b/DynmapCore/src/main/resources/texture_1.txt @@ -4632,10 +4632,6 @@ block:id=%melon_stem,patch0=0:melon_stem,blockcolor=foliagebiome,transparency=TR [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=%copper_golem_statue,id=%waxed_copper_golem_statue,allfaces=0:copper_block,stdrot=true -[26.2-]block:id=%exposed_copper_golem_statue,id=%waxed_exposed_copper_golem_statue,allfaces=0:exposed_copper,stdrot=true -[26.2-]block:id=%weathered_copper_golem_statue,id=%waxed_weathered_copper_golem_statue,allfaces=0:weathered_copper,stdrot=true -[26.2-]block:id=%oxidized_copper_golem_statue,id=%waxed_oxidized_copper_golem_statue,allfaces=0:oxidized_copper,stdrot=true [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 @@ -6184,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/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 0000000000000000000000000000000000000000..eff34ff8f4530b994d0c7587b7bdfff9a66533f2 GIT binary patch literal 648 zcmV;30(bq1P)_p3~r6Ki2wiq0d!JMQvg8b*k%9#0u@O_ zK~#9!?U2oGn?Ml9H>sNYtUr3q4wiE*UhJs1AeKfwQUkr#q=2|JaSNhPkb5eu%?niV zQ+5}OKScZhk^EbY{;Snb%rK+|6k$=sq~Q!k;--F=q=BMkXHr(JV2r{>C|beb2f}oe zY5^4+0njd`T#<%zY+4wKRseG=oB^xPB@v27=&6UDV6ggJk{$g6Van=rAn*y>4tb6Z z2ZF$!pXj&uHTPw?}p_hr5QJD8`g*AIOA{O}L@bIW1PT2T39d90pp0&=q2kSE!g8aDB=-;8cFR9qa!WA;5rz^SBC_ELE=FegNB4j944xo z&_du1!Xoz4Jb=Iph$T3VBjm!-p#{t9hw_J)RX+HpPbi9a`Xa@3XwKv&sR- zbVyPp>GC$;gcb~w&SYd})dV=35U#lW#W$e^WH^=)W))I(C4hjO<0k4M9qXI??UXB@ zyK`4PB#D${F9BdE@1d+fqxV!jzmUC5%0jMX{`|5k^Q3%5U;wk~39HHkK%@S2m60~P ztV&rZq literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..54aecd5afa54d8dd24dcad2c98d23cf7f5411345 GIT binary patch literal 659 zcmV;E0&M+>P)J@G4addUUeTp1#1CV z+A6hL3&-w-Il^(!mC0RU@E85)010Ef^P>J71VBV>v}t%4JtV8I{E1mmufhaSAd4EzHtMu8MTo zWspS~!3L{eH?@w(n_3HDWG8A7ExSwL^peat=QmFwH^H^Qs5@5+w(OY2C?hrl#=`(~ zaHa*!;!4$7yDE8JP^)zudBAk_7i~uB;6m@ zbrAsb%+}qKY;w%1RZWjled+Z`5F$q*N+AU5pBM>lKrPOHP&d?Ros9)>q#G1I3mgf| tO2$Xv<2mL{De&P6Mc$AD2M+uf`~$z8$e1D3#M%G=002ovPDHLkV1nE%A;bUx literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d4130fd9cdd44fd6ea3898f68a7d4993bc82c136 GIT binary patch literal 647 zcmV;20(kw2P)!x;=b4rrE7Itwsc7evZR|@{wwF41EDL-H(9?N+x z>rrMrqy{XR)@yR)6EOKy-y3qo!yw!kQ#FFmvZJ6I!51xIDsv~G#VRlw~nfvG#+Gn z9p^;~X`GTk3LLGFAHxYU?q}vL-c$)BAmji5 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..96e41bac76891c340e1a3be1a67abb5d55a265f9 GIT binary patch literal 684 zcmV;d0#p5oP)CI0MMrL7K3-HzPewgJHi%Y>rT_o{0d!JMQvg8b*k%9#0y#-U zK~#9!?U7AS+b|f%4VuRJ34PfSKMOBcNVQ!TaM~TIh$A?LHF3GE6(sF#AV$-j2dVi4 zqn~oNL*G>T0g(E$tiNUbq{q)=VgQB69uiWp0lWOv+)Gkmq1Wt7`7{yiT~P?xM6j6_ z@`+I2?P&oOuL59mDCLM0Y+_NuR!jtNr@{tMvvvqq5JO2_%mka7wL@l<7lb-BYe8_1 z>GYACSg;_R)#%l=--GG%^HS@Mzhz9lWVmyAVw0c2Uj-$iP#SY3X&!^=-|C*NP z*PE62?2s&>->)}Wg&vXKWCAUvI$*y`40_0VPX#QoqCs3CSaxc>YIj8mu$c~O;hT>H zfJz#INI*kGn#4(xs1T_zP8?Q5mW1s=3~?9}k2|=3iH!TW*F`OOVOhwV@G6fWawB4$ z96_g{s!|9WpoLm<`>VWe_H!S6*C%O~wC~RcX_od>Xu)xplwRzeWEi~xs3XzOd+M(`n)7?9>knSobx#1 z4tJIWL~1d1Np+sotk25=R6B?*B~&|rR(-jIxIajOEaKwsd%}Z^tXZ?>UGN{sPt@IK S|2hT$0000 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)); + } +} From 841afdc71dec9ef0cde58b825602fcd6d269e4db Mon Sep 17 00:00:00 2001 From: Gui <51219838+gui-ace@users.noreply.github.com> Date: Tue, 8 Sep 2026 23:41:54 +0900 Subject: [PATCH 4/7] =?UTF-8?q?=E5=83=8F=E3=81=AE=E3=83=9D=E3=83=BC?= =?UTF-8?q?=E3=82=BA=E5=A4=89=E6=9B=B4=E3=82=92=E8=87=AA=E5=8B=95=E5=8F=8D?= =?UTF-8?q?=E6=98=A0=E3=81=97Paper=E3=81=A8Spigot=E3=81=AE=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E8=A9=A6=E9=A8=93=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/resources/copper-golem-statue.csv | 2 +- .../v26_2/BukkitVersionHelperSpigot26_2.java | 5 ++ .../bukkit/helper/BukkitVersionHelper.java | 5 +- docs/minecraft26-validation.md | 16 +++- .../java/org/dynmap/bukkit/DynmapPlugin.java | 19 ++++- validation/minecraft26/README.md | 42 ++++++++++ validation/minecraft26/ValidationPlugin.java | 79 +++++++++++++++++++ validation/minecraft26/classpath.init.gradle | 9 +++ validation/minecraft26/plugin.yml | 9 +++ 9 files changed, 178 insertions(+), 8 deletions(-) create mode 100644 validation/minecraft26/README.md create mode 100644 validation/minecraft26/ValidationPlugin.java create mode 100644 validation/minecraft26/classpath.init.gradle create mode 100644 validation/minecraft26/plugin.yml diff --git a/DynmapCore/src/main/resources/copper-golem-statue.csv b/DynmapCore/src/main/resources/copper-golem-statue.csv index b7ef6d78f..9af6f9957 100644 --- a/DynmapCore/src/main/resources/copper-golem-statue.csv +++ b/DynmapCore/src/main/resources/copper-golem-statue.csv @@ -1,5 +1,5 @@ # Minecraft 26.2 copper golem statue geometry; client SHA1 2dc72797acbc1b63fc16a11c4ac393605f453754 -# pose,texture,width,height,origin xyz,U endpoint xyz,V endpoint xyz (north; blocks) +# 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 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 index 4ba66dc8d..27a69e649 100644 --- 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 @@ -73,6 +73,11 @@ */ 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; 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 index 1bdfe1072..d3d3e3973 100644 --- a/docs/minecraft26-validation.md +++ b/docs/minecraft26-validation.md @@ -1,6 +1,6 @@ # Minecraft 26.2 候補 -Issue #2 の対象は Paper 26.2 の隔離検証用候補です。自動本番反映や一般向けJAR配布は行いません。 +Issue #2 の対象は Paper / Spigot 26.2 の隔離検証用候補です。自動本番反映や一般向けJAR配布は行いません。 R2マーカー修正 (#1) はこの差分に含めず、ビルド基盤 (#3) を前提にします。 ## 上流と採否 @@ -32,6 +32,13 @@ Acecoreでは以下を調整しています。 - スキン応答のエラー時に元の応答本文をログへ出さない。 - 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比較は維持。 ## ビルド @@ -62,7 +69,8 @@ Paper 26.2 build 105 / Java 25を主対象とし、旧Paperは既存向けJARの 4. 同じ入力で旧Paper向けビルドの起動・レンダー・マーカーを確認。 5. テストサーバーを正常停止し、ソース版・JAR SHA-256・ログを記録。 -候補の起動だけでは26.2の全ブロック・全状態への対応完了とはしません。 -上流PRのcopper golem statueは銅色の立方体による暫定表示です。実モデルへの忠実性は未達です。 -Spigot 26.2、Fabric/Forge 26.2、全旧バージョン、一般プレイヤー操作の網羅試験は別途必要です。 +銅ゴーレム像は256状態のメッシュを単体検査し、同じ256状態を実サーバーにも配置します。 +通常の設置・破壊・ポーズ変更の検証方法は [隔離操作試験](../validation/minecraft26/README.md) を参照してください。 +Fabric/Forge 26.2の新規対応は、今回選択したPaper/Spigot用ソースの取り込み範囲に含みません。 +既存ローダーへの影響は、元のモジュールを保持した標準ビルドと共有コアのテストで確認します。 本番へ進める際は [運用手順](acecore-maintenance.md) のバックアップと個別承認に従います。 diff --git a/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java b/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java index 63e0025a8..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; @@ -1296,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); @@ -1320,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(); @@ -1378,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/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..619fa9d9d --- /dev/null +++ b/validation/minecraft26/ValidationPlugin.java @@ -0,0 +1,79 @@ +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); + world.setGameRule(org.bukkit.GameRule.DO_DAYLIGHT_CYCLE, false); + world.setGameRule(org.bukkit.GameRule.RANDOM_TICK_SPEED, 0); + } + // 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 From 18eed07ec78585a42cfd60242df6053ca1c360c7 Mon Sep 17 00:00:00 2001 From: Gui <51219838+gui-ace@users.noreply.github.com> Date: Wed, 9 Sep 2026 00:11:02 +0900 Subject: [PATCH 5/7] =?UTF-8?q?=E6=96=B0=E3=83=96=E3=83=AD=E3=83=83?= =?UTF-8?q?=E3=82=AF=E3=81=AE=E3=83=A2=E3=83=87=E3=83=AB=E3=82=92=E5=AF=BE?= =?UTF-8?q?=E8=B1=A1=E7=89=88=E3=81=AB=E9=99=90=E5=AE=9A=E3=81=97=E6=A4=9C?= =?UTF-8?q?=E8=A8=BCAPI=E3=82=92Spigot=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DynmapCore/src/main/resources/models_1.txt | 5 +++-- validation/minecraft26/ValidationPlugin.java | 11 +++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/DynmapCore/src/main/resources/models_1.txt b/DynmapCore/src/main/resources/models_1.txt index 8c350f634..60a3e523b 100644 --- a/DynmapCore/src/main/resources/models_1.txt +++ b/DynmapCore/src/main/resources/models_1.txt @@ -880,7 +880,8 @@ patchblock:id=tall_seagrass,id=seagrass,patch0=VertX075,patch1=VertX075@90,patch # Oxeye daisy # 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,id=golden_dandelion,patch0=VertX1Z0ToX0Z1,patch1=VertX1Z0ToX0Z1@90 +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,7 +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 -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 +[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 diff --git a/validation/minecraft26/ValidationPlugin.java b/validation/minecraft26/ValidationPlugin.java index 619fa9d9d..3527acd27 100644 --- a/validation/minecraft26/ValidationPlugin.java +++ b/validation/minecraft26/ValidationPlugin.java @@ -30,8 +30,15 @@ public void onEnable() { getServer().getPluginManager().registerEvents(this, this); org.bukkit.World world = getServer().getWorlds().get(0); world.setTime(6000); - world.setGameRule(org.bukkit.GameRule.DO_DAYLIGHT_CYCLE, false); - world.setGameRule(org.bukkit.GameRule.RANDOM_TICK_SPEED, 0); + setRule(world, "advance_time", "doDaylightCycle", false); + setRule(world, "random_tick_speed", "randomTickSpeed", 0); + } + @SuppressWarnings("unchecked") + private static void setRule(org.bukkit.World world, String current, String legacy, T value) { + org.bukkit.GameRule rule = org.bukkit.GameRule.getByName(current); + if (rule == null) rule = org.bukkit.GameRule.getByName(legacy); + if (rule == null || !rule.getType().isInstance(value) || !world.setGameRule((org.bukkit.GameRule)rule, value)) + throw new IllegalStateException("Cannot set game rule " + current); } // Keep waterlogged samples independent; flowing water would obscure adjacent dry samples. @EventHandler public void fluid(BlockFromToEvent event) { event.setCancelled(true); } From 678be6cf7dfddbeea60930530e5f7c65d2a99a47 Mon Sep 17 00:00:00 2001 From: Gui <51219838+gui-ace@users.noreply.github.com> Date: Wed, 9 Sep 2026 00:24:45 +0900 Subject: [PATCH 6/7] =?UTF-8?q?=E9=9A=94=E9=9B=A2=E6=A4=9C=E8=A8=BC?= =?UTF-8?q?=E3=82=92Paper=E3=81=A8Spigot=E3=81=A7=E5=85=B1=E9=80=9A?= =?UTF-8?q?=E5=8C=96=E3=81=97=E6=9C=80=E7=B5=82=E7=B5=90=E6=9E=9C=E3=82=92?= =?UTF-8?q?=E8=A8=98=E9=8C=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/minecraft26-validation.md | 29 +++++++++++++++++++- validation/minecraft26/ValidationPlugin.java | 18 ++++++------ 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/docs/minecraft26-validation.md b/docs/minecraft26-validation.md index d3d3e3973..96251d341 100644 --- a/docs/minecraft26-validation.md +++ b/docs/minecraft26-validation.md @@ -13,7 +13,8 @@ R2マーカー修正 (#1) はこの差分に含めず、ビルド基盤 (#3) を 新helper、NBT/チャンク読み取り、ブロックモデル・テクスチャのソースを取り込みました。 上流PRの `Plugin/*.jar`、Fabricの新プラットフォーム、Forgeビルドの削除・移動、 作業用指示ファイルは取り込みません。Apache-2.0と既存の著作権・商標表示を維持し、 -追加PNGは上流PRのMinecraft用標準テクスチャ資材と同じものです。 +取り込んだPNGは上流PRのMinecraft用標準テクスチャ資材です。 +銅ゴーレム像用に追加した4枚は、下記SHA-1の公式クライアントから取得した標準テクスチャです。 ソースの公開とバイナリの一般配布は別に判断します。 Acecoreでは以下を調整しています。 @@ -39,6 +40,7 @@ Acecoreでは以下を調整しています。 - パッチの可視範囲検査でUの代わりにVを使っていた計算を修正。台形の端点も検査します。 - 像への右クリック後に実際のブロック状態が変わった場合だけ再描画。 26.2では旧Materialのdata値への変換を使わず、旧helperのID/data比較は維持。 +- golden dandelionと鉢植えのモデルを26.1以降に限定し、旧版で存在しないブロックのエラーを防止。 ## ビルド @@ -74,3 +76,28 @@ Paper 26.2 build 105 / Java 25を主対象とし、旧Paperは既存向けJARの Fabric/Forge 26.2の新規対応は、今回選択したPaper/Spigot用ソースの取り込み範囲に含みません。 既存ローダーへの影響は、元のモジュールを保持した標準ビルドと共有コアのテストで確認します。 本番へ進める際は [運用手順](acecore-maintenance.md) のバックアップと個別承認に従います。 + +## 2026-09-09の実行結果 + +実行JARのソースは `18eed07ec78585a42cfd60242df6053ca1c360c7`。後続の検証プラグイン・記録の変更は本番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/validation/minecraft26/ValidationPlugin.java b/validation/minecraft26/ValidationPlugin.java index 3527acd27..b9e849a4b 100644 --- a/validation/minecraft26/ValidationPlugin.java +++ b/validation/minecraft26/ValidationPlugin.java @@ -30,15 +30,17 @@ public void onEnable() { getServer().getPluginManager().registerEvents(this, this); org.bukkit.World world = getServer().getWorlds().get(0); world.setTime(6000); - setRule(world, "advance_time", "doDaylightCycle", false); - setRule(world, "random_tick_speed", "randomTickSpeed", 0); + // Spigot registers vanilla commands after plugin enablement. + getServer().getScheduler().runTask(this, () -> { + setRule("advance_time", "false"); + setRule("random_tick_speed", "0"); + }); } - @SuppressWarnings("unchecked") - private static void setRule(org.bukkit.World world, String current, String legacy, T value) { - org.bukkit.GameRule rule = org.bukkit.GameRule.getByName(current); - if (rule == null) rule = org.bukkit.GameRule.getByName(legacy); - if (rule == null || !rule.getType().isInstance(value) || !world.setGameRule((org.bukkit.GameRule)rule, value)) - throw new IllegalStateException("Cannot set game rule " + current); + 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); } From 6caa618f03924a153b89d3165cff07136fab03e2 Mon Sep 17 00:00:00 2001 From: Gui <51219838+gui-ace@users.noreply.github.com> Date: Wed, 9 Sep 2026 00:35:51 +0900 Subject: [PATCH 7/7] =?UTF-8?q?=E6=97=A7Forge=E3=81=AE=E5=88=9D=E6=9C=9F?= =?UTF-8?q?=E5=8C=96=E5=89=8D=E3=81=AB=E5=85=AC=E5=BC=8F=E4=BE=9D=E5=AD=98?= =?UTF-8?q?=E5=8F=96=E5=BE=97=E5=85=88=E3=82=92=E7=99=BB=E9=8C=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/minecraft26-validation.md | 3 ++- gradle/common.gradle | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/minecraft26-validation.md b/docs/minecraft26-validation.md index 96251d341..18f0de6a9 100644 --- a/docs/minecraft26-validation.md +++ b/docs/minecraft26-validation.md @@ -79,7 +79,8 @@ Fabric/Forge 26.2の新規対応は、今回選択したPaper/Spigot用ソース ## 2026-09-09の実行結果 -実行JARのソースは `18eed07ec78585a42cfd60242df6053ca1c360c7`。後続の検証プラグイン・記録の変更は本番JARに含みません。 +実行JARのソースは `18eed07ec78585a42cfd60242df6053ca1c360c7`。 +後続変更は検証プラグイン・記録・旧Forgeの依存取得先の登録順です。候補JARの実装変更はありません。 | 対象 | 検証結果 | | --- | --- | diff --git a/gradle/common.gradle b/gradle/common.gradle index 4d3dcf7ed..af049235e 100644 --- a/gradle/common.gradle +++ b/gradle/common.gradle @@ -9,6 +9,9 @@ eclipse { 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/' }