diff --git a/.github/verify-published-pins.sh b/.github/verify-published-pins.sh index eadb217..7aa539d 100644 --- a/.github/verify-published-pins.sh +++ b/.github/verify-published-pins.sh @@ -18,10 +18,10 @@ done require_merged() { local repo="$1" ref="$2" status [[ "$ref" =~ ^[a-f0-9]{40}$ ]] - status="$(gh api "repos/MinecraftModDevelopmentMods/$repo/compare/$ref...master-26.1.2" --jq '.status')" + status="$(gh api "repos/MinecraftModDevelopmentMods/$repo/compare/$ref...master-26.2" --jq '.status')" case "$status" in identical|ahead) ;; - *) echo "::error::$repo $ref is not on upstream master-26.1.2 ($status)."; exit 1 ;; + *) echo "::error::$repo $ref is not on upstream master-26.2 ($status)."; exit 1 ;; esac } @@ -43,12 +43,14 @@ public_jar() { } power_ref="$(value poweradvantage_source_ref)" +unit_support_ref="$(value unit_support_source_ref)" orespawn_ref="$(value orespawn_source_commit)" require_merged basePower "$power_ref" +require_merged basePower "$unit_support_ref" require_merged BaseMetals "$(value basemetals_source_commit)" require_merged OreSpawn "$orespawn_ref" -inputs="${RUNNER_TEMP:?}/forge64-release-dependencies" +inputs="${RUNNER_TEMP:?}/forge65-release-dependencies" mkdir -p "$inputs" power="$inputs/basePower-$(value poweradvantage_version).jar" metals="$inputs/BaseMetals-$(value basemetals_version).jar" @@ -57,11 +59,12 @@ public_jar basePower 1780140 "$(value poweradvantage_public_file_id)" "$(value p public_jar BaseMetals 240967 "$(value basemetals_public_file_id)" "$(value basemetals_deobf_sha256)" "$metals" public_jar OreSpawn 245586 "$(value orespawn_public_file_id)" "$(value orespawn_deobf_sha256)" "$orespawn" -installer="$inputs/forge-26.1.2-64.1.5-installer.jar" -download 'https://maven.minecraftforge.net/net/minecraftforge/forge/26.1.2-64.1.5/forge-26.1.2-64.1.5-installer.jar' \ +installer="$inputs/forge-26.2-65.1.0-installer.jar" +download 'https://maven.minecraftforge.net/net/minecraftforge/forge/26.2-65.1.0/forge-26.2-65.1.0-installer.jar' \ "$(value forge_installer_sha256)" "$installer" { printf 'power_ref=%s\n' "$power_ref" + printf 'unit_support_ref=%s\n' "$unit_support_ref" printf 'orespawn_ref=%s\n' "$orespawn_ref" } >> "${GITHUB_OUTPUT:?}" { diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc08f8b..9a0c8de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,16 +1,16 @@ -name: baseElectric 26.1.2 CI +name: baseElectric 26.2 CI on: push: - branches: [master-26.1.2, 'feature/**'] + branches: [master-26.2, 'feature/**'] pull_request: - branches: [master-26.1.2] + branches: [master-26.2] permissions: contents: read concurrency: - group: baseelectric-26.1.2-${{ github.workflow }}-${{ github.ref }} + group: baseelectric-26.2-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: @@ -34,11 +34,11 @@ jobs: repository: MinecraftModDevelopmentMods/OreSpawn ref: ${{ steps.public-pins.outputs.orespawn_ref }} path: .ci-dependencies/OreSpawn - - name: Check out released basePower source + - name: Check out qualified basePower unit-support source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/basePower - ref: ${{ steps.public-pins.outputs.power_ref }} + ref: ${{ steps.public-pins.outputs.unit_support_ref }} path: .ci-dependencies/basePower - name: Install Java 25 for all build and runtime roles uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 @@ -52,11 +52,11 @@ jobs: -Porg.gradle.java.installations.auto-download=false" >> "$GITHUB_ENV" - name: Set up Gradle uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 - - name: Verify the Forge 64 build inputs + - name: Verify the Forge 65 build inputs shell: bash env: ORESPAWN_REF: ${{ steps.public-pins.outputs.orespawn_ref }} - POWER_REF: ${{ steps.public-pins.outputs.power_ref }} + POWER_REF: ${{ steps.public-pins.outputs.unit_support_ref }} run: | set -euo pipefail orespawn="$GITHUB_WORKSPACE/.ci-dependencies/OreSpawn" @@ -64,7 +64,7 @@ jobs: test "$(git -C "$orespawn" rev-parse HEAD)" = "$ORESPAWN_REF" test "$(git -C "$power" rev-parse HEAD)" = "$POWER_REF" mavenizer="$orespawn/ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar" - printf '%s %s\n' 'BB0DACB3DEB2A711CA67DD402D5FDAB5A9847C37C7B9B596DEC7CF37378FA085' "$mavenizer" | sha256sum -c - + printf '%s %s\n' '5ABAB52A3F1BE115381C3CE80D5FD38DBE6C9F4C0B9ECF70A957700EC90FB88B' "$mavenizer" | sha256sum -c - echo "MAVENIZER=$mavenizer" >> "$GITHUB_ENV" - name: Build and audit release artifacts shell: bash @@ -78,20 +78,20 @@ jobs: - name: Upload audited release candidate uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - name: baseElectric-26.1.2-${{ github.sha }} + name: baseElectric-26.2-${{ github.sha }} if-no-files-found: error retention-days: 30 path: | - build/libs/baseElectric-2.2.17.2601021.jar - build/libs/baseElectric-2.2.17.2601021-sources.jar - build/libs/baseElectric-2.2.17.2601021-javadoc.jar + build/libs/baseElectric-2.2.18.2602001.jar + build/libs/baseElectric-2.2.18.2602001-sources.jar + build/libs/baseElectric-2.2.18.2602001-javadoc.jar build/release/SHA256SUMS CHANGELOG.txt - name: Upload diagnostics on failure if: failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - name: baseElectric-26.1.2-diagnostics-${{ github.sha }} + name: baseElectric-26.2-diagnostics-${{ github.sha }} if-no-files-found: ignore retention-days: 14 path: | diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 22f5431..e6145f9 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,9 +2,9 @@ name: CodeQL on: push: - branches: [master-26.1.2, 'feature/**'] + branches: [master-26.2, 'feature/**'] pull_request: - branches: [master-26.1.2] + branches: [master-26.2] permissions: contents: read @@ -12,7 +12,7 @@ permissions: security-events: write concurrency: - group: baseelectric-26.1.2-${{ github.workflow }}-${{ github.ref }} + group: baseelectric-26.2-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: @@ -36,11 +36,11 @@ jobs: repository: MinecraftModDevelopmentMods/OreSpawn ref: ${{ steps.public-pins.outputs.orespawn_ref }} path: .ci-dependencies/OreSpawn - - name: Check out released basePower source + - name: Check out qualified basePower unit-support source uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: MinecraftModDevelopmentMods/basePower - ref: ${{ steps.public-pins.outputs.power_ref }} + ref: ${{ steps.public-pins.outputs.unit_support_ref }} path: .ci-dependencies/basePower - name: Install Java 25 for all build and runtime roles uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 @@ -54,11 +54,11 @@ jobs: -Porg.gradle.java.installations.auto-download=false" >> "$GITHUB_ENV" - name: Set up Gradle uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6 - - name: Verify the Forge 64 build inputs + - name: Verify the Forge 65 build inputs shell: bash env: ORESPAWN_REF: ${{ steps.public-pins.outputs.orespawn_ref }} - POWER_REF: ${{ steps.public-pins.outputs.power_ref }} + POWER_REF: ${{ steps.public-pins.outputs.unit_support_ref }} run: | set -euo pipefail orespawn="$GITHUB_WORKSPACE/.ci-dependencies/OreSpawn" @@ -66,7 +66,7 @@ jobs: test "$(git -C "$orespawn" rev-parse HEAD)" = "$ORESPAWN_REF" test "$(git -C "$power" rev-parse HEAD)" = "$POWER_REF" mavenizer="$orespawn/ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar" - printf '%s %s\n' 'BB0DACB3DEB2A711CA67DD402D5FDAB5A9847C37C7B9B596DEC7CF37378FA085' "$mavenizer" | sha256sum -c - + printf '%s %s\n' '5ABAB52A3F1BE115381C3CE80D5FD38DBE6C9F4C0B9ECF70A957700EC90FB88B' "$mavenizer" | sha256sum -c - echo "MAVENIZER=$mavenizer" >> "$GITHUB_ENV" - name: Initialize CodeQL uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4 diff --git a/.github/workflows/validate-gradle-build.yml b/.github/workflows/validate-gradle-build.yml index 531f53f..d8bacce 100644 --- a/.github/workflows/validate-gradle-build.yml +++ b/.github/workflows/validate-gradle-build.yml @@ -3,11 +3,11 @@ name: Validate Gradle Wrapper on: push: branches: - - master-26.1.2 + - master-26.2 - 'feature/**' pull_request: branches: - - master-26.1.2 + - master-26.2 permissions: contents: read diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 68912b2..aba38ac 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,12 @@ +baseElectric 2.2.18.2602001 (Minecraft 26.2 / Forge) + +- Target Minecraft 26.2 and Forge 65 with Java 25. +- Keep the shared Base Metals migration hook and existing machine, item and saved-data identities. +- Retain exact dependency, native pack, artifact and classpath guards. +- Pass the combined profile03 machine, migration, actor/order, client and two-world endurance checks, including independent 66-checkpoint replay. +- Complete the full release, cold-cache and manual checks. Publish after basePower so the expansion uses the released dependency. +- Pin the verified public basePower, Base Metals and OreSpawn releases. + baseElectric 2.2.17.2601021 (Minecraft 26.1.2 / Forge) - Bring baseElectric to Minecraft 26.1.2 with Forge 64.1.5 and Java 25. diff --git a/README.md b/README.md index d2c3c01..25a9076 100644 --- a/README.md +++ b/README.md @@ -1,91 +1,76 @@ # baseElectric -**Minecraft 26.1.2 (Forge), version 2.2.17.2601021.** - -baseElectric continues DrCyano's Electric Advantage. It adds electric machines, -generation, storage, automation and defence to basePower. Its equipment appears -in the shared basePower creative tab. - -This checkout targets Minecraft **26.1.2** and -Forge **64.1.5**, using official runtime names, MCP **20260409.101008**, -ForgeGradle **7.0.34**, Gradle **9.6.1**, and Temurin **25.0.3+9**. -The frozen profile12 family has completed automated qualification and manual -testing. See the -[family qualification record](../../PowerAdvantage/docs/26.1.2/QUALIFICATION.md) -for the exact tested jars, completed checks and scope limits. Manual acceptance -is complete. [This release is available on CurseForge](https://www.curseforge.com/minecraft/mc-mods/baseelectric/files/9577930), -MMD Maven and GitHub Releases. All three player-jar downloads match the final -restart and endurance-tested checksum. - -basePower **2.4.16.2601021** and Base Metals **3.1.2.2601021** are required on -both client and server. Their public source and ordinary-jar checkpoints are -recorded in `gradle.properties`. -The build rejects old 1.21.11 inputs. OreSpawn -**4.1.1.2601021** is pinned to its public release (CurseForge 9572926). -See the [26.1.2 notes](docs/NATIVE2612.md). - -The public pins use Power source `a684e71e` / jar `23ABCC1F` (CurseForge 9576332) -and Base Metals source `5e708468` / jar `67862388` (9576007). Their public -downloads match the accepted dependency jars. Power is published first, then -Steam, then Electric. Electric's promoted jar changes only its manifest to -record the merged Power source; every other archive entry is byte-identical -to the accepted candidate. Restart and endurance qualification for those final -jar bytes is recorded separately from the earlier candidate's results. -The new clean release suite passes 117 unit tests and 28 native checks, and its -warm and fresh empty-cache path-with-spaces reproductions match all three -archives. Fresh ECJ passes all 117 tests with the complete compiled inventory, -and the standalone source audit passes all nine checks after its exact OreSpawn -constants were updated. The original stale-pin failures remain preserved. - -The completed [1.21.11 release](https://www.curseforge.com/minecraft/mc-mods/baseelectric/files/9567881) -and its [qualification notes](docs/NATIVE12111.md) are historical evidence, -not proof of this port. New gameplay, migration and graphical checks must use -the actual 26.1.2 jars. - -Back up your world and try the upgrade on a copy. Replace Electric Advantage -and Power Advantage with baseElectric and basePower; do not install both sets. - -## Building locally - -Use Temurin 25.0.3+9 for Gradle, Minecraft, compilation, tests, Mavenizer and -Slime Launcher. No Java 8 helper is required. Set -`-Porg.gradle.java.installations.paths=` if needed. -Use the isolated `D:/GradleCaches/baseelectric-2612-port` cache for local work. - -The independent Forge/resource checks do not require sibling jars: +**Minecraft 26.2 Forge, version 2.2.18.2602001. Automated and manual testing complete.** + +baseElectric continues DrCyano's Electric Advantage and uses basePower's shared +API, machines and creative tab. Existing `baseelectric` registry and saved-data +identities are retained. + +This port targets Forge **65.1.0**, official Minecraft **26.2** names, +MCP **20260616.103818**, Java **25.0.3+9**, ForgeGradle **7.0.34** and the +checksum-pinned Gradle **9.6.1** wrapper. Native pack formats are data +**107.1** and client **88.0**. + +The earlier [26.1.2 release](https://www.curseforge.com/minecraft/mc-mods/baseelectric/files/9577930) +remains available on CurseForge, MMD Maven and GitHub Releases. The 26.2 +release is being prepared separately; the version and dependency pins below +apply to this branch. + +## Build + +The coordinated dependencies are +[basePower **2.4.17.2602001**](https://www.curseforge.com/minecraft/mc-mods/basepower/files/9583433), +[Base Metals **3.1.2.2602001**](https://www.curseforge.com/minecraft/mc-mods/base-metals/files/9583122) +and [OreSpawn **4.1.1.2602001**](https://www.curseforge.com/minecraft/mc-mods/mmd-orespawn/files/9582731). +Base Metals is required on both client and server. These two published +dependency patches match the jars used for the combined tests; older downloads +do not include the same migration and retained-settings repairs. + +All three dependency downloads have been checked against their release builds. +Exact source, download and SHA-256 pins are kept together in `gradle.properties`. + +The Mavenizer fixture and its source-rule, patch, licence and provenance files +are checksum-sealed from the existing OS262 checkout. The established +`-Pforge64MavenizerJar` property remains a path alias; it selects the Forge65 +fixture here. Dependencies stay separate mods and must match the source and +artifact pins in `gradle.properties`. + +Use Temurin 25 and clear `JAVA_TOOL_OPTIONS`, `JDK_JAVA_OPTIONS` and +`_JAVA_OPTIONS` before qualification. The prepared sibling layout is the +default; explicit `*DeobfJar` and `*RuntimeJar`/`*PlayerJar` flags change +paths, not the required bytes. With these exact coordinated inputs: + +Unit support keeps its separately qualified Power source revision in +`unit_support_source_ref`. Pass that source directory with `-PpowerUnitSource` +when the sibling Power checkout is newer; the four source hashes remain fixed. +Hosted builds check out this test-only revision separately from the public +Power player pin. ```text -./gradlew nativeResourceChecks compileNativeApiDiagnostics verifyRecipeTagGuards processResources --max-workers=2 --no-daemon +./gradlew clean check build javadoc verifyReleaseDependencies verifyReleaseArtifacts writeReleaseChecksums --no-build-cache --no-daemon +./gradlew verifyEclipseProductionClasspath --no-daemon node tools/verify-native-port.js node tools/generate-recipe-unlocks.js --check ``` -For a full local build, use the exact local dependency pins in -`gradle.properties`. Path overrides never replace source or hash checks: +## Qualification -```text --PpowerAdvantageRuntimeJar=/path/to/basePower-2.4.16.2601021.jar --PbaseMetalsRuntimeJar=/path/to/BaseMetals-3.1.2.2601021.jar --PforgeInstallerJar=/path/to/forge-26.1.2-64.1.5-installer.jar -``` +Combined profile03 passed the machine, migration, actor/dimension, actual +transformer-order and real-client checks, plus two 30-minute worlds, restart +and independent 66-checkpoint replay. See [26.2 port status](docs/NATIVE262.md) +for the counts and exact inputs. The [family qualification record](https://github.com/MinecraftModDevelopmentMods/basePower/blob/master-26.2/docs/26.2/QUALIFICATION.md) +keeps the completed checks and their scope limits together. -Forge 64 uses the ordinary native jar for both play and development. The former -`*DeobfJar` path flags remain aliases for the same bytes. OreSpawn and the -Mavenizer fixture default to the sibling `MinecraftMineralogy/OS2612/OreSpawn` -checkout. Use `-PoreSpawnRuntimeJar` and `-Pforge64MavenizerJar` to override paths. -For the prepared cache, use `--offline` with `ORESPAWN_MAVENIZER_OFFLINE=true`. - -```text -./gradlew check build javadoc verifyLocalRuntimeInputs writeReleaseChecksums verifyEclipseProductionClasspath --no-build-cache -``` - -Use `gradlew.bat` on Windows. Output jars go to `build/libs`. Dependencies -remain separate mods. The 26.1.2 CI and CodeQL jobs require merged source pins -and checksum-matching public dependencies before checkout or compilation. -Local jars do not satisfy that gate. +The final root build and cold-cache checks passed, and manual testing was +accepted on 12 November 2026. Publication follows the dependency order: +OreSpawn and Base Metals, then basePower and baseSteam, then this expansion. +The accepted 26.1.2 records remain historical proof of their original bytes, +not a substitute for the 26.2 results. ## Candidate09 Verification History +This section records the earlier 26.1.2 work, not qualification of this 26.2 candidate. + The previous candidate09 passed 117 unit tests, 28 independent native resource tests and 117 tests from fresh ECJ output, with no failures or skips. The ECJ gate compares every compiled test method with the Gradle XML inventory. diff --git a/build.gradle b/build.gradle index 9282a68..548f82a 100644 --- a/build.gradle +++ b/build.gradle @@ -203,7 +203,7 @@ sourceSets.main.resources { def forgeRunModClassesDirectory = layout.buildDirectory.dir('forge-run-mod-classes/main') def prepareForgeRunModClasses = tasks.register('prepareForgeRunModClasses', Sync) { group = 'ide' - description = 'Merges classes and processed resources for Forge 26.1.2 launches.' + description = 'Merges classes and processed resources for Forge 26.2 launches.' dependsOn tasks.named('classes') from sourceSets.main.output into forgeRunModClassesDirectory @@ -321,12 +321,12 @@ def requirePowerPin = { || !(project.poweradvantage_source_ref ==~ /[a-f0-9]{40}/) || ![project.poweradvantage_deobf_sha256, project.poweradvantage_runtime_sha256] .every { it ==~ /[A-F0-9]{64}/ }) { - throw new GradleException('The owner-approved basePower 26.1.2 source and artifact pins are required.') + throw new GradleException('The owner-approved basePower 26.2 source and artifact pins are required.') } } // Resolve and check only the dependencies required by the selected tasks. def powerDefaultJar = "../../PowerAdvantage/build/libs/basePower-${project.poweradvantage_version}.jar" -def metalsDefaultJar = "../../../../BaseMetals/BaseMetals 2612/BaseMetals/build/libs/BaseMetals-${project.basemetals_version}.jar" +def metalsDefaultJar = "../../../../BaseMetals/BaseMetals 262/BaseMetals/build/libs/BaseMetals-${project.basemetals_version}.jar" def powerAdvantageDeobfJar = providers.provider { requirePowerPin() pinnedFile('powerAdvantageDeobfJar', project.poweradvantage_deobf_sha256, @@ -337,7 +337,7 @@ def baseMetalsDeobfJar = providers.provider { pinnedFile('baseMetalsDeobfJar', project.basemetals_deobf_sha256, providers.gradleProperty('baseMetalsRuntimeJar').getOrElse(metalsDefaultJar)) } -def oreSpawnProject = '../../../../MinecraftMineralogy/OS2612/OreSpawn' +def oreSpawnProject = '../../../../MinecraftMineralogy/OS262/OreSpawn' def oreSpawnDeobfJar = providers.provider { requireCommittedPins('orespawn_') pinnedFile('oreSpawnDeobfJar', project.orespawn_deobf_sha256, @@ -362,8 +362,14 @@ def unitLoaderJava = providers.provider { "${powerUnitSource}/test-rig/unit-support/zone/moddev/mc/advantageworks/unit/Forge64UnitLoader.java") } def pinnedUnitSupport = layout.buildDirectory.dir('generated-unit-support') + +def unitEntityTrackerJava = providers.provider { + requireCommittedPins('unit_') + pinnedFile('unitEntityTrackerJava', project.unit_entity_tracker_java_sha256, + "${powerUnitSource}/test-rig/unit-support/zone/moddev/mc/advantageworks/unit/NativeEmptyEntityTracker.java") +} def preparePinnedUnitSupport = tasks.register('preparePinnedUnitSupport', Sync) { - from unitRegistriesJava, unitLoaderJava + from unitRegistriesJava, unitLoaderJava, unitEntityTrackerJava into pinnedUnitSupport.map { it.dir('zone/moddev/mc/advantageworks/unit') } } sourceSets.test.java.srcDir pinnedUnitSupport @@ -503,7 +509,7 @@ tasks.register('nativeUnitDiagnostics', Test) { } tasks.register('nativeResourceChecks', Test) { group = 'verification' - description = 'Checks Electric resources against native Forge 64 without sibling mod jars.' + description = 'Checks Electric resources against native Forge 65 without sibling mod jars.' dependsOn compileNativeResourceChecks, tasks.named('processResources') useJUnit() testClassesDirs = files(nativeResourceCheckClasses) @@ -590,13 +596,13 @@ def releaseJar = tasks.named('jar', Jar) tasks.register('releaseJar') { group = 'build' - description = 'Builds the native Forge 64 player jar.' + description = 'Builds the native Forge 65 player jar.' dependsOn releaseJar } tasks.register('deobfJar') { group = 'build' - description = 'Builds the same native Forge 64 jar used for development and play.' + description = 'Builds the same native Forge 65 jar used for development and play.' dependsOn tasks.named('jar') } @@ -671,22 +677,22 @@ tasks.register('verifyReleaseConfiguration') { requireCommittedPins('orespawn_') requireCommittedPins('forge_') def pack = new JsonSlurper().parse(file('src/main/resources/pack.mcmeta')).pack - if (pack.min_format != [101, 1] || pack.max_format != [101, 1] + if (pack.min_format != [107, 1] || pack.max_format != [107, 1] || pack.containsKey('pack_format') || pack.containsKey('supported_formats') || !(file('src/main/resources/META-INF/mods.toml').text =~ /(?m)^showAsResourcePack=false$/)) { - throw new GradleException('Root metadata must declare data 101.1 with the native hidden Forge client pack') + throw new GradleException('Root metadata must declare data 107.1 with the native hidden Forge client pack') } - if (project.mod_version != '2.2.17.2601021') { + if (project.mod_version != '2.2.18.2602001') { throw new GradleException("Unexpected baseElectric release version: ${project.mod_version}") } - if (project.minecraft_version != '26.1.2' - || project.minecraft_version_range != '[26.1.2]' - || project.forge_version != '64.1.5' - || project.forge_version_range != '[64.1.5,65)' - || project.loader_version_range != '[64,65)' + if (project.minecraft_version != '26.2' + || project.minecraft_version_range != '[26.2]' + || project.forge_version != '65.1.0' + || project.forge_version_range != '[65.1.0,66)' + || project.loader_version_range != '[65,66)' || project.mapping_channel != 'official' - || project.mapping_version != '26.1.2' - || project.mcp_version != '20260409.101008') { + || project.mapping_version != '26.2' + || project.mcp_version != '20260616.103818') { throw new GradleException('Unexpected Minecraft, Forge, or mappings target') } if (project.loader_name != 'forge' || project.loader_code != '1' @@ -706,17 +712,17 @@ tasks.register('verifyReleaseConfiguration') { } if (project.cf_requirements != 'basepower,base-metals' || project.cf_optionals != '' - || project.cf_versions != '26.1.2') { + || project.cf_versions != '26.2') { throw new GradleException('Unexpected CurseForge dependency or game-version metadata') } - if (project.poweradvantage_version != '2.4.16.2601021' + if (project.poweradvantage_version != '2.4.17.2602001' || project.poweradvantage_source_repository != 'MinecraftModDevelopmentMods/basePower') { throw new GradleException('Unexpected basePower compile dependency identity') } - if (!(project.basemetals_version ==~ /3\.\d+\.\d+\.2601021/) - || project.orespawn_version != '4.1.1.2601021' - || project.basemetals_built_on != '26.1.2-64.0.9' - || project.orespawn_built_on != '26.1.2-64.0.9' + if (!(project.basemetals_version ==~ /3\.\d+\.\d+\.2602001/) + || project.orespawn_version != '4.1.1.2602001' + || project.basemetals_built_on != '26.2-65.1.0' + || project.orespawn_built_on != '26.2-65.1.0' || !(project.basemetals_source_commit ==~ /[a-f0-9]{40}/) || !(project.basemetals_deobf_sha256 ==~ /[A-F0-9]{64}/) || !(project.basemetals_runtime_sha256 ==~ /[A-F0-9]{64}/) @@ -724,18 +730,18 @@ tasks.register('verifyReleaseConfiguration') { || project.orespawn_deobf_sha256 != project.orespawn_runtime_sha256 || project.basemetals_deobf_sha256 != project.basemetals_runtime_sha256 || project.poweradvantage_deobf_sha256 != project.poweradvantage_runtime_sha256 - || project.forge_installer_sha256 != '6E01323837051176762BD466340A601DA122F179FE6A00AC616E05429AE07648') { + || project.forge_installer_sha256 != '813FBBFECC3086A492783B9F5023AE15007737B42E17AAB75F48BA77403314DF') { throw new GradleException('Unexpected native dependency pins') } String mainSource = file( 'src/main/java/zone/moddev/mc/baseelectric/ElectricAdvantage.java').getText('UTF-8') if (!mainSource.contains('MODID = "baseelectric"') - || !mainSource.contains('VERSION = "2.2.17.2601021"')) { + || !mainSource.contains('VERSION = "2.2.18.2602001"')) { throw new GradleException('baseElectric source identity changed') } String metadata = file('src/main/resources/META-INF/mods.toml').getText('UTF-8').replace('\r\n', '\n') ['modId="baseelectric"', 'displayName="baseElectric"', 'modId="basepower"', 'modId="basemetals"', - 'versionRange="[2.4.16.2601021,3.0.0)"', 'versionRange="[3.1.2.2601021,4.0.0)"'].each { marker -> + 'versionRange="[2.4.17.2602001,3.0.0)"', 'versionRange="[3.1.2.2602001,4.0.0)"'].each { marker -> if (!metadata.contains(marker)) { throw new GradleException("Source mods.toml is missing ${marker}") } @@ -768,7 +774,7 @@ def auditModInput = { File jarFile, String modId, String version, List r def verifyOreSpawnNativeInputs = tasks.register('verifyOreSpawnNativeInputs') { group = 'verification' - description = 'Verifies the unchanged public OreSpawn jar and its own exact native build provenance.' + description = 'Verifies the approved local OreSpawn jar and its own exact native build provenance.' doLast { requireCommittedPins('orespawn_') auditModInput(oreSpawnDeobfJar.get(), 'orespawn', project.orespawn_version, []) @@ -781,7 +787,7 @@ def verifyOreSpawnNativeInputs = tasks.register('verifyOreSpawnNativeInputs') { tasks.register('verifyLocalNativeInputs') { group = 'verification' - description = 'Verifies explicit Base Metals and OreSpawn 26.1.2 development and player JARs.' + description = 'Verifies explicit Base Metals and OreSpawn 26.2 development and player JARs.' dependsOn tasks.named('verifyReleaseConfiguration') dependsOn verifyOreSpawnNativeInputs doLast { @@ -858,7 +864,7 @@ tasks.register('verifyReleaseDependencies') { ['fields.csv', 'methods.csv'].each { name -> String csv = zip.getInputStream(zip.getEntry(name)).getText('UTF-8').replace('\r\n', '\n') if (csv != 'searge,name,side,desc') { - throw new GradleException('Forge 64 official runtime mappings must be empty header-only CSVs') + throw new GradleException('Forge 65 official runtime mappings must be empty header-only CSVs') } } } @@ -1181,7 +1187,7 @@ tasks.register('validateMavenReleaseCredentials') { group = 'publishing' description = 'Rejects remote publication from this local port.' doLast { - throw new GradleException('Remote Maven publication is disabled on the local 26.1.2 port.') + throw new GradleException('Remote Maven publication is disabled on the local 26.2 port.') } } @@ -1257,7 +1263,7 @@ tasks.register('configureEclipseBuildship') { def quoteEclipseLaunchPaths = { String name, String arguments -> if (arguments.contains('--to-srg') || arguments.contains('--to-obf')) { - throw new GradleException("${name} must not remap the official Forge 64 runtime") + throw new GradleException("${name} must not remap the official Forge 65 runtime") } // ForgeGradle flattens path arguments without quoting them for Eclipse. Map nextOptions = [ @@ -1653,7 +1659,7 @@ tasks.register('verifyEclipseProductionClasspath') { || !programArguments.startsWith('--main net.minecraftforge.bootstrap.ForgeBootstrap ') || !(programArguments =~ /(?:^|\s)--launchTarget\s+${target}(?:\s|$)/).find() || !vmArguments.contains('--add-opens java.base/java.lang.invoke=ALL-UNNAMED')) { - throw new GradleException("${name} does not define the Forge 64 bootstrap and native launch target") + throw new GradleException("${name} does not define the Forge 65 bootstrap and native launch target") } ['--cache', '--metadata'].each { option -> def argument = programArguments =~ /(?:^|\s)${option}\s+(?:"([^"]+)"|([^"\s]+))(?=\s+--|$)/ diff --git a/docs/NATIVE262.md b/docs/NATIVE262.md new file mode 100644 index 0000000..2baf344 --- /dev/null +++ b/docs/NATIVE262.md @@ -0,0 +1,71 @@ +# Minecraft 26.2 combined checks passed + +Version 2.2.18.2602001 targets Forge65.1.0, MCP20260616.103818, Java25 and +native pack formats107.1/88.0. This candidate is local-only. The combined +checks below passed; the final root cold-cache gate is still pending. +Ready for manual testing once that gate is confirmed. Overall sign-off, +manual acceptance and publication are not claimed. + +## Exact inputs + +- Electric player/development SHA-256: + A7D12A66CA91A6BACCFEFD2CED9D3EC962F5FEB73BF632E1683F99084384F938. +- Power source f84b2362449e39eff5e76696dd64ce4cb144da4f; player/development + 7E456DE1A45140E86415A701D186FEDE08C4AB63D53C6B7848935DB70CBC68B1. +- Base Metals source 523335a59ecff399e40a7c66eb121a3aabdc45ba; player/development + 15CBD0C8DD95BBA846969929B8767887BA4B8152DFB10C9C58FB314AD39FB9E1. +- OreSpawn4.1.1.2602001 local retained-settings repair, source + dcaaa933299dd8b1ebc73e31c9e5acd36dd7957c; player/development + BC0658DF2E149CC23E65E5771F3FF62E2BB13FFDA4E316AB632EB92EF7FA5A1F. + No public file ID is assigned to this local candidate. +- Power's checksum-pinned unit agent and committed support sources are used + separately from player bytes. No helper or test classes ship in the mod. + +## Passed child gates + +- Clean check/build/Javadoc: 49 tasks / 117 unit tests, plus 28 independent native resource tests, with no failures or skips. +- Exact source/artifact pins, release archives/checksums, GameTest source + compilation and Eclipse production-classpath isolation. +- Fresh ECJ main/test/GameTest compilation and the same complete unit inventory, + including strict inventory-rejection controls. +- Committed-source offline and fresh unseeded-cache builds with paths containing + spaces reproduce all three release archives. The cold build executes 52 tasks, + including the 28 native tests; both regenerated Forge SDK jars also match. + No rebuild was needed for the later docs-only ancestry merges. +- All 50 recipe-unlock checks. Static source audits remain separate from runtime proof. +- Native entity bind-group layout and vertex sinks preserve the existing renderer + geometry, UV, lightmap, overlay and pose checks. A deferred collector check + confirms that later state mutation does not change submitted drill geometry. +- The native empty entity-ID tracker is an explicitly hash-pinned test fixture. + Native Entity/load methods and all four hydroturbine assertions are unchanged. +- Failed setup, compiler and test attempts are preserved separately. The + provisional old-Power/public-OreSpawn runs are not relabelled as this candidate. + +## Passed combined checks + +These results use frozen profile03, SHA-256 +A98D4F9B54A0AE47392D9A3CF81335F5E228F718C7D322DF9838A94AD27D9736, +and basePower's combined-family rig: + +- All eight machine campaigns, including moving, partial and bridge networks. +- All eight machine migration routes and the additional 26.1.2 route. +- Oil, resource and all three retained-generation routes. +- Nine actor/dimension routes. Six dimension routes retain raw wolf differences + backed by independent native controls; no other semantic difference is waived. +- Both actual transformer orders for machines and actors, with the instrumented + sidecars kept separate from ordinary production qualification. All 39 owned + game JVMs closed; 117 strict closed logs were audited. +- Real client07: 39 GUIs, 351 text checks, 26 tank gauges and 1,247 frames. +- Two genuine worlds ran for 1,800 seconds each, passed restart and passed + independent 66-checkpoint replay. The family verification root's + `endurance-independent-replay-03.json` records `PASS`. + +The [family qualification record](../../../PowerAdvantage/docs/26.2/QUALIFICATION.md) +is being finalized. Its remaining root cold-cache gate must be confirmed before +manual testing. Hydroturbine orientation/spin geometry in a fresh client world +remains an explicit manual gap. Historical records and failed receipts remain +unchanged and bound to their original inputs. + +Hosted CI still requires merged, public dependency inputs; local candidate +pins do not waive that gate. Base Metals and OreSpawn 26.2 remain unpublished +local inputs. No 26.2 push, tag, publisher dispatch or upload. diff --git a/gradle.properties b/gradle.properties index 3a82cf5..db1d75d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,18 +7,18 @@ org.gradle.workers.max=2 net.minecraftforge.gradle.merge-source-sets=false reobf=false -minecraft_version=26.1.2 -minecraft_version_range=[26.1.2] -forge_version=64.1.5 -forge_installer_sha256=6E01323837051176762BD466340A601DA122F179FE6A00AC616E05429AE07648 -forge_shim_sha256=0C74CB2A8E7A71AEB7055396C1E25864584A2D837D7DD42136A06D0B41ADD545 -forge_server_sha256=C6B85C178B037519464D436A75B7C68408CBE591576270BA0E826542B50BF41B -forge_universal_sha256=687C2698ECC1906CA2AD398A445C2498CF8BC09F1CBE6C2A6E24BFC9F90736C7 -forge_version_range=[64.1.5,65) -loader_version_range=[64,65) +minecraft_version=26.2 +minecraft_version_range=[26.2] +forge_version=65.1.0 +forge_installer_sha256=813FBBFECC3086A492783B9F5023AE15007737B42E17AAB75F48BA77403314DF +forge_shim_sha256=8D113D3DFFF0F0978A1989E22A8040FAD0FE5E332EF766B3702EB29687C9F4D2 +forge_server_sha256=2DDA94C321F928934AE7E3B8DB45AAE0FD994A9FA7BBDCDDC0AF1F9170A581DA +forge_universal_sha256=3C8816B687BA6F7404E35ED11397F6ABFB00A8C800286E43E038DBBD8FA5525F +forge_version_range=[65.1.0,66) +loader_version_range=[65,66) mapping_channel=official -mapping_version=26.1.2 -mcp_version=20260409.101008 +mapping_version=26.2 +mcp_version=20260616.103818 loader_name=forge loader_code=1 @@ -31,40 +31,44 @@ curseforge_project_id=1783006 mod_id=baseelectric mod_name=baseElectric mod_license=GPL-3.0-only -mod_version=2.2.17.2601021 +mod_version=2.2.18.2602001 mod_group=zone.moddev.mc.baseelectric mod_authors=DrCyano mod_description=Electric-powered machines and infrastructure for basePower. cf_requirements=basepower,base-metals cf_optionals= -cf_versions=26.1.2 +cf_versions=26.2 -poweradvantage_version=2.4.16.2601021 +poweradvantage_version=2.4.17.2602001 poweradvantage_pin_state=MERGED_SOURCE poweradvantage_source_repository=MinecraftModDevelopmentMods/basePower -# Exact merged parent source; the hosted gate also checks its public player jar. -poweradvantage_source_ref=a684e71e5397cb5a1a4879dcf0b6a2be0815e85d -poweradvantage_public_file_id=9576332 -poweradvantage_deobf_sha256=23ABCC1FEFDAA6988BF709437EB165C8948C757E773ADAB738092EB93CA8D2B0 -poweradvantage_runtime_sha256=23ABCC1FEFDAA6988BF709437EB165C8948C757E773ADAB738092EB93CA8D2B0 +# Released basePower, checked against its CurseForge, Maven and GitHub downloads. +poweradvantage_source_ref=98863570ae84c5658a6b8ec2f8878e1f10009192 +poweradvantage_public_file_id=9583433 +poweradvantage_deobf_sha256=7E456DE1A45140E86415A701D186FEDE08C4AB63D53C6B7848935DB70CBC68B1 +poweradvantage_runtime_sha256=7E456DE1A45140E86415A701D186FEDE08C4AB63D53C6B7848935DB70CBC68B1 -basemetals_version=3.1.2.2601021 -basemetals_built_on=26.1.2-64.0.9 -# Published shared-hook patch; family qualification is recorded separately. -basemetals_source_commit=5e708468302a7fb3b35aca09d5f832f8882f88f3 -basemetals_public_file_id=9576007 -basemetals_deobf_sha256=6786238835D4D8A653C769F3B0E61D226959146300E17523799CFDF17540FD19 -basemetals_runtime_sha256=6786238835D4D8A653C769F3B0E61D226959146300E17523799CFDF17540FD19 +basemetals_version=3.1.2.2602001 +basemetals_built_on=26.2-65.1.0 +# Released shared-hook patch, verified against the qualified player jar. +basemetals_source_commit=a68fe5a74f05ea8dae61bc718e67062f2fc4063b +basemetals_public_file_id=9583122 +basemetals_deobf_sha256=15CBD0C8DD95BBA846969929B8767887BA4B8152DFB10C9C58FB314AD39FB9E1 +basemetals_runtime_sha256=15CBD0C8DD95BBA846969929B8767887BA4B8152DFB10C9C58FB314AD39FB9E1 +# Qualified test-only source; independent of the released basePower player pin. +unit_support_source_ref=f84b2362449e39eff5e76696dd64ce4cb144da4f unit_bootstrap_sha256=088FC137BEBB9B2E75C596DE868499E6099CF228BECFCF07EAE36791245FD1B6 unit_bootstrap_java_sha256=D4B72FD65D9F8549B142507C6446E3B1E047B637784AF9FA74E8F28413E14A51 unit_registries_java_sha256=01DDE50C9874C2DC501BE2F699CD8D16D6974FACFAAC1B803434CA8C64227ABF unit_loader_java_sha256=455CA9403D9CBEA72E7D055966D6CDC822E634418C14B3CAD0500588DEE35E5B +unit_entity_tracker_java_sha256=EB2A83A35F617BC52D322332C824BE83A3BFE4C83CEB0418F77687EA93978E6D -orespawn_version=4.1.1.2601021 -orespawn_built_on=26.1.2-64.0.9 -orespawn_source_commit=101fd12b598934c353e417c57edc5c2bbefd5f53 -orespawn_public_file_id=9572926 -orespawn_deobf_sha256=810284ECB32D5249381F246498CEFA57E70FFF7CCC40110F799FC276CBC42BF7 -orespawn_runtime_sha256=810284ECB32D5249381F246498CEFA57E70FFF7CCC40110F799FC276CBC42BF7 +orespawn_version=4.1.1.2602001 +orespawn_built_on=26.2-65.1.0 +orespawn_source_commit=a3973534f51c24ccfb8313541f47204c75d9dbeb +# Released retained-settings patch; the player bytes match qualification. +orespawn_public_file_id=9582731 +orespawn_deobf_sha256=BC0658DF2E149CC23E65E5771F3FF62E2BB13FFDA4E316AB632EB92EF7FA5A1F +orespawn_runtime_sha256=BC0658DF2E149CC23E65E5771F3FF62E2BB13FFDA4E316AB632EB92EF7FA5A1F diff --git a/gradle/forge64-mavenizer.gradle b/gradle/forge64-mavenizer.gradle index a84b873..f40f1f8 100644 --- a/gradle/forge64-mavenizer.gradle +++ b/gradle/forge64-mavenizer.gradle @@ -1,22 +1,26 @@ import java.security.MessageDigest import org.gradle.jvm.toolchain.JvmVendorSpec -def fixture = file(providers.gradleProperty('forge64MavenizerJar').getOrElse( - '../../../../MinecraftMineralogy/OS2612/OreSpawn/ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar')) -def expected = 'BB0DACB3DEB2A711CA67DD402D5FDAB5A9847C37C7B9B596DEC7CF37378FA085' -if (!fixture.isFile()) { - throw new GradleException("Missing Forge 64 Mavenizer fixture: ${fixture}. Set -Pforge64MavenizerJar=.") -} -def actual = MessageDigest.getInstance('SHA-256').digest(fixture.bytes).encodeHex().toString().toUpperCase(Locale.ROOT) -if (actual != expected) { - throw new GradleException("Forge 64 Mavenizer fixture SHA-256 mismatch: expected ${expected}, got ${actual}") -} - -def rules = new File(fixture.parentFile, 'minecraft-source-compatibility.json') -def expectedRules = '21D1F5984E735BCEA1B1EFB9F965655796B39538FC91AAED1C3474004710423D' -if (!rules.isFile() || MessageDigest.getInstance('SHA-256').digest(rules.bytes) - .encodeHex().toString().toUpperCase(Locale.ROOT) != expectedRules) { - throw new GradleException("Missing or mismatched Forge 64 Mavenizer rules: ${rules}") +// Keep the preparation tool and its source-rule/license evidence together. +// A different checkout layout can override the jar path without editing this file. +def tool = 'ci-fixtures/tools/minecraft-mavenizer-0.5.21-orespawn-compat.jar' +def defaultJar = project.extensions.extraProperties.has('forge64MavenizerDefault') + ? project.forge64MavenizerDefault + : "../../../../MinecraftMineralogy/OS262/OreSpawn/${tool}" +def fixture = file(providers.gradleProperty('forge64MavenizerJar').getOrElse(defaultJar)) +def checksums = [ + (fixture.name): '5ABAB52A3F1BE115381C3CE80D5FD38DBE6C9F4C0B9ECF70A957700EC90FB88B', + 'minecraft-source-compatibility.json': '9437E03FC5E1CB5D605D72F0538C4DF4417B64DB0A57D0AABDC5184781517AC1', + 'minecraft-mavenizer-0.5.21-orespawn-compat.patch': '2DA8DD0FD5F112F5B7591113AED06D9A58C584A25F8705E26445A6D2E9D5C78E', + 'LICENSE-MAVENIZER.txt': '20C17D8B8C48A600800DFD14F95D5CB9FF47066A9641DDEAB48DC54AEC96E331', + 'README.md': 'EAD1477F393897C491A10FB86178213A99C360571A8063D551DA0579DF65BA6F' +] +checksums.each { name, expected -> + File input = new File(fixture.parentFile, name) + if (!input.isFile() || MessageDigest.getInstance('SHA-256').digest(input.bytes) + .encodeHex().toString().toUpperCase(Locale.ROOT) != expected) { + throw new GradleException("Missing or altered Forge 65 Mavenizer fixture: ${input}") + } } fgtools.configure('mavenizer') { diff --git a/src/main/java/zone/moddev/mc/baseelectric/ElectricAdvantage.java b/src/main/java/zone/moddev/mc/baseelectric/ElectricAdvantage.java index bcedea4..e7530be 100644 --- a/src/main/java/zone/moddev/mc/baseelectric/ElectricAdvantage.java +++ b/src/main/java/zone/moddev/mc/baseelectric/ElectricAdvantage.java @@ -24,13 +24,13 @@ import zone.moddev.mc.baseelectric.recipe.RecipeConditions; import zone.moddev.mc.baseelectric.migration.ElectricLegacyMigrations; -/** Forge 26.1.2 entry point for baseElectric. */ +/** Forge 26.2 entry point for baseElectric. */ @Mod(ElectricAdvantage.MODID) public final class ElectricAdvantage { public static final String MODID = "baseelectric"; public static final String LEGACY_MODID = "electricadvantage"; public static final String NAME = "baseElectric"; - public static final String VERSION = "2.2.17.2601021"; + public static final String VERSION = "2.2.18.2602001"; public static final Logger LOGGER = LogManager.getLogger(MODID); public static ElectricAdvantage INSTANCE; diff --git a/src/main/java/zone/moddev/mc/baseelectric/graphics/ElectricRenderTypes.java b/src/main/java/zone/moddev/mc/baseelectric/graphics/ElectricRenderTypes.java index 9fae384..17ae643 100644 --- a/src/main/java/zone/moddev/mc/baseelectric/graphics/ElectricRenderTypes.java +++ b/src/main/java/zone/moddev/mc/baseelectric/graphics/ElectricRenderTypes.java @@ -3,6 +3,7 @@ import com.mojang.blaze3d.pipeline.BlendFunction; import com.mojang.blaze3d.pipeline.ColorTargetState; import com.mojang.blaze3d.pipeline.RenderPipeline; +import net.minecraft.client.renderer.BindGroupLayouts; import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.client.renderer.rendertype.RenderSetup; import net.minecraft.client.renderer.rendertype.RenderType; @@ -19,7 +20,8 @@ private static RenderPipeline pipeline(boolean translucent) { var builder = RenderPipeline.builder(RenderPipelines.ENTITY_SNIPPET) .withLocation(Identifier.fromNamespaceAndPath("baseelectric", translucent ? "pipeline/unshaded_translucent" : "pipeline/unshaded")) - .withShaderDefine("NO_CARDINAL_LIGHTING").withSampler("Sampler1").withCull(false); + .withShaderDefine("NO_CARDINAL_LIGHTING") + .withBindGroupLayout(BindGroupLayouts.SAMPLER1).withCull(false); if (translucent) builder.withColorTargetState(new ColorTargetState(BlendFunction.TRANSLUCENT)); RenderPipeline pipeline = builder.build(); RenderPipelines.PIPELINES_BY_LOCATION.put(pipeline.getLocation(), pipeline); @@ -28,7 +30,7 @@ private static RenderPipeline pipeline(boolean translucent) { static RenderType unshaded(Identifier texture, boolean translucent) { var setup = RenderSetup.builder(translucent ? TRANSLUCENT : OPAQUE) - .withTexture("Sampler0", texture).useLightmap().useOverlay().bufferSize(256); + .withTexture("Sampler0", texture).useLightmap().useOverlay(); if (translucent) setup.sortOnUpload(); return RenderType.create("baseelectric_unshaded", setup.createRenderSetup()); } diff --git a/src/main/java/zone/moddev/mc/baseelectric/graphics/HydroturbineRenderer.java b/src/main/java/zone/moddev/mc/baseelectric/graphics/HydroturbineRenderer.java index 81472d9..2ace839 100644 --- a/src/main/java/zone/moddev/mc/baseelectric/graphics/HydroturbineRenderer.java +++ b/src/main/java/zone/moddev/mc/baseelectric/graphics/HydroturbineRenderer.java @@ -3,7 +3,6 @@ import zone.moddev.mc.baseelectric.ElectricAdvantage; import zone.moddev.mc.baseelectric.entities.HydroturbineEntity; import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.rendertype.RenderTypes; import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.client.renderer.entity.state.EntityRenderState; diff --git a/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserDrillRenderer.java b/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserDrillRenderer.java index 1bbfeb3..cee6e9e 100644 --- a/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserDrillRenderer.java +++ b/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserDrillRenderer.java @@ -3,7 +3,7 @@ import zone.moddev.mc.baseelectric.ElectricAdvantage; import zone.moddev.mc.baseelectric.machines.ElectricDrillTileEntity; import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.renderer.MultiBufferSource; +import com.mojang.blaze3d.vertex.VertexConsumer; import net.minecraft.client.renderer.rendertype.RenderType; import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; @@ -51,13 +51,13 @@ public static final class State extends BlockEntityRenderState { } public void render(final ElectricDrillTileEntity e, final float partialTick, final PoseStack matrices, - final MultiBufferSource buffers, final int packedLight, final int packedOverlay) { + final VertexConsumer vertices, final int packedLight, final int packedOverlay) { float laserBlastLength = e.getDrillLength(); if(laserBlastLength > 0){ transform(matrices, e.getFacing()); - draw(laserBlastLength, matrices.last(), buffers.getBuffer(beamType), packedOverlay); + draw(laserBlastLength, matrices.last(), vertices, packedOverlay); matrices.popPose(); } } diff --git a/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserTurretRenderer.java b/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserTurretRenderer.java index 40e46bc..5209951 100644 --- a/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserTurretRenderer.java +++ b/src/main/java/zone/moddev/mc/baseelectric/graphics/LaserTurretRenderer.java @@ -3,7 +3,7 @@ import zone.moddev.mc.baseelectric.ElectricAdvantage; import zone.moddev.mc.baseelectric.machines.LaserTurretTileEntity; import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.renderer.MultiBufferSource; +import com.mojang.blaze3d.vertex.VertexConsumer; import net.minecraft.client.renderer.rendertype.RenderType; import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; @@ -62,11 +62,11 @@ private static void capture(LaserTurretTileEntity entity, State state, float par } public void render(final LaserTurretTileEntity e, final float partialTick, final PoseStack matrices, - final MultiBufferSource buffers, final int packedLight, final int packedOverlay) { + final VertexConsumer vertices, final int packedLight, final int packedOverlay) { State state = new State(); capture(e, state, partialTick); transform(matrices, state.yaw, state.pitch); - draw(state, matrices.last(), buffers.getBuffer(renderType), packedLight, packedOverlay); + draw(state, matrices.last(), vertices, packedLight, packedOverlay); matrices.popPose(); } diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 4020e36..39729b0 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -31,13 +31,13 @@ side="BOTH" [[dependencies.baseelectric]] modId="basepower" mandatory=true -versionRange="[2.4.16.2601021,3.0.0)" +versionRange="[2.4.17.2602001,3.0.0)" ordering="AFTER" side="BOTH" [[dependencies.baseelectric]] modId="basemetals" mandatory=true -versionRange="[3.1.2.2601021,4.0.0)" +versionRange="[3.1.2.2602001,4.0.0)" ordering="AFTER" side="BOTH" diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index 0140236..a866191 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,7 +1,7 @@ { "pack":{ - "min_format":[101,1], - "max_format":[101,1], + "min_format":[107,1], + "max_format":[107,1], "description":"baseElectric" } } diff --git a/src/test/java/zone/moddev/mc/baseelectric/entities/ElectricOperationalHydroturbineAnchorTest.java b/src/test/java/zone/moddev/mc/baseelectric/entities/ElectricOperationalHydroturbineAnchorTest.java index a3f75a9..4556de5 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/entities/ElectricOperationalHydroturbineAnchorTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/entities/ElectricOperationalHydroturbineAnchorTest.java @@ -102,19 +102,14 @@ private static Level world() throws Exception { Field field = allocator.getDeclaredField("theUnsafe"); field.setAccessible(true); Level world = (Level)allocator.getMethod("allocateInstance", Class.class) - .invoke(field.get(null), NoTickWorld.class); + .invoke(field.get(null), ServerLevel.class); Field random = Level.class.getDeclaredField("random"); random.setAccessible(true); random.set(world, RandomSource.create(0)); + zone.moddev.mc.advantageworks.unit.NativeEmptyEntityTracker.install((ServerLevel) world); return world; } - private static final class NoTickWorld extends ServerLevel { - private NoTickWorld() { - super(null, null, null, null, null, null, false, 0L, Collections.emptyList(), false); - } - } - private static final class ControlEntity extends Entity { ControlEntity(EntityType type, Level world) { super(type, world); } @Override protected void defineSynchedData(net.minecraft.network.syncher.SynchedEntityData.Builder builder) {} diff --git a/src/test/java/zone/moddev/mc/baseelectric/graphics/RendererBufferContractTest.java b/src/test/java/zone/moddev/mc/baseelectric/graphics/RendererBufferContractTest.java index c410f59..bff6d79 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/graphics/RendererBufferContractTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/graphics/RendererBufferContractTest.java @@ -8,7 +8,7 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; -import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.SubmitNodeCollector; import org.joml.Matrix4f; import net.minecraft.client.renderer.rendertype.RenderType; import com.mojang.math.Axis; @@ -82,6 +82,29 @@ public class RendererBufferContractTest { assertArrayEquals(new float[] {0, 1}, vertex.uv, 0F); } assertNormals(buffer); + LaserDrillRenderer.State state = renderer.createRenderState(); + state.length = drill.getDrillLength(); + state.facing = drill.getFacing(); + RecordingBuffer deferred = new RecordingBuffer(); + renderer.submit(state, matrices, deferred.collector(), null); + assertSame(before, matrices.last()); + assertEquals(matrix, matrices.last().pose()); + assertTrue(matrices.isEmpty()); + assertTrue(deferred.vertices.isEmpty()); + assertEquals(1, deferred.pending.size()); + state.length = 99; + state.facing = direction.getOpposite(); + deferred.flush(); + assertEquals(16, deferred.vertices.size()); + for (int index = 0; index < buffer.vertices.size(); index++) { + Vertex expected = buffer.vertices.get(index), actual = deferred.vertices.get(index); + assertArrayEquals(expected.position, actual.position, 0.00001F); + assertArrayEquals(expected.normal, actual.normal, 0.00001F); + assertArrayEquals(expected.uv, actual.uv, 0F); + assertArrayEquals(expected.color, actual.color); + assertEquals(FULL_BRIGHT, actual.light); + assertEquals(net.minecraft.client.renderer.texture.OverlayTexture.NO_OVERLAY, actual.overlay); + } } } @@ -183,10 +206,28 @@ private static final class Vertex { int overlay; } - private static final class RecordingBuffer implements VertexConsumer, MultiBufferSource { + private static final class RecordingBuffer implements VertexConsumer { final List vertices = new ArrayList<>(); + final List pending = new ArrayList<>(); Vertex vertex = new Vertex(); - @Override public VertexConsumer getBuffer(RenderType type) { return this; } + SubmitNodeCollector collector() { + return (SubmitNodeCollector) java.lang.reflect.Proxy.newProxyInstance( + SubmitNodeCollector.class.getClassLoader(), new Class[] {SubmitNodeCollector.class}, + (proxy, method, arguments) -> { + if (!method.getName().equals("submitCustomGeometry")) { + throw new AssertionError("Unexpected native submission: " + method); + } + assertNotNull((RenderType) arguments[1]); + PoseStack.Pose pose = ((PoseStack) arguments[0]).last().copy(); + var geometry = (SubmitNodeCollector.CustomGeometryRenderer) arguments[2]; + pending.add(() -> geometry.render(pose, this)); + return null; + }); + } + void flush() { + pending.forEach(Runnable::run); + pending.clear(); + } @Override public VertexConsumer addVertex(float x, float y, float z) { vertex = new Vertex(); vertex.position = new float[] {x, y, z}; diff --git a/src/test/java/zone/moddev/mc/baseelectric/machines/Native118ConstructionTest.java b/src/test/java/zone/moddev/mc/baseelectric/machines/Native118ConstructionTest.java index 32712ec..6e097b7 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/machines/Native118ConstructionTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/machines/Native118ConstructionTest.java @@ -84,7 +84,7 @@ private PacketWorld() { try { zone.moddev.mc.baseelectric.init.Entities.LED = type; assertNotNull(block.getTicker(null, block.defaultBlockState(), type)); - assertNull(block.getTicker(null, block.defaultBlockState(), BlockEntityType.CHEST)); + assertNull(block.getTicker(null, block.defaultBlockState(), net.minecraft.world.level.block.entity.BlockEntityTypes.CHEST)); } finally { zone.moddev.mc.baseelectric.init.Entities.LED = previous; } diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/BlockLootResourceTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/BlockLootResourceTest.java index 58e4fb2..e95216e 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/BlockLootResourceTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/BlockLootResourceTest.java @@ -35,8 +35,8 @@ public class BlockLootResourceTest { @Test public void resourcePackDeclaresTheNativeTwentySixFormat() throws Exception { JsonObject pack = read(Paths.get("src/main/resources/pack.mcmeta")).getAsJsonObject("pack"); - assertEquals(JsonParser.parseString("[101,1]"), pack.get("min_format")); - assertEquals(JsonParser.parseString("[101,1]"), pack.get("max_format")); + assertEquals(JsonParser.parseString("[107,1]"), pack.get("min_format")); + assertEquals(JsonParser.parseString("[107,1]"), pack.get("max_format")); assertFalse(pack.has("pack_format")); assertFalse(pack.has("supported_formats")); assertFalse(pack.has("forge:server_data_pack_format")); @@ -44,9 +44,9 @@ public class BlockLootResourceTest { .matcher(Files.readString(Path.of("src/main/resources/META-INF/mods.toml"))).find()); zone.moddev.mc.baseelectric.verification.NativeTestBootstrap.initialize(); var version = net.minecraft.SharedConstants.getCurrentVersion(); - assertEquals(new net.minecraft.server.packs.metadata.pack.PackFormat(84, 0), + assertEquals(new net.minecraft.server.packs.metadata.pack.PackFormat(88, 0), version.packVersion(net.minecraft.server.packs.PackType.CLIENT_RESOURCES)); - assertEquals(new net.minecraft.server.packs.metadata.pack.PackFormat(101, 1), + assertEquals(new net.minecraft.server.packs.metadata.pack.PackFormat(107, 1), version.packVersion(net.minecraft.server.packs.PackType.SERVER_DATA)); var proof = zone.moddev.mc.baseelectric.verification.NativePackResourceProof.read(); assertEquals(0, proof.getAsJsonArray("warningsAndErrors").size()); @@ -73,7 +73,7 @@ public class BlockLootResourceTest { assertEquals("COMPATIBLE", client.get("loaderCompatibility").getAsString()); assertEquals("COMPATIBLE", server.get("loaderCompatibility").getAsString()); JsonObject insufficient = pack.deepCopy(); - insufficient.add("min_format", JsonParser.parseString("[84,0]")); + insufficient.add("min_format", JsonParser.parseString("[88,0]")); insufficient.remove("pack_format"); insufficient.remove("supported_formats"); var broad = net.minecraft.server.packs.metadata.pack.PackFormat.packCodec( diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/BuildWorkflowContractTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/BuildWorkflowContractTest.java index 488db44..69057e6 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/BuildWorkflowContractTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/BuildWorkflowContractTest.java @@ -46,8 +46,9 @@ public class BuildWorkflowContractTest { assertTrue(published < source.indexOf("repository: MinecraftModDevelopmentMods/" + repository)); } assertTrue(source.contains("ref: ${{ steps.public-pins.outputs.orespawn_ref }}")); - assertTrue(source.contains("ref: ${{ steps.public-pins.outputs.power_ref }}")); - assertTrue(source.contains("branches: [master-26.1.2")); + assertTrue(source.contains("ref: ${{ steps.public-pins.outputs.unit_support_ref }}")); + assertFalse(source.contains("ref: ${{ steps.public-pins.outputs.power_ref }}")); + assertTrue(source.contains("branches: [master-26.2")); assertTrue(source.contains("-Pforge64MavenizerJar=$MAVENIZER")); assertTrue(source.contains("-PpowerAdvantageDeobfJar=$POWER_PLAYER")); assertFalse(source.contains("forge47")); @@ -61,6 +62,11 @@ public class BuildWorkflowContractTest { assertTrue(script.contains("$(value " + dependency + "_public_file_id)")); } assertTrue(script.contains("sha256sum -c -")); + assertTrue(script.contains("unit_support_ref=\"$(value unit_support_source_ref)\"")); + assertTrue(script.contains("require_merged basePower \"$unit_support_ref\"")); + String properties = Files.readString(Paths.get("gradle.properties")); + assertTrue(properties.contains("unit_support_source_ref=f84b2362449e39eff5e76696dd64ce4cb144da4f")); + assertTrue(properties.contains("unit_entity_tracker_java_sha256=EB2A83A35F617BC52D322332C824BE83A3BFE4C83CEB0418F77687EA93978E6D")); assertTrue(script.contains("$(value poweradvantage_pin_state)")); assertTrue(script.contains("!= 'MERGED_SOURCE'")); assertTrue(script.indexOf("!= 'MERGED_SOURCE'") < script.indexOf("require_merged()")); diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java index 414aeab..7e21771 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/NativePackRangeContractTest.java @@ -98,7 +98,7 @@ public class NativePackRangeContractTest { assertEquals(java.util.Set.of("forge", "minecraft", "basepower", "basemetals"), dependencies.keySet()); var metals = dependencies.getAsJsonObject("basemetals"); assertTrue("Forge must require Base Metals on both sides", metals.get("mandatory").getAsBoolean()); - assertEquals("[3.1.2.2601021,4.0.0)", metals.get("versionRange").getAsString()); + assertEquals("[3.1.2.2602001,4.0.0)", metals.get("versionRange").getAsString()); assertEquals("AFTER", metals.get("ordering").getAsString()); assertEquals("BOTH", metals.get("side").getAsString()); var control = proof.getAsJsonObject("optionalBaseMetalsControl"); @@ -117,9 +117,9 @@ public class NativePackRangeContractTest { JsonObject pack = side.getAsJsonObject("nativeMetadata"); var range = PackFormat.packCodec(type).codec().parse(JsonOps.INSTANCE, pack).getOrThrow(); assertEquals(type.toString(), type == PackType.CLIENT_RESOURCES, - range.isValueInRange(PackFormat.of(84, 0))); + range.isValueInRange(PackFormat.of(88, 0))); assertEquals(type.toString(), type == PackType.SERVER_DATA, - range.isValueInRange(PackFormat.of(101, 1))); + range.isValueInRange(PackFormat.of(107, 1))); assertFalse(range.isValueInRange(PackFormat.of(83))); assertFalse(range.isValueInRange(PackFormat.of(102))); } @@ -143,11 +143,11 @@ public class NativePackRangeContractTest { } @Test public void dataOnlyRangeDoesNotQualifyClientResources() { - JsonObject dataOnly = JsonParser.parseString("{\"min_format\":[101,1],\"max_format\":[101,1]}") + JsonObject dataOnly = JsonParser.parseString("{\"min_format\":[107,1],\"max_format\":[107,1]}") .getAsJsonObject(); var range = PackFormat.packCodec(PackType.CLIENT_RESOURCES).codec() .parse(JsonOps.INSTANCE, dataOnly).getOrThrow(); - assertFalse(range.isValueInRange(PackFormat.of(84, 0))); - assertTrue(range.isValueInRange(PackFormat.of(101, 1))); + assertFalse(range.isValueInRange(PackFormat.of(88, 0))); + assertTrue(range.isValueInRange(PackFormat.of(107, 1))); } } diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeResourceTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeResourceTest.java index 99e5965..672a7fa 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeResourceTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeResourceTest.java @@ -32,7 +32,7 @@ public class RecipeResourceTest { String text = new String(Files.readAllBytes(file), StandardCharsets.UTF_8); JsonObject json = new JsonParser().parse(text).getAsJsonObject(); String type = json.get("type").getAsString(); - assertTrue(file + " must use the 26.1.2 result template codec", json.getAsJsonObject("result").has("id")); + assertTrue(file + " must use the 26.2 result template codec", json.getAsJsonObject("result").has("id")); assertFalse(file + " still has pre-1.21.11 Forge conditions", json.has("conditions")); assertTrue(file + " has unsupported serializer " + type, "minecraft:crafting_shaped".equals(type) @@ -96,7 +96,7 @@ private static void assertNativeCodecShapes() throws ReflectiveOperationExceptio } for (String obsolete : List.of("{\"item\":\"minecraft:apple\"}", "{\"tag\":\"baseelectric:codec_test_choices\"}")) { - assertTrue("Forge 64 must reject old ingredient objects: " + obsolete, + assertTrue("Forge 65 must reject old ingredient objects: " + obsolete, net.minecraft.world.item.crafting.Ingredient.CODEC.parse(ops, JsonParser.parseString(obsolete)).error().isPresent()); } diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeUnlockContractTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeUnlockContractTest.java index 1589dee..6c6bf5b 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeUnlockContractTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/RecipeUnlockContractTest.java @@ -19,7 +19,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import com.mojang.serialization.JsonOps; -import net.minecraft.advancements.criterion.ItemPredicate; +import net.minecraft.advancements.predicates.ItemPredicate; import net.minecraft.world.item.Items; import org.junit.Test; import static org.junit.Assert.*; diff --git a/src/test/java/zone/moddev/mc/baseelectric/resources/ShaderResourceContractTest.java b/src/test/java/zone/moddev/mc/baseelectric/resources/ShaderResourceContractTest.java index 436fc83..7cb2410 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/resources/ShaderResourceContractTest.java +++ b/src/test/java/zone/moddev/mc/baseelectric/resources/ShaderResourceContractTest.java @@ -15,7 +15,7 @@ public class ShaderResourceContractTest { String pipeline = Files.readString(PIPELINES); assertTrue(pipeline.contains("RenderPipelines.ENTITY_SNIPPET")); assertTrue(pipeline.contains("withShaderDefine(\"NO_CARDINAL_LIGHTING\")")); - assertTrue(pipeline.contains("withSampler(\"Sampler1\")")); + assertTrue(pipeline.contains("withBindGroupLayout(BindGroupLayouts.SAMPLER1)")); assertTrue(pipeline.contains("withCull(false)")); assertTrue(pipeline.contains("BlendFunction.TRANSLUCENT")); assertFalse(pipeline.contains("ShaderInstance")); @@ -29,7 +29,7 @@ public class ShaderResourceContractTest { assertFalse(vertex.contains("IViewRotMat")); for (String renderer : Arrays.asList("HydroturbineRenderer", "LaserDrillRenderer", "LaserTurretRenderer")) { String source = Files.readString(PIPELINES.resolveSibling(renderer + ".java")); - assertFalse("Forge 64 warns about mod-owned class annotations: " + renderer, source.contains("@OnlyIn")); + assertFalse("Forge 65 warns about mod-owned class annotations: " + renderer, source.contains("@OnlyIn")); } String registration = Files.readString(PIPELINES.resolveSibling("ClientRegistration.java")); assertTrue(registration.contains("value = Dist.CLIENT")); diff --git a/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java b/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java index 928bddf..3ee723b 100644 --- a/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java +++ b/src/test/java/zone/moddev/mc/baseelectric/verification/NativePackResourceProof.java @@ -234,7 +234,7 @@ public static void main(String[] args) throws Exception { } private static void initializeNativeModList(ModFile mod) throws ReflectiveOperationException { - // Forge 64 freezes discovery before ModList's static initialization. No mod code runs in this child. + // Forge 65 freezes discovery before ModList's static initialization. No mod code runs in this child. Class stateType = Class.forName("net.minecraftforge.fml.loading.ModSorter$State"); var constructor = stateType.getDeclaredConstructor(List.class, List.class); constructor.setAccessible(true); diff --git a/tools/verification/AuditedJUnit.java b/tools/verification/AuditedJUnit.java index 42511ed..4dd922c 100644 --- a/tools/verification/AuditedJUnit.java +++ b/tools/verification/AuditedJUnit.java @@ -30,7 +30,7 @@ public static void main(String[] args) throws Exception { XMLStreamWriter xml = XMLOutputFactory.newFactory().createXMLStreamWriter(output, "UTF-8"); xml.writeStartDocument("UTF-8", "1.0"); xml.writeStartElement("testsuite"); - xml.writeAttribute("name", "baseElectric-26.1.2-ECJ"); + xml.writeAttribute("name", "baseElectric-26.2-ECJ"); xml.writeAttribute("tests", Integer.toString(result.getRunCount())); xml.writeAttribute("failures", Integer.toString(result.getFailureCount())); xml.writeAttribute("ignored", Integer.toString(result.getIgnoreCount())); diff --git a/tools/verification/Invoke-ElectricPackagedSmoke.ps1 b/tools/verification/Invoke-ElectricPackagedSmoke.ps1 index f15f3d7..c0f62cf 100644 --- a/tools/verification/Invoke-ElectricPackagedSmoke.ps1 +++ b/tools/verification/Invoke-ElectricPackagedSmoke.ps1 @@ -30,7 +30,7 @@ $target = "$($pins.minecraft_version)-$($pins.forge_version)" $forgeDir = "libraries/net/minecraftforge/forge/$target" $winArgs = "$forgeDir/win_args.txt" $receipt = [ordered]@{ - status = 'FAIL'; scope = 'Packaged Forge 26.1.2 dedicated server and legacy inventory probe; no client or whole-world upgrade proof' + status = 'FAIL'; scope = 'Packaged Forge 26.2 dedicated server and legacy inventory probe; no client or whole-world upgrade proof' baseMetalsIncluded = !$WithoutBaseMetals seed = $seed; java = $javaPath; inputs = @(); checks = [ordered]@{}; exitCode = $null; error = $null } @@ -63,8 +63,8 @@ function Send-Command([string]$Command) { } try { - if ($target -cne '26.1.2-64.1.5' -or $pins.mod_version -cne '2.2.17.2601021') { - throw 'This smoke runner is bound to baseElectric 2.2.17.2601021 on Forge 64.1.5.' + if ($target -cne '26.2-65.1.0' -or $pins.mod_version -cne '2.2.18.2602001') { + throw 'This smoke runner is bound to baseElectric 2.2.18.2602001 on Forge 65.1.0.' } if ($pins.poweradvantage_pin_state -notin @('LOCAL_SOURCE', 'MERGED_SOURCE') -or $PowerSha256 -ne $pins.poweradvantage_runtime_sha256) { throw 'Packaged smoke requires the exact source-pinned basePower player JAR.' @@ -78,16 +78,16 @@ try { $receipt.javaSha256 = (Get-FileHash -LiteralPath $javaPath).Hash $argsText = Get-Content -LiteralPath (Join-Path $seed $winArgs) -Raw $shim = "forge-$target-shim.jar" - if (!$argsText.Contains("-jar $shim")) { throw 'Unexpected Forge 64 server argument file.' } + if (!$argsText.Contains("-jar $shim")) { throw 'Unexpected Forge 65 server argument file.' } $receipt.shimSha256 = (Get-FileHash -LiteralPath (Join-Path $seed $shim)).Hash - if ($receipt.shimSha256 -cne $pins.forge_shim_sha256) { throw 'Forge shim differs from the recorded 64.1.5 runtime pin.' } + if ($receipt.shimSha256 -cne $pins.forge_shim_sha256) { throw 'Forge shim differs from the recorded 65.1.0 runtime pin.' } $receipt.seedArgumentsSha256 = (Get-FileHash -LiteralPath (Join-Path $seed $winArgs)).Hash $forgeUniversal = Join-Path $seed "$forgeDir/forge-$target-universal.jar" $receipt.forgeUniversalSha256 = (Get-FileHash -LiteralPath $forgeUniversal).Hash - if ($receipt.forgeUniversalSha256 -cne $pins.forge_universal_sha256) { throw 'Forge universal differs from the recorded 64.1.5 runtime pin.' } + if ($receipt.forgeUniversalSha256 -cne $pins.forge_universal_sha256) { throw 'Forge universal differs from the recorded 65.1.0 runtime pin.' } $forgeServer = Join-Path $seed "$forgeDir/forge-$target-server.jar" $receipt.forgeServerSha256 = (Get-FileHash -LiteralPath $forgeServer).Hash - if ($receipt.forgeServerSha256 -cne $pins.forge_server_sha256) { throw 'Forge server differs from the recorded 64.1.5 runtime pin.' } + if ($receipt.forgeServerSha256 -cne $pins.forge_server_sha256) { throw 'Forge server differs from the recorded 65.1.0 runtime pin.' } if ((Get-Content -LiteralPath $EulaFile -Raw) -notmatch '(?m)^eula=true\s*$') { throw 'Pass the existing accepted EULA from the local smoke fixture.' } diff --git a/tools/verification/Verify-ElectricEcj.ps1 b/tools/verification/Verify-ElectricEcj.ps1 index e6e5a21..b83f3c3 100644 --- a/tools/verification/Verify-ElectricEcj.ps1 +++ b/tools/verification/Verify-ElectricEcj.ps1 @@ -67,16 +67,16 @@ function Invoke-Ecj([string]$Name, [string[]]$Sources, [string[]]$Libraries) { } $report = [ordered]@{ status = 'RUNNING'; project = $ProjectRoot; evidence = $Evidence - scope = 'Pinned local baseElectric 26.1.2 candidate; fresh ECJ main/test/helper outputs and worldless Java 25 JUnit; no Gradle or Minecraft launch' + scope = 'Pinned local baseElectric 26.2 candidate; fresh ECJ main/test/helper outputs and worldless Java 25 JUnit; no Gradle or Minecraft launch' compiler = $null; toolchains = $null; libraries = @(); sources = @(); gradleInventory = @() compilations = [ordered]@{}; junit = $null; negativeControl = $null; apiPinState = $null } try { $properties = ConvertFrom-StringData -StringData (Get-Content -LiteralPath (Join-Path $ProjectRoot 'gradle.properties') -Raw) $report.apiPinState = $properties.poweradvantage_pin_state - if ($properties.mod_id -ne 'baseelectric' -or $properties.mod_version -ne '2.2.17.2601021' -or - $properties.minecraft_version -ne '26.1.2' -or $properties.forge_version -ne '64.1.5' -or - $properties.poweradvantage_version -ne '2.4.16.2601021' -or $properties.basemetals_version -ne '3.1.2.2601021' -or - $properties.orespawn_version -ne '4.1.1.2601021' -or + if ($properties.mod_id -ne 'baseelectric' -or $properties.mod_version -ne '2.2.18.2602001' -or + $properties.minecraft_version -ne '26.2' -or $properties.forge_version -ne '65.1.0' -or + $properties.poweradvantage_version -ne '2.4.17.2602001' -or $properties.basemetals_version -ne '3.1.2.2602001' -or + $properties.orespawn_version -ne '4.1.1.2602001' -or $properties.poweradvantage_pin_state -notin @('LOCAL_SOURCE', 'MERGED_SOURCE') -or $properties.poweradvantage_source_ref -cnotmatch '^[a-f0-9]{40}$' -or $properties.poweradvantage_runtime_sha256 -cnotmatch '^[A-F0-9]{64}$' -or @@ -84,7 +84,7 @@ try { $properties.poweradvantage_deobf_sha256 -cnotmatch '^[A-F0-9]{64}$' -or $properties.basemetals_deobf_sha256 -cnotmatch '^[A-F0-9]{64}$' -or $properties.orespawn_deobf_sha256 -cnotmatch '^[A-F0-9]{64}$') { - throw 'This verifier requires the source-pinned baseElectric 26.1.2 inputs' + throw 'This verifier requires the source-pinned baseElectric 26.2 inputs' } $report.compiler = Get-Pin $Compiler if ($report.compiler.sha256 -ne 'D0D43F8E2D7003E5EFED612E2CBB5F01870043397D8F1BBE536FD9128F4FCBF7') { throw 'ECJ compiler pin mismatch' } @@ -151,10 +151,11 @@ try { } $report.gradleInventory += Get-Pin $xml.FullName } - if ($classes.Count -ne 33 -or $expected -ne 117 -or $sources.test.Count -ne 36 -or $sources.main.Count -ne 87) { throw 'Unexpected Electric 26.1.2 source/test inventory' } + if ($classes.Count -ne 33 -or $expected -ne 117 -or $sources.test.Count -ne 36 -or $sources.main.Count -ne 87) { throw 'Unexpected Electric 26.2 source/test inventory' } $support = @(Get-ChildItem -LiteralPath (Join-Path $ProjectRoot 'build/generated-unit-support') -Recurse -File -Filter '*.java' | Sort-Object Name) - if ($support.Count -ne 2) { throw 'Expected exactly the two pinned native unit support sources' } - $supportPins = @{ 'ForgeUnitRegistries.java' = $properties.unit_registries_java_sha256; 'Forge64UnitLoader.java' = $properties.unit_loader_java_sha256 } + if ($support.Count -ne 3) { throw 'Expected exactly the three pinned native unit support sources' } + $supportPins = @{ 'ForgeUnitRegistries.java' = $properties.unit_registries_java_sha256; 'Forge64UnitLoader.java' = $properties.unit_loader_java_sha256; + 'NativeEmptyEntityTracker.java' = $properties.unit_entity_tracker_java_sha256 } foreach ($source in $support) { $pin = Get-Pin $source.FullName if (!$supportPins.ContainsKey($source.Name) -or $pin.sha256 -cne $supportPins[$source.Name]) { throw 'Pinned unit support source mismatch' } diff --git a/tools/verify-native-port.js b/tools/verify-native-port.js index c5b407a..ae35226 100644 --- a/tools/verify-native-port.js +++ b/tools/verify-native-port.js @@ -35,26 +35,33 @@ function check(name, run) { catch (error) { checks.push({name, pass: false, error: error.message}); } } -check('Exact Forge 64 and local port identity', () => { +check('Exact Forge 65 and public release identity', () => { const props = Object.fromEntries(read('gradle.properties').toString().split(/\r?\n/) .filter(line => /^[a-z][a-z_\d]*=/.test(line)).map(line => line.split(/=(.*)/s).slice(0, 2))); for (const [key, value] of Object.entries({ - minecraft_version: '26.1.2', forge_version: '64.1.5', mapping_channel: 'official', - mapping_version: '26.1.2', mcp_version: '20260409.101008', java_version: '25', - mod_id: 'baseelectric', mod_name: 'baseElectric', mod_version: '2.2.17.2601021', - poweradvantage_version: '2.4.16.2601021', basemetals_version: '3.1.2.2601021', - orespawn_source_commit: '101fd12b598934c353e417c57edc5c2bbefd5f53', - orespawn_deobf_sha256: '810284ECB32D5249381F246498CEFA57E70FFF7CCC40110F799FC276CBC42BF7', - orespawn_version: '4.1.1.2601021', curseforge_project_id: '1783006', + minecraft_version: '26.2', forge_version: '65.1.0', mapping_channel: 'official', + mapping_version: '26.2', mcp_version: '20260616.103818', java_version: '25', + mod_id: 'baseelectric', mod_name: 'baseElectric', mod_version: '2.2.18.2602001', + poweradvantage_version: '2.4.17.2602001', basemetals_version: '3.1.2.2602001', + poweradvantage_pin_state: 'MERGED_SOURCE', + poweradvantage_source_ref: '98863570ae84c5658a6b8ec2f8878e1f10009192', + poweradvantage_public_file_id: '9583433', + basemetals_source_commit: 'a68fe5a74f05ea8dae61bc718e67062f2fc4063b', + basemetals_public_file_id: '9583122', + orespawn_source_commit: 'a3973534f51c24ccfb8313541f47204c75d9dbeb', + orespawn_public_file_id: '9582731', + unit_support_source_ref: 'f84b2362449e39eff5e76696dd64ce4cb144da4f', + orespawn_deobf_sha256: 'BC0658DF2E149CC23E65E5771F3FF62E2BB13FFDA4E316AB632EB92EF7FA5A1F', + orespawn_version: '4.1.1.2602001', curseforge_project_id: '1783006', cf_requirements: 'basepower,base-metals' })) assert.equal(props[key], value, key); assert.equal(props.reobf, 'false'); assert.deepEqual(json('src/main/resources/pack.mcmeta').pack, - {min_format:[101,1], max_format:[101,1], description:'baseElectric'}); + {min_format:[107,1], max_format:[107,1], description:'baseElectric'}); const mods = read('src/main/resources/META-INF/mods.toml').toString(); assert.match(mods, /^showAsResourcePack=false$/m); - assert.match(mods, /modId="basepower"\s+mandatory=true\s+versionRange="\[2\.4\.16\.2601021,3\.0\.0\)"/); - assert.match(mods, /modId="basemetals"\s+mandatory=true\s+versionRange="\[3\.1\.2\.2601021,4\.0\.0\)"/); + assert.match(mods, /modId="basepower"\s+mandatory=true\s+versionRange="\[2\.4\.17\.2602001,3\.0\.0\)"/); + assert.match(mods, /modId="basemetals"\s+mandatory=true\s+versionRange="\[3\.1\.2\.2602001,4\.0\.0\)"/); const build = read('build.gradle').toString(); assert.match(build, /inputs\.files\(javadocTool\.map/); assert.match(build, /legal\/java\.base/);