Build every Minecraft version from one shared src/ with Stonecutter #31
@@ -47,8 +47,8 @@ git clone --recurse-submodules https://git.selimaj.dev/saturnclientmc/saturnclie
|
|||||||
cd saturnclient
|
cd saturnclient
|
||||||
|
|
||||||
./gradlew buildAll # every version → build/allJars/
|
./gradlew buildAll # every version → build/allJars/
|
||||||
./gradlew :mc-1.21.11:build # a single version
|
./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.10)
|
||||||
./gradlew :mc-1.21.11:runClient # launch a development client
|
./gradlew :1.21.11:runClient # launch a development client
|
||||||
```
|
```
|
||||||
|
|
||||||
Building needs Java 21.
|
Building needs Java 21.
|
||||||
|
|||||||
+31
-11
@@ -4,12 +4,30 @@ How Saturn Client supports several Minecraft versions, and how to change or add
|
|||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
- `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`.
|
Saturn is moving from one full copy of the version-specific code per Minecraft version to a single copy built with [Stonecutter](https://stonecutter.kikugie.dev/) (issue #8). During the move there are two kinds of version:
|
||||||
- `versions/<mc>/`: one module per Minecraft version, implementing those interfaces (providers, refs, mixins). Each is a full copy, and they differ only where Minecraft's API differs.
|
|
||||||
- `gradle.properties`: the Minecraft, Yarn, Fabric Loader and Fabric API versions.
|
|
||||||
- `src/`: the version-specific code and the three mixin configs.
|
|
||||||
|
|
||||||
`settings.gradle` includes every folder under `versions/` automatically, as the Gradle project `:mc-<mc>`.
|
- `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`.
|
||||||
|
- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:<mc>`, and `versions/<mc>/` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`.
|
||||||
|
- `versions/<mc>/src/`: the versions not moved yet (1.21.4 to 1.21.10), each a full copy, as the Gradle project `:mc-<mc>` with its own `build.gradle`.
|
||||||
|
|
||||||
|
`settings.gradle` lists the Stonecutter versions in `stonecutterVersions` and includes every other folder under `versions/` as `:mc-<mc>`. The root `build.gradle` builds each Stonecutter version, and `stonecutter.gradle` configures the root project (shared repositories, the `common` wiring and `buildAll`).
|
||||||
|
|
||||||
|
## Version-specific code with Stonecutter
|
||||||
|
|
||||||
|
The code in `src/` is always plain Java for the **active** version (1.21.11, set in `stonecutter.gradle`). Code for other versions sits in comments that Stonecutter swaps before building each version:
|
||||||
|
|
||||||
|
```java
|
||||||
|
//? if >=1.21.9 {
|
||||||
|
public void render(MatrixStack matrices, OrderedRenderCommandQueue queue, int light, PlayerEntityRenderState state, float limbAngle, float limbDistance) {
|
||||||
|
//?} else
|
||||||
|
/*public void render(MatrixStack matrices, VertexConsumerProvider consumers, int light, PlayerEntityRenderState state, float limbAngle, float limbDistance) {*/
|
||||||
|
```
|
||||||
|
|
||||||
|
- `./gradlew "Set active project to <mc>"` (or the Stonecutter IntelliJ plugin) rewrites `src/` so that version's code is the uncommented one, for editing it in the IDE.
|
||||||
|
- `./gradlew "Reset active project"` switches back to 1.21.11. **Run it before committing**, so `src/` is always committed with 1.21.11 active.
|
||||||
|
- Each version's processed copy is compiled from `versions/<mc>/build/generated/stonecutter/`, which is also where to look when a non-active version fails to compile.
|
||||||
|
|
||||||
|
The `emotes` repository uses the same setup, and its `BentCubeRenderer` and `PlayerModelMixin` are small examples of version comments.
|
||||||
|
|
||||||
## Porting a change to the other versions
|
## Porting a change to the other versions
|
||||||
|
|
||||||
@@ -22,13 +40,13 @@ scripts/port.sh --to 1.21.9,1.21.10 # only some versions
|
|||||||
scripts/port.sh --commit <rev> # port what a commit changed instead
|
scripts/port.sh --commit <rev> # port what a commit changed instead
|
||||||
```
|
```
|
||||||
|
|
||||||
The script applies the diff under `versions/<from>/src` to each other version with `git apply --3way`:
|
The script applies the diff under one version's source to each other version with `git apply --3way`. The Stonecutter `src/` counts as one version (1.21.11), so changes port between it and the old copies in both directions:
|
||||||
|
|
||||||
- **applied**: the files matched, and nothing else is needed.
|
- **applied**: the files matched, and nothing else is needed.
|
||||||
- **CONFLICTS**: that version's code really differs. The file gets normal conflict markers, with the version's own code in `ours` and the ported change in `theirs`. Adapt the change to that version's API and resolve.
|
- **CONFLICTS**: that version's code really differs. The file gets normal conflict markers, with the version's own code in `ours` and the ported change in `theirs`. Adapt the change to that version's API and resolve.
|
||||||
- **already has this change**: nothing to do, which is safe to see when re-running.
|
- **already has this change**: nothing to do, which is safe to see when re-running.
|
||||||
|
|
||||||
Only `src/` is ported. `build.gradle` and `gradle.properties` are version-specific on purpose. Then build everything:
|
Only source is ported. `build.gradle` and `gradle.properties` are version-specific on purpose. Then build everything:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./gradlew compileJava
|
./gradlew compileJava
|
||||||
@@ -38,7 +56,9 @@ The **Check** workflow runs the same compile on every pull request, so a version
|
|||||||
|
|
||||||
## Adding a Minecraft version
|
## Adding a Minecraft version
|
||||||
|
|
||||||
1. Copy the closest existing version: `cp -r versions/1.21.11 versions/<new>`. Delete its `build/`, `.gradle/` and `run/` folders if present.
|
Add new versions to Stonecutter rather than copying a folder:
|
||||||
2. In `versions/<new>/gradle.properties`, set `minecraft_version`, `yarn_mappings`, `loader_version` and `fabric_api_version`. The right values are listed at <https://fabricmc.net/develop>.
|
|
||||||
3. Build it with `./gradlew :mc-<new>:compileJava` and fix what Minecraft changed. Check the mixin configs in `src/main/resources/*.mixins.json` as well: a mixin whose target changed fails at startup, not at compile time, so launch it with `./gradlew :mc-<new>:runClient`.
|
1. Create `versions/<new>/gradle.properties` with `minecraft_version`, `yarn_mappings`, `loader_version` and `fabric_api_version` (copy 1.21.11's and change the values; they're listed at <https://fabricmc.net/develop>).
|
||||||
4. The release workflow builds every folder under `versions/`, and "Publish to Modrinth" takes the game version from each jar's name, so neither needs changing.
|
2. Add `<new>` to `stonecutterVersions` in `settings.gradle`.
|
||||||
|
3. Build it with `./gradlew :<new>:compileJava` and put what Minecraft changed behind version comments. Check the mixin configs in `src/main/resources/*.mixins.json` as well: a mixin whose target changed fails at startup, not at compile time, so launch it with `./gradlew :<new>:runClient`.
|
||||||
|
4. The release workflow builds everything through `buildAll`, and "Publish to Modrinth" takes the game version from each jar's name, so neither needs changing.
|
||||||
|
|||||||
+87
-51
@@ -1,65 +1,101 @@
|
|||||||
subprojects {
|
plugins {
|
||||||
apply plugin: "java"
|
id 'net.fabricmc.fabric-loom-remap' version "${loom_version}"
|
||||||
|
id 'maven-publish'
|
||||||
|
}
|
||||||
|
|
||||||
repositories {
|
version = "${project.mod_version}+${project.minecraft_version}"
|
||||||
maven { url "https://maven.fabricmc.net/" }
|
group = project.maven_group
|
||||||
maven { url "https://git.selimaj.dev/api/packages/selimaj-dev/maven" }
|
|
||||||
maven { url "https://git.selimaj.dev/api/packages/saturnclientmc/maven" }
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
base {
|
||||||
implementation "de.javagl:obj:0.4.0"
|
archivesName = project.archives_base_name
|
||||||
implementation "com.formdev:svgSalamander:1.1.4"
|
}
|
||||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.0'
|
|
||||||
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.17.0'
|
repositories {
|
||||||
implementation 'com.fasterxml.jackson.core:jackson-core:2.17.0'
|
maven { name = "Selimaj"; url = 'https://git.selimaj.dev/api/packages/selimaj-dev/maven' }
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// To change the versions see the gradle.properties file
|
||||||
|
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||||
|
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||||
|
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||||
|
|
||||||
|
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||||
|
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
|
||||||
|
|
||||||
|
// Saturn's emote library (limb bending, Emotecraft emotes)
|
||||||
|
include modImplementation("org.saturnclient:emotes-fabric:${project.emotes_version}+${project.minecraft_version}")
|
||||||
|
|
||||||
|
implementation project(":common")
|
||||||
|
|
||||||
|
include implementation("dev.selimaj:session-java:0.2.0")
|
||||||
|
include implementation("de.javagl:obj:0.4.0")
|
||||||
|
include implementation("com.formdev:svgSalamander:1.1.4")
|
||||||
|
include implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0")
|
||||||
|
include implementation("com.fasterxml.jackson.core:jackson-annotations:2.17.0")
|
||||||
|
include implementation("com.fasterxml.jackson.core:jackson-core:2.17.0")
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ================================================================
|
||||||
|
* Resource Processing
|
||||||
|
* ================================================================
|
||||||
|
* Injects version values into fabric.mod.json.
|
||||||
|
*/
|
||||||
|
processResources {
|
||||||
|
inputs.property "version", project.version
|
||||||
|
inputs.property "minecraft_version", project.minecraft_version
|
||||||
|
inputs.property "loader_version", project.loader_version
|
||||||
|
filteringCharset "UTF-8"
|
||||||
|
|
||||||
|
filesMatching("fabric.mod.json") {
|
||||||
|
expand(
|
||||||
|
"version": project.version,
|
||||||
|
"minecraft_version": project.minecraft_version,
|
||||||
|
"loader_version": project.loader_version
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configure(subprojects.findAll { it.name != "common" }) {
|
tasks.withType(JavaCompile).configureEach {
|
||||||
dependencies {
|
it.options.release = 21
|
||||||
implementation project(":common")
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
main {
|
|
||||||
resources {
|
|
||||||
srcDir project(":common").file("src/main/resources")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register("buildAll") {
|
java {
|
||||||
group = "build"
|
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
|
||||||
description = "Builds all subprojects and collects their remapped jars"
|
// if it is present.
|
||||||
|
// If you remove this line, sources will not be generated.
|
||||||
|
withSourcesJar()
|
||||||
|
|
||||||
// Only build remapped jars (not full build)
|
sourceCompatibility = JavaVersion.VERSION_21
|
||||||
dependsOn subprojects.collect { proj ->
|
targetCompatibility = JavaVersion.VERSION_21
|
||||||
proj.tasks.matching { it.name == "remapJar" }
|
}
|
||||||
}
|
|
||||||
|
|
||||||
doLast {
|
jar {
|
||||||
def outputDir = file("$buildDir/allJars")
|
inputs.property "archivesName", project.base.archivesName
|
||||||
outputDir.mkdirs()
|
|
||||||
|
|
||||||
subprojects.each { proj ->
|
from("LICENSE") {
|
||||||
def remapTask = proj.tasks.findByName("remapJar")
|
rename { "${it}_${inputs.properties.archivesName}"}
|
||||||
|
}
|
||||||
|
|
||||||
if (remapTask != null) {
|
from project(":common").sourceSets.main.output
|
||||||
def jarFile = remapTask.archiveFile.get().asFile
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
}
|
||||||
|
|
||||||
if (jarFile.exists() && !jarFile.name.contains("sources")) {
|
// configure the maven publication
|
||||||
copy {
|
publishing {
|
||||||
from jarFile
|
publications {
|
||||||
into outputDir
|
create("mavenJava", MavenPublication) {
|
||||||
rename { "${jarFile.name}" }
|
artifactId = project.archives_base_name
|
||||||
}
|
from components.java
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
println "All remapped jars collected in: $outputDir"
|
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
|
||||||
}
|
repositories {
|
||||||
|
// Add repositories to publish to here.
|
||||||
|
// Notice: This block does NOT have the same function as the block in the top level.
|
||||||
|
// The repositories here will be used for publishing your artifact, not for
|
||||||
|
// retrieving dependencies.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+46
-18
@@ -1,11 +1,15 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Port a change made in one Minecraft version's code to the other versions.
|
# Port a change made in one Minecraft version's code to the other versions.
|
||||||
#
|
#
|
||||||
# Takes the diff under versions/<from>/src and applies it to versions/<to>/src
|
# Takes the diff under one version's source folder and applies it to the others
|
||||||
# with `git apply --3way`: it applies cleanly where the files match, and leaves
|
# with `git apply --3way`: it applies cleanly where the files match, and leaves
|
||||||
# normal merge conflicts only where a version really differs. Only src/ is
|
# normal merge conflicts only where a version really differs. Only source is
|
||||||
# ported; build.gradle and gradle.properties are version-specific on purpose.
|
# ported; build.gradle and gradle.properties are version-specific on purpose.
|
||||||
#
|
#
|
||||||
|
# Versions moved to Stonecutter (stonecutterVersions in settings.gradle) share
|
||||||
|
# the top-level src/, which counts as one version: the active one set in
|
||||||
|
# stonecutter.gradle. The others keep their own copy in versions/<v>/src.
|
||||||
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# scripts/port.sh [--from VERSION] [--to V1,V2,...] [--commit REV] [--dry-run]
|
# scripts/port.sh [--from VERSION] [--to V1,V2,...] [--commit REV] [--dry-run]
|
||||||
#
|
#
|
||||||
@@ -33,25 +37,39 @@ while [ $# -gt 0 ]; do
|
|||||||
--to) to="$2"; shift 2 ;;
|
--to) to="$2"; shift 2 ;;
|
||||||
--commit) commit="$2"; shift 2 ;;
|
--commit) commit="$2"; shift 2 ;;
|
||||||
--dry-run) dry_run=true; shift ;;
|
--dry-run) dry_run=true; shift ;;
|
||||||
-h|--help) sed -n '2,20p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
-h|--help) sed -n '2,23p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||||
*) echo "Unknown option: $1 (see --help)" >&2; exit 2 ;;
|
*) echo "Unknown option: $1 (see --help)" >&2; exit 2 ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
all_versions=$(ls -d versions/*/ | xargs -n1 basename | sort -t. -k1,1n -k2,2n -k3,3n)
|
# Versions sharing the Stonecutter src/, and the one that stands for them.
|
||||||
|
stonecutter_versions=$(sed -n 's/^def stonecutterVersions = \[\(.*\)\]/\1/p' settings.gradle | tr -d '" ' | tr ',' ' ')
|
||||||
|
stonecutter_active=$(sed -n 's/^stonecutter\.active "\(.*\)"/\1/p' stonecutter.gradle 2>/dev/null || true)
|
||||||
|
|
||||||
|
is_stonecutter() {
|
||||||
|
printf '%s\n' $stonecutter_versions | grep -qx "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Where a version's source lives.
|
||||||
|
src_of() {
|
||||||
|
if is_stonecutter "$1"; then echo "src"; else echo "versions/$1/src"; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
old_versions=$(for d in versions/*/; do [ -d "$d/src" ] && basename "$d"; done)
|
||||||
|
all_versions=$(printf '%s\n' $old_versions $stonecutter_active | grep . | sort -t. -k1,1n -k2,2n -k3,3n)
|
||||||
|
|
||||||
version_exists() {
|
version_exists() {
|
||||||
[ -d "versions/$1/src" ]
|
[ -d "$(src_of "$1")" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
# Versions with changes, from the working tree or from the given commit.
|
# Versions with changes, from the working tree or from the given commit.
|
||||||
changed_versions() {
|
changed_versions() {
|
||||||
if [ -n "$commit" ]; then
|
if [ -n "$commit" ]; then
|
||||||
git show --name-only --format= "$commit" -- versions/
|
git show --name-only --format= "$commit" -- versions/ src/
|
||||||
else
|
else
|
||||||
git diff HEAD --name-only -- versions/
|
git diff HEAD --name-only -- versions/ src/
|
||||||
git ls-files --others --exclude-standard -- versions/
|
git ls-files --others --exclude-standard -- versions/ src/
|
||||||
fi | sed -n 's#^versions/\([^/]*\)/src/.*#\1#p' | sort -u
|
fi | sed -n -e 's#^versions/\([^/]*\)/src/.*#\1#p' -e "s#^src/.*#${stonecutter_active}#p" | sort -u
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ -z "$from" ]; then
|
if [ -z "$from" ]; then
|
||||||
@@ -65,6 +83,10 @@ if [ -z "$from" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
version_exists "$from" || { echo "No such version: $from" >&2; exit 2; }
|
version_exists "$from" || { echo "No such version: $from" >&2; exit 2; }
|
||||||
|
if is_stonecutter "$from"; then
|
||||||
|
from="$stonecutter_active"
|
||||||
|
fi
|
||||||
|
from_src=$(src_of "$from")
|
||||||
|
|
||||||
if [ -z "$to" ]; then
|
if [ -z "$to" ]; then
|
||||||
to=$(printf '%s\n' $all_versions | grep -vx "$from" | paste -sd, -)
|
to=$(printf '%s\n' $all_versions | grep -vx "$from" | paste -sd, -)
|
||||||
@@ -72,10 +94,10 @@ fi
|
|||||||
|
|
||||||
# New files are only included in `git diff HEAD` once git knows about them.
|
# New files are only included in `git diff HEAD` once git knows about them.
|
||||||
if [ -z "$commit" ]; then
|
if [ -z "$commit" ]; then
|
||||||
untracked=$(git ls-files --others --exclude-standard -- "versions/$from/src")
|
untracked=$(git ls-files --others --exclude-standard -- "$from_src")
|
||||||
if [ -n "$untracked" ]; then
|
if [ -n "$untracked" ]; then
|
||||||
if $dry_run; then
|
if $dry_run; then
|
||||||
echo "note: new files in versions/$from/src are untracked and won't be ported in a dry run:" >&2
|
echo "note: new files in $from_src are untracked and won't be ported in a dry run:" >&2
|
||||||
printf ' %s\n' $untracked >&2
|
printf ' %s\n' $untracked >&2
|
||||||
else
|
else
|
||||||
printf '%s\n' "$untracked" | xargs git add --intent-to-add --
|
printf '%s\n' "$untracked" | xargs git add --intent-to-add --
|
||||||
@@ -85,20 +107,20 @@ fi
|
|||||||
|
|
||||||
# --full-index gives --3way the real blob ids to merge against.
|
# --full-index gives --3way the real blob ids to merge against.
|
||||||
if [ -n "$commit" ]; then
|
if [ -n "$commit" ]; then
|
||||||
patch=$(git show --full-index --binary --format= "$commit" -- "versions/$from/src")
|
patch=$(git show --full-index --binary --format= "$commit" -- "$from_src")
|
||||||
else
|
else
|
||||||
patch=$(git diff HEAD --full-index --binary -- "versions/$from/src")
|
patch=$(git diff HEAD --full-index --binary -- "$from_src")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$patch" ]; then
|
if [ -z "$patch" ]; then
|
||||||
echo "No changes under versions/$from/src to port." >&2
|
echo "No changes under $from_src to port." >&2
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
files=$(printf '%s\n' "$patch" | grep -c '^diff --git' || true)
|
files=$(printf '%s\n' "$patch" | grep -c '^diff --git' || true)
|
||||||
echo "Porting $files file(s) from $from${commit:+ (commit $commit)}"
|
echo "Porting $files file(s) from $from${commit:+ (commit $commit)}"
|
||||||
|
|
||||||
from_re=$(printf '%s' "$from" | sed 's/\./\\./g')
|
from_re=$(printf '%s' "$from_src" | sed 's/\./\\./g')
|
||||||
tmp=$(mktemp -d)
|
tmp=$(mktemp -d)
|
||||||
trap 'rm -rf "$tmp"' EXIT
|
trap 'rm -rf "$tmp"' EXIT
|
||||||
|
|
||||||
@@ -109,14 +131,20 @@ for target in "${targets[@]}"; do
|
|||||||
if [ "$target" = "$from" ]; then
|
if [ "$target" = "$from" ]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
if is_stonecutter "$target" && [ "$target" != "$stonecutter_active" ]; then
|
||||||
|
printf ' %-8s skipped: shares src/ with %s\n' "$target" "$stonecutter_active"
|
||||||
|
[ "$from" = "$stonecutter_active" ] || status=1
|
||||||
|
continue
|
||||||
|
fi
|
||||||
if ! version_exists "$target"; then
|
if ! version_exists "$target"; then
|
||||||
printf ' %-8s skipped: no such version\n' "$target"
|
printf ' %-8s skipped: no such version\n' "$target"
|
||||||
status=1
|
status=1
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Point the patch's file headers at the target version.
|
# Point the patch's file headers at the target version's source folder.
|
||||||
printf '%s\n' "$patch" | sed -E "/^(diff --git |--- |\+\+\+ |rename (from|to) |copy (from|to) )/ s#versions/${from_re}/#versions/${target}/#g" > "$tmp/$target.patch"
|
target_src=$(src_of "$target")
|
||||||
|
printf '%s\n' "$patch" | sed -E "/^(diff --git |--- |\+\+\+ |rename (from|to) |copy (from|to) )/ s#([ab]/|(from|to) )${from_re}/#\1${target_src}/#g" > "$tmp/$target.patch"
|
||||||
|
|
||||||
if git apply --check --reverse "$tmp/$target.patch" 2>/dev/null; then
|
if git apply --check --reverse "$tmp/$target.patch" 2>/dev/null; then
|
||||||
printf ' %-8s already has this change\n' "$target"
|
printf ' %-8s already has this change\n' "$target"
|
||||||
@@ -135,7 +163,7 @@ for target in "${targets[@]}"; do
|
|||||||
if output=$(git apply --3way "$tmp/$target.patch" 2>&1); then
|
if output=$(git apply --3way "$tmp/$target.patch" 2>&1); then
|
||||||
printf ' %-8s applied\n' "$target"
|
printf ' %-8s applied\n' "$target"
|
||||||
else
|
else
|
||||||
conflicts=$(git diff --name-only --diff-filter=U -- "versions/$target")
|
conflicts=$(git diff --name-only --diff-filter=U -- "$target_src")
|
||||||
if [ -n "$conflicts" ]; then
|
if [ -n "$conflicts" ]; then
|
||||||
printf ' %-8s CONFLICTS in:\n' "$target"
|
printf ' %-8s CONFLICTS in:\n' "$target"
|
||||||
printf '%s\n' "$conflicts" | sed 's/^/ /'
|
printf '%s\n' "$conflicts" | sed 's/^/ /'
|
||||||
|
|||||||
+23
-4
@@ -1,21 +1,40 @@
|
|||||||
pluginManagement {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
maven { url "https://maven.fabricmc.net/" }
|
maven { url "https://maven.fabricmc.net/" }
|
||||||
|
maven { url "https://maven.kikugie.dev/releases" }
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id "dev.kikugie.stonecutter" version "0.9.8"
|
||||||
|
}
|
||||||
|
|
||||||
rootProject.name = "saturn-client"
|
rootProject.name = "saturn-client"
|
||||||
|
|
||||||
include("common")
|
include("common")
|
||||||
|
|
||||||
def versionsDir = file("versions")
|
// Versions built by Stonecutter from the shared src/ (see stonecutter.gradle). Each one's
|
||||||
|
// versions/<v>/gradle.properties holds its Minecraft, Yarn and Fabric API versions.
|
||||||
|
def stonecutterVersions = ["1.21.11"]
|
||||||
|
|
||||||
versionsDir.eachDir { dir ->
|
stonecutter {
|
||||||
def version = dir.name
|
kotlinController = false // stonecutter.gradle configures the root project
|
||||||
def projectName = "mc-${version}"
|
centralScript = "build.gradle" // build.gradle configures each version
|
||||||
|
create(rootProject) {
|
||||||
|
versions(*stonecutterVersions)
|
||||||
|
vcsVersion = "1.21.11"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Versions not moved to Stonecutter yet still build from their own copy in versions/<v>/src,
|
||||||
|
// as projects named mc-<v>.
|
||||||
|
file("versions").eachDir { dir ->
|
||||||
|
if (dir.name in stonecutterVersions) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
def projectName = "mc-${dir.name}"
|
||||||
include(projectName)
|
include(projectName)
|
||||||
project(":${projectName}").projectDir = dir
|
project(":${projectName}").projectDir = dir
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
plugins {
|
||||||
|
id "dev.kikugie.stonecutter"
|
||||||
|
}
|
||||||
|
|
||||||
|
// The version whose code is uncommented in src/. Switch with "Set active project to <v>", and run
|
||||||
|
// "Reset active project" before committing.
|
||||||
|
stonecutter.active "1.21.11"
|
||||||
|
|
||||||
|
subprojects {
|
||||||
|
apply plugin: "java"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven { url "https://maven.fabricmc.net/" }
|
||||||
|
maven { url "https://git.selimaj.dev/api/packages/selimaj-dev/maven" }
|
||||||
|
maven { url "https://git.selimaj.dev/api/packages/saturnclientmc/maven" }
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation "de.javagl:obj:0.4.0"
|
||||||
|
implementation "com.formdev:svgSalamander:1.1.4"
|
||||||
|
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.0'
|
||||||
|
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.17.0'
|
||||||
|
implementation 'com.fasterxml.jackson.core:jackson-core:2.17.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configure(subprojects.findAll { it.name != "common" }) {
|
||||||
|
dependencies {
|
||||||
|
implementation project(":common")
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
resources {
|
||||||
|
srcDir project(":common").file("src/main/resources")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register("buildAll") {
|
||||||
|
group = "build"
|
||||||
|
description = "Builds all subprojects and collects their remapped jars"
|
||||||
|
|
||||||
|
// Only build remapped jars (not full build)
|
||||||
|
dependsOn subprojects.collect { proj ->
|
||||||
|
proj.tasks.matching { it.name == "remapJar" }
|
||||||
|
}
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
def outputDir = file("$buildDir/allJars")
|
||||||
|
outputDir.mkdirs()
|
||||||
|
|
||||||
|
subprojects.each { proj ->
|
||||||
|
def remapTask = proj.tasks.findByName("remapJar")
|
||||||
|
|
||||||
|
if (remapTask != null) {
|
||||||
|
def jarFile = remapTask.archiveFile.get().asFile
|
||||||
|
|
||||||
|
if (jarFile.exists() && !jarFile.name.contains("sources")) {
|
||||||
|
copy {
|
||||||
|
from jarFile
|
||||||
|
into outputDir
|
||||||
|
rename { "${jarFile.name}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println "All remapped jars collected in: $outputDir"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id 'net.fabricmc.fabric-loom-remap' version "${loom_version}"
|
|
||||||
id 'maven-publish'
|
|
||||||
}
|
|
||||||
|
|
||||||
version = "${project.mod_version}+${project.minecraft_version}"
|
|
||||||
group = project.maven_group
|
|
||||||
|
|
||||||
base {
|
|
||||||
archivesName = project.archives_base_name
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
maven { name = "Selimaj"; url = 'https://git.selimaj.dev/api/packages/selimaj-dev/maven' }
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
// To change the versions see the gradle.properties file
|
|
||||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
|
||||||
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
|
||||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
|
||||||
|
|
||||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
|
||||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
|
|
||||||
|
|
||||||
// Saturn's emote library (limb bending, Emotecraft emotes)
|
|
||||||
include modImplementation("org.saturnclient:emotes-fabric:${project.emotes_version}+${project.minecraft_version}")
|
|
||||||
|
|
||||||
implementation project(":common")
|
|
||||||
|
|
||||||
include implementation("dev.selimaj:session-java:0.2.0")
|
|
||||||
include implementation("de.javagl:obj:0.4.0")
|
|
||||||
include implementation("com.formdev:svgSalamander:1.1.4")
|
|
||||||
include implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0")
|
|
||||||
include implementation("com.fasterxml.jackson.core:jackson-annotations:2.17.0")
|
|
||||||
include implementation("com.fasterxml.jackson.core:jackson-core:2.17.0")
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ================================================================
|
|
||||||
* Resource Processing
|
|
||||||
* ================================================================
|
|
||||||
* Injects version values into fabric.mod.json.
|
|
||||||
*/
|
|
||||||
processResources {
|
|
||||||
inputs.property "version", project.version
|
|
||||||
inputs.property "minecraft_version", project.minecraft_version
|
|
||||||
inputs.property "loader_version", project.loader_version
|
|
||||||
filteringCharset "UTF-8"
|
|
||||||
|
|
||||||
filesMatching("fabric.mod.json") {
|
|
||||||
expand(
|
|
||||||
"version": project.version,
|
|
||||||
"minecraft_version": project.minecraft_version,
|
|
||||||
"loader_version": project.loader_version
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType(JavaCompile).configureEach {
|
|
||||||
it.options.release = 21
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
|
|
||||||
// if it is present.
|
|
||||||
// If you remove this line, sources will not be generated.
|
|
||||||
withSourcesJar()
|
|
||||||
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_21
|
|
||||||
targetCompatibility = JavaVersion.VERSION_21
|
|
||||||
}
|
|
||||||
|
|
||||||
jar {
|
|
||||||
inputs.property "archivesName", project.base.archivesName
|
|
||||||
|
|
||||||
from("LICENSE") {
|
|
||||||
rename { "${it}_${inputs.properties.archivesName}"}
|
|
||||||
}
|
|
||||||
|
|
||||||
from project(":common").sourceSets.main.output
|
|
||||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
|
||||||
}
|
|
||||||
|
|
||||||
// configure the maven publication
|
|
||||||
publishing {
|
|
||||||
publications {
|
|
||||||
create("mavenJava", MavenPublication) {
|
|
||||||
artifactId = project.archives_base_name
|
|
||||||
from components.java
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
|
|
||||||
repositories {
|
|
||||||
// Add repositories to publish to here.
|
|
||||||
// Notice: This block does NOT have the same function as the block in the top level.
|
|
||||||
// The repositories here will be used for publishing your artifact, not for
|
|
||||||
// retrieving dependencies.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
pluginManagement {
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
name = 'Fabric'
|
|
||||||
url = 'https://maven.fabricmc.net/'
|
|
||||||
}
|
|
||||||
mavenCentral()
|
|
||||||
gradlePluginPortal()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user