Minecraft 26.2 (#380)

This commit is contained in:
ZekerZhayard authored and GitHub committed 2026-06-18 16:32:03 +08:00
1 parent 055cd711b3
commit fff855f1b0
28 files changed
+382 -278

No files matched your search

+27 -7
View File
@@ -3,14 +3,30 @@ name: Build
description: Build project with Gradle and upload artifact
inputs:
is-snapshot:
description: Whether this is a snapshot build
required: false
default: 'true'
artifact-name:
description: Artifact name for upload
required: true
outputs:
mod_name:
description: Display name of the mod
value: ${{ steps.info.outputs.mod_name }}
edition:
description: Target mod loader edition
value: ${{ steps.info.outputs.edition }}
short_version:
description: Shortened version identifier
value: ${{ steps.info.outputs.short_version }}
loaders:
description: List of supported mod loaders
value: ${{ steps.info.outputs.loaders }}
game_versions:
description: List of compatible Minecraft game versions
value: ${{ steps.info.outputs.game_versions }}
java:
description: List of compatible Java versions
value: ${{ steps.info.outputs.java }}
runs:
using: composite
steps:
@@ -22,9 +38,13 @@ runs:
- name: Build with Gradle
shell: pwsh
env:
IS_SNAPSHOT: ${{ inputs.is-snapshot }}
run: ./gradlew clean build --info --stacktrace
run: ./gradlew clean build --info --stacktrace -Pbuild_type=${{ github.event_name }}
- name: Generate metadata JSONs
if: github.event_name != 'pull_request'
shell: pwsh
id: info
run: ./.github/scripts/Get-PublishInfo.ps1 -ArtifactDir 'Bootstrap/build/libs' -Type '${{ github.event_name }}'
- uses: actions/upload-artifact@v7
with:
@@ -0,0 +1,56 @@
name: Publish to Object Storage
description: >-
Upload build artifacts to an S3-compatible object store (AWS S3, Cloudflare
R2, MinIO, etc.). Requires the AWS CLI to be pre-installed on the runner.
inputs:
artifact-path:
description: Path to the directory containing build artifacts.
required: true
endpoint-url:
description: S3-compatible endpoint URL.
required: true
bucket:
description: S3 bucket name.
required: true
access-key-id:
description: S3-compatible access key ID.
required: true
secret-access-key:
description: S3-compatible secret access key.
required: true
region:
description: AWS region (use 'auto' for Cloudflare R2).
required: false
default: 'auto'
target-path:
description: Key prefix in the bucket (e.g., 'mods').
required: false
default: ''
files:
description: Glob pattern for files to upload.
required: false
default: '*'
runs:
using: composite
steps:
- name: Validate artifact path
shell: pwsh
run: |
$path = "${{ inputs.artifact-path }}"
if (-not (Test-Path -LiteralPath $path)) {
throw "Artifact path not found: $path"
}
- name: Upload to object storage
shell: pwsh
env:
AWS_ACCESS_KEY_ID: ${{ inputs.access-key-id }}
AWS_SECRET_ACCESS_KEY: ${{ inputs.secret-access-key }}
AWS_DEFAULT_REGION: ${{ inputs.region }}
run: |
$ErrorActionPreference = "Stop"
Get-ChildItem -Path "${{ inputs.artifact-path }}" -Filter "${{ inputs.files }}" | ForEach-Object {
aws s3 cp "$_.FullName" "s3://${{ inputs.bucket }}/${{ inputs.target-path }}$($_.Name)" --endpoint-url "${{ inputs.endpoint-url }}"
}
@@ -0,0 +1,56 @@
name: Publish to GitHub Release
description: Upload build artifacts to a GitHub Release. Requires contents:write permission at the workflow level.
inputs:
artifact-path:
description: Path to the directory containing build artifacts.
required: true
tag-name:
description: Git tag for the release.
required: true
token:
description: GitHub token with contents:write permission.
required: true
files:
description: Glob pattern(s) for files to upload (passed to gh release create).
required: false
default: '*'
notes-file:
description: Path to file containing release body text.
required: false
prerelease:
description: Mark as a pre-release (true/false).
required: false
default: 'false'
generate-notes:
description: Auto-generate release notes from merged commits (true/false).
required: false
default: 'false'
replace:
description: Delete existing release with the same tag before creating (true/false).
required: false
default: 'false'
runs:
using: composite
steps:
- name: Validate artifact path
shell: pwsh
run: |
$path = "${{ inputs.artifact-path }}"
if (-not (Test-Path -LiteralPath $path)) {
throw "Artifact path not found: $path"
}
- name: Create GitHub Release
shell: pwsh
env:
GH_TOKEN: ${{ inputs.token }}
run: |
$ErrorActionPreference = "Stop"
$tag = '${{ inputs.tag-name }}'
if('${{ inputs.replace }}' -eq 'true') { gh release delete "$tag" --yes --cleanup-tag }
gh release create "$tag" '${{ inputs.artifact-path }}/${{ inputs.files }}' --title "CustomSkinLoader $tag" `
$(if('${{ inputs.prerelease }}' -eq 'true') { '--prerelease' }) `
$(if('${{ inputs.notes-file }}') { '--notes-file'; '${{ inputs.notes-file }}' } elseif ('${{ inputs.generate-notes }}' -eq 'true') { '--generate-notes' })
-30
View File
@@ -1,30 +0,0 @@
# Composite action: upload jars to R2/COS, generate and upload JSON metadata
name: Publish
description: Upload built artifacts to object storage and publish JSON metadata
inputs:
artifact-dir:
description: Directory containing built artifacts (relative to workspace)
required: true
type:
description: Release type - 'beta' or 'release'
required: true
runs:
using: composite
steps:
# Generate JSON metadata, upload to R2/COS root, and output CDN URLs
- name: Generate and upload JSON metadata
id: publish-files
shell: pwsh
run: ./.github/scripts/Publish-Files.ps1 -ArtifactDir '${{ inputs.artifact-dir }}' -Type '${{ inputs.type }}'
# Refresh Tencent Cloud CDN cache for the JSON files
- name: Refresh CDN
uses: linrongda/tencent-cdn-action@v2
with:
secret-id: ${{ env.COS_SECRET_ID }}
secret-key: ${{ env.COS_SECRET_KEY }}
action: purgeUrls
paths: ${{ steps.publish-files.outputs.cdn-urls }}
continue-on-error: true
+58 -19
View File
@@ -1,29 +1,68 @@
param()
param(
[string]$ArtifactDir = '',
[string]$Type = ''
)
$ErrorActionPreference = "Stop"
$props = Get-Content "gradle.properties"
# ---- Output build.info.json to GITHUB_OUTPUT ----
$info = Get-Content "build.info.json" -Raw | ConvertFrom-Json
function Get-Prop($key) {
($props | Select-String "^$key=") -replace "^.*=", "" | ForEach-Object { $_.Trim() }
$info.PSObject.Properties | ForEach-Object {
$name = $_.Name
$value = $_.Value
if ($value -is [array]) {
"$name<<EOF" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
$value | Out-File -FilePath $env:GITHUB_OUTPUT -Append
"EOF" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
} else {
"$name=$value" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
}
}
function Set-MultilineOutput($name, $value) {
"$name<<EOF" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
$value | Out-File -FilePath $env:GITHUB_OUTPUT -Append
"EOF" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
# ---- Generate metadata JSONs ----
if (-not $ArtifactDir) { return }
if (-not (Test-Path -LiteralPath $ArtifactDir)) { throw "ArtifactDir not found: $ArtifactDir" }
$jar = Get-ChildItem -Path $ArtifactDir -Filter "*.jar" | Where-Object { $_.Name -notlike "*-sources.jar" } | Select-Object -First 1
if (-not $jar) { throw "No jar found in $ArtifactDir" }
$JarFilename = $jar.Name
$version = $info.mod_version
$isSnapshot = ($Type -ne "release")
$shortVersion = if ($isSnapshot) { "$version-s$env:GITHUB_RUN_NUMBER" } else { $version }
"short_version=$shortVersion" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
$mcVersionList = $info.game_versions | ForEach-Object {
$parts = $_ -split '\.'
"$($parts[0]).$($parts[1])"
} | Sort-Object -Unique | Sort-Object {
$v = $_ -split '\.'
[int]$v[0] * 100000 + [int]$v[1]
}
$loaders = Get-Prop "loaders"
$gameVersions = Get-Prop "game_versions"
$java = Get-Prop "java"
$version = Get-Prop "mod_version"
$suffix = if ($isSnapshot) { "-beta" } else { "" }
$jarKey = "mods/$JarFilename"
$baseUrl = "https://csl.3-3.dev"
$loadersList = $loaders -split "," | ForEach-Object { $_.Trim() }
$gameVersionsList = $gameVersions -split "," | ForEach-Object { $_.Trim() }
$javaList = $java -split "," | ForEach-Object { $_.Trim() }
@{
version = $shortVersion
downloads = @{ Universal = "$baseUrl/$jarKey" }
launchermeta = @{}
} | ConvertTo-Json -Depth 10 | Set-Content -Path "$ArtifactDir/latest$suffix.json" -NoNewline
Set-MultilineOutput "loaders" $loadersList
Set-MultilineOutput "game-versions" $gameVersionsList
Set-MultilineOutput "java" $javaList
"short-version=$version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
$details = [ordered]@{}
foreach ($mcVer in $mcVersionList) {
$details[$mcVer] = @{
Fabric = "$baseUrl/$jarKey"
Forge = "$baseUrl/$jarKey"
NeoForge = "$baseUrl/$jarKey"
Quilt = "$baseUrl/$jarKey"
}
}
@{
version = $shortVersion
timestamp = [System.DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()
details = $details
} | ConvertTo-Json -Depth 10 | Set-Content -Path "$ArtifactDir/detail$suffix.json" -NoNewline
-86
View File
@@ -1,86 +0,0 @@
param(
[string]$ArtifactDir,
[string]$Type # "beta" or "release"
)
$ErrorActionPreference = "Stop"
$suffix = if ($Type -eq "beta") { "-beta" } else { "" }
# ---- Find the built jar ----
$jar = Get-ChildItem -Path $ArtifactDir -Filter "*.jar" | Where-Object { $_.Name -notlike "*-sources.jar" } | Select-Object -First 1
if (-not $jar) { throw "No jar found in $ArtifactDir" }
$jarFilename = $jar.Name
$jarKey = "mods/$jarFilename"
# ---- Derive short version from gradle.properties + build number ----
# mod_version=15.0, IS_SNAPSHOT=true, GITHUB_RUN_NUMBER=33 -> 15.0-s33
# mod_version=15.0, IS_SNAPSHOT=false -> 15.0
$version = ((Get-Content "gradle.properties" | Select-String "^mod_version=") -replace "^mod_version=", "").Trim()
$isSnapshot = if ($env:IS_SNAPSHOT) { $env:IS_SNAPSHOT -ne "false" } else { $true }
if ($isSnapshot) {
$shortVersion = "$version-s$env:GITHUB_RUN_NUMBER"
} else {
$shortVersion = "$version"
}
# ---- Read MC major versions from gradle.properties ----
$mcVersions = ((Get-Content "gradle.properties" | Select-String "^minecraft_major_versions=") -replace "^.*=", "").Trim()
$mcVersionList = $mcVersions -split "," | ForEach-Object { $_.Trim() }
$baseUrl = "_BASE_URL_"
# ---- Generate latest(-beta).json ----
$latestJson = @{
version = $shortVersion
downloads = @{ Universal = "$baseUrl/$jarKey" }
launchermeta = @{}
} | ConvertTo-Json -Depth 10
# ---- Generate detail(-beta).json ----
$details = [ordered]@{}
foreach ($mcVer in $mcVersionList) {
$details[$mcVer] = @{
Fabric = "$baseUrl/$jarKey"
Forge = "$baseUrl/$jarKey"
NeoForge = "$baseUrl/$jarKey"
Quilt = "$baseUrl/$jarKey"
}
}
$detailJson = @{
version = $shortVersion
timestamp = [System.DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()
details = $details
} | ConvertTo-Json -Depth 10
# ---- Upload files to R2 ----
$env:AWS_ACCESS_KEY_ID = $env:R2_SECRET_ID
$env:AWS_SECRET_ACCESS_KEY = $env:R2_SECRET_KEY
$env:AWS_DEFAULT_REGION = "auto"
aws s3 cp "$ArtifactDir/$jarFilename" "s3://$env:R2_BUCKET/$jarKey" --endpoint-url $($env:R2_BASE_URL.TrimEnd('/'))
$latestJson -replace $baseUrl, "https://csl.3-3.dev" | Set-Content -Path "$ArtifactDir/latest$suffix.json" -NoNewline
$detailJson -replace $baseUrl, "https://csl.3-3.dev" | Set-Content -Path "$ArtifactDir/detail$suffix.json" -NoNewline
aws s3 cp "$ArtifactDir/latest$suffix.json" "s3://$env:R2_BUCKET/latest$suffix.json" --endpoint-url $($env:R2_BASE_URL.TrimEnd('/'))
aws s3 cp "$ArtifactDir/detail$suffix.json" "s3://$env:R2_BUCKET/detail$suffix.json" --endpoint-url $($env:R2_BASE_URL.TrimEnd('/'))
# ---- Upload files to COS ----
$cdnBase = "https://csl.littleservice.cn"
try {
pip install coscmd -q --disable-pip-version-check
coscmd config -a $env:COS_SECRET_ID -s $env:COS_SECRET_KEY -b $env:COS_BUCKET -r ap-shanghai
coscmd upload "$ArtifactDir/$jarFilename" "$jarKey"
$latestJson -replace $baseUrl, $cdnBase | Set-Content -Path "$ArtifactDir/latest$suffix.json" -NoNewline
$detailJson -replace $baseUrl, $cdnBase | Set-Content -Path "$ArtifactDir/detail$suffix.json" -NoNewline
coscmd upload "$ArtifactDir/latest$suffix.json" "latest$suffix.json"
coscmd upload "$ArtifactDir/detail$suffix.json" "detail$suffix.json"
} catch {
Write-Warning "COS JSON upload failed: $_"
}
# ---- Output CDN URLs for subsequent refresh step ----
"cdn-urls<<EOF" | Out-File $env:GITHUB_OUTPUT -Append
"${cdnBase}/latest${suffix}.json" | Out-File $env:GITHUB_OUTPUT -Append
"${cdnBase}/detail${suffix}.json" | Out-File $env:GITHUB_OUTPUT -Append
"EOF" | Out-File $env:GITHUB_OUTPUT -Append
+43 -32
View File
@@ -17,20 +17,10 @@ jobs:
with:
artifact-name: CustomSkinLoader-Beta-${{ github.run_number }}
publish:
name: Publish
publish-release:
name: Publish to GitHub Release
needs: build
runs-on: windows-latest
environment: Build
env:
IS_SNAPSHOT: 'true'
R2_SECRET_ID: ${{ secrets.R2_SECRET_ID }}
R2_SECRET_KEY: ${{ secrets.R2_SECRET_KEY }}
R2_BUCKET: ${{ secrets.R2_BUCKET }}
R2_BASE_URL: ${{ secrets.R2_BASE_URL }}
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
steps:
- uses: actions/checkout@v6
@@ -39,12 +29,7 @@ jobs:
name: CustomSkinLoader-Beta-${{ github.run_number }}
path: artifact
- uses: ./.github/actions/publish
with:
artifact-dir: artifact
type: beta
- name: Generate CI-Build body
- name: Generate release body
shell: pwsh
run: |
@"
@@ -54,20 +39,46 @@ jobs:
[How to use?](https://github.com/xfl03/MCCustomSkinLoader/wiki/How-to-Use)
"@ | Set-Content -Path ci-build-body.md -NoNewline
- name: Move CI-Build tag to current commit
uses: richardsimko/update-tag@v1
- uses: ./.github/actions/publish-release
with:
tag_name: CI-Build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
artifact-path: artifact
tag-name: CI-Build
token: ${{ secrets.GITHUB_TOKEN }}
files: '*.jar'
prerelease: 'true'
replace: 'true'
notes-file: ci-build-body.md
- name: GitHub PreRelease
uses: softprops/action-gh-release@v3
publish-object-storage:
name: Publish to Object Storage
needs: build
runs-on: windows-latest
environment: Build
steps:
- uses: actions/checkout@v6
- uses: actions/download-artifact@v8
with:
tag_name: CI-Build
name: CustomSkinLoader CI-Build
prerelease: true
body_path: ci-build-body.md
files: artifact/*.jar
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
name: CustomSkinLoader-Beta-${{ github.run_number }}
path: artifact
- name: Upload jar to R2
uses: ./.github/actions/publish-object-storage
with:
artifact-path: artifact
endpoint-url: ${{ secrets.R2_BASE_URL }}
bucket: ${{ secrets.R2_BUCKET }}
access-key-id: ${{ secrets.R2_SECRET_ID }}
secret-access-key: ${{ secrets.R2_SECRET_KEY }}
target-path: mods/
files: '*.jar'
- name: Upload JSONs to R2
uses: ./.github/actions/publish-object-storage
with:
artifact-path: artifact
endpoint-url: ${{ secrets.R2_BASE_URL }}
bucket: ${{ secrets.R2_BUCKET }}
access-key-id: ${{ secrets.R2_SECRET_ID }}
secret-access-key: ${{ secrets.R2_SECRET_KEY }}
files: '*.json'
+67 -32
View File
@@ -10,28 +10,25 @@ jobs:
build:
name: Build
runs-on: windows-latest
outputs:
mod_name: ${{ steps.build.outputs.mod_name }}
edition: ${{ steps.build.outputs.edition }}
short_version: ${{ steps.build.outputs.short_version }}
loaders: ${{ steps.build.outputs.loaders }}
game_versions: ${{ steps.build.outputs.game_versions }}
java: ${{ steps.build.outputs.java }}
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/build
id: build
with:
is-snapshot: 'false'
artifact-name: CustomSkinLoader-Release-${{ github.run_number }}
publish:
name: Publish
publish-release:
name: Publish to GitHub Release
needs: build
runs-on: windows-latest
environment: Build
env:
IS_SNAPSHOT: 'false'
R2_SECRET_ID: ${{ secrets.R2_SECRET_ID }}
R2_SECRET_KEY: ${{ secrets.R2_SECRET_KEY }}
R2_BUCKET: ${{ secrets.R2_BUCKET }}
R2_BASE_URL: ${{ secrets.R2_BASE_URL }}
COS_SECRET_ID: ${{ secrets.COS_SECRET_ID }}
COS_SECRET_KEY: ${{ secrets.COS_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
steps:
- uses: actions/checkout@v6
@@ -40,15 +37,60 @@ jobs:
name: CustomSkinLoader-Release-${{ github.run_number }}
path: artifact
- uses: ./.github/actions/publish
- uses: ./.github/actions/publish-release
with:
artifact-dir: artifact
type: release
artifact-path: artifact
tag-name: ${{ github.event.release.tag_name }}
token: ${{ secrets.GITHUB_TOKEN }}
files: '*.jar'
generate-notes: 'true'
- name: Get publish info from gradle.properties
id: info
shell: pwsh
run: ./.github/scripts/Get-PublishInfo.ps1
publish-object-storage:
name: Publish to Object Storage
needs: build
runs-on: windows-latest
environment: Build
steps:
- uses: actions/checkout@v6
- uses: actions/download-artifact@v8
with:
name: CustomSkinLoader-Release-${{ github.run_number }}
path: artifact
- name: Upload jar to R2
uses: ./.github/actions/publish-object-storage
with:
artifact-path: artifact
endpoint-url: ${{ secrets.R2_BASE_URL }}
bucket: ${{ secrets.R2_BUCKET }}
access-key-id: ${{ secrets.R2_SECRET_ID }}
secret-access-key: ${{ secrets.R2_SECRET_KEY }}
target-path: mods/
files: '*.jar'
- name: Upload JSONs to R2
uses: ./.github/actions/publish-object-storage
with:
artifact-path: artifact
endpoint-url: ${{ secrets.R2_BASE_URL }}
bucket: ${{ secrets.R2_BUCKET }}
access-key-id: ${{ secrets.R2_SECRET_ID }}
secret-access-key: ${{ secrets.R2_SECRET_KEY }}
files: '*.json'
publish-mod-sites:
name: Publish to Mod Sites
needs: build
runs-on: windows-latest
environment: Build
steps:
- uses: actions/checkout@v6
- uses: actions/download-artifact@v8
with:
name: CustomSkinLoader-Release-${{ github.run_number }}
path: artifact
- uses: Kir-Antipov/[email protected]
with:
@@ -58,25 +100,18 @@ jobs:
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
curseforge-id: 286924
curseforge-token: ${{ secrets.CURSEFORGE_API_KEY }}
name: CustomSkinLoader_Universal_${{ steps.info.outputs.short-version }}
version: ${{ steps.info.outputs.short-version }}-Universal
name: ${{ needs.build.outputs.mod_name }}_${{ needs.build.outputs.edition }}_${{ needs.build.outputs.short_version }}
version: ${{ needs.build.outputs.short_version }}-${{ needs.build.outputs.edition }}
version-type: release
loaders: |
${{ steps.info.outputs.loaders }}
${{ needs.build.outputs.loaders }}
game-versions: |
${{ steps.info.outputs.game-versions }}
${{ needs.build.outputs.game_versions }}
game-version-filter: releases
java: |
${{ steps.info.outputs.java }}
${{ needs.build.outputs.java }}
retry-attempts: 2
retry-delay: 10000
fail-mode: fail
files: |
artifact/*.jar
- name: GitHub Release
uses: softprops/action-gh-release@v3
with:
files: artifact/*.jar
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+1 -1
View File
@@ -38,4 +38,4 @@ bin/
.vscode/
### Mac OS ###
.DS_Store
.DS_Store
@@ -39,7 +39,7 @@ public final class InterfacePatch extends PatchSupport {
modified |= this.requireModified("native-image.interface", this.addInterface(context.getCurrentClassNode(), FAKE_NATIVE_IMAGE));
}
if (context.isTarget(IDENTIFIER)) {
modified |= this.requireModified("resource-location.patch", this.makeMethodPublicNonFinal(context.findMethod(IDENTIFIER, "<init>", "(" + objectDesc(STRING) + objectDesc(STRING) + ")V")));
modified |= this.requireModified("identifier.patch", this.makeMethodPublicNonFinal(context.findMethod(IDENTIFIER, "<init>", "(" + objectDesc(STRING) + objectDesc(STRING) + ")V")));
}
return modified;
@@ -88,11 +88,11 @@ public final class SkinTexturePatch extends PatchSupport {
private boolean replaceSkinTextureDownloaderProcessLegacySkin(ClassTransformationContext context) {
boolean modified = false;
// 24w46a ~ 25w37a (1.21.4 ~ 1.21.8)
modified |= this.applyIfMatches("[769,772],[0x400000DE,0x4000010C]", "skin-texture-downloader.process-legacy-skin.string", () -> replaceSkinTextureDownloaderProcessLegacySkin(
modified |= this.applyIfMatches("[769,772],[0x400000DE,0x4000010C]", "skin-texture-downloader.process-legacy-skin.v1", () -> replaceSkinTextureDownloaderProcessLegacySkin(
context, context.findMethod(SKIN_TEXTURE_DOWNLOADER, "lambda$downloadAndRegisterSkin$0", "(" + objectDesc(PATH) + objectDesc(STRING) + "Z)" + objectDesc(NATIVE_IMAGE))
));
// 1.21.9-pre1+ (1.21.9+)
modified |= this.applyIfMatches("[773,800],[804,0x40000000],[0x4000010D,]", "skin-texture-downloader.process-legacy-skin.downloaded-texture", () -> replaceSkinTextureDownloaderProcessLegacySkin(
modified |= this.applyIfMatches("[773,800],[804,0x40000000],[0x4000010D,]", "skin-texture-downloader.process-legacy-skin.v2", () -> replaceSkinTextureDownloaderProcessLegacySkin(
context, context.findMethod(SKIN_TEXTURE_DOWNLOADER, "lambda$downloadAndRegisterSkin$0", "(" + objectDesc(PATH) + objectDesc(CLIENT_ASSET_DOWNLOADED_TEXTURE) + "Z)" + objectDesc(NATIVE_IMAGE))
));
return modified;
@@ -2,6 +2,7 @@ package customskinloader.bootstrap.fabric.v1;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -26,7 +27,7 @@ final class TransformerBootstrap {
private static final Logger LOGGER = BootstrapLogger.LOGGER;
private static final TransformerBootstrapSupport SUPPORT = new TransformerBootstrapSupport(TransformerBootstrap.class, "intermediary");
private static final Object LOCK = new Object();
private static final List<PendingMixinTarget> PENDING_MIXIN_TARGETS = new ArrayList<PendingMixinTarget>();
private static final List<PendingMixinTarget> PENDING_MIXIN_TARGETS = new ArrayList<>();
private static final String DUMMY_MIXIN = "customskinloader.bootstrap.fabric.v1.mixin.DummyMixin";
private TransformerBootstrap() {
@@ -45,7 +46,7 @@ final class TransformerBootstrap {
private static void releaseRuntimeArtifacts() {
try {
java.nio.file.Path commonJar = CommonJarInstaller.releaseCommonJar(FabricLoader.getInstance().getGameDir(), "intermediary");
Path commonJar = CommonJarInstaller.releaseCommonJar(FabricLoader.getInstance().getGameDir(), "intermediary");
FabricLauncherBase.getLauncher().addToClassPath(commonJar, "customskinloader.");
LOGGER.info("Added CustomSkinLoader Common jar to Fabric class path: " + BootstrapLogger.formatPath(commonJar));
} catch (Exception exception) {
@@ -135,7 +136,7 @@ final class TransformerBootstrap {
targetClassNames.add(targetInternalName);
Map<String, List<Object>> mixinMapping = (Map<String, List<Object>>) getField(mixinConfig, "mixinMapping");
List<Object> mappedMixins = mixinMapping.computeIfAbsent(targetBinaryName, k -> new ArrayList<Object>());
List<Object> mappedMixins = mixinMapping.computeIfAbsent(targetBinaryName, k -> new ArrayList<>());
if (!mappedMixins.contains(mixinInfo)) {
mappedMixins.add(mixinInfo);
}
@@ -5,8 +5,8 @@ import net.minecraftforge.fml.loading.moddiscovery.ModsFolderLocator;
import customskinloader.bootstrap.util.ModLocatorUtils;
public final class BridgeModLocator extends ModsFolderLocator {
public BridgeModLocator() {
public final class CommonModLocator extends ModsFolderLocator {
public CommonModLocator() {
ModLocatorUtils.initialize(this, ModsFolderLocator.class, FMLPaths.GAMEDIR.get(), "srg");
}
@@ -74,12 +74,12 @@ final class TransformerBootstrap {
// NeoForge
public cpw.mods.modlauncher.api.TargetType getTargetType() {
return cpw.mods.modlauncher.api.TargetType.CLASS;
return cpw.mods.modlauncher.api.TargetType.CLASS;
}
@Override
public String[] labels() {
return new String[]{"customskinloader:" + this.targetClassName.replace('/', '.')};
return new String[] {"customskinloader:" + this.targetClassName.replace('/', '.')};
}
}
}
@@ -1 +1 @@
customskinloader.bootstrap.forge.v2.BridgeModLocator
customskinloader.bootstrap.forge.v2.CommonModLocator
@@ -1 +1 @@
customskinloader.bootstrap.forge.v2.BridgeModLocator
customskinloader.bootstrap.forge.v2.CommonModLocator
@@ -4,8 +4,8 @@ import customskinloader.bootstrap.util.ModLocatorUtils;
import net.neoforged.fml.loading.FMLPaths;
import net.neoforged.fml.loading.moddiscovery.ModsFolderLocator;
public final class BridgeModLocator extends ModsFolderLocator {
public BridgeModLocator() {
public final class CommonModLocator extends ModsFolderLocator {
public CommonModLocator() {
ModLocatorUtils.initialize(this, ModsFolderLocator.class, FMLPaths.GAMEDIR.get(), "official");
}
@@ -1 +1 @@
customskinloader.bootstrap.neoforge.v1.BridgeModLocator
customskinloader.bootstrap.neoforge.v1.CommonModLocator
@@ -4,8 +4,8 @@ import customskinloader.bootstrap.util.ModLocatorUtils;
import net.neoforged.fml.loading.FMLPaths;
import net.neoforged.fml.loading.moddiscovery.locators.ModsFolderLocator;
public final class BridgeModLocator extends ModsFolderLocator {
public BridgeModLocator() {
public final class CommonModLocator extends ModsFolderLocator {
public CommonModLocator() {
ModLocatorUtils.initialize(this, ModsFolderLocator.class, FMLPaths.GAMEDIR.get(), "official");
}
@@ -1 +1 @@
customskinloader.bootstrap.neoforge.v2.BridgeModLocator
customskinloader.bootstrap.neoforge.v2.CommonModLocator
@@ -47,7 +47,7 @@ public class CustomSkinAPIPlus extends CustomSkinAPI {
@Override
public String getName() {
return "CustomSKinAPIPlus";
return "CustomSkinAPIPlus";
}
public static class CustomSkinAPIPlusPayload{
@@ -1,16 +1,14 @@
package customskinloader.loader.jsonapi;
import java.util.List;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import customskinloader.loader.JsonAPILoader;
import customskinloader.loader.MojangAPILoader;
import customskinloader.plugin.ICustomSkinLoaderPlugin;
import customskinloader.profile.UserProfile;
import customskinloader.utils.TextureUtil;
import java.util.List;
public class MinecraftCapesAPI implements JsonAPILoader.IJsonAPI {
@@ -1,5 +1,7 @@
package customskinloader.loader.jsonapi;
import java.util.List;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import customskinloader.CustomSkinLoader;
@@ -10,8 +12,6 @@ import customskinloader.plugin.ICustomSkinLoaderPlugin;
import customskinloader.profile.UserProfile;
import customskinloader.utils.TextureUtil;
import java.util.List;
/**
* Wynntils cape API
* <a href="https://wynntils.com/">Home</a>
@@ -73,18 +73,9 @@ public class ProfileCache {
return;
saveLocalProfile(username,profile);
}
public void putLoader(String username, Function<UserProfile, ?> loader) {
this.profileLoaders.putIfAbsent(username, new ConcurrentLinkedDeque<>());
this.profileLoaders.get(username).offerLast(loader);
}
private CachedProfile getCachedProfile(String username){
CachedProfile cp=cachedProfiles.get(username.toLowerCase());
if(cp!=null)
return cp;
cp=new CachedProfile();
cachedProfiles.put(username.toLowerCase(), cp);
return cp;
return cachedProfiles.computeIfAbsent(username.toLowerCase(), k -> new CachedProfile());
}
private UserProfile loadLocalProfile(String username){
File localProfile=new File(PROFILE_CACHE_DIR,username.toLowerCase()+".json");
@@ -142,8 +142,8 @@ public class HttpRequestUtil {
CustomSkinLoader.logger.debug("Encoded URL: " + url);
}
HttpURLConnection c = (HttpURLConnection) (new URL(url)).openConnection();
c.setReadTimeout(1000 * 5);
c.setConnectTimeout(1000 * 5);
c.setReadTimeout(1000 * 10);
c.setConnectTimeout(1000 * 10);
c.setDoInput(true);
c.setUseCaches(false);
c.setInstanceFollowRedirects(true);
@@ -202,8 +202,11 @@ public class HttpRequestUtil {
}
//Load Content
InputStream is = "gzip".equals(c.getContentEncoding()) ? new GZIPInputStream(c.getInputStream()) : c.getInputStream();
byte[] bytes = IOUtils.toByteArray(is);
byte[] bytes;
try (InputStream is = "gzip".equals(c.getContentEncoding()) ? new GZIPInputStream(c.getInputStream()) : c.getInputStream()) {
bytes = IOUtils.toByteArray(is);
}
if (request.checkPNG && (bytes.length <= 4 || bytes[1] != (byte) 'P' || bytes[2] != (byte) 'N' || bytes[3] != (byte) 'G')) {
CustomSkinLoader.logger.debug("Failed to request (Not Standard PNG)");
responce.success = false;
+8 -20
View File
@@ -1,27 +1,15 @@
import groovy.json.JsonSlurper
import org.apache.tools.ant.filters.ReplaceTokens
import org.gradle.api.attributes.java.TargetJvmVersion
def requireBuildProperty = { String propertyName ->
def propertyValue = rootProject.findProperty(propertyName)?.toString()?.trim()
if (!propertyValue) {
throw new GradleException("Missing ${propertyName} in gradle.properties")
}
propertyValue
}
def info = new JsonSlurper().parse(file("build.info.json"))
def isTruthy = { String value ->
if (value == null) {
return true
}
value.trim().toLowerCase(Locale.ROOT) == 'true'
}
def releaseName = requireBuildProperty('mod_name')
def releaseGroup = requireBuildProperty('mod_group')
def releaseVersion = requireBuildProperty('mod_version')
def releaseGroup = info['mod_group']
def releaseName = info['mod_name']
def releaseVersion = info['mod_version']
def releaseEdition = info['edition']
def releaseIsSnapshot = build_type != 'release'
def releaseBuildNumber = System.getenv('GITHUB_RUN_NUMBER')?.trim() ?: '0'
def releaseIsSnapshot = isTruthy(System.getenv('IS_SNAPSHOT'))
def releaseFullVersion = (releaseIsSnapshot ? "${releaseVersion}-SNAPSHOT-${releaseBuildNumber}" : releaseVersion).toString()
group = releaseGroup
@@ -32,7 +20,7 @@ ext {
modVersion = releaseVersion
modBuildNumber = releaseBuildNumber
modFullVersion = releaseFullVersion
releaseArchiveBaseName = "${releaseName}_Universal".toString()
releaseArchiveBaseName = "${releaseName}_${releaseEdition}".toString()
}
def macroValues = {
+30
View File
@@ -0,0 +1,30 @@
{
"mod_group": "customskinloader",
"mod_name": "CustomSkinLoader",
"mod_version": "15.0",
"edition": "Universal",
"loaders": [
"fabric", "forge", "neoforge", "quilt"
],
"game_versions": [
"1.8", "1.8.8", "1.8.9",
"1.9", "1.9.4",
"1.10", "1.10.2",
"1.11", "1.11.2",
"1.12", "1.12.1", "1.12.2",
"1.13.2",
"1.14", "1.14.1", "1.14.2", "1.14.3", "1.14.4",
"1.15", "1.15.1", "1.15.2",
"1.16", "1.16.1", "1.16.2", "1.16.3", "1.16.4", "1.16.5",
"1.17", "1.17.1",
"1.18", "1.18.1", "1.18.2",
"1.19", "1.19.1", "1.19.2", "1.19.3", "1.19.4",
"1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4", "1.20.5", "1.20.6",
"1.21", "1.21.1", "1.21.2", "1.21.3", "1.21.4", "1.21.5", "1.21.6", "1.21.7", "1.21.8", "1.21.9", "1.21.10", "1.21.11",
"26.1", "26.1.1", "26.1.2", "26.2"
],
"java": [
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 25
]
}
+4 -12
View File
@@ -1,16 +1,8 @@
mod_name=CustomSkinLoader
mod_group=customskinloader
mod_version=15.0
edition=Universal
minecraft_major_versions=1.8,1.9,1.10,1.11,1.12,1.13,1.14,1.15,1.16,1.17,1.18,1.19,1.20,1.21,26.1
build_type=beta
minecraft_version=26.1.2
fabric_v1_version=0.19.2
minecraft_version=26.2
fabric_v1_version=0.19.3
forge_v1_version=14.23.5.2864
forge_v2_version=36.2.42
neoforge_v1_version=20.6.13-beta
neoforge_v2_version=26.1.2.59-beta
loaders=fabric,forge,neoforge,quilt
game_versions=1.8,1.8.8,1.8.9,1.9,1.9.4,1.10,1.10.2,1.11,1.11.2,1.12,1.12.1,1.12.2,1.13.2,1.14,1.14.1,1.14.2,1.14.3,1.14.4,1.15,1.15.1,1.15.2,1.16,1.16.1,1.16.2,1.16.3,1.16.4,1.16.5,1.17,1.17.1,1.18,1.18.1,1.18.2,1.19,1.19.1,1.19.2,1.19.3,1.19.4,1.20,1.20.1,1.20.2,1.20.3,1.20.4,1.20.5,1.20.6,1.21,1.21.1,1.21.2,1.21.3,1.21.4,1.21.5,1.21.6,1.21.7,1.21.8,1.21.9,1.21.10,1.21.11,26.1,26.1.1,26.1.2
java=8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25
neoforge_v2_version=26.2.0.1-beta