Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
wagyourtail committed Nov 22, 2023
1 parent 6ea5559 commit 723501f
Show file tree
Hide file tree
Showing 14 changed files with 616 additions and 13 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Build Release
on:
release:
types: [ created ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '17'

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Publish
run: ./gradlew publish -Pmvn.user=${{ secrets.MAVEN_USER }} -Pmvn.key=${{ secrets.MAVEN_TOKEN }}

- uses: actions/upload-artifact@v2
with:
name: PatchBase Artifacts
path: ./build/libs/
30 changes: 30 additions & 0 deletions .github/workflows/build_snapshot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Build Snapshot

on:
push:
branches-ignore:
- 'feature/**'

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
cache: 'gradle'

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Publish
run: ./gradlew publish -Pversion_snapshot -Pmvn.user=${{ secrets.MAVEN_USER }} -Pmvn.key=${{ secrets.MAVEN_TOKEN }} -x test

- uses: actions/upload-artifact@v2
with:
name: PatchBase Snapshot Artifacts
path: ./build/libs/
8 changes: 1 addition & 7 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,7 @@ build/
!**/src/test/**/build/

### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
.idea
out/
!**/src/main/**/out/
!**/src/test/**/out/
Expand Down
104 changes: 99 additions & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,19 +1,113 @@
import java.net.URI

plugins {
id("java")
kotlin("jvm") version "1.8.21"
`java-gradle-plugin`
`maven-publish`
}

version = if (project.hasProperty("version_snapshot")) project.properties["version"] as String + "-SNAPSHOT" else project.properties["version"] as String
group = project.properties["maven_group"] as String

base {
archivesName.set(project.properties["archives_base_name"] as String)
}

group = "org.example"
version = "1.0-SNAPSHOT"
val installer by sourceSets.creating

sourceSets {
main {
compileClasspath += installer.output
runtimeClasspath += installer.output
}
}

repositories {
maven("https://maven.wagyourtail.xyz/releases")
maven("https://maven.wagyourtail.xyz/snapshots")
maven("https://maven.jemnetworks.com/snapshots")
mavenCentral()
}

configurations {
implementation {
extendsFrom(configurations.named("installerImplementation").get())
}
}

dependencies {
testImplementation(platform("org.junit:junit-bom:5.9.1"))
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation(kotlin("test"))

runtimeOnly(gradleApi())

implementation("xyz.wagyourtail.unimined:unimined:1.1.0-SNAPSHOT")
"installerImplementation"("io.github.java-diff-utils:java-diff-utils:4.12")
"installerImplementation"("io.github.prcraftmc:class-diff:1.0-SNAPSHOT")
"installerImplementation"("org.jetbrains:annotations:24.0.1")
}

gradlePlugin {
plugins {
create("xyz.wagyourtail.patchbase") {
id = "xyz.wagyourtail.patchbase"
implementationClass = "xyz.wagyourtail.patchbase.gradle.PatchPlugin"
}
}
}

gradlePlugin {
plugins {
create("xyz.wagyourtail.patchbase-creator") {
id = "xyz.wagyourtail.patchbase-creator"
implementationClass = "xyz.wagyourtail.patchbase.gradle.PatchCreatorPlugin"
}
}
}

tasks.jar {
from(sourceSets.main.get().output, installer.output)
}

project.evaluationDependsOnChildren()

val installerJar by tasks.registering(Jar::class) {
group = "build"
archiveClassifier.set("installer")
from(installer.output)
}

tasks.test {
useJUnitPlatform()
}

tasks.build {
dependsOn(installerJar)
}

publishing {
repositories {
maven {
name = "WagYourMaven"
url = if (project.hasProperty("version_snapshot")) {
URI.create("https://maven.wagyourtail.xyz/snapshots/")
} else {
URI.create("https://maven.wagyourtail.xyz/releases/")
}
credentials {
username = project.findProperty("mvn.user") as String? ?: System.getenv("USERNAME")
password = project.findProperty("mvn.key") as String? ?: System.getenv("TOKEN")
}
}
}
publications {
create<MavenPublication>("maven") {
groupId = project.group as String
artifactId = project.properties["archives_base_name"] as String? ?: project.name
version = project.version as String

artifact(installerJar.get()) {
classifier = "installer"
}
}
}
}
8 changes: 8 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
kotlin.code.style=official

org.gradle.jvmargs=-Xmx1G
org.gradle.parallel=true

maven_group=xyz.wagyourtail.unimined
archives_base_name=patchbase
version=1.0.0
3 changes: 2 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
rootProject.name = "ExampleClient"
rootProject.name = "patchbase"

include("class-diff")
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package xyz.wagyourtail.patchbase.installer;

import io.github.prcraftmc.classdiff.ClassPatcher;
import io.github.prcraftmc.classdiff.format.DiffReader;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.file.*;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class PatchbaseInstaller {

/*
* create your installer around this method.
*/
public void patch(Path patchJar, Path baseJar, Path outputJar) throws IOException {
Files.createDirectories(outputJar.getParent());
Files.copy(baseJar, outputJar, StandardCopyOption.REPLACE_EXISTING);
try (FileSystem fs = openZipFileSystem(outputJar)) {
forEachInZip(patchJar, (entry, is) -> {
if (entry.endsWith(".cdiff")) {
try {
readZipInputStreamFor(baseJar, entry.substring(0, entry.length() - 6), true, original -> {
try {
ClassWriter cw = new ClassWriter(0);
ClassNode node = new ClassNode();
new ClassReader(original).accept(node, ClassReader.SKIP_DEBUG);
ClassPatcher.patch(node, new DiffReader(is.readAllBytes()));
node.accept(cw);
Path p = fs.getPath(entry.substring(0, entry.length() - 6));
if (p.getParent() != null) Files.createDirectories(p.getParent());
Files.write(p, cw.toByteArray(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
} catch (IOException e) {
throw new RuntimeException(e);
}
return null;
});
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
try {
Path p = fs.getPath(entry);
if (p.getParent() != null) Files.createDirectories(p.getParent());
Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
}
}

public static <T> T readZipInputStreamFor(Path path, String entry, boolean throwIfMissing, Function<InputStream, T> action) throws IOException {
try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(path))) {
var zipEntry = zis.getNextEntry();
while (zipEntry != null) {
if (zipEntry.isDirectory()) {
zipEntry = zis.getNextEntry();
continue;
}
if (zipEntry.getName().equals(entry)) {
return action.apply(zis);
}
zipEntry = zis.getNextEntry();
}
}
if (throwIfMissing) {
throw new IllegalArgumentException("Missing file " + entry + " in " + path);
}
return null;
}

public static void forEachInZip(Path path, BiConsumer<String, InputStream> action) throws IOException {
try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(path))) {
var entry = zis.getNextEntry();
while (entry != null) {
if (entry.isDirectory()) {
entry = zis.getNextEntry();
continue;
}
action.accept(entry.getName(), zis);
entry = zis.getNextEntry();
}
}
}

public static FileSystem openZipFileSystem(Path path) throws IOException {
return openZipFileSystem(path, Map.of());
}

public static FileSystem openZipFileSystem(Path path, Map<String, Object> args) throws IOException {
if (!Files.exists(path) && args.getOrDefault("create", false).equals(true)) {
try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(path))) {
zos.closeEntry();
}
}
return FileSystems.newFileSystem(URI.create("jar:" + path.toUri()), args, null);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package xyz.wagyourtail.patchbase.gradle

import org.gradle.api.Project
import xyz.wagyourtail.patchbase.installer.PatchbaseInstaller
import xyz.wagyourtail.unimined.api.minecraft.MinecraftConfig
import xyz.wagyourtail.unimined.internal.minecraft.MinecraftProvider
import xyz.wagyourtail.unimined.internal.minecraft.patch.MinecraftJar
import xyz.wagyourtail.unimined.internal.minecraft.patch.jarmod.JarModAgentMinecraftTransformer
import xyz.wagyourtail.unimined.internal.minecraft.patch.jarmod.JarModMinecraftTransformer
import xyz.wagyourtail.unimined.util.withSourceSet

fun MinecraftConfig.patchBase(action: PatchBaseMinecraftTransformer.() -> Unit = {}) {
customPatcher(PatchBaseMinecraftTransformer(this.project, this as MinecraftProvider), action)
}

class PatchBaseMinecraftTransformer(project: Project, provider: MinecraftProvider) : JarModAgentMinecraftTransformer(project, provider) {
val patchBase = project.configurations.maybeCreate("patchBase".withSourceSet(provider.sourceSet))

override fun transform(minecraft: MinecraftJar): MinecraftJar {
val patchDep = patchBase.dependencies.last()
val patchJar = patchBase.files(patchDep).first { it.extension == "jar" || it.extension == "zip" }
val outputFolder = minecraft.path.parent.resolve(patchDep.name).resolve(patchDep.version)

val patchedMC = MinecraftJar(
minecraft,
parentPath = outputFolder,
patches = minecraft.patches + "patchbase"
)

PatchbaseInstaller().patch(patchJar.toPath(), minecraft.path, patchedMC.path)

return super.transform(patchedMC)
}

}
Loading

0 comments on commit 723501f

Please sign in to comment.