diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 65fd529..cfbee71 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,8 +1,12 @@ name: Build Plugin +permissions: + contents: write + on: push: branches: [ main, develop ] + tags: [ 'v*' ] pull_request: branches: [ main ] @@ -11,62 +15,62 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Setup Java 25 - uses: actions/setup-java@v4 - with: - java-version: '25' - distribution: 'temurin' - - - name: Cache Gradle Dependencies - uses: actions/cache@v4 - with: - path: ~/.gradle - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - - name: Grant Execute Permission for Gradlew - run: chmod +x gradlew - - - name: Build with Gradle - run: ./gradlew shadowJar - - - name: Run Tests - run: ./gradlew test - - - name: Upload Artifact - uses: actions/upload-artifact@v4 - with: - name: plugin-jar - path: build/libs/*.jar - + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Java 25 + uses: actions/setup-java@v4 + with: + java-version: '25' + distribution: 'temurin' + + - name: Cache Gradle Dependencies + uses: actions/cache@v4 + with: + path: ~/.gradle + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Grant Execute Permission for Gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew shadowJar + + - name: Run Tests + run: ./gradlew test + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: plugin-jar + path: build/libs/*.jar + release: needs: build runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Setup Java 25 - uses: actions/setup-java@v4 - with: - java-version: '25' - distribution: 'temurin' - - - name: Grant Execute Permission for Gradlew - run: chmod +x gradlew - - - name: Build with Gradle - run: ./gradlew shadowJar - - - name: Create Release - uses: softprops/action-gh-release@v1 - with: - files: build/libs/*.jar - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Java 25 + uses: actions/setup-java@v4 + with: + java-version: '25' + distribution: 'temurin' + + - name: Grant Execute Permission for Gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew shadowJar + + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + files: build/libs/*.jar + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/build.gradle b/build.gradle index 8df6db3..1356cdf 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java' id 'org.jetbrains.gradle.plugin.idea-ext' version '1.3' + id 'com.gradleup.shadow' version '9.3.1' } import org.gradle.internal.os.OperatingSystem @@ -26,11 +27,10 @@ ext { } } -if (!project.hasProperty('hytaleHome')) { - throw new GradleException('Your Hytale install could not be detected automatically. If you are on an unsupported platform or using a custom install location, please define the install location using the hytale_home property.'); -} -else if (!file(project.findProperty('hytaleHome')).exists()) { - throw new GradleException("Failed to find Hytale at the expected location. Please make sure you have installed the game. The expected location can be changed using the hytale_home property. Currently looking in ${project.findProperty('hytaleHome')}") +def hytaleHomePath = project.findProperty('hytaleHome') +def hasHytaleHome = hytaleHomePath && file(hytaleHomePath).exists() +if (!hasHytaleHome) { + logger.lifecycle("Hytale install not detected; run configs that launch the server will be skipped. Set -Phytale_home=/path/to/Hytale to enable them.") } java { @@ -45,16 +45,27 @@ javadoc { } // Adds the Hytale server as a build dependency, allowing you to reference and -// compile against their code. This requires you to have Hytale installed using -// the official launcher for now. +// compile against their code without bundling it. When a local install is +// present, we still use its jar for launching the server in IDE run configs. dependencies { - implementation(files("$hytaleHome/install/$patchline/package/game/latest/Server/HytaleServer.jar")) + compileOnly("com.hypixel.hytale:Server:$hytale_build") + if (hasHytaleHome) { + runtimeOnly(files("$hytaleHome/install/$patchline/package/game/latest/Server/HytaleServer.jar")) + } + + // Your dependencies here } -// Create the working directory to run the server if it does not already exist. -def serverRunDir = file("$projectDir/run") -if (!serverRunDir.exists()) { - serverRunDir.mkdirs() +repositories { + mavenCentral() + maven { + name = "hytale-release" + url = uri("https://maven.hytale.com/release") + } + maven { + name = "hytale-pre-release" + url = uri("https://maven.hytale.com/pre-release") + } } // Updates the manifest.json file with the latest properties defined in the @@ -78,54 +89,78 @@ tasks.named('processResources') { dependsOn 'updatePluginManifest' } -def createServerRunArguments(String srcDir) { - def programParameters = '--allow-op --disable-sentry --assets="' + "${hytaleHome}/install/$patchline/package/game/latest/Assets.zip" + '"' - def modPaths = [] - if (includes_pack.toBoolean()) { - modPaths << srcDir - } - if (load_user_mods.toBoolean()) { - modPaths << "${hytaleHome}/UserData/Mods" - } - if (!modPaths.isEmpty()) { - programParameters += ' --mods="' + modPaths.join(',') + '"' - } - return programParameters +tasks.named('shadowJar') { + archiveClassifier.set('') + mergeServiceFiles() } -// Creates a run configuration in IDEA that will run the Hytale server with -// your plugin and the default assets. -idea.project.settings.runConfigurations { - 'HytaleServer'(org.jetbrains.gradle.ext.Application) { - mainClass = 'com.hypixel.hytale.Main' - moduleName = project.idea.module.name + '.main' - programParameters = createServerRunArguments(sourceSets.main.java.srcDirs.first().parentFile.absolutePath) - workingDirectory = serverRunDir.absolutePath - } +// Ensure the shaded jar is produced during a normal build. +tasks.named('build') { + dependsOn 'shadowJar' } -// Creates a launch.json file for VSCode with the same configuration -tasks.register('generateVSCodeLaunch') { - def vscodeDir = file("$projectDir/.vscode") - def launchFile = file("$vscodeDir/launch.json") - doLast { - if (!vscodeDir.exists()) { - vscodeDir.mkdirs() +if (hasHytaleHome) { + // Create the working directory to run the server if it does not already exist. + def serverRunDir = file("$projectDir/run") + if (!serverRunDir.exists()) { + serverRunDir.mkdirs() + } + + def createServerRunArguments = { String srcDir -> + def programParameters = '--allow-op --disable-sentry --assets="' + "${hytaleHome}/install/$patchline/package/game/latest/Assets.zip" + '"' + def modPaths = [] + if (includes_pack.toBoolean()) { + modPaths << srcDir } - def programParams = createServerRunArguments("\${workspaceFolder}") - def launchConfig = [ - version: "0.2.0", - configurations: [ - [ - type: "java", - name: "HytaleServer", - request: "launch", - mainClass: "com.hypixel.hytale.Main", - args: programParams, - cwd: "\${workspaceFolder}/run" - ] + if (load_user_mods.toBoolean()) { + modPaths << "${hytaleHome}/UserData/Mods" + } + if (!modPaths.isEmpty()) { + programParameters += ' --mods="' + modPaths.join(',') + '"' + } + return programParameters + } + + // Creates a run configuration in IDEA that will run the Hytale server with + // your plugin and the default assets. + idea.project.settings.runConfigurations { + 'HytaleServer'(org.jetbrains.gradle.ext.Application) { + mainClass = 'com.hypixel.hytale.Main' + moduleName = project.idea.module.name + '.main' + programParameters = createServerRunArguments(sourceSets.main.java.srcDirs.first().parentFile.absolutePath) + workingDirectory = serverRunDir.absolutePath + } + } + + // Creates a launch.json file for VSCode with the same configuration + tasks.register('generateVSCodeLaunch') { + def vscodeDir = file("$projectDir/.vscode") + def launchFile = file("$vscodeDir/launch.json") + doLast { + if (!vscodeDir.exists()) { + vscodeDir.mkdirs() + } + def programParams = createServerRunArguments("\${workspaceFolder}") + def launchConfig = [ + version: "0.2.0", + configurations: [ + [ + type: "java", + name: "HytaleServer", + request: "launch", + mainClass: "com.hypixel.hytale.Main", + args: programParams, + cwd: "\${workspaceFolder}/run" + ] + ] ] - ] - launchFile.text = groovy.json.JsonOutput.prettyPrint(groovy.json.JsonOutput.toJson(launchConfig)) + launchFile.text = groovy.json.JsonOutput.prettyPrint(groovy.json.JsonOutput.toJson(launchConfig)) + } + } +} else { + tasks.register('generateVSCodeLaunch') { + doLast { + logger.lifecycle("Skipped VSCode launch configuration because hytale_home is not set or the install path is missing.") + } } } diff --git a/gradle.properties b/gradle.properties index e0e99eb..ba33300 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,6 +19,11 @@ includes_pack=true # official launcher. patchline=release +# The exact Hytale build to compile against. Use the build string from the +# launcher (format YYYY.MM.DD-) so Gradle pulls the matching server jar +# for your selected patchline. +hytale_build=2026.01.27-734d39026 + # Determines if the development server should also load mods from the user's # standard mods folder. This lets you test mods by installing them where a # normal player would, instead of adding them as dependencies or adding them @@ -29,4 +34,4 @@ load_user_mods=false # manually. You may also want to use a custom path if you are building in # a non-standard environment like a build server. The home path should # the folder that contains the install and UserData folder. -# hytale_home=./test-file \ No newline at end of file +# hytale_home=./test-file