Document Gradle and Paper workflow
This commit is contained in:
21
.env.example
21
.env.example
@@ -1,9 +1,24 @@
|
|||||||
# Dev-server config for this project's tools/ scripts.
|
# Configuration for tools/*.sh. Values are read as KEY=value data, not executed.
|
||||||
# Plain KEY=value only (no shell expansion). Environment variables take precedence.
|
# Unquoted values may contain spaces; matching outer quotes are removed.
|
||||||
|
|
||||||
|
# Paper server
|
||||||
PAPER_VERSION=26.2
|
PAPER_VERSION=26.2
|
||||||
PAPER_BUILD=129
|
PAPER_BUILD=129
|
||||||
|
PAPER_USER_AGENT="majinnaibu-plugin-dev/1.0 (https://github.com/majinnaibu)"
|
||||||
|
JAVA_OPTS="-Xms2G -Xmx2G"
|
||||||
|
STOP_TIMEOUT=60
|
||||||
MINECRAFT_SERVER_JAR=paper-26.2-129.jar
|
MINECRAFT_SERVER_JAR=paper-26.2-129.jar
|
||||||
# Relative paths are resolved from this directory; ~/ is expanded.
|
# Relative paths are resolved from the project root; ~/ is expanded.
|
||||||
MINECRAFT_SERVER_PATH=./server
|
MINECRAFT_SERVER_PATH=./server
|
||||||
MINECRAFT_BACKUP_PATH=./backups
|
MINECRAFT_BACKUP_PATH=./backups
|
||||||
|
|
||||||
|
# Modrinth publishing
|
||||||
|
# Release version is read from Gradle's Git-sensitive semantic version and checked against the jar's plugin.yml.
|
||||||
|
MODRINTH_TOKEN=
|
||||||
|
MODRINTH_PROJECT_ID=metropolis-builder
|
||||||
|
MODRINTH_CHANGELOG=
|
||||||
|
MODRINTH_GAME_VERSIONS=26.2
|
||||||
|
MODRINTH_LOADERS=paper
|
||||||
|
MODRINTH_VERSION_TYPE=
|
||||||
|
MODRINTH_DEPENDENCIES=
|
||||||
|
MODRINTH_FILE=
|
||||||
|
|||||||
33
CONTRIBUTING.md
Normal file
33
CONTRIBUTING.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Contributing
|
||||||
|
|
||||||
|
## Development Setup
|
||||||
|
|
||||||
|
Use Java 25 or newer. The Gradle wrapper downloads Gradle 9.8; dependencies are declared in `build.gradle` and resolved from Maven Central, PaperMC, and EngineHub.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./gradlew build
|
||||||
|
```
|
||||||
|
|
||||||
|
The standard build runs JUnit 5 tests without starting Minecraft. Tests use Mockito for Bukkit and external-plugin boundaries. Keep domain and configuration behavior testable without a running server.
|
||||||
|
|
||||||
|
## Live Server Tests
|
||||||
|
|
||||||
|
Live tests are opt-in and run separately from `build`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
METROPOLIS_RCON_HOST=127.0.0.1 \
|
||||||
|
METROPOLIS_RCON_PORT=25575 \
|
||||||
|
METROPOLIS_RCON_PASSWORD=... \
|
||||||
|
METROPOLIS_SERVER_DIR=/path/to/server \
|
||||||
|
./gradlew integrationTest
|
||||||
|
```
|
||||||
|
|
||||||
|
Use a disposable or backed-up Paper server with compatible WorldGuard and WorldEdit plugin jars installed. Keep RCON local, use a temporary password, and restore the server after tests that modify regions or worlds.
|
||||||
|
|
||||||
|
## Pull Requests
|
||||||
|
|
||||||
|
- Keep changes focused and include tests for behavior changes.
|
||||||
|
- Run `./gradlew build` before submitting.
|
||||||
|
- Run `integrationTest` only when changing behavior that requires Paper or the external plugins; do not add it to the default build.
|
||||||
|
- Update `README.md` and project descriptions when user-facing setup, commands, or dependencies change.
|
||||||
|
- Keep generated build output, server data, credentials, and local `.env` files out of commits.
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"id": "metropolis",
|
"id": "metropolis",
|
||||||
"title": "Metropolis",
|
"title": "Metropolis",
|
||||||
"description": "Legacy Bukkit plugin that automatically creates protected home plots and roads as players join a Minecraft server.",
|
"description": "Paper plugin that automatically creates protected home plots and connecting roads as players join a Minecraft server.",
|
||||||
"docId": "Metropolis",
|
"docId": "Metropolis",
|
||||||
"image": {
|
"image": {
|
||||||
"url": "Pixel-art aerial view of a growing Minecraft city planned in a square grid, small player home plots connected by pale roads, a protected central spawn, blocky green landscape, subtle WorldGuard-inspired boundary lines, warm daylight, clean game-plugin thumbnail composition, no words or logos.",
|
"url": "Pixel-art aerial view of a growing Minecraft city planned in a square grid, small player home plots connected by pale roads, a protected central spawn, blocky green landscape, subtle WorldGuard-inspired boundary lines, warm daylight, clean game-plugin thumbnail composition, no words or logos.",
|
||||||
|
|||||||
@@ -1,18 +1,12 @@
|
|||||||
# Metropolis
|
# Metropolis
|
||||||
|
|
||||||
Metropolis is a legacy Bukkit plugin that automatically expands a protected Minecraft city as players join the server. Each player receives a home plot surrounded by roads and positioned beside the existing city, with WorldGuard regions protecting the city and individual homes.
|
Metropolis is a Paper plugin that expands a protected Minecraft city as players join. It generates home plots and connecting roads, uses WorldGuard to protect the city and homes, and supports reserved plots and home teleportation.
|
||||||
|
|
||||||
## Details
|
## Platform
|
||||||
|
|
||||||
- Platform: Bukkit/Minecraft server plugin
|
- Paper 26.2, Java 25+
|
||||||
- Language: Java
|
- WorldGuard 7.0.19 and WorldEdit 7.4.5
|
||||||
- Bukkit API: 1.7.9-R0.2
|
- Built with Gradle 9.8 and Git-sensitive semantic versioning
|
||||||
- Dependencies: WorldGuard 5.9 and WorldEdit 5.6.3
|
|
||||||
- Features: automatic home plots, road and plot generation, WorldGuard region management, reserved plots, home teleportation, and configurable plot and road materials
|
|
||||||
- Configuration: `plugins/Metropolis/config.yml`
|
- Configuration: `plugins/Metropolis/config.yml`
|
||||||
- Source: https://github.com/headhunter45/Metropolis
|
- Unit tests run without a server; live integration tests use the separate Gradle `integrationTest` task.
|
||||||
- License: GNU General Public License v3
|
- License: GNU General Public License v3
|
||||||
|
|
||||||
## Image prompt
|
|
||||||
|
|
||||||
Pixel-art aerial view of a growing Minecraft city planned in a square grid, small player home plots connected by pale roads, a protected central spawn, blocky green landscape, subtle WorldGuard-inspired boundary lines, warm daylight, clean game-plugin thumbnail composition, no words or logos.
|
|
||||||
114
README.md
114
README.md
@@ -1,47 +1,67 @@
|
|||||||
Metropolis generates a home for each user connecting to your world with roads between them. As new users connect the city expands.
|
# Metropolis
|
||||||
|
|
||||||
WorldGuard regions are used for each home and for the city as a whole.
|
Metropolis expands a protected Minecraft city as players join. Each player can receive a home plot connected by generated roads; WorldGuard protects the city, homes, and reserved plots.
|
||||||
|
|
||||||
One region called "City" is created to protect the spawn and roads. As the assigned blocks expand this region is automatically updated.
|
## Requirements
|
||||||
|
|
||||||
Each user gets assigned a home region named "h_username" where username is replaced with their username. This region is surrounded by a road and located next to an existing region.
|
- Paper 26.2, with Java 25 or newer
|
||||||
|
- WorldGuard 7.0.19
|
||||||
After creation these regions can be modified as normal via WorldGuard commands.
|
- WorldEdit 7.4.5
|
||||||
|
|
||||||
INSTALL:
|
WorldGuard and WorldEdit are required plugin dependencies. Install them alongside Metropolis in the server's `plugins` directory.
|
||||||
To install just drop the jar into your plugins folder. All necessarry data will be created on first launch.
|
|
||||||
|
## Build and Test
|
||||||
CONFIG:
|
|
||||||
Edit the config.yml file. You can set the height to clear above roads, the road width, the plot size (incluing half the road width on either side), the road material, and the level at which the road is generated.
|
Build the plugin and run the server-free unit tests:
|
||||||
|
|
||||||
Changelog:
|
```sh
|
||||||
v0.5
|
./gradlew clean build
|
||||||
Added example docs
|
```
|
||||||
Added Commands to plugin.yml to move and evict homes
|
|
||||||
Added floor and road supports to config file and generation
|
The plugin jar is written to `build/libs/`. The Gradle wrapper uses Gradle 9.8, and Git-sensitive semantic versioning derives the artifact and `plugin.yml` versions from repository tags and commits.
|
||||||
v0.4.6
|
|
||||||
Added optional generation of a sign identifying owner in plots on creation
|
Run the opt-in live-server tests against a running Paper server with WorldGuard, WorldEdit, and RCON enabled:
|
||||||
Added a Cuboid constructor that takes a worldedit selection
|
|
||||||
Added a debug mode that enables extra logging. MetropolisPlugin.DEBUG should be true for snapshots and false for release builds.
|
```sh
|
||||||
Added an occupied Plots list to MetropolisPlugin to keep track of both player homes and reserved plots.
|
METROPOLIS_RCON_HOST=127.0.0.1 \
|
||||||
Added the Plot class as a parent of PlayerHome and moved relevant code to it.
|
METROPOLIS_RCON_PORT=25575 \
|
||||||
Added a command to reserve plots that aren't tied to a player. This can be used to setup a larger protected area around spawn
|
METROPOLIS_RCON_PASSWORD=... \
|
||||||
v0.4.5
|
METROPOLIS_SERVER_DIR=/path/to/server \
|
||||||
v0.4.4
|
./gradlew integrationTest
|
||||||
Added a welcome message telling players where their home is.
|
```
|
||||||
Switched from PlayerLoginEvent to PlayerJoinEvent
|
|
||||||
v0.4.3
|
`integrationTest` is separate from the normal `test` and `build` tasks. Keep RCON bound to a trusted interface and do not commit its password.
|
||||||
Removed call to saveconfig on plugin unload.
|
|
||||||
v0.4.2
|
## Server Scripts
|
||||||
Made city region refresh on server restart.
|
|
||||||
v0.4.1
|
Copy `.env.example` to `.env` and configure the Paper version/build and server paths. The scripts read `.env` as key/value data.
|
||||||
v0.4
|
|
||||||
v0.3
|
- `tools/build-plugin.sh` builds and tests the plugin.
|
||||||
Added command to generate a home for a user that is not currently logged in.
|
- `tools/deploy-plugin.sh` copies the Gradle-built jar to the configured server.
|
||||||
v0.2.1
|
- `tools/start-server.sh` downloads the configured Paper build if needed and starts it.
|
||||||
Made config file save on load and disable.
|
- `tools/backup-server.sh` and `tools/restore-server.sh` back up or restore the configured server.
|
||||||
v0.2
|
- `tools/publish-local.sh` publishes the artifact to the local Maven repository.
|
||||||
Added configuration options.
|
- `tools/publish-modrinth.sh` uploads a built jar after checking its version.
|
||||||
|
|
||||||
v0.1
|
## Configuration
|
||||||
Initial Release
|
|
||||||
|
The default configuration is in `src/main/resources/config.yml` and is copied to `plugins/Metropolis/config.yml` on first startup. Materials use Bukkit names; the previous numeric IDs for stone, grass, cobblestone, and bedrock are still accepted when loading a configuration.
|
||||||
|
|
||||||
|
Player home ownership and selected-home data use UUIDs. Existing name-keyed `currentHomes.yml` entries and name-based WorldGuard home regions are recognized during migration.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
- `/metropolis` displays the plugin version.
|
||||||
|
- `/metropolis-home-acquire` acquires an available home plot.
|
||||||
|
- `/metropolis-home-generate <player>` generates a home for a known online or cached offline player.
|
||||||
|
- `/metropolis-home-list` lists Metropolis plots.
|
||||||
|
- `/metropolis-home-go [player]` teleports to a home.
|
||||||
|
- `/metropolis-home-move <home-number> [player]` changes a player's selected home.
|
||||||
|
- `/metropolis-home-evict <player>` removes a player's home ownership.
|
||||||
|
- `/metropolis-plot-reserve <name> <minX> <minY> <minZ> <maxX> <maxY> <maxZ>` reserves coordinates; a player may instead provide a WorldEdit selection.
|
||||||
|
- `/metropolis-plot-go <plot-name> [player]` teleports to a plot.
|
||||||
|
- `/metropolis-flag-reset` reapplies Metropolis protection flags.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
GNU General Public License v3.
|
||||||
2
TODO.md
2
TODO.md
@@ -22,7 +22,7 @@
|
|||||||
| MET-018 | Done | Build the plugin with Gradle and use the provided server scripts to smoke-test it on modern Paper with its required plugins installed. |
|
| MET-018 | Done | Build the plugin with Gradle and use the provided server scripts to smoke-test it on modern Paper with its required plugins installed. |
|
||||||
| MET-019 | Done | Address bugs and incompatibilities found by unit tests, integration tests, or modern Paper server testing. |
|
| MET-019 | Done | Address bugs and incompatibilities found by unit tests, integration tests, or modern Paper server testing. |
|
||||||
| MET-020 | Done | Adopt the git-sensitive semantic versioning Gradle plugin used by MobScores and ScoreKeeper, using the existing 0.5-SNAPSHOT version as the migration baseline; verify version/tag behavior and enable the Gradle configuration cache when compatible. |
|
| MET-020 | Done | Adopt the git-sensitive semantic versioning Gradle plugin used by MobScores and ScoreKeeper, using the existing 0.5-SNAPSHOT version as the migration baseline; verify version/tag behavior and enable the Gradle configuration cache when compatible. |
|
||||||
| MET-021 | Ready | Update README.md, CONTRIBUTING.md, other documentation, and project scripts with the Gradle build, test, versioning, and modern Paper server workflow. |
|
| MET-021 | Done | Update README.md, CONTRIBUTING.md, other documentation, and project scripts with the Gradle build, test, versioning, and modern Paper server workflow. |
|
||||||
| MET-022 | Planning | (Optional) Add new features, quality-of-life improvements, or CI configuration after the modernization and documentation tasks are complete. |
|
| MET-022 | Planning | (Optional) Add new features, quality-of-life improvements, or CI configuration after the modernization and documentation tasks are complete. |
|
||||||
| GIT-009 | Planning | i have three reserve plots and one just got overwritten when a new player joined. |
|
| GIT-009 | Planning | i have three reserve plots and one just got overwritten when a new player joined. |
|
||||||
| GIT-008 | Ready | Implement multiple plot sizes by granting multiple plots around each other.
|
| GIT-008 | Ready | Implement multiple plot sizes by granting multiple plots around each other.
|
||||||
|
|||||||
@@ -4,30 +4,99 @@ set -euo pipefail
|
|||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
|
||||||
# shellcheck source=setup-env.sh
|
if [[ ! -r "$PROJECT_ROOT/.env" ]]; then
|
||||||
source "$SCRIPT_DIR/setup-env.sh"
|
echo "Error: $PROJECT_ROOT/.env is missing or unreadable. Copy .env.example to .env and set its values." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
load_project_env() {
|
||||||
|
local env_line env_key env_value first_char last_char
|
||||||
|
while IFS= read -r env_line || [[ -n "$env_line" ]]; do
|
||||||
|
env_line="${env_line%$'\r'}"
|
||||||
|
[[ "$env_line" =~ ^[[:space:]]*(#|$) ]] && continue
|
||||||
|
[[ "$env_line" == *=* ]] || continue
|
||||||
|
|
||||||
|
env_key="${env_line%%=*}"
|
||||||
|
env_value="${env_line#*=}"
|
||||||
|
env_key="${env_key#"${env_key%%[![:space:]]*}"}"
|
||||||
|
env_key="${env_key%"${env_key##*[![:space:]]}"}"
|
||||||
|
[[ "$env_key" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]] || continue
|
||||||
|
env_value="${env_value#"${env_value%%[![:space:]]*}"}"
|
||||||
|
env_value="${env_value%"${env_value##*[![:space:]]}"}"
|
||||||
|
|
||||||
|
if (( ${#env_value} >= 2 )); then
|
||||||
|
first_char="${env_value:0:1}"
|
||||||
|
last_char="${env_value:$((${#env_value} - 1)):1}"
|
||||||
|
if [[ "$first_char" == "$last_char" && ( "$first_char" == '"' || "$first_char" == "'" ) ]]; then
|
||||||
|
env_value="${env_value:1:$((${#env_value} - 2))}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${!env_key:-}" ]]; then
|
||||||
|
export "$env_key=$env_value"
|
||||||
|
fi
|
||||||
|
done < "$PROJECT_ROOT/.env"
|
||||||
|
}
|
||||||
|
load_project_env
|
||||||
|
|
||||||
MODRINTH_TOKEN="${MODRINTH_TOKEN:-}"
|
MODRINTH_TOKEN="${MODRINTH_TOKEN:-}"
|
||||||
MODRINTH_PROJECT_ID="${MODRINTH_PROJECT_ID:-${MODRINTH_PROJECT_SLUG:-metropolis-builder}}"
|
MODRINTH_PROJECT_ID="${MODRINTH_PROJECT_ID:-metropolis-builder}"
|
||||||
MODRINTH_VERSION="${MODRINTH_VERSION:-${VERSION:-$(grep -E '<version>|<project>' pom.xml | head -n2 | tail -n1 | sed -E 's#.*<version>([^<]+)</version>.*#\1#')}}"
|
MODRINTH_VERSION="${MODRINTH_VERSION:-${VERSION:-}}"
|
||||||
|
if [[ -z "$MODRINTH_VERSION" ]]; then
|
||||||
|
MODRINTH_VERSION=$(cd "$PROJECT_ROOT" && ./gradlew -q properties --property version | sed -n 's/^version: //p' | head -n1)
|
||||||
|
fi
|
||||||
MODRINTH_CHANGELOG="${MODRINTH_CHANGELOG:-Auto release via publish-modrinth.sh}"
|
MODRINTH_CHANGELOG="${MODRINTH_CHANGELOG:-Auto release via publish-modrinth.sh}"
|
||||||
MODRINTH_GAME_VERSIONS="${MODRINTH_GAME_VERSIONS:-1.21,1.21.1,1.21.2,1.21.3,1.21.4,1.21.5,1.21.6,1.21.7}"
|
MODRINTH_GAME_VERSIONS="${MODRINTH_GAME_VERSIONS:-26.2}"
|
||||||
MODRINTH_LOADERS="${MODRINTH_LOADERS:-paper}"
|
MODRINTH_LOADERS="${MODRINTH_LOADERS:-paper}"
|
||||||
|
MODRINTH_VERSION_TYPE="${MODRINTH_VERSION_TYPE:-}"
|
||||||
MODRINTH_FILE="${MODRINTH_FILE:-}"
|
MODRINTH_FILE="${MODRINTH_FILE:-}"
|
||||||
MODRINTH_DEPENDENCIES="${MODRINTH_DEPENDENCIES:-}"
|
MODRINTH_DEPENDENCIES="${MODRINTH_DEPENDENCIES:-}"
|
||||||
|
|
||||||
|
if [[ -z "$MODRINTH_VERSION" ]]; then
|
||||||
|
echo "Error: could not determine the project version from Gradle." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ -z "$MODRINTH_VERSION_TYPE" ]]; then
|
||||||
|
if [[ "$MODRINTH_VERSION" == *-* ]]; then
|
||||||
|
MODRINTH_VERSION_TYPE="beta"
|
||||||
|
else
|
||||||
|
MODRINTH_VERSION_TYPE="release"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
case "$MODRINTH_VERSION_TYPE" in
|
||||||
|
release|beta|alpha) ;;
|
||||||
|
*) echo "Error: MODRINTH_VERSION_TYPE must be release, beta, or alpha." >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
MODRINTH_VERSION_NAME="Metropolis $MODRINTH_VERSION"
|
||||||
|
|
||||||
|
if [[ -n "$MODRINTH_FILE" && "$MODRINTH_FILE" != /* ]]; then
|
||||||
|
MODRINTH_FILE="$PROJECT_ROOT/$MODRINTH_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -z "$MODRINTH_TOKEN" ]]; then
|
if [[ -z "$MODRINTH_TOKEN" ]]; then
|
||||||
echo "Error: MODRINTH_TOKEN is not set in $PROJECT_ROOT/.env" >&2
|
echo "Error: MODRINTH_TOKEN is not set in $PROJECT_ROOT/.env" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z "$MODRINTH_FILE" ]]; then
|
if [[ -z "$MODRINTH_FILE" ]]; then
|
||||||
MODRINTH_FILE=$(find "$PROJECT_ROOT/target" -maxdepth 1 -type f -name '*.jar' ! -name '*-sources.jar' ! -name '*-javadoc.jar' | head -n1 || true)
|
MODRINTH_FILE="$PROJECT_ROOT/build/libs/Metropolis-$MODRINTH_VERSION.jar"
|
||||||
fi
|
fi
|
||||||
if [[ -z "$MODRINTH_FILE" || ! -f "$MODRINTH_FILE" ]]; then
|
if [[ -z "$MODRINTH_FILE" || ! -f "$MODRINTH_FILE" ]]; then
|
||||||
echo "Error: no jar found for Modrinth upload. Build the project first or set MODRINTH_FILE." >&2
|
echo "Error: no jar found for Modrinth upload. Build the project first or set MODRINTH_FILE." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
if ! command -v unzip >/dev/null; then
|
||||||
|
echo "Error: 'unzip' is required to verify the plugin version in the jar." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
JAR_VERSION=$(unzip -p "$MODRINTH_FILE" plugin.yml 2>/dev/null | sed -n 's/^version: //p' | tr -d "'\"" | head -n1 || true)
|
||||||
|
if [[ -z "$JAR_VERSION" ]]; then
|
||||||
|
echo "Error: could not read the plugin version from $MODRINTH_FILE." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ "$JAR_VERSION" != "$MODRINTH_VERSION" ]]; then
|
||||||
|
echo "Error: jar version $JAR_VERSION does not match Gradle version $MODRINTH_VERSION. Rebuild the plugin and retry." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
csv_to_json_array() {
|
csv_to_json_array() {
|
||||||
jq -cn --arg csv "$1" '$csv | split(",") | map(gsub("^\\s+|\\s+$"; "")) | map(select(length > 0))'
|
jq -cn --arg csv "$1" '$csv | split(",") | map(gsub("^\\s+|\\s+$"; "")) | map(select(length > 0))'
|
||||||
@@ -36,19 +105,41 @@ MODRINTH_GAME_VERSIONS_JSON=$(csv_to_json_array "$MODRINTH_GAME_VERSIONS")
|
|||||||
MODRINTH_LOADERS_JSON=$(csv_to_json_array "$MODRINTH_LOADERS")
|
MODRINTH_LOADERS_JSON=$(csv_to_json_array "$MODRINTH_LOADERS")
|
||||||
|
|
||||||
if [[ -n "$MODRINTH_DEPENDENCIES" ]]; then
|
if [[ -n "$MODRINTH_DEPENDENCIES" ]]; then
|
||||||
MODRINTH_DEPENDENCIES_ARG=(--form "dependencies=$MODRINTH_DEPENDENCIES")
|
if ! MODRINTH_DEPENDENCIES_JSON=$(jq -ce 'if type == "array" then . else error("dependencies must be a JSON array") end' <<<"$MODRINTH_DEPENDENCIES"); then
|
||||||
|
echo "Error: MODRINTH_DEPENDENCIES must be a JSON array." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
MODRINTH_DEPENDENCIES_ARG=()
|
MODRINTH_DEPENDENCIES_JSON='[]'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
curl -fsSL \
|
MODRINTH_DATA=$(jq -cn \
|
||||||
-X POST "https://api.modrinth.com/v2/version" \
|
--arg project_id "$MODRINTH_PROJECT_ID" \
|
||||||
-H "Authorization: $MODRINTH_TOKEN" \
|
--arg name "$MODRINTH_VERSION_NAME" \
|
||||||
-F "project_id=$MODRINTH_PROJECT_ID" \
|
--arg version_number "$MODRINTH_VERSION" \
|
||||||
-F "version_number=$MODRINTH_VERSION" \
|
--arg version_type "$MODRINTH_VERSION_TYPE" \
|
||||||
-F "changelog=$MODRINTH_CHANGELOG" \
|
--arg changelog "$MODRINTH_CHANGELOG" \
|
||||||
-F "game_versions=${MODRINTH_GAME_VERSIONS_JSON}" \
|
--argjson featured false \
|
||||||
-F "loaders=${MODRINTH_LOADERS_JSON}" \
|
--argjson dependencies "$MODRINTH_DEPENDENCIES_JSON" \
|
||||||
-F "file=@$MODRINTH_FILE" \
|
--argjson game_versions "$MODRINTH_GAME_VERSIONS_JSON" \
|
||||||
"${MODRINTH_DEPENDENCIES_ARG[@]}" \
|
--argjson loaders "$MODRINTH_LOADERS_JSON" \
|
||||||
| jq .
|
'{project_id: $project_id, name: $name, version_number: $version_number, version_type: $version_type, featured: $featured, changelog: $changelog, dependencies: $dependencies, game_versions: $game_versions, loaders: $loaders, file_parts: ["file"], primary_file: "file"}')
|
||||||
|
|
||||||
|
CURL_ARGS=(
|
||||||
|
-X POST "https://api.modrinth.com/v2/version"
|
||||||
|
-H "Authorization: $MODRINTH_TOKEN"
|
||||||
|
-F "data=$MODRINTH_DATA;type=application/json"
|
||||||
|
-F "file=@$MODRINTH_FILE"
|
||||||
|
)
|
||||||
|
|
||||||
|
HTTP_RESPONSE=$(curl -sS -w $'\n%{http_code}' "${CURL_ARGS[@]}")
|
||||||
|
HTTP_STATUS="${HTTP_RESPONSE##*$'\n'}"
|
||||||
|
HTTP_BODY="${HTTP_RESPONSE%$'\n'*}"
|
||||||
|
if [[ "$HTTP_STATUS" != 2?? ]]; then
|
||||||
|
echo "Error: Modrinth API returned HTTP $HTTP_STATUS:" >&2
|
||||||
|
if ! printf '%s\n' "$HTTP_BODY" | jq -r '.description // .error // .' >&2; then
|
||||||
|
printf '%s\n' "$HTTP_BODY" >&2
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
printf '%s\n' "$HTTP_BODY" | jq .
|
||||||
|
|||||||
Reference in New Issue
Block a user