Compare commits
113 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cec41319d | ||
|
|
eb22d4cadc | ||
|
|
a0a046f9f6 | ||
|
|
9210044b8d | ||
|
|
df203d4b4b | ||
|
|
16a958d129 | ||
|
|
76628e8ccc | ||
|
|
e8f3fd2d71 | ||
|
|
fac72eac9d | ||
|
|
f4eac20ff8 | ||
|
|
e3a29180fd | ||
|
|
51f1a08f6e | ||
|
|
5a507f800f | ||
|
|
ab47b06ba9 | ||
|
|
7001f2bcba | ||
|
|
8d7a5275a8 | ||
|
|
30fa6d02c7 | ||
|
|
a18cf3348a | ||
|
|
a84cdaf355 | ||
|
|
23c8fc65a4 | ||
|
|
f8acb832f1 | ||
|
|
b6dbcbde02 | ||
|
|
f5f09302b2 | ||
|
|
512fa7fbd4 | ||
|
|
9458005b5b | ||
|
|
b1be888dd4 | ||
|
|
4f9de809f8 | ||
|
|
1fb04c069c | ||
|
|
fd2431046c | ||
|
|
19ee3f58f8 | ||
|
|
8d0bdb60f0 | ||
|
|
0f23414198 | ||
|
|
40ebddadff | ||
|
|
08556a63b8 | ||
|
|
ea7046f93d | ||
|
|
6768795594 | ||
|
|
e7236212d8 | ||
|
|
3e3abda71e | ||
|
|
f67d3948d2 | ||
|
|
bc3c3db080 | ||
|
|
691be801d8 | ||
|
|
56b9326c09 | ||
|
|
b6ea33dce1 | ||
|
|
367876e8b8 | ||
|
|
eb096142d6 | ||
|
|
9ccd5bdee7 | ||
|
|
dc05029ef5 | ||
|
|
926a3a5688 | ||
|
|
b27556e1eb | ||
|
|
64521f7a39 | ||
|
|
b4ca00bd3b | ||
|
|
bca7b79f77 | ||
|
|
2e0c8901a1 | ||
|
|
3e6ef1a605 | ||
|
|
d9a55ae938 | ||
|
|
7e843ea100 | ||
|
|
b241f74615 | ||
|
|
c5460941c4 | ||
|
|
890425a8b6 | ||
|
|
8c5c4664ea | ||
|
|
901b889f2d | ||
|
|
cf1dd9f9e1 | ||
|
|
8ef3fe199f | ||
|
|
97fe6b1f14 | ||
|
|
4af80debe2 | ||
|
|
513492192b | ||
|
|
e0b4a819b1 | ||
|
|
5c0cf11bfe | ||
|
|
63a884ea75 | ||
|
|
7c7090a582 | ||
|
|
fc70a976bd | ||
|
|
0de90b134c | ||
|
|
6eca74698b | ||
|
|
7c85f0926c | ||
|
|
4ff158266a | ||
|
|
fda8981028 | ||
|
|
7f44a04490 | ||
|
|
818ab46b73 | ||
|
|
5ae5733741 | ||
|
|
2042450f9b | ||
|
|
676b0f88cf | ||
|
|
65d6c5bb32 | ||
|
|
5168698498 | ||
|
|
f512b9510c | ||
|
|
ba71a7f5a2 | ||
|
|
1ebe9d3f47 | ||
|
|
d9bddabbf8 | ||
|
|
3c3aea9c86 | ||
|
|
3806364197 | ||
|
|
e9d3512383 | ||
|
|
09cc5003cd | ||
|
|
1781ca282a | ||
|
|
ba08a5d8f1 | ||
|
|
b1e00b43be | ||
|
|
a2499a8713 | ||
|
|
07665d7571 | ||
|
|
4587b32480 | ||
|
|
15869fd774 | ||
|
|
2e24bdfff8 | ||
|
|
1f8a3d85d1 | ||
|
|
f359324bea | ||
|
|
e0ff1365cf | ||
|
|
b347a7d0bf | ||
|
|
977ac22df9 | ||
|
|
323d41603c | ||
|
|
8dadfecf28 | ||
|
|
5f1d7c6d31 | ||
|
|
7ba6ef9ad8 | ||
|
|
eb1170408f | ||
|
|
c50c9988fc | ||
|
|
d46384f68a | ||
|
|
b7f8239235 | ||
|
|
f31c57b897 |
19
.gitattributes
vendored
@@ -1,17 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=lf
|
||||
|
||||
3
.github/FUNDING.yml
vendored
@@ -1,5 +1,4 @@
|
||||
|
||||
#github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
github: itzg
|
||||
custom:
|
||||
- https://www.buymeacoffee.com/itzg
|
||||
- https://paypal.me/itzg
|
||||
|
||||
109
.github/workflows/build-multiarch.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Build and publish multiarch
|
||||
name: Test and Build multi-architecture
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@@ -10,6 +10,13 @@ on:
|
||||
- "*.md"
|
||||
- "docs/**"
|
||||
- "examples/**"
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
types: [assigned, opened, synchronize, labeled]
|
||||
paths-ignore:
|
||||
- "*.md"
|
||||
- "docs/**"
|
||||
- "examples/**"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -18,59 +25,88 @@ jobs:
|
||||
matrix:
|
||||
variant:
|
||||
- java17
|
||||
- java17-graalvm-ce
|
||||
- java17-jdk
|
||||
- java17-openj9
|
||||
- java17-alpine
|
||||
- java8
|
||||
- java8-graalvm-ce
|
||||
- java8-multiarch
|
||||
- java8-openj9
|
||||
- java8-jdk
|
||||
- java11
|
||||
- java11-openj9
|
||||
- java11-jdk
|
||||
include:
|
||||
# JAVA 17:
|
||||
- variant: java17
|
||||
baseImage: eclipse-temurin:17
|
||||
# jammy doesn't work until minecraft updates to https://github.com/netty/netty/issues/12343
|
||||
baseImage: eclipse-temurin:17-jre-focal
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
mcVersion: LATEST
|
||||
mcVersion: 1.18.2
|
||||
- variant: java17-graalvm-ce
|
||||
baseImage: ghcr.io/graalvm/graalvm-ce:ol8-java17
|
||||
platforms: linux/amd64,linux/arm64
|
||||
mcVersion: 1.18.2
|
||||
- variant: java17-jdk
|
||||
baseImage: eclipse-temurin:17-focal
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
mcVersion: 1.18.2
|
||||
- variant: java17-openj9
|
||||
baseImage: ibm-semeru-runtimes:open-17-jdk
|
||||
baseImage: ibm-semeru-runtimes:open-17-jre
|
||||
platforms: linux/amd64,linux/arm64
|
||||
mcVersion: LATEST
|
||||
mcVersion: 1.18.2
|
||||
- variant: java17-alpine
|
||||
baseImage: eclipse-temurin:17-jdk-alpine
|
||||
baseImage: eclipse-temurin:17-jre-alpine
|
||||
platforms: linux/amd64
|
||||
mcVersion: LATEST
|
||||
- variant: java8
|
||||
baseImage: openjdk:8-jdk-alpine3.8
|
||||
platforms: linux/amd64
|
||||
mcVersion: 1.12.2
|
||||
- variant: java8-multiarch
|
||||
baseImage: eclipse-temurin:8-jdk
|
||||
platforms: linux/amd64,linux/arm64
|
||||
mcVersion: 1.12.2
|
||||
- variant: java8-openj9
|
||||
baseImage: ibm-semeru-runtimes:open-8-jdk
|
||||
platforms: linux/amd64,linux/arm64
|
||||
mcVersion: 1.12.2
|
||||
mcVersion: 1.18.2
|
||||
# JAVA 11:
|
||||
- variant: java11
|
||||
baseImage: adoptopenjdk:11-jre-hotspot
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
mcVersion: 1.16.5
|
||||
- variant: java11-jdk
|
||||
baseImage: adoptopenjdk:11-jdk-hotspot
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
mcVersion: 1.16.5
|
||||
- variant: java11-openj9
|
||||
baseImage: ibm-semeru-runtimes:open-11-jdk
|
||||
baseImage: ibm-semeru-runtimes:open-11-jre
|
||||
platforms: linux/amd64,linux/arm64
|
||||
mcVersion: 1.16.5
|
||||
# JAVA 8: NOTE: Unable to go past 8u312 because of Forge dependencies
|
||||
- variant: java8
|
||||
baseImage: openjdk:8-jre-alpine3.9
|
||||
platforms: linux/amd64
|
||||
mcVersion: 1.12.2
|
||||
- variant: java8-graalvm-ce
|
||||
baseImage: ghcr.io/graalvm/graalvm-ce:java8
|
||||
platforms: linux/amd64
|
||||
mcVersion: 1.12.2
|
||||
- variant: java8-multiarch
|
||||
baseImage: eclipse-temurin:8u312-b07-jre-focal
|
||||
platforms: linux/amd64,linux/arm64
|
||||
mcVersion: 1.12.2
|
||||
- variant: java8-jdk
|
||||
baseImage: eclipse-temurin:8u312-b07-jdk-focal
|
||||
platforms: linux/amd64,linux/arm64
|
||||
mcVersion: 1.12.2
|
||||
- variant: java8-openj9
|
||||
baseImage: ibm-semeru-runtimes:open-8u312-b07-jre
|
||||
platforms: linux/amd64,linux/arm64
|
||||
mcVersion: 1.12.2
|
||||
env:
|
||||
IMAGE_TO_TEST: ${{ github.repository_owner }}/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }}
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2.4.0
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# for build-files step
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
# NOTE for forks: if your Docker Hub organization doesn't match your Github repo's,
|
||||
# then the use of ${{ github.repository_owner }} will need to be replaced.
|
||||
@@ -86,19 +122,13 @@ jobs:
|
||||
org.opencontainers.image.authors=Geoff Bourne <itzgeoff@gmail.com>
|
||||
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1.2.0
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USER }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
uses: docker/setup-qemu-action@v2.0.0
|
||||
|
||||
- name: Build for test
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
uses: docker/build-push-action@v3.0.0
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
tags: ${{ env.IMAGE_TO_TEST }}
|
||||
@@ -115,15 +145,28 @@ jobs:
|
||||
- name: Run tests
|
||||
env:
|
||||
MINECRAFT_VERSION: ${{ matrix.mcVersion }}
|
||||
VARIANT: ${{ matrix.variant }}
|
||||
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
|
||||
run: |
|
||||
tests/test.sh
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USER }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build and push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
uses: docker/build-push-action@v3.0.0
|
||||
with:
|
||||
platforms: ${{ matrix.platforms }}
|
||||
push: ${{ github.ref_type == 'tag' || github.ref_name == 'master' }}
|
||||
push: >
|
||||
${{
|
||||
github.ref_type == 'tag'
|
||||
|| github.ref_name == 'master'
|
||||
|| ( github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci/push-image') )
|
||||
}}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
# ensure latest base image is used
|
||||
pull: true
|
||||
|
||||
6
.github/workflows/ci.yml
vendored
@@ -21,13 +21,13 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
uses: docker/build-push-action@v3.0.0
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64
|
||||
|
||||
21
.github/workflows/generate-toc.yml
vendored
@@ -1,21 +0,0 @@
|
||||
name: Generate README table of contents
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- README.md
|
||||
jobs:
|
||||
generate:
|
||||
if: github.repository == 'itzg/docker-minecraft-server'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- run: |
|
||||
curl https://raw.githubusercontent.com/ekalinin/github-markdown-toc/master/gh-md-toc -o gh-md-toc
|
||||
chmod a+x gh-md-toc
|
||||
./gh-md-toc --insert --no-backup README.md
|
||||
- uses: stefanzweifel/git-auto-commit-action@v4.13.1
|
||||
with:
|
||||
commit_message: "docs: Auto update markdown TOC"
|
||||
64
.github/workflows/pr.yml
vendored
@@ -1,64 +0,0 @@
|
||||
name: PullRequest
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
types: [assigned, opened, synchronize, labeled]
|
||||
paths-ignore:
|
||||
- "*.md"
|
||||
- "docs/**"
|
||||
- "examples/**"
|
||||
|
||||
env:
|
||||
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
|
||||
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64
|
||||
tags: ${{ env.IMAGE_TO_TEST }}
|
||||
load: true
|
||||
cache-from: type=gha
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
tests/test.sh
|
||||
|
||||
- name: Gather Docker metadata
|
||||
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: |
|
||||
itzg/minecraft-server
|
||||
|
||||
- name: Login to DockerHub
|
||||
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USER }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Push
|
||||
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
pull: true
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
2
.github/workflows/stale-check.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Process Stale Issues
|
||||
uses: actions/stale@v4.1.0
|
||||
uses: actions/stale@v5
|
||||
with:
|
||||
stale-issue-label: status/stale
|
||||
stale-pr-label: status/stale
|
||||
|
||||
1
.gitignore
vendored
@@ -3,3 +3,4 @@
|
||||
/.idea/
|
||||
*.iml
|
||||
/gh-md-toc
|
||||
personal-build-and-develop.*
|
||||
|
||||
@@ -23,10 +23,17 @@ $env:IMAGE_TO_TEST="mc-dev"
|
||||
docker build -t $env:IMAGE_TO_TEST .
|
||||
pushd "tests/setuponlytests/$env:FOLDER_TO_TEST/"
|
||||
docker-compose run mc
|
||||
docker-compose down --remove-orphans
|
||||
docker-compose down -v --remove-orphans
|
||||
popd
|
||||
```
|
||||
|
||||
PowerShell: Building different images of Java for testing
|
||||
```powershell
|
||||
$env:BASE_IMAGE='eclipse-temurin:8u312-b07-jre'
|
||||
$env:IMAGE_TO_TEST="mc-dev"
|
||||
docker build --build-arg BASE_IMAGE=$env:BASE_IMAGE -t $env:IMAGE_TO_TEST .
|
||||
```
|
||||
|
||||
Bash: (Example of building and testing ForgeAPI)
|
||||
```bash
|
||||
export MODS_FORGEAPI_KEY='$2a$...'
|
||||
@@ -35,7 +42,7 @@ export IMAGE_TO_TEST="mc-dev"
|
||||
docker build -t $IMAGE_TO_TEST .
|
||||
pushd tests/setuponlytests/$FOLDER_TO_TEST/
|
||||
docker-compose run mc
|
||||
docker-compose down --remove-orphans
|
||||
docker-compose down -v --remove-orphans
|
||||
popd
|
||||
```
|
||||
|
||||
@@ -71,7 +78,7 @@ In the cloned copy of [`mc-image-helper`](https://github.com/itzg/mc-image-helpe
|
||||
Assuming [http-server](https://www.npmjs.com/package/http-server) is installed globally, start a static web server using:
|
||||
|
||||
```shell
|
||||
http-server ./build/distributions -p 0
|
||||
http-server ./build/distributions -p 8080
|
||||
```
|
||||
|
||||
Note the port that was selected by http-server and pass the build arguments, such as:
|
||||
@@ -81,7 +88,7 @@ Note the port that was selected by http-server and pass the build arguments, suc
|
||||
--build-arg MC_HELPER_BASE_URL=http://host.docker.internal:8080
|
||||
```
|
||||
|
||||
Now the image can be built like normal and it will install mc-image-helper from the locally built copy.
|
||||
Now the image can be built like normal, and it will install mc-image-helper from the locally built copy.
|
||||
|
||||
## Generating release notes
|
||||
|
||||
|
||||
154
Dockerfile
@@ -1,79 +1,75 @@
|
||||
# syntax = docker/dockerfile:1.3
|
||||
|
||||
ARG BASE_IMAGE=eclipse-temurin:17-jdk
|
||||
FROM ${BASE_IMAGE}
|
||||
|
||||
# CI system should set this to a hash or git revision of the build directory and it's contents to
|
||||
# ensure consistent cache updates.
|
||||
ARG BUILD_FILES_REV=1
|
||||
RUN --mount=target=/build,source=build \
|
||||
REV=${BUILD_FILES_REV} /build/run.sh install-packages
|
||||
|
||||
RUN --mount=target=/build,source=build \
|
||||
REV=${BUILD_FILES_REV} /build/run.sh setup-user
|
||||
|
||||
COPY --chmod=644 files/sudoers* /etc/sudoers.d
|
||||
|
||||
EXPOSE 25565 25575
|
||||
|
||||
# hook into docker BuildKit --platform support
|
||||
# see https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
ARG TARGETVARIANT
|
||||
|
||||
ARG EASY_ADD_VER=0.7.1
|
||||
ADD https://github.com/itzg/easy-add/releases/download/${EASY_ADD_VER}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add
|
||||
RUN chmod +x /usr/bin/easy-add
|
||||
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=1.2.0 --var app=restify --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=1.5.1 --var app=rcon-cli --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=0.10.3 --var app=mc-monitor --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=1.8.0 --var app=mc-server-runner --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=0.1.1 --var app=maven-metadata-release --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
ARG MC_HELPER_VERSION=1.16.6
|
||||
ARG MC_HELPER_BASE_URL=https://github.com/itzg/mc-image-helper/releases/download/v${MC_HELPER_VERSION}
|
||||
RUN curl -fsSL ${MC_HELPER_BASE_URL}/mc-image-helper-${MC_HELPER_VERSION}.tgz \
|
||||
| tar -C /usr/share -zxf - \
|
||||
&& ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/bin/mc-image-helper /usr/bin
|
||||
|
||||
VOLUME ["/data"]
|
||||
WORKDIR /data
|
||||
|
||||
STOPSIGNAL SIGTERM
|
||||
|
||||
ENV UID=1000 GID=1000 \
|
||||
MEMORY="1G" \
|
||||
TYPE=VANILLA VERSION=LATEST \
|
||||
ENABLE_RCON=true RCON_PORT=25575 RCON_PASSWORD=minecraft \
|
||||
ENABLE_AUTOPAUSE=false AUTOPAUSE_TIMEOUT_EST=3600 AUTOPAUSE_TIMEOUT_KN=120 AUTOPAUSE_TIMEOUT_INIT=600 \
|
||||
AUTOPAUSE_PERIOD=10 AUTOPAUSE_KNOCK_INTERFACE=eth0 \
|
||||
ENABLE_AUTOSTOP=false AUTOSTOP_TIMEOUT_EST=3600 AUTOSTOP_TIMEOUT_INIT=1800 AUTOSTOP_PERIOD=10
|
||||
|
||||
COPY --chmod=755 scripts/start* /
|
||||
COPY --chmod=755 bin/ /usr/local/bin/
|
||||
COPY --chmod=755 bin/mc-health /health.sh
|
||||
COPY --chmod=644 files/server.properties /tmp/server.properties
|
||||
COPY --chmod=644 files/log4j2.xml /tmp/log4j2.xml
|
||||
COPY --chmod=755 files/autopause /autopause
|
||||
COPY --chmod=755 files/autostop /autostop
|
||||
|
||||
RUN dos2unix /start* /autopause/* /autostop/*
|
||||
|
||||
ENTRYPOINT [ "/start" ]
|
||||
HEALTHCHECK --start-period=1m CMD mc-health
|
||||
# syntax = docker/dockerfile:1.3
|
||||
|
||||
ARG BASE_IMAGE=eclipse-temurin:17-jre-focal
|
||||
FROM ${BASE_IMAGE}
|
||||
|
||||
# CI system should set this to a hash or git revision of the build directory and it's contents to
|
||||
# ensure consistent cache updates.
|
||||
ARG BUILD_FILES_REV=1
|
||||
RUN --mount=target=/build,source=build \
|
||||
REV=${BUILD_FILES_REV} /build/run.sh install-packages
|
||||
|
||||
RUN --mount=target=/build,source=build \
|
||||
REV=${BUILD_FILES_REV} /build/run.sh setup-user
|
||||
|
||||
COPY --chmod=644 files/sudoers* /etc/sudoers.d
|
||||
|
||||
EXPOSE 25565 25575
|
||||
|
||||
# hook into docker BuildKit --platform support
|
||||
# see https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
ARG TARGETVARIANT
|
||||
|
||||
ARG EASY_ADD_VER=0.7.1
|
||||
ADD https://github.com/itzg/easy-add/releases/download/${EASY_ADD_VER}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add
|
||||
RUN chmod +x /usr/bin/easy-add
|
||||
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=1.2.0 --var app=restify --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=1.6.0 --var app=rcon-cli --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=0.10.3 --var app=mc-monitor --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=1.8.1 --var app=mc-server-runner --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=0.1.1 --var app=maven-metadata-release --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
ARG MC_HELPER_VERSION=1.20.1
|
||||
ARG MC_HELPER_BASE_URL=https://github.com/itzg/mc-image-helper/releases/download/v${MC_HELPER_VERSION}
|
||||
RUN curl -fsSL ${MC_HELPER_BASE_URL}/mc-image-helper-${MC_HELPER_VERSION}.tgz \
|
||||
| tar -C /usr/share -zxf - \
|
||||
&& ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/bin/mc-image-helper /usr/bin
|
||||
|
||||
VOLUME ["/data"]
|
||||
WORKDIR /data
|
||||
|
||||
STOPSIGNAL SIGTERM
|
||||
|
||||
# End user MUST set EULA and change RCON_PASSWORD
|
||||
ENV TYPE=VANILLA VERSION=LATEST EULA="" UID=1000 GID=1000 RCON_PASSWORD=minecraft
|
||||
|
||||
COPY --chmod=755 scripts/start* /
|
||||
COPY --chmod=755 bin/ /usr/local/bin/
|
||||
COPY --chmod=755 bin/mc-health /health.sh
|
||||
COPY --chmod=644 files/server.properties /tmp/server.properties
|
||||
COPY --chmod=644 files/log4j2.xml /tmp/log4j2.xml
|
||||
COPY --chmod=755 files/autopause /autopause
|
||||
COPY --chmod=755 files/autostop /autostop
|
||||
COPY --chmod=755 files/rconcmds /rconcmds
|
||||
|
||||
RUN dos2unix /start* /autopause/* /autostop/* /rconcmds/*
|
||||
|
||||
ENTRYPOINT [ "/start" ]
|
||||
HEALTHCHECK --start-period=1m --interval=5s --retries=24 CMD mc-health
|
||||
|
||||
433
README.md
@@ -21,131 +21,6 @@ where, in this case, the standard server port 25565, will be exposed on your hos
|
||||
|
||||
By default, the container will download the latest version of the "vanilla" [Minecraft: Java Edition server](https://www.minecraft.net/en-us/download/server) provided by Mojang. The [`VERSION`](#versions) and the [`TYPE`](#server-types) can be configured to create many variations of desired Minecraft server.
|
||||
|
||||
**TABLE OF CONTENTS**
|
||||
|
||||
<!--ts-->
|
||||
* [Mitigated Log4jShell Vulnerability](#mitigated-log4jshell-vulnerability)
|
||||
* [Looking for a Bedrock Dedicated Server](#looking-for-a-bedrock-dedicated-server)
|
||||
* [Interacting with the server](#interacting-with-the-server)
|
||||
* [Data Directory](#data-directory)
|
||||
* [Attaching data directory to host filesystem](#attaching-data-directory-to-host-filesystem)
|
||||
* [Converting anonymous /data volume to named volume](#converting-anonymous-data-volume-to-named-volume)
|
||||
* [Versions](#versions)
|
||||
* [Running Minecraft server on different Java version](#running-minecraft-server-on-different-java-version)
|
||||
* [Deprecated Image Tags](#deprecated-image-tags)
|
||||
* [Healthcheck](#healthcheck)
|
||||
* [Deployment Templates and Examples](#deployment-templates-and-examples)
|
||||
* [Helm Charts](#helm-charts)
|
||||
* [Examples](#examples)
|
||||
* [Amazon Web Services (AWS) Deployment](#amazon-web-services-aws-deployment)
|
||||
* [Using Docker Compose](#using-docker-compose)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
* [Server types](#server-types)
|
||||
* [Running a Forge Server](#running-a-forge-server)
|
||||
* [Running a Fabric Server](#running-a-fabric-server)
|
||||
* [Running a Bukkit/Spigot server](#running-a-bukkitspigot-server)
|
||||
* [Running a Paper server](#running-a-paper-server)
|
||||
* [Running an Airplane server](#running-an-airplane-server)
|
||||
* [Running a Pufferfish server](#running-a-pufferfish-server)
|
||||
* [Running a Purpur server](#running-a-purpur-server)
|
||||
* [Running a Magma server](#running-a-magma-server)
|
||||
* [Running a Mohist server](#running-a-mohist-server)
|
||||
* [Running a Catserver type server](#running-a-catserver-type-server)
|
||||
* [Running a Canyon server](#running-a-canyon-server)
|
||||
* [Running a SpongeVanilla server](#running-a-spongevanilla-server)
|
||||
* [Running a Limbo server](#running-a-limbo-server)
|
||||
* [Running a Crucible server](#running-a-crucible-server)
|
||||
* [Running a server with a Feed the Beast modpack](#running-a-server-with-a-feed-the-beast-modpack)
|
||||
* [Environment Variables:](#environment-variables)
|
||||
* [Upgrading](#upgrading)
|
||||
* [Example](#example)
|
||||
* [Running a server with a CurseForge modpack](#running-a-server-with-a-curseforge-modpack)
|
||||
* [Modpack data directory](#modpack-data-directory)
|
||||
* [Buggy start scripts](#buggy-start-scripts)
|
||||
* [Fixing "unable to launch forgemodloader"](#fixing-unable-to-launch-forgemodloader)
|
||||
* [Running a server with a packwiz modpack](#running-a-server-with-a-packwiz-modpack)
|
||||
* [Working with mods and plugins](#working-with-mods-and-plugins)
|
||||
* [Optional plugins, mods, and config attach points](#optional-plugins-mods-and-config-attach-points)
|
||||
* [Auto-downloading SpigotMC/Bukkit/PaperMC plugins](#auto-downloading-spigotmcbukkitpapermc-plugins)
|
||||
* [Downloadable mod/plugin pack for Forge, Fabric, and Bukkit-like Servers](#downloadable-modplugin-pack-for-forge-fabric-and-bukkit-like-servers)
|
||||
* [ForgeAPI usage to use non-version specific projects](#forgeapi-usage-to-use-non-version-specific-projects)
|
||||
* [Generic pack files](#generic-pack-files)
|
||||
* [Mod/Plugin URL Listing File](#modplugin-url-listing-file)
|
||||
* [Remove old mods/plugins](#remove-old-modsplugins)
|
||||
* [Working with world data](#working-with-world-data)
|
||||
* [Downloadable world](#downloadable-world)
|
||||
* [Cloning world from a container path](#cloning-world-from-a-container-path)
|
||||
* [Overwrite world on start](#overwrite-world-on-start)
|
||||
* [Datapacks](#datapacks)
|
||||
* [VanillaTweaks](#vanillatweaks)
|
||||
* [Server configuration](#server-configuration)
|
||||
* [Message of the Day](#message-of-the-day)
|
||||
* [Difficulty](#difficulty)
|
||||
* [Whitelist Players](#whitelist-players)
|
||||
* [Op/Administrator Players](#opadministrator-players)
|
||||
* [Server icon](#server-icon)
|
||||
* [Rcon](#rcon)
|
||||
* [Query](#query)
|
||||
* [Max players](#max-players)
|
||||
* [Max world size](#max-world-size)
|
||||
* [Allow Nether](#allow-nether)
|
||||
* [Announce Player Achievements](#announce-player-achievements)
|
||||
* [Enable Command Block](#enable-command-block)
|
||||
* [Force Gamemode](#force-gamemode)
|
||||
* [Generate Structures](#generate-structures)
|
||||
* [Hardcore](#hardcore)
|
||||
* [Snooper](#snooper)
|
||||
* [Max Build Height](#max-build-height)
|
||||
* [Max Tick Time](#max-tick-time)
|
||||
* [Spawn Animals](#spawn-animals)
|
||||
* [Spawn Monsters](#spawn-monsters)
|
||||
* [Spawn NPCs](#spawn-npcs)
|
||||
* [Set spawn protection](#set-spawn-protection)
|
||||
* [View Distance](#view-distance)
|
||||
* [Level Seed](#level-seed)
|
||||
* [Game Mode](#game-mode)
|
||||
* [PVP Mode](#pvp-mode)
|
||||
* [Level Type and Generator Settings](#level-type-and-generator-settings)
|
||||
* [Custom Server Resource Pack](#custom-server-resource-pack)
|
||||
* [Level / World Save Name](#level--world-save-name)
|
||||
* [Online mode](#online-mode)
|
||||
* [Allow flight](#allow-flight)
|
||||
* [Server name](#server-name)
|
||||
* [Server port](#server-port)
|
||||
* [Other server property mappings](#other-server-property-mappings)
|
||||
* [Miscellaneous Options](#miscellaneous-options)
|
||||
* [Replacing variables inside configs](#replacing-variables-inside-configs)
|
||||
* [Patching existing files](#patching-existing-files)
|
||||
* [Running with a custom server JAR](#running-with-a-custom-server-jar)
|
||||
* [Force re-download of the server file](#force-re-download-of-the-server-file)
|
||||
* [Running as alternate user/group ID](#running-as-alternate-usergroup-id)
|
||||
* [Memory Limit](#memory-limit)
|
||||
* [JVM Options](#jvm-options)
|
||||
* [Interactive and Color Console](#interactive-and-color-console)
|
||||
* [Server Shutdown Options](#server-shutdown-options)
|
||||
* [OpenJ9 Specific Options](#openj9-specific-options)
|
||||
* [Enabling rolling logs](#enabling-rolling-logs)
|
||||
* [Timezone Configuration](#timezone-configuration)
|
||||
* [Enable Remote JMX for Profiling](#enable-remote-jmx-for-profiling)
|
||||
* [Enable Aikar's Flags](#enable-aikars-flags)
|
||||
* [HTTP Proxy](#http-proxy)
|
||||
* [Using "noconsole" option](#using-noconsole-option)
|
||||
* [Explicitly disable GUI](#explicitly-disable-gui)
|
||||
* [Stop Duration](#stop-duration)
|
||||
* [Setup only](#setup-only)
|
||||
* [Enable Flare Flags](#enable-flare-flags)
|
||||
* [Enable timestamps in init logs](#enable-timestamps-in-init-logs)
|
||||
* [Autopause](#autopause)
|
||||
* [Description](#description)
|
||||
* [Enabling Autopause](#enabling-autopause)
|
||||
* [Autostop](#autostop)
|
||||
* [Running on RaspberryPi](#running-on-raspberrypi)
|
||||
* [Contributing](#contributing)
|
||||
|
||||
<!-- Added by: runner, at: Sun Feb 13 15:02:50 UTC 2022 -->
|
||||
|
||||
<!--te-->
|
||||
|
||||
## Mitigated Log4jShell Vulnerability
|
||||
|
||||
**Please ensure you have pulled the latest image** since [all official mitigations](https://www.minecraft.net/en-us/article/important-message--security-vulnerability-java-edition) are automatically applied by the container startup process.
|
||||
@@ -211,9 +86,14 @@ Everything the container manages is located under the **container's** `/data` pa
|
||||
|
||||
### Attaching data directory to host filesystem
|
||||
|
||||
In most cases the easier way to persist and work with the minecraft data files is to use the `-v` argument to map a directory on your host machine to the container's `/data` directory, such as the following where `/home/user/minecraft-data` would be a directory of your choosing on your host machine:
|
||||
In most cases the easiest way to persist and work with the minecraft data files is to use the [volume mounting](https://docs.docker.com/storage/volumes/) `-v` argument to map a directory on your host machine to the container's `/data` directory. In the following example, the path `/home/user/minecraft-data` **must be** a directory on your host machine:
|
||||
|
||||
docker run -d -v /home/user/minecraft-data:/data ...
|
||||
-v /home/user/minecraft-data:/data
|
||||
------------------------- -----
|
||||
| |
|
||||
| +-- must always be /data
|
||||
|
|
||||
+-- replace with a directory on your host machine
|
||||
|
||||
When attached in this way you can stop the server, edit the configuration under your attached directory and start the server again to pick up the new configuration.
|
||||
|
||||
@@ -288,16 +168,18 @@ the server jar remain in the `/data` directory. It is safe to remove those._
|
||||
When using the image `itzg:/minecraft-server` without a tag, the `latest` image tag is implied from the table below. To use a different version of Java, please use an alternate tag to run your Minecraft server container.
|
||||
|
||||
| Tag name | Java version | Linux | JVM Type | Architecture |
|
||||
|-----------------|-------------|--------|----------|-------------------|
|
||||
| latest | 17 | Debian | Hotspot | amd64,arm64,armv7 |
|
||||
| java8 | 8 | Alpine | Hotspot | amd64 |
|
||||
| java8-multiarch | 8 | Debian | Hotspot | amd64,arm64,armv7 |
|
||||
| java8-openj9 | 8 | Debian | OpenJ9 | amd64 |
|
||||
| java11 | 11 | Debian | Hotspot | amd64,arm64,armv7 |
|
||||
| java11-openj9 | 11 | Debian | OpenJ9 | amd64 |
|
||||
| java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 |
|
||||
| java17-openj9 | 17 | Debian | OpenJ9 | amd64 |
|
||||
| java17-alpine | 17 | Alpine | Hotspot | amd64 |
|
||||
|-------------------|-------------|--------|------------|-------------------|
|
||||
| latest | 17 | Debian | Hotspot | amd64,arm64,armv7 |
|
||||
| java8 | 8 | Alpine | Hotspot | amd64 |
|
||||
| java8-multiarch | 8 | Debian | Hotspot | amd64,arm64,armv7 |
|
||||
| java8-openj9 | 8 | Debian | OpenJ9 | amd64 |
|
||||
| java8-graalvm-ce | 8 | Oracle | GraalVM CE | amd64 |
|
||||
| java11 | 11 | Debian | Hotspot | amd64,arm64,armv7 |
|
||||
| java11-openj9 | 11 | Debian | OpenJ9 | amd64 |
|
||||
| java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 |
|
||||
| java17-openj9 | 17 | Debian | OpenJ9 | amd64 |
|
||||
| java17-graalvm-ce | 17 | Oracle | GraalVM CE | amd64,arm64 |
|
||||
| java17-alpine | 17 | Alpine | Hotspot | amd64 |
|
||||
|
||||
For example, to use Java version 8 on any supported architecture:
|
||||
|
||||
@@ -317,11 +199,43 @@ The following image tags have been deprecated and are no longer receiving update
|
||||
- multiarch-latest
|
||||
- java16/java16-openj9
|
||||
|
||||
## Related Projects
|
||||
|
||||
### [itzg/minecraft-bedrock-server](https://github.com/itzg/docker-minecraft-bedrock-server)
|
||||
|
||||
Docker image that runs a Minecraft Bedrock server.
|
||||
|
||||
### [mc-router](https://github.com/itzg/mc-router)
|
||||
|
||||
Lightweight multiplexer/proxy for Minecraft Java servers. Provided as a stand-alone application and a Docker image.
|
||||
|
||||
### [itzg/bungeecord](https://github.com/itzg/docker-bungeecord/)
|
||||
|
||||
Docker image that runs a proxy powered by Bungeecord, Velocity, or Waterfall
|
||||
|
||||
### [itzg/mc-backup](https://github.com/itzg/docker-mc-backup)
|
||||
|
||||
Docker image that runs as a side-car container to backup world data.
|
||||
|
||||
### [rcon-cli](https://github.com/itzg/rcon-cli)
|
||||
|
||||
A tool that is bundled with this image to provide CLI access to an RCON endpoint.
|
||||
|
||||
### [mc-monitor](https://github.com/itzg/mc-monitor)
|
||||
|
||||
A tool that is bundled with this image that provides health checks and metrics reporting, such as a Prometheus exporter or a telegraf data source.
|
||||
|
||||
### [mc-image-helper](https://github.com/itzg/mc-image-helper)
|
||||
|
||||
A tool that is bundled with this image to provide complex, re-usable preparation operations.
|
||||
|
||||
### [itzg/rcon](https://github.com/itzg/docker-rcon-web-admin)
|
||||
|
||||
An image that dockerizes [rcon-web-admin](https://github.com/rcon-web-admin/rcon-web-admin).
|
||||
|
||||
## Healthcheck
|
||||
|
||||
This image contains [mc-monitor](https://github.com/itzg/mc-monitor) and uses
|
||||
its `status` command to continually check on the container's. That can be observed
|
||||
from the `STATUS` column of `docker ps`
|
||||
This image contains [mc-monitor](https://github.com/itzg/mc-monitor) and uses its `status` command to continually check on the container's. That can be observed from the `STATUS` column of `docker ps`
|
||||
|
||||
```
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
@@ -335,6 +249,16 @@ You can also query the container's health in a script friendly way:
|
||||
healthy
|
||||
```
|
||||
|
||||
There's actually a wrapper script called `mc-health` that takes care of calling `mc-monitor status` with the correct arguments. If needing to customize the health checks parameters, such as in a compose file, then use something like the following in the service declaration:
|
||||
|
||||
```yaml
|
||||
healthcheck:
|
||||
test: mc-health
|
||||
start_period: 1m
|
||||
interval: 5s
|
||||
retries: 20
|
||||
```
|
||||
|
||||
Some orchestration systems, such as Portainer, don't allow for disabling the default `HEALTHCHECK` declared by this image. In those cases you can approximate the disabling of healthchecks by setting the environment variable `DISABLE_HEALTHCHECK` to `true`.
|
||||
|
||||
## Deployment Templates and Examples
|
||||
@@ -445,6 +369,33 @@ docker run -d -v /path/on/host:/data ... \
|
||||
|
||||
See the [Working with mods and plugins](#working-with-mods-and-plugins) section to set up Fabric mods and configuration.
|
||||
|
||||
### Running a Quilt Server
|
||||
|
||||
Enable [Quilt server](https://quiltmc.org/) mode by adding a `-e TYPE=QUILT` to your command-line.
|
||||
|
||||
```
|
||||
docker run -d -v /path/on/host:/data \
|
||||
-e TYPE=QUILT \
|
||||
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
|
||||
```
|
||||
|
||||
By default, the container will install the latest [quilt server launcher](https://quiltmc.org/install/server/), using the latest [quilt-installer](https://github.com/QuiltMC/quilt-installer) against the minecraft version you have defined with `VERSION` (defaulting to the latest vanilla release of the game).
|
||||
|
||||
A specific loader or installer version other than the latest can be requested using `QUILT_LOADER_VERSION` and `QUILT_INSTALLER_VERSION` respectively, such as:
|
||||
|
||||
```
|
||||
docker run -d -v /path/on/host:/data ... \
|
||||
-e TYPE=QUILT \
|
||||
-e QUILT_LOADER_VERSION=0.16.0 \
|
||||
-e QUILT_INSTALLER_VERSION=0.4.1
|
||||
```
|
||||
|
||||
> If you wish to use an alternative launcher you can:
|
||||
> * Provide the path to a custom launcher jar available to the container with `QUILT_LAUNCHER`, relative to `/data` (such as `-e QUILT_LAUNCHER=quilt-server-custom.jar`)
|
||||
> * Provide the URL to a custom launcher jar with `QUILT_LAUNCHER_URL` (such as `-e QUILT_LAUNCHER_URL=http://HOST/quilt-server-custom.jar`)
|
||||
|
||||
See the [Working with mods and plugins](#working-with-mods-and-plugins) section to set up Quilt mods and configuration.
|
||||
|
||||
### Running a Bukkit/Spigot server
|
||||
|
||||
Enable Bukkit/Spigot server mode by adding a `-e TYPE=BUKKIT` or `-e TYPE=SPIGOT` to your command-line.
|
||||
@@ -482,34 +433,22 @@ If you have attached a host directory to the `/data` volume, then you can instal
|
||||
|
||||
[You can also auto-download plugins using `SPIGET_RESOURCES`.](#auto-downloading-spigotmcbukkitpapermc-plugins)
|
||||
|
||||
### Running an Airplane server
|
||||
|
||||
An [Airplane](https://airplane.gg) server, which is "a stable, optimized, well supported 1.17 Paper fork."
|
||||
|
||||
-e TYPE=AIRPLANE
|
||||
|
||||
> NOTE: The `VERSION` variable is used to select an Airplane type to download. The available options are "LATEST" and "PURPUR", both 1.17.1. Airplane does not support 1.18 -- use Paper/Pufferfish/Purpur.
|
||||
|
||||
Extra variables:
|
||||
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded
|
||||
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [Flare](https://blog.airplane.gg/flare) profiler
|
||||
|
||||
### Running a Pufferfish server
|
||||
|
||||
A [Pufferfish](https://github.com/pufferfish-gg/Pufferfish) server, which is "a highly optimized Paper fork designed for large servers requiring both maximum performance, stability, and "enterprise" features."
|
||||
|
||||
-e TYPE=PUFFERFISH
|
||||
|
||||
> NOTE: The `VERSION` variable is used to select a Pufferfish branch to download from. The available options are "LATEST" and "1.18"
|
||||
> NOTE: The `VERSION` variable is used to select branch latest, 1.18, or 1.17. Use PUFFERFISH_BUILD to really select the SERVER VERSION number.
|
||||
|
||||
Extra variables:
|
||||
- `PUFFERFISH_BUILD=lastSuccessfulBuild` : set a specific Pufferfish build to use
|
||||
- `PUFFERFISH_BUILD=lastSuccessfulBuild` : set a specific Pufferfish build to use. Example: selecting build 47 => 1.18.1, or build 50 => 1.18.2 etc
|
||||
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded
|
||||
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [Flare](https://blog.airplane.gg/flare) profiler
|
||||
|
||||
### Running a Purpur server
|
||||
|
||||
A [Purpur](https://purpur.pl3x.net/) server, which is "drop-in replacement for Paper servers designed for configurability, new fun and exciting gameplay features, and performance built on top of Airplane."
|
||||
A [Purpur](https://purpurmc.org/) server, which is "a drop-in replacement for Paper servers designed for configurability and new, fun, exciting gameplay features."
|
||||
|
||||
-e TYPE=PURPUR
|
||||
|
||||
@@ -519,6 +458,7 @@ Extra variables:
|
||||
- `PURPUR_BUILD=LATEST` : set a specific Purpur build to use
|
||||
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded
|
||||
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [Flare](https://blog.airplane.gg/flare) profiler
|
||||
- `PURPUR_DOWNLOAD_URL=<url>` : set URL to download Purpur from custom URL.
|
||||
|
||||
### Running a Magma server
|
||||
|
||||
@@ -526,8 +466,6 @@ A [Magma](https://magmafoundation.org/) server, which is a combination of Forge
|
||||
|
||||
-e TYPE=MAGMA
|
||||
|
||||
By default, the "stable" channel is used, but you can set `MAGMA_CHANNEL` to "dev" to access dev channel versions.
|
||||
|
||||
> **NOTE** there are limited base versions supported, so you will also need to set `VERSION`, such as "1.12.2", "1.16.5", etc.
|
||||
|
||||
|
||||
@@ -551,6 +489,16 @@ A [Catserver](http://catserver.moe/) type server can be used with
|
||||
|
||||
> **NOTE** Catserver only provides a single release stream, so `VERSION` is ignored
|
||||
|
||||
### Running a Loliserver type server
|
||||
|
||||
A [Loliserver](https://github.com/Loli-Server/LoliServer) type server can be used with
|
||||
|
||||
-e TYPE=LOLISERVER
|
||||
|
||||
> **NOTE** Loliserver only provides a single release stream, so `VERSION` is ignored
|
||||
|
||||
> **Disclaimer** The retrieval of the serverjar is not bulletproof. It can and probably will change in the future.
|
||||
|
||||
### Running a Canyon server
|
||||
|
||||
[Canyon](https://github.com/canyonmodded/canyon) is a fork of CraftBukkit for Minecraft Beta 1.7.3. It includes multiple enhancements whilst also retaining compatibility with old Bukkit plugins and mods as much as possible.
|
||||
@@ -569,7 +517,7 @@ Enable SpongeVanilla server mode by adding a `-e TYPE=SPONGEVANILLA` to your com
|
||||
|
||||
By default the container will run the latest `STABLE` version.
|
||||
If you want to run a specific version, you can add `-e SPONGEVERSION=1.11.2-6.1.0-BETA-19` to your command-line.
|
||||
|
||||
|
||||
Beware that current [Sponge](https://www.spongepowered.org) `STABLE` versions for Minecraft 1.12 require using [the Java 8 tag](#running-minecraft-server-on-different-java-version):
|
||||
|
||||
docker run -d -v /path/on/host:/data -e TYPE=SPONGEVANILLA \
|
||||
@@ -614,8 +562,8 @@ Crucible is only available for 1.7.10, so be sure to set `VERSION=1.7.10`.
|
||||
[Feed the Beast application](https://www.feed-the-beast.com/) modpacks are supported by using `-e TYPE=FTBA` (**note** the "A" at the end of the type). This server type will automatically take care of downloading and installing the modpack and appropriate version of Forge, so the `VERSION` does not need to be specified.
|
||||
|
||||
### Environment Variables:
|
||||
- `FTB_MODPACK_ID`: **required**, the numerical ID of the modpack to install. The ID can be located by [finding the modpack](https://www.feed-the-beast.com/modpack) and using the "ID" displayed next to the name
|
||||
- `FTB_MODPACK_VERSION_ID`: optional, the numerical Id of the version to install. If not specified, the latest version will be installed. The "Version ID" can be obtained by drilling into the Versions tab and clicking a specific version.
|
||||
- `FTB_MODPACK_ID`: **required**, the numerical ID of the modpack to install. The ID can be located by [finding the modpack](https://www.feed-the-beast.com/modpack) and hovering over the name of the modpack, [as shown here](docs/ftba-identifier-popup.png).
|
||||
- `FTB_MODPACK_VERSION_ID`: optional, the numerical Id of the version to install. If not specified, the latest version will be installed. The "Version ID" can be obtained by drilling into the Versions tab and hovering over the version name, [as shown here](docs/ftba-version-id-popup.png).
|
||||
|
||||
### Upgrading
|
||||
|
||||
@@ -629,7 +577,7 @@ The following example runs the latest version of [FTB Presents Direwolf20 1.12](
|
||||
docker run -d --name mc-ftb -e EULA=TRUE \
|
||||
-e TYPE=FTBA -e FTB_MODPACK_ID=31 \
|
||||
-p 25565:25565 \
|
||||
itzg/minecraft-server:multiarch
|
||||
itzg/minecraft-server:java8-multiarch
|
||||
```
|
||||
|
||||
> Normally you will also add `-v` volume for `/data` since the mods and config are installed there along with world data.
|
||||
@@ -732,6 +680,20 @@ For example, the following will auto-download the [EssentialsX](https://www.spig
|
||||
|
||||
-e SPIGET_RESOURCES=9089,34315
|
||||
|
||||
### Auto-download mods from Modrinth
|
||||
|
||||
[Modrinth](https://modrinth.com/) is an open source modding platform with a clean, easy to use website for finding [Fabric and Forge mods](https://modrinth.com/mods). At startup, the container will automatically locate and download the newest versions of mod files that correspond to the `TYPE` and `VERSION` in use. Older file versions downloaded previously will automatically be cleaned up.
|
||||
|
||||
- **MODRINTH_PROJECTS** : comma separated list of project slugs (short name) or IDs. The project ID can be located in the "Technical information" section. The slug is the part of the page URL that follows `/mod/`:
|
||||
```
|
||||
https://modrinth.com/mod/fabric-api
|
||||
----------
|
||||
|
|
||||
+-- project slug
|
||||
```
|
||||
- **MODRINTH_DOWNLOAD_OPTIONAL_DEPENDENCIES**=true : required dependencies of the project will _always_ be downloaded and optional dependencies can also be downloaded by setting this to `true`
|
||||
- **MODRINTH_ALLOWED_VERSION_TYPE**=release : the version type is used to determine the newest version to use from each project. The allowed values are `release`, `beta`, `alpha`.
|
||||
|
||||
### Downloadable mod/plugin pack for Forge, Fabric, and Bukkit-like Servers
|
||||
|
||||
Like the `WORLD` option above, you can specify the URL or path of a "mod pack"
|
||||
@@ -892,6 +854,14 @@ The following diagram shows how this option can be used in a compose deployment
|
||||
### Overwrite world on start
|
||||
The world will only be downloaded or copied if it doesn't exist already. Set `FORCE_WORLD_COPY=TRUE` to force overwrite the world on every server start.
|
||||
|
||||
### Custom worlds directory path
|
||||
To set a custom worlds directory for the Multiverse plugin on a baremetal server, you'd pass the `--world-dir` argument after the jar file.
|
||||
In order to accomplish the same in a containerized server, set the `EXTRA_ARGS` environment variable in your command line or docker compose yaml to the same argument string. For example:
|
||||
```
|
||||
docker run -d -e EXTRA_ARGS='--world-dir ./worlds/'
|
||||
```
|
||||
`--world-container`, `-W`, and `--universe` are aliases to `--world-dir` and can also be used.
|
||||
|
||||
### Datapacks
|
||||
Datapacks can be installed in a similar manner to mods/plugins. There are many environment variables which function in the same way they do for [mods](#working-with-mods-and-plugins):
|
||||
* `DATAPACKS`
|
||||
@@ -904,28 +874,30 @@ Datapacks will be placed in `/data/$LEVEL/datapacks`
|
||||
|
||||
### VanillaTweaks
|
||||
|
||||
VanillaTweaks datapacks can be installed with a share code from the website UI **OR** a json file to specify packs to download and install.
|
||||
[VanillaTweaks](https://vanillatweaks.net/) datapacks, crafting tweaks, and resource packs can be installed with a share code from the website **OR** a json file to specify packs to download and install. Datapacks and crafting tweaks will be installed into the current world directory specified by `$LEVEL`. As new versions of the packs are retrieved the previous versions will automatically be cleaned up.
|
||||
|
||||
Datapacks will be placed in `/data/$LEVEL/datapacks`
|
||||
Resourcepacks will be placed in `/data/resourcepacks`
|
||||
The share code is the part following the hash sign, as shown here:
|
||||
|
||||
```
|
||||
https://vanillatweaks.net/share/#MGr52E
|
||||
------
|
||||
|
|
||||
+- share code MGr52E
|
||||
```
|
||||
|
||||
Accepted Parameters:
|
||||
|
||||
- `VANILLATWEAKS_FILE`
|
||||
- `VANILLATWEAKS_SHARECODE`
|
||||
- `REMOVE_OLD_VANILLATWEAKS`
|
||||
- `REMOVE_OLD_VANILLATWEAKS_DEPTH`
|
||||
- `REMOVE_OLD_VANILLATWEAKS_INCLUDE`
|
||||
- `REMOVE_OLD_VANILLATWEAKS_EXCLUDE`
|
||||
- `VANILLATWEAKS_FILE`: comma separated list of JSON VanillaTweak pack files accessible within the container
|
||||
- `VANILLATWEAKS_SHARECODE`: comma separated list of share codes
|
||||
|
||||
Example of expected Vanillatweaks sharecode:
|
||||
Example of expected VanillaTweaks share codes:
|
||||
**Note**: ResourcePacks, DataPacks, and CraftingTweaks all have separate sharecodes
|
||||
|
||||
```yaml
|
||||
VANILLATWEAKS_SHARECODE: MGr52E,tF1zL2,LnEDwT
|
||||
```
|
||||
|
||||
Example of expected Vanillatweaks file format:
|
||||
Example of expected VanillaTweaks files:
|
||||
|
||||
```yaml
|
||||
VANILLATWEAKS_FILE: /config/vt-datapacks.json,/config/vt-craftingtweaks.json,/config/vt-resourcepacks.json
|
||||
@@ -934,11 +906,12 @@ VANILLATWEAKS_FILE: /config/vt-datapacks.json,/config/vt-craftingtweaks.json,/co
|
||||
Datapacks Json:
|
||||
```json
|
||||
{
|
||||
"type": "datapacks",
|
||||
"version": "1.18",
|
||||
"packs": {
|
||||
"survival": [
|
||||
"graves",
|
||||
"multiplayer sleep",
|
||||
"multiplayer sleep"
|
||||
],
|
||||
"items": ["armored elytra"]
|
||||
}
|
||||
@@ -952,8 +925,7 @@ Resourcepacks Json:
|
||||
"version": "1.18",
|
||||
"packs": {
|
||||
"aesthetic": ["CherryPicking", "BlackNetherBricks", "AlternateBlockDestruction"]
|
||||
},
|
||||
"result": "ok"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -968,8 +940,7 @@ CraftingTweaks Json:
|
||||
"double slabs",
|
||||
"back to blocks"
|
||||
]
|
||||
},
|
||||
"result": "ok"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1218,30 +1189,9 @@ environment variable set to `false`, such as
|
||||
### Level Type and Generator Settings
|
||||
|
||||
By default, a standard world is generated with hills, valleys, water, etc. A different level type can
|
||||
be configured by setting `LEVEL_TYPE` to an expected type, for example
|
||||
be configured by setting `LEVEL_TYPE` to [an expected type listed here](https://minecraft.fandom.com/wiki/Server.properties#level-type).
|
||||
|
||||
- DEFAULT
|
||||
- FLAT
|
||||
- LARGEBIOMES
|
||||
- AMPLIFIED
|
||||
- CUSTOMIZED
|
||||
- BUFFET
|
||||
- BIOMESOP (Biomes O' Plenty for 1.12 and older)
|
||||
- BIOMESOPLENTY (Biomes O' Plenty for 1.15 and above)
|
||||
|
||||
Descriptions are available at the [gamepedia](http://minecraft.gamepedia.com/Server.properties).
|
||||
|
||||
When using a level type of `FLAT`, `CUSTOMIZED`, and `BUFFET`, you can further configure the world generator
|
||||
by passing [custom generator settings](http://minecraft.gamepedia.com/Superflat).
|
||||
**Since generator settings usually have ;'s in them, surround the -e value with a single quote, like below.**
|
||||
|
||||
For example (just the `-e` bits):
|
||||
|
||||
-e LEVEL_TYPE=flat -e 'GENERATOR_SETTINGS=3;minecraft:bedrock,3*minecraft:stone,52*minecraft:sandstone;2;'
|
||||
|
||||
In Minecraft 1.13+ you need to pass json ([generator site](https://misode.github.io/world/)) like this (details see [here](https://github.com/itzg/docker-minecraft-server/issues/999#issuecomment-907849644)):
|
||||
|
||||
-e LEVEL_TYPE=flat -e 'GENERATOR_SETTINGS={"biome":"minecraft:the_void","layers":[{"block":"minecraft:bedrock","height":1},{"block":"minecraft:stone","height":10},{"block":"minecraft:dirt","height":1}],"structures":{"structures":{}}}'
|
||||
For some of the level types, `GENERATOR_SETTINGS` can be used to further customize the world generation [as described here](https://minecraft.fandom.com/wiki/Server.properties#generator-settings).
|
||||
|
||||
### Custom Server Resource Pack
|
||||
|
||||
@@ -1495,6 +1445,10 @@ environment variable. The JVM requires `-XX` options to precede `-X` options, so
|
||||
For some cases, if e.g. after removing mods, it could be necessary to startup minecraft with an additional `-D` parameter like `-Dfml.queryResult=confirm`. To address this you can use the environment variable `JVM_DD_OPTS`, which builds the params from a given list of values separated by space, but without the `-D` prefix. To make things running under systems (e.g. Plesk), which doesn't allow `=` inside values, a `:` (colon) could be used instead. The upper example would look like this:
|
||||
`JVM_DD_OPTS=fml.queryResult:confirm`, and will be converted to `-Dfml.queryResult=confirm`.
|
||||
|
||||
### Jarfile Options
|
||||
Options that would usually be passed to the jar file (those which are written after the filename) can be passed via the `EXTRA_ARGS` environment variable.
|
||||
See [Custom worlds directory path](#custom-worlds-directory-path) for an example.
|
||||
|
||||
### Interactive and Color Console
|
||||
|
||||
If you would like to `docker attach` to the Minecraft server console with color and interactive capabilities, then add
|
||||
@@ -1603,7 +1557,15 @@ To enable the JVM flags required to fully support the [Flare profiling suite](ht
|
||||
|
||||
-e USE_FLARE_FLAGS=true
|
||||
|
||||
Flare is built-in to Airplane/Pufferfish/Purpur, and is available in [plugin form](https://github.com/TECHNOVE/FlarePlugin) for other server types.
|
||||
Flare is built-in to Pufferfish/Purpur, and is available in [plugin form](https://github.com/TECHNOVE/FlarePlugin) for other server types.
|
||||
|
||||
### Enable support for optimized SIMD operations
|
||||
|
||||
To enable support for optimized SIMD operations, the JVM flag can be set with the following variable:
|
||||
|
||||
-e USE_SIMD_FLAGS=true
|
||||
|
||||
SIMD optimized operations are supported by Pufferfish and Purpur.
|
||||
|
||||
### Enable timestamps in init logs
|
||||
|
||||
@@ -1619,6 +1581,75 @@ To also include the timestamp with each log, set `LOG_TIMESTAMP` to "true". The
|
||||
[init] 2022-02-05 16:58:33+00:00 Starting the Minecraft server...
|
||||
```
|
||||
|
||||
### Auto-execute RCON commands
|
||||
|
||||
RCON commands can be configured to execute when the server starts, a client connects, or a client disconnects.
|
||||
|
||||
> When declaring several commands within a compose file environment variable, it's easiest to use YAML's `|-` [block style indicator](https://yaml-multiline.info/).
|
||||
|
||||
**On Server Start:**
|
||||
|
||||
```yaml
|
||||
RCON_CMDS_STARTUP: |-
|
||||
gamerule doFireTick false
|
||||
pregen start 200
|
||||
```
|
||||
|
||||
**On Client Connection:**
|
||||
|
||||
```yaml
|
||||
RCON_CMDS_ON_CONNECT: |-
|
||||
team join New @a[team=]
|
||||
```
|
||||
|
||||
**Note:**
|
||||
* On client connect we only know there was a connection, and not who connected. RCON commands will need to be used for that.
|
||||
|
||||
**On Client Disconnect:**
|
||||
|
||||
```yaml
|
||||
RCON_CMDS_ON_DISCONNECT: |-
|
||||
gamerule doFireTick true
|
||||
```
|
||||
|
||||
**On First Client Connect**
|
||||
|
||||
```yaml
|
||||
RCON_CMDS_FIRST_CONNECT: |-
|
||||
pregen stop
|
||||
```
|
||||
|
||||
**On Last Client Disconnect**
|
||||
|
||||
```yaml
|
||||
RCON_CMDS_LAST_DISCONNECT: |-
|
||||
kill @e[type=minecraft:boat]
|
||||
pregen start 200
|
||||
|
||||
```
|
||||
|
||||
**Example of rules for new players**
|
||||
|
||||
Uses team NEW and team OLD to track players on the server. So move player with no team to NEW, run a command, move them to team OLD.
|
||||
[Reference Article](https://www.minecraftforum.net/forums/minecraft-java-edition/redstone-discussion-and/2213523-detect-players-first-join)
|
||||
|
||||
```yaml
|
||||
RCON_CMDS_STARTUP: |-
|
||||
/pregen start 200
|
||||
/gamerule doFireTick false
|
||||
/team add New
|
||||
/team add Old
|
||||
RCON_CMDS_ON_CONNECT: |-
|
||||
/team join New @a[team=]
|
||||
/give @a[team=New] birch_boat
|
||||
/team join Old @a[team=New]
|
||||
RCON_CMDS_FIRST_CONNECT: |-
|
||||
/pregen stop
|
||||
RCON_CMDS_LAST_DISCONNECT: |-
|
||||
/kill @e[type=minecraft:boat]
|
||||
/pregen start 200
|
||||
```
|
||||
|
||||
## Autopause
|
||||
|
||||
### Description
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
. "/start-utils"
|
||||
: "${CONSOLE_IN_NAMED_PIPE:=/tmp/minecraft-console-in}"
|
||||
|
||||
if [ $# = 0 ]; then
|
||||
@@ -12,4 +12,12 @@ if [ ! -p "${CONSOLE_IN_NAMED_PIPE}" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
gosu minecraft bash -c "echo $* > '${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}'"
|
||||
if [ "$(id -u)" = 0 ]; then
|
||||
if [[ $(getDistro) == alpine ]]; then
|
||||
exec su-exec minecraft bash -c "echo $* > '${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}'"
|
||||
else
|
||||
exec gosu minecraft bash -c "echo $* > '${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}'"
|
||||
fi
|
||||
else
|
||||
echo "$@" >"${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}"
|
||||
fi
|
||||
|
||||
@@ -22,6 +22,5 @@ apk add --no-cache -U \
|
||||
nano \
|
||||
sudo \
|
||||
knock \
|
||||
ttf-dejavu \
|
||||
tar \
|
||||
zstd
|
||||
12
build/ol/install-gosu.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ $(uname -m) == "aarch64" ]]; then
|
||||
curl -sL -o /bin/gosu https://github.com/tianon/gosu/releases/download/1.14/gosu-arm64
|
||||
chmod +x /bin/gosu
|
||||
elif [[ $(uname -m) == "x86_64" ]]; then
|
||||
curl -sL -o /bin/gosu https://github.com/tianon/gosu/releases/download/1.14/gosu-amd64
|
||||
chmod +x /bin/gosu
|
||||
else
|
||||
echo "Not supported!"
|
||||
exit 1
|
||||
fi
|
||||
37
build/ol/install-packages.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
microdnf install dnf -y
|
||||
|
||||
dnf install 'dnf-command(config-manager)' -y
|
||||
dnf config-manager --set-enabled ol8_codeready_builder
|
||||
tee /etc/yum.repos.d/ol8-epel.repo<<EOF
|
||||
[ol8_developer_EPEL]
|
||||
name= Oracle Linux \$releasever EPEL (\$basearch)
|
||||
baseurl=https://yum.oracle.com/repo/OracleLinux/OL8/developer/EPEL/\$basearch/
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
|
||||
gpgcheck=1
|
||||
enabled=1
|
||||
EOF
|
||||
dnf update -y
|
||||
|
||||
dnf install -y ImageMagick \
|
||||
file \
|
||||
sudo \
|
||||
net-tools \
|
||||
iputils \
|
||||
curl \
|
||||
git \
|
||||
jq \
|
||||
dos2unix \
|
||||
mysql \
|
||||
tzdata \
|
||||
rsync \
|
||||
nano \
|
||||
unzip \
|
||||
zstd \
|
||||
lbzip2 \
|
||||
knock
|
||||
|
||||
bash /build/ol/install-gosu.sh
|
||||
2
build/ol/setup-user.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
groupadd --gid 1000 minecraft
|
||||
useradd --system --shell /bin/false --uid 1000 -g minecraft --home /data minecraft
|
||||
@@ -22,7 +22,7 @@ apt-get install -y \
|
||||
nano \
|
||||
unzip \
|
||||
zstd \
|
||||
knockd \
|
||||
ttf-dejavu
|
||||
lbzip2 \
|
||||
knockd
|
||||
|
||||
apt-get clean
|
||||
BIN
docs/ftba-identifier-popup.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
docs/ftba-version-id-popup.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
@@ -9,7 +9,9 @@ services:
|
||||
environment:
|
||||
EULA: "true"
|
||||
TYPE: CURSEFORGE
|
||||
CF_SERVER_MOD: https://media.forgecdn.net/files/3482/169/Valhelsia+3-3.4.4-SERVER.zip
|
||||
CF_SERVER_MOD: /modpacks/SIMPLE-SERVER-FILES-0.3.20.zip
|
||||
# CF_SERVER_MOD: /modpacks/createlive3serverfiles+1.4.2.zip
|
||||
# CF_SERVER_MOD: /modpacks/Valhelsia+3-3.5.1-SERVER.zip
|
||||
# CF_SERVER_MOD: https://media.forgecdn.net/files/3012/800/SkyFactory-4_Server_4.2.2.zip
|
||||
# CF_SERVER_MOD: /modpacks/${MODPACK:-SkyFactory_4_Server_4.1.0.zip}
|
||||
ports:
|
||||
|
||||
19
examples/docker-compose-generic-pack-atm7.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
mc:
|
||||
image: itzg/minecraft-server
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./modpacks:/modpacks:ro
|
||||
environment:
|
||||
EULA: "true"
|
||||
MEMORY: 2G
|
||||
TYPE: FORGE
|
||||
VERSION: 1.18.2
|
||||
FORGEVERSION: 40.1.30
|
||||
# Need to download Server-Files-0.4.13.zip and
|
||||
# put it in modpacks directory next to this compose file
|
||||
GENERIC_PACK: /modpacks/Server-Files-0.4.13.zip
|
||||
ports:
|
||||
- "25565:25565"
|
||||
17
examples/docker-compose-magma.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
mc:
|
||||
image: itzg/minecraft-server:java8
|
||||
tty: true
|
||||
stdin_open: true
|
||||
ports:
|
||||
- "25565:25565"
|
||||
environment:
|
||||
EULA: "TRUE"
|
||||
TYPE: MAGMA
|
||||
VERSION: 1.16.5
|
||||
volumes:
|
||||
- data:/data
|
||||
volumes:
|
||||
data: {}
|
||||
18
examples/docker-compose-modrinth.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
mc:
|
||||
image: itzg/minecraft-server
|
||||
tty: true
|
||||
stdin_open: true
|
||||
ports:
|
||||
- "25565:25565"
|
||||
environment:
|
||||
EULA: "TRUE"
|
||||
TYPE: FABRIC
|
||||
MODRINTH_PROJECTS: fallingtree
|
||||
volumes:
|
||||
- data:/data
|
||||
|
||||
volumes:
|
||||
data: {}
|
||||
36
examples/docker-compose-rconcmd.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
minecraft:
|
||||
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||
ports:
|
||||
- "25565:25565"
|
||||
volumes:
|
||||
- "mc:/data"
|
||||
environment:
|
||||
EULA: "TRUE"
|
||||
TYPE: FABRIC
|
||||
MODS_FORGEAPI_PROJECTIDS: 433175
|
||||
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
|
||||
MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "TRUE"
|
||||
REMOVE_OLD_FORGEAPI_MODS: "TRUE"
|
||||
# YAML Heredoc, be sure to use '|-' this will remove the first newline and final new line.
|
||||
# This is versus '|' that will leaving with two empty strings at top and bottom.
|
||||
RCON_CMDS_STARTUP: |-
|
||||
/gamerule doFireTick false
|
||||
/team add New
|
||||
/team add Old
|
||||
/chunky radius 1000
|
||||
/chunky start
|
||||
RCON_CMDS_ON_CONNECT: |-
|
||||
/team join New @a[team=]
|
||||
/give @a[team=New] birch_boat
|
||||
/team join Old @a[team=New]
|
||||
RCON_CMDS_FIRST_CONNECT: |-
|
||||
/chunky pause
|
||||
RCON_CMDS_LAST_DISCONNECT: |-
|
||||
/kill @e[type=minecraft:boat]
|
||||
/chunky continue
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
mc: {}
|
||||
@@ -1,27 +1,27 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
rlcraft:
|
||||
mc:
|
||||
image: itzg/minecraft-server:java8
|
||||
container_name: rlcraft
|
||||
volumes:
|
||||
- rlcraft-modpack:/modpacks:ro
|
||||
- rlcraft-data:/data
|
||||
- data:/data
|
||||
- ./modpacks:/modpacks:ro
|
||||
environment:
|
||||
EULA: "true"
|
||||
TYPE: "FORGE"
|
||||
VERSION: "1.12.2"
|
||||
FORGEVERSION: "14.23.5.2855"
|
||||
FORGEVERSION: "14.23.5.2860"
|
||||
OVERRIDE_SERVER_PROPERTIES: "true"
|
||||
DIFFICULTY: "hard"
|
||||
MAX_TICK_TIME: "-1"
|
||||
VIEW_DISTANCE: "6"
|
||||
ALLOW_FLIGHT: "true"
|
||||
ENABLE_COMMAND_BLOCK: "true"
|
||||
VIEW_DISTANCE: "10"
|
||||
MEMORY: "4G"
|
||||
GENERIC_PACK: "/modpacks/RLCraft_Server_Pack_1.12.2_Beta_v2.8.2.zip"
|
||||
# Download from https://www.curseforge.com/minecraft/modpacks/rlcraft and place in modpacks subdir
|
||||
GENERIC_PACK: "/modpacks/RLCraft+Server+Pack+1.12.2+-+Release+v2.9.1c.zip"
|
||||
ports:
|
||||
- 25565:25565
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
rlcraft-data:
|
||||
rlcraft-modpack:
|
||||
data:
|
||||
|
||||
@@ -3,6 +3,8 @@ version: "3.8"
|
||||
services:
|
||||
mc:
|
||||
image: itzg/minecraft-server
|
||||
tty: true
|
||||
stdin_open: true
|
||||
ports:
|
||||
- 25565:25565
|
||||
environment:
|
||||
|
||||
@@ -5,11 +5,11 @@ services:
|
||||
# Only using IMAGE variable to allow for local testing
|
||||
image: ${IMAGE:-itzg/minecraft-server}
|
||||
ports:
|
||||
- 25565:25565
|
||||
- "25565:25565"
|
||||
environment:
|
||||
EULA: "TRUE"
|
||||
TYPE: SPIGOT
|
||||
SPIGET_RESOURCES: 9089,34315,3836
|
||||
SPIGET_RESOURCES: 34315,3836
|
||||
volumes:
|
||||
- data:/data
|
||||
|
||||
|
||||
@@ -35,20 +35,17 @@ spec:
|
||||
name: main
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- mcstatus
|
||||
- localhost
|
||||
- ping
|
||||
initialDelaySeconds: 5
|
||||
command: [ "/usr/local/bin/mc-monitor", "status", "--host", "localhost" ]
|
||||
# Give it i + p * f seconds to be ready, so 120 seconds
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 5
|
||||
failureThreshold: 20
|
||||
# Monitor ongoing liveness
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
- mcstatus
|
||||
- localhost
|
||||
- ping
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
command: ["/usr/local/bin/mc-monitor", "status", "--host", "localhost"]
|
||||
initialDelaySeconds: 120
|
||||
periodSeconds: 60
|
||||
volumeMounts:
|
||||
- name: mc-data
|
||||
mountPath: /data
|
||||
|
||||
@@ -20,12 +20,16 @@ mc_server_listening() {
|
||||
mc-monitor status --host localhost --port "$SERVER_PORT" --timeout 10s >& /dev/null
|
||||
}
|
||||
|
||||
java_clients_connected() {
|
||||
java_clients_connections() {
|
||||
local connections
|
||||
if java_running ; then
|
||||
connections=$(mc-monitor status --host localhost --port "$SERVER_PORT" --show-player-count)
|
||||
else
|
||||
connections=0
|
||||
fi
|
||||
(( connections > 0 ))
|
||||
echo $connections
|
||||
}
|
||||
|
||||
java_clients_connected() {
|
||||
(( $(java_clients_connections) > 0 ))
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
[unpauseMCServer-server]
|
||||
sequence = 25565
|
||||
seq_timeout = 1
|
||||
command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh
|
||||
command = /autopause/resume.sh
|
||||
tcpflags = syn
|
||||
[unpauseMCServer-rcon]
|
||||
sequence = 25575
|
||||
seq_timeout = 1
|
||||
command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh
|
||||
command = /autopause/resume.sh
|
||||
tcpflags = syn
|
||||
[unpauseMCServer-bedrock]
|
||||
sequence = 19132:udp
|
||||
command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh
|
||||
command = /autopause/resume.sh
|
||||
|
||||
@@ -10,13 +10,16 @@
|
||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
||||
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
||||
<Policies>
|
||||
<!-- Based on filePattern resolution, so daily -->
|
||||
<TimeBasedTriggeringPolicy />
|
||||
<SizeBasedTriggeringPolicy size="100 MB" />
|
||||
<OnStartupTriggeringPolicy />
|
||||
</Policies>
|
||||
<DefaultRolloverStrategy>
|
||||
<Delete basePath="logs">
|
||||
<IfFileName glob="*.log.gz" />
|
||||
<IfLastModified age="7d" />
|
||||
<IfAccumulatedFileCount exceeds="20"/>
|
||||
</Delete>
|
||||
</DefaultRolloverStrategy>
|
||||
</RollingRandomAccessFile>
|
||||
|
||||
101
files/rconcmds/rcon-cmds-daemon.sh
Normal file
@@ -0,0 +1,101 @@
|
||||
#!/bin/bash
|
||||
|
||||
: "${RCON_CMDS_STARTUP:=}"
|
||||
: "${RCON_CMDS_ON_CONNECT:=}"
|
||||
: "${RCON_CMDS_ON_DISCONNECT:=}"
|
||||
: "${RCON_CMDS_FIRST_CONNECT:=}"
|
||||
: "${RCON_CMDS_LAST_DISCONNECT:=}"
|
||||
: "${RCON_CMDS_PERIOD:=10}"
|
||||
|
||||
# needed for the clients connected function residing in autopause
|
||||
# shellcheck source=/autopause/autopause-fcns.sh
|
||||
. /autopause/autopause-fcns.sh
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
|
||||
run_command(){
|
||||
rcon_cmd="$1"
|
||||
logRcon "running - $rcon_cmd"
|
||||
output=$(rcon-cli "$rcon_cmd")
|
||||
logRcon "$output"
|
||||
}
|
||||
|
||||
|
||||
# wait for java process to be started
|
||||
while :
|
||||
do
|
||||
if java_process_exists ; then
|
||||
break
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
CLIENTCONNECTIONS=0
|
||||
STATE=INIT
|
||||
|
||||
while :
|
||||
do
|
||||
case X$STATE in
|
||||
XINIT)
|
||||
# Server startup
|
||||
if mc_server_listening ; then
|
||||
logRcon "MCServer is listening, running startup"
|
||||
if [[ "$RCON_CMDS_STARTUP" ]]; then
|
||||
while read -r cmd; do
|
||||
run_command "$cmd"
|
||||
done <<< "$RCON_CMDS_STARTUP"
|
||||
fi
|
||||
if
|
||||
[[ -z "$RCON_CMDS_ON_CONNECT" ]] &&
|
||||
[[ -z "$RCON_CMDS_ON_DISCONNECT" ]] &&
|
||||
[[ -z "$RCON_CMDS_FIRST_CONNECT" ]] &&
|
||||
[[ -z "$RCON_CMDS_LAST_DISCONNECT" ]]
|
||||
then
|
||||
logRcon "No addition rcon commands are given, stopping rcon cmd service"
|
||||
exit 0
|
||||
fi
|
||||
STATE=II
|
||||
fi
|
||||
;;
|
||||
XII)
|
||||
CURR_CLIENTCONNECTIONS=$(java_clients_connections)
|
||||
# First client connection
|
||||
# Setting priority run order: on first client connection is usually to STOP maintence, aka DO THIS FIRST
|
||||
if (( CURR_CLIENTCONNECTIONS > 0 )) && (( CLIENTCONNECTIONS == 0 )) && [[ "$RCON_CMDS_FIRST_CONNECT" ]]; then
|
||||
logRcon "First Clients has Connected, running first connect cmds"
|
||||
while read -r cmd; do
|
||||
run_command "$cmd"
|
||||
done <<< "$RCON_CMDS_FIRST_CONNECT"
|
||||
fi
|
||||
|
||||
# When a client joins
|
||||
if (( CURR_CLIENTCONNECTIONS > CLIENTCONNECTIONS )) && [[ "$RCON_CMDS_ON_CONNECT" ]]; then
|
||||
logRcon "Clients have Connected, running connect cmds"
|
||||
while read -r cmd; do
|
||||
run_command "$cmd"
|
||||
done <<< "$RCON_CMDS_ON_CONNECT"
|
||||
# When a client leaves
|
||||
elif (( CURR_CLIENTCONNECTIONS < CLIENTCONNECTIONS )) && [[ "$RCON_CMDS_ON_DISCONNECT" ]]; then
|
||||
logRcon "Clients have Disconnected, running disconnect cmds"
|
||||
while read -r cmd; do
|
||||
run_command "$cmd"
|
||||
done <<< "$RCON_CMDS_ON_DISCONNECT"
|
||||
fi
|
||||
|
||||
# Last client connection
|
||||
# Setting priority run order: on last client connection is usually to START maintence, aka DO THIS LAST
|
||||
if (( CURR_CLIENTCONNECTIONS == 0 )) && (( CLIENTCONNECTIONS > 0 )) && [[ "$RCON_CMDS_LAST_DISCONNECT" ]]; then
|
||||
logRcon "ALL Clients have Disconnected, running last disconnect cmds"
|
||||
while read -r cmd; do
|
||||
run_command "$cmd"
|
||||
done <<< "$RCON_CMDS_LAST_DISCONNECT"
|
||||
fi
|
||||
CLIENTCONNECTIONS=$CURR_CLIENTCONNECTIONS
|
||||
;;
|
||||
*)
|
||||
logRcon "Error: invalid state: $STATE"
|
||||
;;
|
||||
esac
|
||||
sleep "$RCON_CMDS_PERIOD"
|
||||
done
|
||||
@@ -1,2 +1,2 @@
|
||||
%minecraft ALL=(ALL) NOPASSWD:/usr/bin/pkill
|
||||
%minecraft ALL=(ALL) NOPASSWD:/usr/sbin/knockd
|
||||
minecraft ALL=(ALL) NOPASSWD:/usr/bin/pkill
|
||||
minecraft ALL=(ALL) NOPASSWD:/usr/sbin/knockd
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
|
||||
# The Dockerfile ENVs take precedence here, but defaulting for testing consistency
|
||||
: "${UID:=1000}"
|
||||
: "${GID:=1000}"
|
||||
|
||||
umask 0002
|
||||
chmod g+w /data
|
||||
|
||||
|
||||
@@ -4,7 +4,19 @@
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
|
||||
: "${SERVER_PORT:=25565}"
|
||||
: "${ENABLE_AUTOPAUSE:=false}"
|
||||
: "${AUTOPAUSE_TIMEOUT_EST:=3600}"
|
||||
: "${AUTOPAUSE_TIMEOUT_KN:=120}"
|
||||
: "${AUTOPAUSE_TIMEOUT_INIT:=600}"
|
||||
: "${AUTOPAUSE_PERIOD:=10}"
|
||||
: "${AUTOPAUSE_KNOCK_INTERFACE:=eth0}"
|
||||
export SERVER_PORT
|
||||
export ENABLE_AUTOPAUSE
|
||||
export AUTOPAUSE_TIMEOUT_EST
|
||||
export AUTOPAUSE_TIMEOUT_KN
|
||||
export AUTOPAUSE_TIMEOUT_INIT
|
||||
export AUTOPAUSE_PERIOD
|
||||
export AUTOPAUSE_KNOCK_INTERFACE
|
||||
|
||||
log "Autopause functionality enabled"
|
||||
|
||||
|
||||
@@ -4,7 +4,15 @@
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
|
||||
: "${SERVER_PORT:=25565}"
|
||||
: "${ENABLE_AUTOSTOP:=false}"
|
||||
: "${AUTOSTOP_TIMEOUT_EST:=3600}"
|
||||
: "${AUTOSTOP_TIMEOUT_INIT:=1800}"
|
||||
: "${AUTOSTOP_PERIOD:=10}"
|
||||
export SERVER_PORT
|
||||
export ENABLE_AUTOSTOP
|
||||
export AUTOSTOP_TIMEOUT_EST
|
||||
export AUTOSTOP_TIMEOUT_INIT
|
||||
export AUTOSTOP_PERIOD
|
||||
|
||||
log "Autostop functionality enabled"
|
||||
|
||||
|
||||
@@ -7,7 +7,18 @@ IFS=$'\n\t'
|
||||
|
||||
: "${EULA:=}"
|
||||
: "${PROXY:=}"
|
||||
: "${ENABLE_AUTOPAUSE:=false}"
|
||||
: "${ENABLE_AUTOSTOP:=false}"
|
||||
: "${RCON_CMDS_STARTUP:=}"
|
||||
: "${RCON_CMDS_ON_CONNECT:=}"
|
||||
: "${RCON_CMDS_ON_DISCONNECT:=}"
|
||||
: "${RCON_CMDS_FIRST_CONNECT:=}"
|
||||
: "${RCON_CMDS_LAST_DISCONNECT:=}"
|
||||
: "${RCON_CMDS_PERIOD:=10}"
|
||||
: "${RCON_PASSWORD_FILE:=}"
|
||||
: "${RCON_PASSWORD:=minecraft}"
|
||||
: "${RCON_PORT:=25575}"
|
||||
export RCON_PASSWORD RCON_PORT
|
||||
|
||||
shopt -s nullglob
|
||||
|
||||
@@ -66,11 +77,27 @@ if [[ $RCON_PASSWORD_FILE ]]; then
|
||||
log ""
|
||||
fi
|
||||
|
||||
# Some Docker management UIs grab all the image declared variables and present them for configuration.
|
||||
# When upgrading images across Java versions, that creates a mismatch in PATH's expected by base image.
|
||||
if ! which java > /dev/null; then
|
||||
log "ERROR: PATH should not be explicitly passed into the container"
|
||||
log " Remove configuration of that variable."
|
||||
function fixJavaPath() {
|
||||
# Some Docker management UIs grab all the image declared variables and present them for configuration.
|
||||
# When upgrading images across Java versions, that creates a mismatch in PATH's expected by base image.
|
||||
if ! which java > /dev/null; then
|
||||
log "ERROR: your Docker provider has an annoying flaw where it"
|
||||
log " tries to set PATH even though the container establishes"
|
||||
log " a very specific value."
|
||||
sleep 2
|
||||
# now find where java might be
|
||||
for d in /opt/java/openjdk/bin /usr/bin; do
|
||||
if [ -x "${d}/java" ]; then
|
||||
PATH="${PATH}:${d}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
if ! fixJavaPath; then
|
||||
log "ERROR: could not locate path that contains java"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -94,7 +121,9 @@ case "X$VERSION" in
|
||||
;;
|
||||
esac
|
||||
export VANILLA_VERSION
|
||||
log "Resolved version given ${VERSION} into ${VANILLA_VERSION}"
|
||||
MAJOR_VANILLA_VERSION=$(get_major_version "$VANILLA_VERSION")
|
||||
export MAJOR_VANILLA_VERSION
|
||||
log "Resolved version given ${VERSION} into ${VANILLA_VERSION} and major version ${MAJOR_VANILLA_VERSION}"
|
||||
|
||||
cd /data || exit 1
|
||||
|
||||
@@ -108,6 +137,18 @@ if isTrue "${ENABLE_AUTOSTOP}"; then
|
||||
${SCRIPTS:-/}start-autostop
|
||||
fi
|
||||
|
||||
if
|
||||
[[ "$RCON_CMDS_STARTUP" ]] ||
|
||||
[[ "$RCON_CMDS_ON_CONNECT" ]] ||
|
||||
[[ "$RCON_CMDS_ON_DISCONNECT" ]] ||
|
||||
[[ "$RCON_CMDS_FIRST_CONNECT" ]] ||
|
||||
[[ "$RCON_CMDS_LAST_DISCONNECT" ]]
|
||||
then
|
||||
log "Starting RCON commands"
|
||||
# shellcheck source=start-rconcmds
|
||||
${SCRIPTS:-/}start-rconcmds
|
||||
fi
|
||||
|
||||
if versionLessThan 1.7; then
|
||||
echo "
|
||||
MC_HEALTH_EXTRA_ARGS=(
|
||||
@@ -135,6 +176,10 @@ case "${TYPE^^}" in
|
||||
exec "${SCRIPTS:-/}start-deployFabric" "$@"
|
||||
;;
|
||||
|
||||
QUILT)
|
||||
exec "${SCRIPTS:-/}start-deployQuilt" "$@"
|
||||
;;
|
||||
|
||||
FTBA)
|
||||
evaluateJavaCompatibilityForForge
|
||||
exec "${SCRIPTS:-/}start-deployFTBA" "$@"
|
||||
@@ -173,12 +218,13 @@ case "${TYPE^^}" in
|
||||
exec "${SCRIPTS:-/}start-deployCatserver" "$@"
|
||||
;;
|
||||
|
||||
PURPUR)
|
||||
exec "${SCRIPTS:-/}start-deployPurpur" "$@"
|
||||
LOLISERVER)
|
||||
evaluateJavaCompatibilityForForge
|
||||
exec "${SCRIPTS:-/}start-deployLoliserver" "$@"
|
||||
;;
|
||||
|
||||
AIRPLANE)
|
||||
exec "${SCRIPTS:-/}start-deployAirplane" "$@"
|
||||
PURPUR)
|
||||
exec "${SCRIPTS:-/}start-deployPurpur" "$@"
|
||||
;;
|
||||
|
||||
PUFFERFISH)
|
||||
@@ -207,7 +253,7 @@ case "${TYPE^^}" in
|
||||
log "Invalid type: '$TYPE'"
|
||||
log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTBA (multiarch-only),"
|
||||
log " CURSEFORGE, SPONGEVANILLA, PURPUR, CUSTOM,"
|
||||
log " MAGMA, MOHIST, CATSERVER, AIRPLANE, PUFFERFISH, CANYON, LIMBO, CRUCIBLE"
|
||||
log " MAGMA, MOHIST, CATSERVER, LOLISERVER, AIRPLANE, PUFFERFISH, CANYON, LIMBO, CRUCIBLE"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
set -euo pipefail
|
||||
isDebugging && set -x
|
||||
|
||||
IFS=$'\n\t'
|
||||
|
||||
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "PURPUR" ] ; then
|
||||
log "ERROR: Airplane server type only supports VERSION=LATEST, VERSION=PURPUR."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
: ${AIRPLANE_TYPE:=airplane}
|
||||
|
||||
if [ "${VERSION}" = "LATEST" ] ; then
|
||||
AIRPLANE_TYPE="airplane"
|
||||
fi
|
||||
|
||||
if [ "${VERSION}" = "PURPUR" ]; then
|
||||
AIRPLANE_TYPE="airplanepurpur"
|
||||
fi
|
||||
|
||||
log "Using ${AIRPLANE_TYPE} 1.17.1 (1.18 unsupported - use Paper/Pufferfish/Purpur for newer versions)"
|
||||
|
||||
export SERVER=${AIRPLANE_TYPE}-1.17.1.jar
|
||||
|
||||
log "Removing old Airplane versions ..."
|
||||
shopt -s nullglob
|
||||
for f in airplane*.jar; do
|
||||
[[ $f != $SERVER ]] && rm $f
|
||||
done
|
||||
|
||||
if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
|
||||
downloadUrl="https://airplane.gg/dl/launcher-${AIRPLANE_TYPE}1.17.1.jar"
|
||||
log "Downloading Airplane from $downloadUrl ..."
|
||||
if ! get -o "$SERVER" "$downloadUrl"; then
|
||||
log "ERROR: failed to download from $downloadUrl (status=$?)"
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
|
||||
# Normalize on Spigot for later operations
|
||||
export FAMILY=SPIGOT
|
||||
|
||||
exec "${SCRIPTS:-/}start-spiget" "$@"
|
||||
@@ -33,7 +33,10 @@ export TYPE=CURSEFORGE
|
||||
FTB_SERVER_MOD=${FTB_SERVER_MOD:-$CF_SERVER_MOD}
|
||||
|
||||
log "Looking for Feed-The-Beast / CurseForge server modpack."
|
||||
requireVar FTB_SERVER_MOD
|
||||
if [[ ! $FTB_SERVER_MOD ]]; then
|
||||
log "ERROR: CF_SERVER_MOD or FTB_SERVER_MOD is required to be set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
downloadModpack() {
|
||||
srv_modpack=${FTB_SERVER_MOD}
|
||||
@@ -133,31 +136,32 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
|
||||
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||
fi
|
||||
|
||||
entryScriptExpr="
|
||||
-name ServerStart.sh
|
||||
-o -name serverstart.sh
|
||||
-o -name ServerStartLinux.sh
|
||||
-o -name LaunchServer.sh
|
||||
-o -name server-start.sh
|
||||
-o -name start-server.sh
|
||||
-o -name startserver.sh
|
||||
-o -name StartServer.sh
|
||||
"
|
||||
|
||||
if [[ -d ${FTB_BASE_DIR} ]]; then
|
||||
startScriptCount=$(find "${FTB_BASE_DIR}" $entryScriptExpr |wc -l)
|
||||
if (( startScriptCount > 1 )); then
|
||||
log "Conflicting FTB/CurseForge packages have been installed. Please cleanup ${FTB_BASE_DIR}"
|
||||
exit 2
|
||||
findStartScript() {
|
||||
entryScriptExpr=(
|
||||
-name ServerStart.sh
|
||||
-o -name serverstart.sh
|
||||
-o -name ServerStartLinux.sh
|
||||
-o -name LaunchServer.sh
|
||||
-o -name server-start.sh
|
||||
-o -name start-server.sh
|
||||
-o -name startserver.sh
|
||||
-o -name StartServer.sh
|
||||
-o -name run.sh
|
||||
-o -name start.sh
|
||||
)
|
||||
|
||||
if [ -d "${FTB_BASE_DIR}" ]; then
|
||||
find "${FTB_BASE_DIR}" \( "${entryScriptExpr[@]}" \) -print -quit
|
||||
fi
|
||||
else
|
||||
startScriptCount=0
|
||||
fi
|
||||
}
|
||||
|
||||
startScript=$(findStartScript)
|
||||
|
||||
# only download and install if a mod pack isn't already installed
|
||||
# also check for the start script rather than just the folder
|
||||
# this allows saving just the world separate from the rest of the data directory
|
||||
if [[ $startScriptCount = 0 ]]; then
|
||||
if [[ ! $startScript ]]; then
|
||||
downloadModpack
|
||||
srv_modpack=${FTB_SERVER_MOD}
|
||||
|
||||
@@ -165,49 +169,61 @@ if [[ $startScriptCount = 0 ]]; then
|
||||
mkdir -p "${FTB_BASE_DIR}"
|
||||
unzip -o "${srv_modpack}" -d "${FTB_BASE_DIR}" | awk '{printf "."} END {print ""}'
|
||||
|
||||
installScript=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f -name install.sh)
|
||||
installScriptExpr=(
|
||||
-name install.sh
|
||||
-o -name FTBInstall.sh
|
||||
-o -name Install.sh
|
||||
)
|
||||
|
||||
installScript=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( "${installScriptExpr[@]}" \) -print -quit)
|
||||
if [[ "$installScript" ]]; then
|
||||
(
|
||||
cd "$(dirname "${installScript}")"
|
||||
chmod +x ./install.sh
|
||||
log "Running included install.sh"
|
||||
./install.sh
|
||||
chmod +x "${installScript}"
|
||||
log "Running included $(basename "${installScript}"). This might take a minute or two..."
|
||||
"${installScript}" > install.log
|
||||
)
|
||||
fi
|
||||
|
||||
startScript=$(findStartScript)
|
||||
fi
|
||||
|
||||
if [[ $(find "${FTB_BASE_DIR}" $entryScriptExpr | wc -l) = 0 ]]; then
|
||||
# start script provided by unzipped+installed modpack?
|
||||
if [[ ! $startScript ]]; then
|
||||
# no, then look for a forge jar to run
|
||||
|
||||
# Allow up to 2 levels since some modpacks have a top-level directory named
|
||||
# for the modpack
|
||||
forgeJar=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( -path "/libraries/*" -o -path "/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
|
||||
if [[ "$forgeJar" ]]; then
|
||||
FTB_BASE_DIR=$(dirname "${forgeJar}")
|
||||
export FTB_BASE_DIR
|
||||
log "No entry script found, so building one for ${forgeJar}"
|
||||
cat > "${FTB_BASE_DIR}/ServerStart.sh" <<EOF
|
||||
# Allow up to 2 levels since some modpacks have a top-level directory named for the modpack
|
||||
forgeJar=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( -path "/libraries/*" -o -path "/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
|
||||
if [[ "$forgeJar" ]]; then
|
||||
FTB_BASE_DIR=$(dirname "${forgeJar}")
|
||||
export FTB_BASE_DIR
|
||||
log "No entry script found, so building one for ${forgeJar}"
|
||||
cat > "${FTB_BASE_DIR}/ServerStart.sh" <<EOF
|
||||
#!/bin/sh
|
||||
. ./settings-local.sh
|
||||
java \${JAVA_PARAMETERS} -Xmx\${MAX_RAM} -jar $(basename "${forgeJar}") nogui
|
||||
EOF
|
||||
chmod +x "${FTB_BASE_DIR}/ServerStart.sh"
|
||||
else
|
||||
log "Please make sure you are using the server version of the FTB modpack!"
|
||||
exit 2
|
||||
fi
|
||||
startScript="${FTB_BASE_DIR}/ServerStart.sh"
|
||||
chmod +x "$startScript"
|
||||
else
|
||||
log "ERROR: Modpack missing start script and unable to find Forge jar to generate one"
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
scriptCount=$(find "${FTB_BASE_DIR}" $entryScriptExpr | wc -l)
|
||||
if [[ $scriptCount = 0 ]]; then
|
||||
log "Please make sure you are using the server version of the FTB modpack!"
|
||||
exit 2
|
||||
elif (( scriptCount > 1 )); then
|
||||
log "Ambiguous startup scripts in FTB modpack! Found:"
|
||||
find "${FTB_BASE_DIR}" $entryScriptExpr
|
||||
exit 2
|
||||
# Modpacks that use https://github.com/BloodyMods/ServerStarter will sometimes specify an
|
||||
# extra subpath where all the server files get installed. Need to transplant EULA file there.
|
||||
serverSetupConfig=$(find "${FTB_BASE_DIR}" -type f -name server-setup-config.yaml)
|
||||
if [[ $serverSetupConfig && $serverSetupConfig != "~" ]]; then
|
||||
if baseInstallPath=$(mc-image-helper yaml-path --file "$serverSetupConfig" ".install.baseInstallPath"); then
|
||||
resolvedBaseInstallPath="$(dirname "$serverSetupConfig")/${baseInstallPath}"
|
||||
mkdir -p "$resolvedBaseInstallPath"
|
||||
|
||||
cp -n /data/eula.txt "${resolvedBaseInstallPath}/eula.txt"
|
||||
fi
|
||||
fi
|
||||
|
||||
FTB_SERVER_START=$(find "${FTB_BASE_DIR}" $entryScriptExpr)
|
||||
FTB_SERVER_START="$startScript"
|
||||
export FTB_SERVER_START
|
||||
|
||||
FTB_DIR=$(dirname "${FTB_SERVER_START}")
|
||||
@@ -226,15 +242,5 @@ if isTrue "${FTB_LEGACYJAVAFIXER}" && [ ! -e "${legacyJavaFixerPath}" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -e "${FTB_DIR}/FTBInstall.sh" ]; then
|
||||
pushd "${FTB_DIR}"
|
||||
sh FTBInstall.sh
|
||||
popd
|
||||
elif [ -e "${FTB_DIR}/Install.sh" ]; then
|
||||
pushd "${FTB_DIR}"
|
||||
sh Install.sh
|
||||
popd
|
||||
fi
|
||||
|
||||
export FAMILY=FORGE
|
||||
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||
|
||||
@@ -67,6 +67,7 @@ variants=(
|
||||
forge-${mcVersion}-${forgeVersion}-universal.jar
|
||||
forge-${mcVersion}-${forgeVersion}-${mcVersion}-universal.jar
|
||||
fabric-${mcVersion}-${fabricVersion}-server-launch.jar
|
||||
run.sh
|
||||
)
|
||||
for f in "${variants[@]}"; do
|
||||
if [ -f $f ]; then
|
||||
|
||||
@@ -8,7 +8,7 @@ isDebugging && set -x
|
||||
|
||||
get_installer() {
|
||||
if [[ -z $FORGE_INSTALLER_URL ]]; then
|
||||
log "Downloading $normForgeVersion"
|
||||
log "Downloading Forge Installer $normForgeVersion"
|
||||
|
||||
forgeFileNames="
|
||||
$shortForgeVersion/forge-$shortForgeVersion-installer.jar
|
||||
@@ -25,7 +25,7 @@ get_installer() {
|
||||
log "Unable to locate usable URL for $normForgeVersion"
|
||||
exit 2
|
||||
else
|
||||
log "Downloading $FORGE_INSTALLER_URL ..."
|
||||
log "Downloading Forge Installer from $FORGE_INSTALLER_URL ..."
|
||||
if ! get -o "$FORGE_INSTALLER" "$FORGE_INSTALLER_URL"; then
|
||||
log "Failed to download from given location $FORGE_INSTALLER_URL"
|
||||
exit 2
|
||||
@@ -38,6 +38,9 @@ install() {
|
||||
get_installer "$normForgeVersion" "$shortForgeVersion"
|
||||
fi
|
||||
|
||||
# reference issue #1459
|
||||
rm -f run.sh
|
||||
|
||||
log "Installing Forge $shortForgeVersion. This might take a minute or two..."
|
||||
mkdir -p mods
|
||||
tries=3
|
||||
@@ -99,7 +102,7 @@ resolve_versions() {
|
||||
log "Checking Forge version information."
|
||||
case $FORGEVERSION in
|
||||
LATEST)
|
||||
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" "$promosUrl"); then
|
||||
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" --json-value-when-missing "" "$promosUrl"); then
|
||||
log "ERROR: Version $VANILLA_VERSION is not supported by Forge"
|
||||
log " Refer to http://files.minecraftforge.net/ for supported versions"
|
||||
exit 2
|
||||
@@ -107,8 +110,8 @@ resolve_versions() {
|
||||
;;
|
||||
|
||||
RECOMMENDED)
|
||||
if ! FORGE_VERSION=$(get -s --json-path ".promos['$VANILLA_VERSION-recommended']" "$promosUrl"); then
|
||||
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" "$promosUrl"); then
|
||||
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-recommended']" --json-value-when-missing "" "$promosUrl"); then
|
||||
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" --json-value-when-missing "" "$promosUrl"); then
|
||||
log "ERROR: Version $VANILLA_VERSION is not supported by Forge"
|
||||
log " Refer to http://files.minecraftforge.net/ for supported versions"
|
||||
exit 2
|
||||
|
||||
@@ -8,7 +8,7 @@ isDebugging && set -x
|
||||
: ${LIMBO_BUILD:=LATEST}
|
||||
: ${FORCE_REDOWNLOAD:=false}
|
||||
: ${LIMBO_SCHEMA_FILENAME:=default.schem}
|
||||
: ${LEVEL:=Default;${LIMBO_SCHEMA_FILENAME}}
|
||||
: ${LEVEL:=default;${LIMBO_SCHEMA_FILENAME}}
|
||||
# defaults to localhost, if this is not set
|
||||
: ${SERVER_IP:=0.0.0.0}
|
||||
|
||||
|
||||
32
scripts/start-deployLoliserver
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
set -o pipefail
|
||||
set -e
|
||||
|
||||
latestAsset=$(
|
||||
curl -fsSL https://cdn.ci.loliidc.cn:30011/job/LoliServer-1.16.5/lastSuccessfulBuild/artifact/projects/LoliServer/build/libs | \
|
||||
jq '.assets[] | select(.name | match(".*-server.jar"))'
|
||||
)
|
||||
|
||||
if [[ -z "${latestAsset}" ]]; then
|
||||
log "ERROR: latest release of Loliserver is missing server.jar asset"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
isDebugging && log "Latest asset ${latestAsset}"
|
||||
latestJarName=$(echo ${latestAsset} | jq --raw-output '.name')
|
||||
latestJarId=$(echo ${latestAsset} | jq --raw-output '.id')
|
||||
|
||||
|
||||
export SERVER="/data/${latestJarName}"
|
||||
|
||||
if [ ! -f ${SERVER} ]; then
|
||||
log "Downloading ${latestJarName}"
|
||||
curl -H "Accept:application/octet-stream" -o "$SERVER" -fsSL https://cdn.ci.loliidc.cn:30011/job/LoliServer-1.16.5/lastSuccessfulBuild/artifact/projects/LoliServer/build/libs/${latestJarId}
|
||||
fi
|
||||
|
||||
export FAMILY=HYBRID
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||
@@ -5,89 +5,18 @@
|
||||
isDebugging && set -x
|
||||
|
||||
: "${VANILLA_VERSION?}"
|
||||
# stable, dev
|
||||
: "${MAGMA_CHANNEL:=stable}"
|
||||
|
||||
|
||||
magmaDownloadServer() {
|
||||
url=${1?}
|
||||
tagName=${2?}
|
||||
markerFile=${3?}
|
||||
|
||||
export SERVER="/data/magma-server-${VANILLA_VERSION}.jar"
|
||||
|
||||
log "Downloading Magma server file for ${VANILLA_VERSION} @ ${tagName}"
|
||||
if ! curl -o /data/magma-server-${VANILLA_VERSION}.jar -fsSL "$url"; then
|
||||
log "ERROR failed to download Magma server from $url (status=$?)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -n "$SERVER" > "$markerFile"
|
||||
}
|
||||
|
||||
magmaHandleInstaller() {
|
||||
url=${1?}
|
||||
tagName=${2?}
|
||||
markerFile=${3?}
|
||||
|
||||
installerFile="magma-installer-${VANILLA_VERSION}-${tagName}.jar"
|
||||
log "Downloading Magma installer file for ${VANILLA_VERSION} @ ${tagName}"
|
||||
if ! curl -o "$installerFile" -fsSL "$url"; then
|
||||
log "ERROR failed to download Magma installer from $url (status=$?)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "forge" > "$markerFile"
|
||||
|
||||
export FORGE_INSTALLER="$installerFile"
|
||||
export FORGE_INSTALLER_CUSTOM_VERSION="$tagName"
|
||||
|
||||
# now hand off the rest to forge
|
||||
exec ${SCRIPTS:-/}start-deployForge "$@"
|
||||
}
|
||||
|
||||
latestMeta=$(curl -fsSL https://api.magmafoundation.org/api/resources/Magma/${VANILLA_VERSION}/${MAGMA_CHANNEL}/latest || exit $?)
|
||||
if [ $? != 0 ]; then
|
||||
log "ERROR failed to locate latest Magma info for ${VANILLA_VERSION} in channel ${MAGMA_CHANNEL} (error=$?)"
|
||||
if ! downloadUrl=$(get --json-path '$.link' "https://api.magmafoundation.org/api/v2/${VANILLA_VERSION}/latest"); then
|
||||
log "ERROR failed to locate latest Magma download for ${VANILLA_VERSION}. Is that version supported?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tagName=$(echo "${latestMeta}" | jq -r '.tag_name')
|
||||
markerFile=".magma-installed-${VANILLA_VERSION}-${tagName}"
|
||||
if [ -f "${markerFile}" ]; then
|
||||
installedTagName=$(cat "${markerFile}")
|
||||
fi
|
||||
|
||||
if [ ! -f "${markerFile}" ]; then
|
||||
|
||||
if versionLessThan 1.16; then
|
||||
assetType=server
|
||||
else
|
||||
assetType=installer
|
||||
fi
|
||||
|
||||
assetUrl=$(echo "${latestMeta}" | jq -r ".assets | .[].browser_download_url | select(test(\"${assetType}\"))")
|
||||
if [ $? != 0 ] || [ -z "$assetUrl" ]; then
|
||||
log "ERROR failed to extract ${assetType} asset type for ${VANILLA_VERSION} in channel ${MAGMA_CHANNEL}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ${assetType} = server ]]; then
|
||||
magmaDownloadServer "$assetUrl" "$tagName" "$markerFile"
|
||||
else
|
||||
magmaHandleInstaller "$assetUrl" "$tagName" "$markerFile"
|
||||
fi
|
||||
else
|
||||
export SERVER=$(cat "${markerFile}")
|
||||
|
||||
if [[ $SERVER == "forge" ]]; then
|
||||
export FORGE_INSTALLER="magma-installer-${VANILLA_VERSION}-${tagName}.jar"
|
||||
export FORGE_INSTALLER_CUSTOM_VERSION="$tagName"
|
||||
# now hand off the rest to forge
|
||||
exec ${SCRIPTS:-/}start-deployForge "$@"
|
||||
fi
|
||||
if ! SERVER=$(get --output-filename --skip-up-to-date --output /data "$downloadUrl"); then
|
||||
log "ERROR: failed to download Magma server jar from $downloadUrl"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export SERVER
|
||||
export FAMILY=HYBRID
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||
|
||||
@@ -1,10 +1,39 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
set -o pipefail
|
||||
isDebugging && set -x
|
||||
handleDebugMode
|
||||
|
||||
if [[ $PAPER_DOWNLOAD_URL ]]; then
|
||||
: "${PAPER_CUSTOM_JAR:=}"
|
||||
|
||||
ourScript="$0"
|
||||
ourArgs=("$@")
|
||||
|
||||
function handleMissingVersion() {
|
||||
expectedVersion=${VANILLA_VERSION}
|
||||
versions=$(curl -fsSL "https://papermc.io/api/v2/projects/paper" -H "accept: application/json")
|
||||
if [[ $VERSION = LATEST ]]; then
|
||||
tries=0
|
||||
while ((tries++ < 5)); do
|
||||
VANILLA_VERSION=$(echo "$versions" | jq -r ".versions[$((- tries))]")
|
||||
if [[ $(curl -fsSL "https://papermc.io/api/v2/projects/paper/versions/${VANILLA_VERSION}" -H "accept: application/json" \
|
||||
| jq '.builds[-1]') != null ]]; then
|
||||
log "WARN: using ${VANILLA_VERSION} since that's the latest provided by PaperMC"
|
||||
# re-execute the current script with the newly computed version
|
||||
exec "$ourScript" "${ourArgs[@]}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
log "ERROR: ${expectedVersion} is not published by PaperMC"
|
||||
log " Set VERSION to one of the following: "
|
||||
log " $(echo "$versions" | jq -r '.versions | join(", ")')"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [[ $PAPER_CUSTOM_JAR ]]; then
|
||||
export SERVER="$PAPER_CUSTOM_JAR"
|
||||
elif [[ $PAPER_DOWNLOAD_URL ]]; then
|
||||
export SERVER=$(getFilenameFromUrl "${PAPER_DOWNLOAD_URL}")
|
||||
|
||||
if [ -f "$SERVER" ]; then
|
||||
@@ -23,26 +52,16 @@ else
|
||||
0)
|
||||
;;
|
||||
22)
|
||||
versions=$(curl -fsSL "https://papermc.io/api/v2/projects/paper" -H "accept: application/json")
|
||||
if [[ $VERSION = LATEST ]]; then
|
||||
VANILLA_VERSION=$(echo "$versions" | jq -r '.versions[-1]')
|
||||
log "WARN: using ${VANILLA_VERSION} since that's the latest provided by PaperMC"
|
||||
# re-execute the current script with the newly computed version
|
||||
exec "$0" "$@"
|
||||
fi
|
||||
log "ERROR: ${VANILLA_VERSION} is not published by PaperMC"
|
||||
log " Set VERSION to one of the following: "
|
||||
log " $(echo "$versions" | jq -r '.versions | join(", ")')"
|
||||
exit 1
|
||||
handleMissingVersion
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: unknown error while looking up PaperMC version=${VANILLA_VERSION}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
if [ $? != 0 ]; then
|
||||
echo "ERROR: failed to lookup PaperMC build from version ${VANILLA_VERSION}"
|
||||
exit 1
|
||||
|
||||
if [[ $build = null ]]; then
|
||||
handleMissingVersion
|
||||
fi
|
||||
|
||||
export SERVER=$(curl -fsSL "https://papermc.io/api/v2/projects/paper/versions/${VANILLA_VERSION}/builds/${build}" -H "accept: application/json" \
|
||||
|
||||
@@ -1,39 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
|
||||
set -euo pipefail
|
||||
isDebugging && set -x
|
||||
|
||||
IFS=$'\n\t'
|
||||
|
||||
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "1.18" ] ; then
|
||||
log "ERROR: Pufferfish server type only supports VERSION=LATEST, VERSION=1.18. Note that these are branches, not #.#.# versions."
|
||||
if versionLessThan 1.17; then
|
||||
log "ERROR: Pufferfish server type only supports versions 1.17, 1.18 or 1.19, use PUFFERFISH_BUILD to select the the correct build 47 => 1.18.1, 50 => 1.18.2 etc"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
: ${PUFFERFISH_BUILD:=lastSuccessfulBuild}
|
||||
: "${PUFFERFISH_BUILD:=lastSuccessfulBuild}"
|
||||
|
||||
if [ "${VERSION}" = "LATEST" ] || [ "${VERSION}" = "1.18" ]; then
|
||||
PUFFERFISH_BRANCH="1.18"
|
||||
PUFFERFISH_VERSION="1.18.1-R0.1"
|
||||
fi
|
||||
PUFFERFISH_BUILD_JSON=$(curl -X GET -s "https://ci.pufferfish.host/job/Pufferfish-${MAJOR_VANILLA_VERSION}/${PUFFERFISH_BUILD}/api/json")
|
||||
# Example: "url": "https://ci.pufferfish.host/job/Pufferfish-1.18/50/",
|
||||
PUFFERFISH_BUILD_URL=$(jq -n "$PUFFERFISH_BUILD_JSON" | jq -jc '.url // empty' )
|
||||
# Example: "fileName": "pufferfish-paperclip-1.18.2-R0.1-SNAPSHOT-reobf.jar",
|
||||
PUFFERFISH_BUILD_FILENAME=$(jq -n "$PUFFERFISH_BUILD_JSON" | jq -jc '.artifacts[].fileName // empty' )
|
||||
PUFFERFISH_BUILD_DOWNLOAD_URL="${PUFFERFISH_BUILD_URL}artifact/build/libs/${PUFFERFISH_BUILD_FILENAME}"
|
||||
|
||||
log "Using Pufferfish-${PUFFERFISH_BRANCH} branch"
|
||||
|
||||
export SERVER=pufferfish-${PUFFERFISH_BRANCH}-${PUFFERFISH_BUILD}.jar
|
||||
# Setting server to the Jar filename for export.
|
||||
export SERVER=$PUFFERFISH_BUILD_FILENAME
|
||||
|
||||
log "Removing old Pufferfish versions ..."
|
||||
shopt -s nullglob
|
||||
for f in pufferfish-*.jar; do
|
||||
[[ $f != $SERVER ]] && rm $f
|
||||
[[ $f != "$SERVER" ]] && rm "$f"
|
||||
done
|
||||
|
||||
if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
|
||||
artifact="build/libs/pufferfish-paperclip-${PUFFERFISH_VERSION}-SNAPSHOT-reobf.jar"
|
||||
downloadUrl="https://ci.pufferfish.host/job/Pufferfish-${PUFFERFISH_BRANCH}/${PUFFERFISH_BUILD}/artifact/${artifact}"
|
||||
log "Downloading Pufferfish from $downloadUrl ..."
|
||||
if ! get -o "$SERVER" "$downloadUrl"; then
|
||||
log "ERROR: failed to download from $downloadUrl (status=$?)"
|
||||
if [[ ! -f "$SERVER" ]] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
|
||||
log "Downloading Pufferfish from $PUFFERFISH_BUILD_DOWNLOAD_URL ..."
|
||||
if ! get -o "$SERVER" "$PUFFERFISH_BUILD_DOWNLOAD_URL"; then
|
||||
log "ERROR: failed to download from $PUFFERFISH_BUILD_DOWNLOAD_URL (status=$?)"
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
@@ -41,4 +42,4 @@ fi
|
||||
# Normalize on Spigot for later operations
|
||||
export FAMILY=SPIGOT
|
||||
|
||||
exec ${SCRIPTS:-/}start-spiget "$@"
|
||||
exec "${SCRIPTS:-/}start-spiget" "$@"
|
||||
|
||||
@@ -2,31 +2,51 @@
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
: "${PURPUR_DOWNLOAD_URL:=}"
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
isDebugging && set -x
|
||||
|
||||
: "${VANILLA_VERSION:?}"
|
||||
: "${PURPUR_BUILD:=LATEST}"
|
||||
: "${FORCE_REDOWNLOAD:=false}"
|
||||
if [[ $PURPUR_DOWNLOAD_URL ]]; then
|
||||
export SERVER=$(getFilenameFromUrl "${PURPUR_DOWNLOAD_URL}")
|
||||
|
||||
if [[ ${PURPUR_BUILD} == LATEST ]]; then
|
||||
if ! PURPUR_BUILD=$(get --json-path=".builds.latest" "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}"); then
|
||||
log "ERROR: Failed to locate a Purpur build for ${VANILLA_VERSION}."
|
||||
log " Please check if a download is available at https://purpur.pl3x.net/downloads/"
|
||||
exit 1
|
||||
if [ -f "$SERVER" ]; then
|
||||
zarg=(-z "$SERVER")
|
||||
fi
|
||||
fi
|
||||
|
||||
export SERVER="purpur-${VANILLA_VERSION}-${PURPUR_BUILD}.jar"
|
||||
echo "Preparing custom Purpur jar from $PURPUR_DOWNLOAD_URL"
|
||||
|
||||
if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
|
||||
downloadUrl="https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download"
|
||||
log "Downloading Purpur from $downloadUrl ..."
|
||||
if ! get -o "$SERVER" "$downloadUrl"; then
|
||||
log "ERROR: failed to download from $downloadUrl (status=$?)"
|
||||
exit 3
|
||||
curl -fsSL -o "$SERVER" "${zarg[@]}" "${PURPUR_DOWNLOAD_URL}"
|
||||
else
|
||||
: "${VANILLA_VERSION:?}"
|
||||
: "${PURPUR_BUILD:=LATEST}"
|
||||
: "${FORCE_REDOWNLOAD:=false}"
|
||||
|
||||
if [[ ${PURPUR_BUILD} == LATEST ]]; then
|
||||
if ! PURPUR_BUILD=$(get --json-path=".builds.latest" "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}"); then
|
||||
log "ERROR: Failed to locate a Purpur build for ${VANILLA_VERSION}."
|
||||
log " Please check if a download is available at https://purpur.pl3x.net/downloads/"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
export SERVER="purpur-${VANILLA_VERSION}-${PURPUR_BUILD}.jar"
|
||||
|
||||
log "Removing old Purpur versions ..."
|
||||
shopt -s nullglob
|
||||
for f in purpur-*.jar; do
|
||||
[[ $f != "$SERVER" ]] && rm "$f"
|
||||
done
|
||||
|
||||
if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
|
||||
downloadUrl="https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download"
|
||||
log "Downloading Purpur from $downloadUrl ..."
|
||||
if ! get -o "$SERVER" "$downloadUrl"; then
|
||||
log "ERROR: failed to download from $downloadUrl (status=$?)"
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Normalize on Spigot for later operations
|
||||
|
||||
60
scripts/start-deployQuilt
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
|
||||
requireVar VANILLA_VERSION
|
||||
export TYPE=QUILT
|
||||
: "${QUILT_LAUNCHER:=}"
|
||||
: "${QUILT_LAUNCHER_URL:=}"
|
||||
: "${QUILT_INSTALLER_URL:=}"
|
||||
: "${QUILT_INSTALLER_VERSION:=LATEST}"
|
||||
: "${QUILT_LOADER_VERSION:=LATEST}"
|
||||
|
||||
isDebugging && set -x
|
||||
|
||||
# Custom quilt jar
|
||||
if [[ $QUILT_LAUNCHER ]]; then
|
||||
export SERVER=${QUILT_LAUNCHER}
|
||||
# Custom quilt jar url
|
||||
elif [[ $QUILT_LAUNCHER_URL ]]; then
|
||||
export SERVER=quilt-server-$(echo -n "$QUILT_LAUNCHER_URL" | mc-image-helper hash)
|
||||
# Official quilt installer
|
||||
else
|
||||
if [[ ${QUILT_INSTALLER_VERSION^^} = LATEST ]]; then
|
||||
log "Checking Quilt Installer version information."
|
||||
QUILT_INSTALLER_VERSION=$(maven-metadata-release https://maven.quiltmc.org/repository/release/org/quiltmc/quilt-installer/maven-metadata.xml)
|
||||
fi
|
||||
if [[ ${QUILT_LOADER_VERSION^^} = LATEST ]]; then
|
||||
log "Checking Quilt Loader version information."
|
||||
QUILT_LOADER_VERSION=$(maven-metadata-release https://maven.quiltmc.org/repository/release/org/quiltmc/quilt-loader/maven-metadata.xml)
|
||||
fi
|
||||
export INSTALLER=quilt-installer-${QUILT_INSTALLER_VERSION}.jar
|
||||
export SERVER=quilt-server-${VANILLA_VERSION}-${QUILT_LOADER_VERSION}-launch.jar
|
||||
export QUILT_INSTALLER_URL="https://maven.quiltmc.org/repository/release/org/quiltmc/quilt-installer/${QUILT_INSTALLER_VERSION}/quilt-installer-${QUILT_INSTALLER_VERSION}.jar"
|
||||
fi
|
||||
|
||||
if [[ ! -e ${SERVER} && ! -z ${QUILT_INSTALLER_URL} ]]; then
|
||||
log "Downloading and installing $QUILT_INSTALLER_URL ..."
|
||||
if ! get -o "$INSTALLER" "$QUILT_INSTALLER_URL"; then
|
||||
log "Failed to download from given location $QUILT_INSTALLER_URL"
|
||||
exit 2
|
||||
fi
|
||||
if ! java -jar ${INSTALLER} install server ${VANILLA_VERSION} ${QUILT_LOADER_VERSION} --install-dir=./ --download-server; then
|
||||
log "Failed to install $INSTALLER"
|
||||
exit 2
|
||||
fi
|
||||
if ! mv quilt-server-launch.jar ${SERVER}; then
|
||||
log "Failed to rename $SERVER"
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! -e ${SERVER} ]]; then
|
||||
log "$SERVER does not exist, cannot launch server!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export FAMILY=FABRIC
|
||||
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||
@@ -24,12 +24,14 @@ esac
|
||||
if [ -z $SPONGEVERSION ]; then
|
||||
log "Choosing Version for Sponge"
|
||||
if [ "$SPONGEBRANCH" == "stable" ]; then
|
||||
export SPONGEVERSION=`curl -fsSL https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE | jq -r '.buildTypes.stable.latest.version'`
|
||||
SPONGEVERSION=`curl -fsSL https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE | jq -r '.buildTypes.stable.latest.version'`
|
||||
else
|
||||
export SPONGEVERSION=`curl -fsSL https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE | jq -r '.buildTypes.bleeding.latest.version'`
|
||||
SPONGEVERSION=`curl -fsSL https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE | jq -r '.buildTypes.bleeding.latest.version'`
|
||||
fi
|
||||
fi
|
||||
|
||||
VANILLA_VERSION="$SPONGEVERSION"
|
||||
export VANILLA_VERSION
|
||||
export SERVER="spongevanilla-$SPONGEVERSION.jar"
|
||||
|
||||
if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then
|
||||
|
||||
@@ -8,27 +8,25 @@ set -o pipefail
|
||||
export SERVER="minecraft_server.${VANILLA_VERSION// /_}.jar"
|
||||
|
||||
if [ ! -e "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
|
||||
log "Downloading $SERVER ..."
|
||||
log "Locating download for $SERVER ..."
|
||||
debug "Finding version manifest for $VANILLA_VERSION"
|
||||
versionManifestUrl=$(get 'https://launchermeta.mojang.com/mc/game/version_manifest.json' | jq --arg VANILLA_VERSION "$VANILLA_VERSION" --raw-output '[.versions[]|select(.id == $VANILLA_VERSION)][0].url')
|
||||
result=$?
|
||||
if [ $result != 0 ]; then
|
||||
log "ERROR failed to obtain version manifest URL ($result)"
|
||||
log "ERROR: failed to obtain version manifest URL ($result)"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$versionManifestUrl" = "null" ]; then
|
||||
log "ERROR couldn't find a matching manifest entry for $VANILLA_VERSION"
|
||||
log "ERROR: couldn't find a matching manifest entry for $VANILLA_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
debug "Found version manifest at $versionManifestUrl"
|
||||
|
||||
serverDownloadUrl=$(get --json-path '$.downloads.server.url' "${versionManifestUrl}")
|
||||
result=$?
|
||||
if [ $result != 0 ]; then
|
||||
log "ERROR failed to obtain version manifest from $versionManifestUrl ($result)"
|
||||
if ! serverDownloadUrl=$(get --json-path '$.downloads.server.url' "${versionManifestUrl}"); then
|
||||
log "ERROR: failed to obtain version manifest from $versionManifestUrl ($result)"
|
||||
exit 1
|
||||
elif [ "$serverDownloadUrl" = "null" ]; then
|
||||
log "ERROR version $VANILLA_VERSION does not provide a server download"
|
||||
log "ERROR: there is not a server download for version $VANILLA_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -36,7 +34,7 @@ if [ ! -e "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
|
||||
get -o "$SERVER" "$serverDownloadUrl"
|
||||
result=$?
|
||||
if [ $result != 0 ]; then
|
||||
log "ERROR failed to download server from $serverDownloadUrl ($result)"
|
||||
log "ERROR: failed to download server from $serverDownloadUrl ($result)"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -5,16 +5,35 @@
|
||||
isDebugging && set -x
|
||||
|
||||
if [ -n "$ICON" ]; then
|
||||
if [ ! -e server-icon.png ] || [ "${OVERRIDE_ICON}" == "TRUE" ]; then
|
||||
if [ ! -e server-icon.png ] || isTrue "${OVERRIDE_ICON}"; then
|
||||
log "Using server icon from $ICON..."
|
||||
# Not sure what it is yet...call it "img"
|
||||
curl -sSL -o /tmp/icon.img $ICON
|
||||
specs=$(identify /tmp/icon.img | awk '{print $2,$3}')
|
||||
if [ "$specs" = "PNG 64x64" ]; then
|
||||
mv /tmp/icon.img /data/server-icon.png
|
||||
if isURL "$ICON"; then
|
||||
# Not sure what it is yet...call it "img"
|
||||
if ! get -o /tmp/icon.img "$ICON"; then
|
||||
log "ERROR: failed to download icon from $ICON"
|
||||
exit 1
|
||||
fi
|
||||
ICON=/tmp/icon.img
|
||||
iconSrc="url"
|
||||
elif [ -f "$ICON" ]; then
|
||||
iconSrc="file"
|
||||
else
|
||||
log "ERROR: $ICON does not appear to be a URL or existing file"
|
||||
exit 1
|
||||
fi
|
||||
read -r -a specs < <(identify "$ICON" | awk 'NR == 1 { print $2, $3 }')
|
||||
if [ "${specs[0]} ${specs[1]}" = "PNG 64x64" ]; then
|
||||
if [ $iconSrc = url ]; then
|
||||
mv -f /tmp/icon.img /data/server-icon.png
|
||||
else
|
||||
cp -f "$ICON" /data/server-icon.png
|
||||
fi
|
||||
elif [ "${specs[0]}" = GIF ]; then
|
||||
log "Converting GIF image to 64x64 PNG..."
|
||||
convert "$ICON"[0] -resize 64x64! /data/server-icon.png
|
||||
else
|
||||
log "Converting image to 64x64 PNG..."
|
||||
convert /tmp/icon.img -resize 64x64! /data/server-icon.png
|
||||
convert "$ICON" -resize 64x64! /data/server-icon.png
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -91,8 +110,9 @@ if [[ ${GUI,,} = false ]]; then
|
||||
EXTRA_ARGS+=" nogui"
|
||||
fi
|
||||
|
||||
: "${INIT_MEMORY:=${MEMORY}}"
|
||||
: "${MAX_MEMORY:=${MEMORY}}"
|
||||
: "${MEMORY=1G}"
|
||||
: "${INIT_MEMORY=${MEMORY}}"
|
||||
: "${MAX_MEMORY=${MEMORY}}"
|
||||
|
||||
expandedDOpts=
|
||||
if [ -n "$JVM_DD_OPTS" ]; then
|
||||
@@ -102,8 +122,8 @@ if [ -n "$JVM_DD_OPTS" ]; then
|
||||
done
|
||||
fi
|
||||
|
||||
if isTrue ${ENABLE_JMX}; then
|
||||
: ${JMX_PORT:=7091}
|
||||
if isTrue "${ENABLE_JMX}"; then
|
||||
: "${JMX_PORT:=7091}"
|
||||
JVM_OPTS="${JVM_OPTS}
|
||||
-Dcom.sun.management.jmxremote.local.only=false
|
||||
-Dcom.sun.management.jmxremote.port=${JMX_PORT}
|
||||
@@ -166,6 +186,12 @@ if isTrue "${USE_FLARE_FLAGS}"; then
|
||||
"
|
||||
fi
|
||||
|
||||
if isTrue "${USE_SIMD_FLAGS}"; then
|
||||
JVM_XX_OPTS="${JVM_XX_OPTS}
|
||||
--add-modules=jdk.incubator.vector
|
||||
"
|
||||
fi
|
||||
|
||||
if isTrue "${DEBUG_MEMORY}"; then
|
||||
log "Memory usage and availability (in MB)"
|
||||
uname -a
|
||||
|
||||
36
scripts/start-rconcmds
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
|
||||
: "${RCON_CMDS_STARTUP:=}"
|
||||
: "${RCON_CMDS_ON_CONNECT:=}"
|
||||
: "${RCON_CMDS_ON_DISCONNECT:=}"
|
||||
: "${RCON_CMDS_FIRST_CONNECT:=}"
|
||||
: "${RCON_CMDS_LAST_DISCONNECT:=}"
|
||||
: "${RCON_CMDS_PERIOD:=10}"
|
||||
: "${SERVER_PORT:=25565}"
|
||||
export RCON_CMDS_STARTUP
|
||||
export RCON_CMDS_ON_CONNECT
|
||||
export RCON_CMDS_ON_DISCONNECT
|
||||
export RCON_CMDS_FIRST_CONNECT
|
||||
export RCON_CMDS_LAST_DISCONNECT
|
||||
export RCON_CMDS_PERIOD
|
||||
export SERVER_PORT
|
||||
|
||||
log "Rcon cmds functionality enabled"
|
||||
|
||||
isDebugging && set -x
|
||||
|
||||
if ! [[ $RCON_CMDS_PERIOD =~ ^[0-9]+$ ]]; then
|
||||
RCON_CMDS_PERIOD=10
|
||||
export RCON_CMDS_PERIOD
|
||||
log "Warning: RCON_CMDS_PERIOD is not numeric, set to 10 (seconds)"
|
||||
fi
|
||||
if [ "$RCON_CMDS_PERIOD" -eq "0" ] ; then
|
||||
RCON_CMDS_PERIOD=10
|
||||
export RCON_CMDS_PERIOD
|
||||
log "Warning: RCON_CMDS_PERIOD must not be 0, set to 10 (seconds)"
|
||||
fi
|
||||
|
||||
/rconcmds/rcon-cmds-daemon.sh &
|
||||
@@ -17,6 +17,7 @@ FORGEAPI_BASE_URL=${FORGEAPI_BASE_URL:-https://api.curseforge.com/v1}
|
||||
RELEASE_NUMBER_FILTER=1
|
||||
MINECRAFT_GAME_ID=432
|
||||
FILTER_BY_FAMILY=false
|
||||
DOWNLOADED_MODIDS=()
|
||||
out_dir=/data/mods
|
||||
|
||||
# shellcheck source=start-utils
|
||||
@@ -24,8 +25,8 @@ out_dir=/data/mods
|
||||
isDebugging && set -x
|
||||
|
||||
# Remove old mods/plugins
|
||||
if isTrue "${REMOVE_OLD_FORGEAPI_MODS}" && [ -z "${MODS_FORGEAPI_KEY}" ]; then
|
||||
removeOldMods /data/mods
|
||||
if isTrue "${REMOVE_OLD_FORGEAPI_MODS}"; then
|
||||
removeOldMods "/data/mods"
|
||||
fi
|
||||
|
||||
# Family filter is on by default for Forge, Fabric, and Bukkit
|
||||
@@ -56,7 +57,7 @@ updateReleaseNumber(){
|
||||
}
|
||||
|
||||
retrieveVersionTypeNumber(){
|
||||
VERSION_NAME="Minecraft ${VANILLA_VERSION%.*}"
|
||||
VERSION_NAME="Minecraft ${MAJOR_VANILLA_VERSION}"
|
||||
minecraft_types=$(curl -X GET -s \
|
||||
"${FORGEAPI_BASE_URL}/games/${MINECRAFT_GAME_ID}/version-types" \
|
||||
-H 'Accept: application/json' -H 'x-api-key: '${MODS_FORGEAPI_KEY}'')
|
||||
@@ -76,7 +77,7 @@ retrieveVersionTypeNumber(){
|
||||
}
|
||||
|
||||
modFileByProjectID(){
|
||||
project_id=$(echo $1 | tr -d '"')
|
||||
project_id=$(echo "$1" | tr -d '"')
|
||||
project_id_release_type=$2
|
||||
project_id_file_name=$3
|
||||
unset PROJECT_FILE
|
||||
@@ -104,8 +105,8 @@ modFileByProjectID(){
|
||||
total_count=$(jq -n "$project_files" | jq -c '.pagination.totalCount' )
|
||||
|
||||
# Checking for a individual release type input, if not use global
|
||||
if [ $project_id_release_type ]; then
|
||||
updateReleaseNumber $project_id_release_type
|
||||
if [ "$project_id_release_type" ]; then
|
||||
updateReleaseNumber "$project_id_release_type"
|
||||
unset project_id_release_type
|
||||
else
|
||||
updateReleaseNumber $MODS_FORGEAPI_RELEASES
|
||||
@@ -113,38 +114,38 @@ modFileByProjectID(){
|
||||
|
||||
# grabs the highest ID of the releaseTypes selected.
|
||||
# Default is 1 for Release, Beta is 2, and Alpha is 3. Using less than we can validate highest release.
|
||||
if [ $project_id_file_name ]; then
|
||||
if [ "$project_id_file_name" ]; then
|
||||
# Looks for file by name
|
||||
current_project_file=$(jq -n "$project_files" | jq --arg FILE_NAME "$project_id_file_name" -jc '
|
||||
.data | map(select(.fileName<=($FILE_NAME))) | .[0] // empty')
|
||||
elif $( ! isTrue "$MODS_FORGEAPI_IGNORE_GAMETYPE" ) && $FILTER_BY_FAMILY ; then
|
||||
elif isFalse "${MODS_FORGEAPI_IGNORE_GAMETYPE}" && $FILTER_BY_FAMILY ; then
|
||||
# Looks for file by version and server type in lowercase
|
||||
current_project_file=$(jq -n "$project_files" | jq --arg RELEASE_FILTER "$RELEASE_NUMBER_FILTER" --arg GAME_TYPE ${FAMILY,,} -jc '
|
||||
.data | sort_by(.id) | reverse | map(select(.gameVersions[] | ascii_downcase | contains ($GAME_TYPE))) | map(select(.releaseType<=($RELEASE_FILTER|tonumber))) | .[0] // empty')
|
||||
current_project_file=$(jq -n "$project_files" | jq --arg RELEASE_FILTER "$RELEASE_NUMBER_FILTER" --arg GAME_TYPE "${FAMILY,,}" --arg VERSION "$VANILLA_VERSION" -jc '
|
||||
.data | sort_by(.id) | reverse | map(select(.gameVersions[] | ascii_downcase | contains ($GAME_TYPE))) | map(select(.gameVersions[] | contains ($VERSION))) | map(select(.releaseType<=($RELEASE_FILTER|tonumber))) | .[0] // empty')
|
||||
else
|
||||
# Looks for file by version only.
|
||||
current_project_file=$(jq -n "$project_files" | jq --arg RELEASE_FILTER "$RELEASE_NUMBER_FILTER" -jc '
|
||||
.data | sort_by(.id) | reverse | map(select(.releaseType<=($RELEASE_FILTER|tonumber))) | .[0] // empty')
|
||||
current_project_file=$(jq -n "$project_files" | jq --arg RELEASE_FILTER "$RELEASE_NUMBER_FILTER" --arg VERSION "$VANILLA_VERSION" -jc '
|
||||
.data | sort_by(.id) | reverse | map(select(.gameVersions[] | contains ($VERSION))) | map(select(.releaseType<=($RELEASE_FILTER|tonumber))) | .[0] // empty')
|
||||
fi
|
||||
|
||||
# Logic to grab the latest release over the entire pagination
|
||||
if [ ! "$PROJECT_FILE" ]; then
|
||||
PROJECT_FILE=$current_project_file
|
||||
elif [ "$current_project_file" ]; then
|
||||
current_project_file_id=$(jq -n "$current_project_file" | jq -jc '.id' )
|
||||
PROJECT_FILE_ID=$(jq -n "$PROJECT_FILE" | jq -jc '.id' )
|
||||
current_project_file_id=$(jq -n "$current_project_file" | jq -jc '.id // empty' )
|
||||
PROJECT_FILE_ID=$(jq -n "$PROJECT_FILE" | jq -jc '.id // empty' )
|
||||
if (( current_project_file_id > PROJECT_FILE_ID )); then
|
||||
PROJECT_FILE=$current_project_file
|
||||
fi
|
||||
fi
|
||||
|
||||
# check to see if we have gone to far or lost our index and exit with an error
|
||||
if [ -z "$index" ] || [ -z "$total_count" ] || [ $index -ge $total_count ]; then
|
||||
if [ -z "$index" ] || [ -z "$total_count" ] || [ $index -ge "$total_count" ]; then
|
||||
log "ERROR: Unable to retrieve any files for ${project_id} from ForgeAPI also Validate files have release type associated with no. ${RELEASE_NUMBER_FILTER}"
|
||||
exit 2
|
||||
fi
|
||||
# Increment start index to new set.
|
||||
index=$(($index + $pageSize))
|
||||
index=$((index + pageSize))
|
||||
done
|
||||
if [ ! "$PROJECT_FILE" ]; then
|
||||
log "ERROR: Unable to retrieve any files for ${project_id}, Release Type: ${RELEASE_NUMBER_FILTER}, FAMILY_TYPE: ${FAMILY,,}"
|
||||
@@ -157,17 +158,22 @@ downloadModPackfromModFile() {
|
||||
log "ERROR: Project File not found from the ForgeAPI"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# grabs needed values from our json return
|
||||
file_name=$(jq -n "$PROJECT_FILE" | jq -jc '.fileName' )
|
||||
download_url=$(jq -n "$PROJECT_FILE" | jq -jc '.downloadUrl' )
|
||||
|
||||
# trys to make the output directory incase it doesnt exist.
|
||||
mkdir -p "$out_dir"
|
||||
echo "Downloading ${download_url}"
|
||||
if ! get --skip-up-to-date -o "${out_dir}/${file_name}" $download_url ; then
|
||||
log "ERROR: failed to download from ${download_url}"
|
||||
exit 2
|
||||
debug "DEBUG: PROJECT_FILE: ${PROJECT_FILE}"
|
||||
# grabs needed values from our json return
|
||||
file_name=$(jq -n "$PROJECT_FILE" | jq -jc '.fileName // empty' )
|
||||
download_url=$(jq -n "$PROJECT_FILE" | jq -jc '.downloadUrl // empty' )
|
||||
mod_id=$(jq -n "$PROJECT_FILE" | jq -jc '.modId // empty' )
|
||||
|
||||
if [ ! -f "${out_dir}/${file_name}" ]; then
|
||||
echo "Downloading ${download_url}"
|
||||
# Track the mods we have downloaded.
|
||||
DOWNLOADED_MODIDS+=("${mod_id}")
|
||||
if ! get --skip-up-to-date -o "${out_dir}/${file_name}" "${download_url}"; then
|
||||
log "ERROR: failed to download from ${download_url}"
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -177,30 +183,15 @@ downloadDependencies(){
|
||||
required_dependencies=$(jq -n "$dependencies" | jq --arg REQUIRED_FILTER "3" -jc '
|
||||
map(select(.relationType==($REQUIRED_FILTER|tonumber)))')
|
||||
if [ "$required_dependencies" ]; then
|
||||
jq -n "$required_dependencies" | jq -c '.[]?' | while read current_dependency; do
|
||||
while read -r current_dependency; do
|
||||
mod_id=$(jq -n "$current_dependency" | jq -jc '.modId' )
|
||||
|
||||
# BROKEN: Example Voice mod keeps returning the voice mod file id instead of the mod file id.
|
||||
# file_id=$(jq -n "$current_dependency" | jq -jc '.fileId' )
|
||||
# dependency_data=$(curl -X GET -s \
|
||||
# "${FORGEAPI_BASE_URL}/mods/${mod_id}/files/${file_id}/download-url" \
|
||||
# -H 'Accept: application/json' -H 'x-api-key: '${MODS_FORGEAPI_KEY}'')
|
||||
# if [ ! "$dependency_data" ]; then
|
||||
# log "ERROR: unable to retrieve dependency data files for ${project_id} from ForgeAPI"
|
||||
# exit 2
|
||||
# fi
|
||||
# dependency_download_url=$(jq -n "$dependency_data" | jq -jc '.data' )
|
||||
# echo "Downloading dependency ${dependency_download_url}"
|
||||
# if ! get -o "${out_dir}/" $dependency_download_url ; then
|
||||
# log "ERROR: failed to download dependency from ${dependency_download_url}"
|
||||
# exit 2
|
||||
# fi
|
||||
|
||||
# Using current mod path and release to go get the REQUIRED DEPENDENCY
|
||||
# NOTE: we are ASUMING it will be release.
|
||||
modFileByProjectID $mod_id "release"
|
||||
downloadModPackfromModFile
|
||||
done
|
||||
# Validate we have not tried to download the mod yet.
|
||||
if [[ ! "${DOWNLOADED_MODIDS[*]}" =~ $mod_id ]]; then
|
||||
modFileByProjectID "$mod_id" "release"
|
||||
downloadModPackfromModFile
|
||||
fi
|
||||
# needs to be piped in to keep look in main process
|
||||
done < <(jq -n "$required_dependencies" | jq -c '.[]?')
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -213,20 +204,25 @@ if [ "$MODS_FORGEAPI_FILE" ] && [ -z "$MODS_FORGEAPI_PROJECTIDS" ]; then
|
||||
log "ERROR: given MODS_FORGEAPI_FILE file does not exist"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
debug "DEBUG: MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_FILE}"
|
||||
# Needs loop here to look up release types befor calling download.
|
||||
jq -c '.[]?' $MODS_FORGEAPI_FILE | while read current_project; do
|
||||
while read -r current_project; do
|
||||
debug "DEBUG: current_project: ${current_project}"
|
||||
# Per stack overflow we can use //empty to return empty string that works with -z
|
||||
project_id=$(jq -n "$current_project" | jq -r '.projectId // empty' )
|
||||
current_release_type=$(jq -n "$current_project" | jq -r '.releaseType // empty' )
|
||||
current_file_name=$(jq -n "$current_project" | jq -r '.fileName // empty' )
|
||||
|
||||
modFileByProjectID $project_id $current_release_type $current_file_name
|
||||
downloadModPackfromModFile
|
||||
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then
|
||||
downloadDependencies
|
||||
# Validate we have not tried to download the mod yet.
|
||||
if [[ ! "${DOWNLOADED_MODIDS[*]}" =~ $project_id ]]; then
|
||||
modFileByProjectID "$project_id" "$current_release_type" "$current_file_name"
|
||||
downloadModPackfromModFile
|
||||
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then
|
||||
downloadDependencies
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# needs to be piped in to keep look in main process
|
||||
done < <(jq -c '.[]?' $MODS_FORGEAPI_FILE)
|
||||
fi
|
||||
|
||||
# Use only project ids and global release data.
|
||||
@@ -234,10 +230,13 @@ if [ "$MODS_FORGEAPI_PROJECTIDS" ] && [ -z "$MODS_FORGEAPI_FILE" ]; then
|
||||
ensureModKey
|
||||
updateFamilyFilter
|
||||
for project_id in ${MODS_FORGEAPI_PROJECTIDS//,/ }; do
|
||||
modFileByProjectID $project_id
|
||||
downloadModPackfromModFile
|
||||
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then
|
||||
downloadDependencies
|
||||
# Validate we have not tried to download the mod yet.
|
||||
if [[ ! "${DOWNLOADED_MODIDS[*]}" =~ $project_id ]]; then
|
||||
modFileByProjectID $project_id
|
||||
downloadModPackfromModFile
|
||||
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then
|
||||
downloadDependencies
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
@@ -23,29 +23,35 @@ if isTrue "${REMOVE_OLD_MODS}" && [ -z "${MODS_FILE}" ]; then
|
||||
fi
|
||||
|
||||
# If packwiz url passed, bootstrap packwiz and update mods before other modpack processing
|
||||
if [[ "${PACKWIZ_URL}" ]]; then
|
||||
if [[ "${PACKWIZ_URL:-}" ]]; then
|
||||
# Ensure we have the latest packwiz bootstrap installer
|
||||
latestPackwiz=$(curl -fsSL https://api.github.com/repos/packwiz/packwiz-installer-bootstrap/releases/latest)
|
||||
if [[ -z "${latestPackwiz}" ]]; then
|
||||
log "WARNING: Could not retrieve Packwiz bootstrap installer release information"
|
||||
else
|
||||
isDebugging && log "Latest packwiz ${latestPackwiz}"
|
||||
latestPackwizVer=$(echo ${latestPackwiz} | jq --raw-output '.tag_name')
|
||||
latestPackwizUrl=$(echo ${latestPackwiz} | jq --raw-output '.assets[] | select(.name | match("packwiz-installer-bootstrap.jar")) | .url')
|
||||
: "${PACKWIZ_JAR:=packwiz-installer-bootstrap_${latestPackwizVer}.jar}"
|
||||
if [[ ! -e $PACKWIZ_JAR ]]; then
|
||||
latestPackwizVer=$(echo "${latestPackwiz}" | jq --raw-output '.tag_name')
|
||||
latestPackwizUrl=$(echo "${latestPackwiz}" | jq --raw-output '.assets[] | select(.name | match("packwiz-installer-bootstrap.jar")) | .url')
|
||||
: "${PACKWIZ_BOOTSTRAP_JAR:=packwiz-installer-bootstrap_${latestPackwizVer}.jar}"
|
||||
if [[ ! -e $PACKWIZ_BOOTSTRAP_JAR ]]; then
|
||||
log "Downloading Packwiz ${latestPackwizVer}"
|
||||
curl -H "Accept:application/octet-stream" -o "$PACKWIZ_JAR" -fsSL ${latestPackwizUrl}
|
||||
ln -sf "${PACKWIZ_JAR}" packwiz-installer-bootstrap.jar
|
||||
if ! curl -H "Accept:application/octet-stream" -o "$PACKWIZ_BOOTSTRAP_JAR" -fsSL ${latestPackwizUrl}; then
|
||||
log "ERROR: failed to download Packwiz bootstrap installer"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [[ ! -e packwiz-installer-bootstrap.jar ]]; then
|
||||
log "ERROR: Packwiz not available or could not be downloaded from Github!"
|
||||
exit 1
|
||||
fi
|
||||
if isURL "${PACKWIZ_URL}"; then
|
||||
log "Running packwiz against URL: ${PACKWIZ_URL}"
|
||||
java -jar packwiz-installer-bootstrap.jar -g -s server "${PACKWIZ_URL}"
|
||||
log "Running packwiz installer against URL: ${PACKWIZ_URL}"
|
||||
java -jar "${PACKWIZ_BOOTSTRAP_JAR}" -g -s server "${PACKWIZ_URL}"
|
||||
#if bootstrap download fails, download installer manually - then run without updating
|
||||
returnVal=$?
|
||||
if [[ $returnVal ]]; then
|
||||
latestPackwizInstaller=$(curl -fsSL https://api.github.com/repos/packwiz/packwiz-installer/releases/latest)
|
||||
latestPackwizInstallerVer=$(echo "${latestPackwizInstaller}" | jq --raw-output '.tag_name')
|
||||
latestPackwizInstallerUrl=$(echo "${latestPackwizInstaller}" | jq --raw-output '.assets[] | select(.name | match("packwiz-installer.jar")) | .url')
|
||||
log "Packwiz couldn't update - Downloading Packwiz Installer ${latestPackwizInstallerVer}"
|
||||
curl -H "Accept:application/octet-stream" -o "packwiz-installer.jar" -fsSL "${latestPackwizInstallerUrl}"
|
||||
java -jar "${PACKWIZ_BOOTSTRAP_JAR}" -g -bootstrap-no-update -s server "${PACKWIZ_URL}"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -187,73 +193,104 @@ case "X$EFFECTIVE_MANIFEST_FILE" in
|
||||
esac
|
||||
fi
|
||||
|
||||
: "${GENERIC_PACKS:=${GENERIC_PACK}}"
|
||||
: "${GENERIC_PACKS_PREFIX:=}"
|
||||
: "${GENERIC_PACKS_SUFFIX:=}"
|
||||
function genericPacks() {
|
||||
: "${GENERIC_PACKS:=${GENERIC_PACK}}"
|
||||
: "${GENERIC_PACKS_PREFIX:=}"
|
||||
: "${GENERIC_PACKS_SUFFIX:=}"
|
||||
|
||||
if [[ "${GENERIC_PACKS}" ]]; then
|
||||
IFS=',' read -ra packs <<< "${GENERIC_PACKS}"
|
||||
if [[ "${GENERIC_PACKS}" ]]; then
|
||||
IFS=',' read -ra packs <<< "${GENERIC_PACKS}"
|
||||
|
||||
packFiles=()
|
||||
for packEntry in "${packs[@]}"; do
|
||||
pack="${GENERIC_PACKS_PREFIX}${packEntry}${GENERIC_PACKS_SUFFIX}"
|
||||
if isURL "${pack}"; then
|
||||
mkdir -p /data/packs
|
||||
log "Downloading generic pack from $pack"
|
||||
if ! outfile=$(get -o /data/packs --output-filename --skip-up-to-date "$pack"); then
|
||||
log "ERROR: failed to download $pack"
|
||||
exit 2
|
||||
packFiles=()
|
||||
for packEntry in "${packs[@]}"; do
|
||||
pack="${GENERIC_PACKS_PREFIX}${packEntry}${GENERIC_PACKS_SUFFIX}"
|
||||
if isURL "${pack}"; then
|
||||
mkdir -p /data/packs
|
||||
log "Downloading generic pack from $pack"
|
||||
if ! outfile=$(get -o /data/packs --output-filename --skip-up-to-date "$pack"); then
|
||||
log "ERROR: failed to download $pack"
|
||||
exit 2
|
||||
fi
|
||||
packFiles+=("$outfile")
|
||||
else
|
||||
packFiles+=("$pack")
|
||||
fi
|
||||
packFiles+=("$outfile")
|
||||
else
|
||||
packFiles+=("$pack")
|
||||
fi
|
||||
done
|
||||
|
||||
isDebugging && [ -f "$sum_file}" ] && cat "$sum_file"
|
||||
|
||||
log "Checking if generic packs are up to date"
|
||||
if isTrue "${SKIP_GENERIC_PACK_UPDATE_CHECK:-false}" && [ -f "$sum_file" ]; then
|
||||
log "Skipping generic pack update check"
|
||||
elif isTrue "${FORCE_GENERIC_PACK_UPDATE}" || ! checkSum "${sum_file}"; then
|
||||
log "Generic pack(s) are out of date. Re-applying..."
|
||||
|
||||
base_dir=/tmp/generic_pack_base
|
||||
mkdir -p ${base_dir}
|
||||
for pack in "${packFiles[@]}"; do
|
||||
isDebugging && ls -l "${pack}"
|
||||
extract "${pack}" "${base_dir}"
|
||||
done
|
||||
|
||||
# recalculate the actual base directory of content
|
||||
base_dir=$(find "$base_dir" -type d \( -name mods -o -name plugins -o -name config \) -printf '%h' -quit)
|
||||
if [[ ! $base_dir ]]; then
|
||||
log "ERROR: Unable to find content base of generic packs ${GENERIC_PACKS}. Directories:"
|
||||
find /tmp/generic_pack_base -type d -printf ' - %P\n'
|
||||
exit 1
|
||||
isDebugging && [ -f "$sum_file}" ] && cat "$sum_file"
|
||||
|
||||
log "Checking if generic packs are up to date"
|
||||
if isTrue "${SKIP_GENERIC_PACK_UPDATE_CHECK:-false}" && [ -f "$sum_file" ]; then
|
||||
log "Skipping generic pack update check"
|
||||
elif isTrue "${FORCE_GENERIC_PACK_UPDATE}" || ! checkSum "${sum_file}"; then
|
||||
log "Generic pack(s) are out of date. Re-applying..."
|
||||
|
||||
original_base_dir=/data/.tmp/generic_pack_base
|
||||
base_dir=$original_base_dir
|
||||
rm -rf "${base_dir}"
|
||||
mkdir -p "${base_dir}"
|
||||
for pack in "${packFiles[@]}"; do
|
||||
isDebugging && ls -l "${pack}"
|
||||
extract "${pack}" "${base_dir}"
|
||||
done
|
||||
|
||||
# recalculate the actual base directory of content
|
||||
if ! base_dir=$(mc-image-helper find \
|
||||
--max-depth=3 --type=directory --name=mods,plugins,config \
|
||||
--only-shallowest --fail-no-matches --format '%h' \
|
||||
"$base_dir"); then
|
||||
log "ERROR: Unable to find content base of generic packs ${GENERIC_PACKS}. Directories:"
|
||||
mc-image-helper find --name=* --max-depth=3 --type=directory --format '- %P' "$original_base_dir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f /data/manifest.txt ]; then
|
||||
log "Manifest exists from older generic pack, cleaning up ..."
|
||||
while read -r f; do
|
||||
rm -rf "/data/${f}"
|
||||
done < /data/manifest.txt
|
||||
# prune empty dirs
|
||||
find /data -mindepth 1 -depth -type d -empty -delete
|
||||
rm -f /data/manifest.txt
|
||||
fi
|
||||
|
||||
log "Writing generic pack manifest ... "
|
||||
find "${base_dir}" -type f -printf "%P\n" > /data/manifest.txt
|
||||
|
||||
log "Applying generic pack ..."
|
||||
cp -R -f "${base_dir}"/* /data
|
||||
rm -rf $original_base_dir
|
||||
|
||||
log "Saving generic pack(s) checksum"
|
||||
sha1sum "${packFiles[@]}" > "${sum_file}"
|
||||
isDebugging && cat "$sum_file"
|
||||
fi
|
||||
|
||||
if [ -f /data/manifest.txt ]; then
|
||||
log "Manifest exists from older generic pack, cleaning up ..."
|
||||
while read -r f; do
|
||||
rm -rf "/data/${f}"
|
||||
done < /data/manifest.txt
|
||||
# prune empty dirs
|
||||
find /data -mindepth 1 -depth -type d -empty -delete
|
||||
rm -f /data/manifest.txt
|
||||
fi
|
||||
|
||||
log "Writing generic pack manifest ... "
|
||||
find "${base_dir}" -type f -printf "%P\n" > /data/manifest.txt
|
||||
|
||||
log "Applying generic pack ..."
|
||||
cp -R -f "${base_dir}"/* /data
|
||||
rm -rf /tmp/generic_pack_base
|
||||
|
||||
log "Saving generic pack(s) checksum"
|
||||
sha1sum "${packFiles[@]}" > "${sum_file}"
|
||||
isDebugging && cat "$sum_file"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function modrinthProjects() {
|
||||
: "${MODRINTH_PROJECTS:=}"
|
||||
: "${MODRINTH_DOWNLOAD_OPTIONAL_DEPENDENCIES:=true}"
|
||||
: "${MODRINTH_ALLOWED_VERSION_TYPE:=release}"
|
||||
|
||||
if [[ $MODRINTH_PROJECTS ]] && isFamily HYBRID FABRIC; then
|
||||
if [[ ${FAMILY^^} = HYBRID ]]; then
|
||||
loader=forge
|
||||
else
|
||||
loader="${FAMILY,,}"
|
||||
fi
|
||||
mc-image-helper modrinth \
|
||||
--output-directory=/data \
|
||||
--projects="${MODRINTH_PROJECTS}" \
|
||||
--game-version="${VANILLA_VERSION}" \
|
||||
--loader="$loader" \
|
||||
--download-optional-dependencies="$MODRINTH_DOWNLOAD_OPTIONAL_DEPENDENCIES" \
|
||||
--allowed-version-type="$MODRINTH_ALLOWED_VERSION_TYPE"
|
||||
fi
|
||||
}
|
||||
|
||||
genericPacks
|
||||
|
||||
modrinthProjects
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupModconfig" "$@"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
|
||||
: "${SERVER_PROPERTIES:=/data/server.properties}"
|
||||
: "${ENABLE_RCON:=true}"
|
||||
|
||||
# FUNCTIONS
|
||||
function setServerPropValue {
|
||||
@@ -115,6 +116,8 @@ function customizeServerProps {
|
||||
setServerProp "prevent-proxy-connections" PREVENT_PROXY_CONNECTIONS
|
||||
setServerProp "use-native-transport" USE_NATIVE_TRANSPORT
|
||||
setServerProp "simulation-distance" SIMULATION_DISTANCE
|
||||
setServerProp "previews-chat" PREVIEWS_CHAT
|
||||
setServerProp "enforce-secure-profile" ENFORCE_SECURE_PROFILE
|
||||
setServerPropValue "motd" "$(echo "$MOTD" | mc-image-helper asciify)"
|
||||
[[ $LEVEL_TYPE ]] && setServerPropValue "level-type" "${LEVEL_TYPE^^}"
|
||||
|
||||
|
||||
@@ -2,125 +2,18 @@
|
||||
|
||||
set -e -o pipefail
|
||||
|
||||
: "${REMOVE_OLD_VANILLATWEAKS:=false}"
|
||||
: "${VANILLATWEAKS_FILE:=}"
|
||||
: "${VANILLATWEAKS_SHARECODE:=}"
|
||||
: "${REMOVE_OLD_VANILLATWEAKS_DEPTH:=1} "
|
||||
: "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:=*.zip}"
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
isDebugging && set -x
|
||||
|
||||
VT_VERSION=""
|
||||
DATAPACKS_DIR="/data/${LEVEL:-world}/datapacks"
|
||||
RESOURCEPACKS_DIR="/data/resourcepacks"
|
||||
|
||||
# Remove old VANILLATWEAKS
|
||||
if isTrue "${REMOVE_OLD_VANILLATWEAKS}"; then
|
||||
# NOTE: datapacks include crafting tweaks.
|
||||
if [ -d "$DATAPACKS_DIR" ]; then
|
||||
find "$DATAPACKS_DIR" -mindepth 1 -maxdepth ${REMOVE_OLD_VANILLATWEAKS_DEPTH:-16} -wholename "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_VANILLATWEAKS_EXCLUDE:-}" -delete
|
||||
fi
|
||||
if [ -d "$RESOURCEPACKS_DIR" ]; then
|
||||
find "$RESOURCEPACKS_DIR" -mindepth 1 -maxdepth ${REMOVE_OLD_VANILLATWEAKS_DEPTH:-16} -wholename "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_VANILLATWEAKS_EXCLUDE:-}" -delete
|
||||
fi
|
||||
fi
|
||||
|
||||
# Gets the download url and downloads the actual files.
|
||||
getUrlAndDownload(){
|
||||
VT_FILE=$1
|
||||
URL_SUFFIX=$2
|
||||
OUTPUT_FILE=$3
|
||||
PACKS=$(jq -jc '.packs // empty' $VT_FILE)
|
||||
if [ ! "$PACKS" ]; then
|
||||
log "ERROR: unable to retrieve ${URL_SUFFIX} from ${VT_FILE}"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
ZIPDATA_URL="https://vanillatweaks.net/assets/server/zip${URL_SUFFIX}.php"
|
||||
DOWNLOAD_URL=$(curl -X POST -F "packs=${PACKS}" -F "version=${VT_VERSION}" $ZIPDATA_URL | jq -r '.link // empty')
|
||||
if [ ! "$DOWNLOAD_URL" ]; then
|
||||
log "ERROR: unable to retrieve ${URL_SUFFIX} packs from vanillatweaks.net!"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if ! get -o $OUTPUT_FILE "https://vanillatweaks.net${DOWNLOAD_URL}"; then
|
||||
log "ERROR: failed to download ${URL_SUFFIX} from ${DOWNLOAD_URL}"
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
# Datapacks Handler
|
||||
downloadDatapacks(){
|
||||
VT_FILE=$1
|
||||
URL_SUFFIX="datapacks"
|
||||
OUTPUT_FILE="/tmp/vanillatweaks.zip"
|
||||
getUrlAndDownload $VT_FILE $URL_SUFFIX $OUTPUT_FILE
|
||||
mkdir -p "$DATAPACKS_DIR"
|
||||
if ! unzip -o -d "$DATAPACKS_DIR" $OUTPUT_FILE; then
|
||||
log "ERROR: failed to unzip the datapacks ${DATAPACKS} from ${OUTPUT_FILE}"
|
||||
fi
|
||||
rm -f $OUTPUT_FILE
|
||||
}
|
||||
|
||||
# Crafting Tweaks Handler
|
||||
downloadCraftingtweaks(){
|
||||
VT_FILE=$1
|
||||
mkdir -p "$DATAPACKS_DIR"
|
||||
getUrlAndDownload $VT_FILE "craftingtweaks" "${DATAPACKS_DIR}/craftingtweaks.zip"
|
||||
}
|
||||
|
||||
# Resourcepacks Handler
|
||||
downloadResourcepacks(){
|
||||
VT_FILE=$1
|
||||
mkdir -p "$RESOURCEPACKS_DIR"
|
||||
getUrlAndDownload $VT_FILE "resourcepacks" "${RESOURCEPACKS_DIR}/resourcepacks.zip"
|
||||
}
|
||||
|
||||
# Example: VANILLATWEAKS_SHARECODE=MGr52E
|
||||
# Code generated from the UI website, typically a alphanumeric 6 digit code.
|
||||
if [[ "$VANILLATWEAKS_SHARECODE" ]]; then
|
||||
VANILLATWEAKS_FILE=()
|
||||
for SHARECODE in ${VANILLATWEAKS_SHARECODE//,/ }; do
|
||||
TMP_FILE="/tmp/${SHARECODE}.json"
|
||||
SHARECODE_LOOKUP_URL="https://vanillatweaks.net/assets/server/sharecode.php?code=${SHARECODE}"
|
||||
if ! get -o "$TMP_FILE" "$SHARECODE_LOOKUP_URL"; then
|
||||
log "ERROR: Unable to use ${SHARECODE} share code provided to retrieve vanillatweaks file"
|
||||
exit 2
|
||||
fi
|
||||
VANILLATWEAKS_FILE+="${TMP_FILE},"
|
||||
done
|
||||
fi
|
||||
|
||||
# Use vanillatweaks file to specify VT and datapacks and crafting tweaks
|
||||
if [[ "$VANILLATWEAKS_FILE" ]]; then
|
||||
for VT_FILE in ${VANILLATWEAKS_FILE//,/ }; do
|
||||
if [ ! -f "$VT_FILE" ]; then
|
||||
log "ERROR: given VANILLATWEAKS_FILE file does not exist"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
VT_VERSION=$(jq -jc '.version // empty' $VT_FILE)
|
||||
if [ ! "$VT_VERSION" ]; then
|
||||
log "ERROR: unable to retrieve version from $VT_FILE"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
TYPE=$(jq -jc '.type // empty' $VT_FILE)
|
||||
if [[ "$TYPE" = "datapacks" ]]; then
|
||||
downloadDatapacks $VT_FILE
|
||||
elif [[ "$TYPE" = "craftingtweaks" ]]; then
|
||||
downloadCraftingtweaks $VT_FILE
|
||||
elif [[ "$TYPE" = "resourcepacks" ]]; then
|
||||
downloadResourcepacks $VT_FILE
|
||||
fi
|
||||
|
||||
# cleans up temp vanilla tweaks file download to get stored packs
|
||||
if [[ "$VANILLATWEAKS_SHARECODE" ]]; then
|
||||
rm -f $VT_FILE
|
||||
fi
|
||||
done
|
||||
if [[ ${VANILLATWEAKS_FILE} || ${VANILLATWEAKS_SHARECODE} ]]; then
|
||||
mc-image-helper vanillatweaks \
|
||||
--output-directory="/data" \
|
||||
--world-subdir="${LEVEL:-world}" \
|
||||
--share-codes="$VANILLATWEAKS_SHARECODE" \
|
||||
--pack-files="$VANILLATWEAKS_FILE"
|
||||
fi
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupDatapack" "$@"
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
handleDebugMode
|
||||
|
||||
: ${SPIGET_RESOURCES:=}
|
||||
: ${SPIGET_DOWNLOAD_TOLERANCE:=5} # in minutes
|
||||
: "${SPIGET_RESOURCES:=}"
|
||||
: "${SPIGET_DOWNLOAD_TOLERANCE:=5}" # in minutes
|
||||
|
||||
acceptArgs=(--accept application/zip --accept application/java-archive --accept application/octet-stream)
|
||||
|
||||
containsJars() {
|
||||
file=${1?}
|
||||
@@ -17,7 +20,7 @@ containsJars() {
|
||||
if [[ $line =~ $pat ]]; then
|
||||
return 0
|
||||
fi
|
||||
done <<<$(unzip -l "$file")
|
||||
done < <(unzip -l "$file" | tail -n +4)
|
||||
|
||||
return 1
|
||||
}
|
||||
@@ -31,7 +34,7 @@ containsPlugin() {
|
||||
if [[ $line =~ $pat ]]; then
|
||||
return 0
|
||||
fi
|
||||
done <<<$(unzip -l "$file")
|
||||
done < <(unzip -l "$file" | tail -n +4)
|
||||
|
||||
return 1
|
||||
}
|
||||
@@ -44,12 +47,12 @@ getResourceFromSpiget() {
|
||||
mkdir -p /data/plugins
|
||||
|
||||
versionfile="/data/plugins/.${resource}-version.json"
|
||||
versionfileNew="/tmp/.${resource}-version.json"
|
||||
versionfileNew="${versionfile}.tmp"
|
||||
|
||||
if [ -f "$versionfile" ]; then
|
||||
if [[ -n $(find "$versionfile" -mmin +${SPIGET_DOWNLOAD_TOLERANCE}) ]]; then
|
||||
urlVersion="https://api.spiget.org/v2/resources/${resource}/versions/latest"
|
||||
if ! curl -o "${versionfileNew}" -fsSL -H "User-Agent: itzg/minecraft-server" "${extraCurlArgs[@]}" "${urlVersion}"; then
|
||||
if ! get -o "${versionfileNew}" "${urlVersion}"; then
|
||||
log "ERROR failed to download resource version meta data '${resource}' from ${urlVersion}"
|
||||
exit 2
|
||||
fi
|
||||
@@ -71,7 +74,7 @@ getResourceFromSpiget() {
|
||||
else
|
||||
if downloadResourceFromSpiget "${resource}"; then
|
||||
urlVersion="https://api.spiget.org/v2/resources/${resource}/versions/latest"
|
||||
if ! curl -o "${versionfileNew}" -fsSL -H "User-Agent: itzg/minecraft-server" "${extraCurlArgs[@]}" "${urlVersion}"; then
|
||||
if ! get -o "${versionfileNew}" "${urlVersion}"; then
|
||||
log "ERROR failed to download resource version meta data '${resource}' from ${urlVersion}"
|
||||
exit 2
|
||||
fi
|
||||
@@ -84,29 +87,37 @@ getResourceFromSpiget() {
|
||||
downloadResourceFromSpiget() {
|
||||
resource=${1?}
|
||||
|
||||
tmpfile="/tmp/${resource}.zip"
|
||||
url="https://api.spiget.org/v2/resources/${resource}/download"
|
||||
if ! curl -o "${tmpfile}" -fsSL -H "User-Agent: itzg/minecraft-server" "${extraCurlArgs[@]}" "${url}"; then
|
||||
log "ERROR failed to download resource '${resource}' from ${url}"
|
||||
exit 2
|
||||
tempDir="/data/plugins/tmp-${resource}"
|
||||
mkdir -p $tempDir
|
||||
resourceUrl="https://api.spiget.org/v2/resources/${resource}"
|
||||
if ! outfile=$(get_silent --output-filename -o $tempDir "${acceptArgs[@]}" "${resourceUrl}/download"); then
|
||||
log "ERROR: failed to download resource '${resource}' from ${resourceUrl}/download"
|
||||
if externalUrl=$(get --json-path '$.file.externalUrl' "${resourceUrl}"); then
|
||||
log " Visit $externalUrl to pre-download the resource"
|
||||
log " instead of using SPIGET_RESOURCES"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if containsJars "${tmpfile}"; then
|
||||
log "Extracting contents of resource ${resource} into plugins"
|
||||
unzip -o -q -d /data/plugins "${tmpfile}"
|
||||
rm "${tmpfile}"
|
||||
elif containsPlugin "${tmpfile}"; then
|
||||
if ! fileType=$(get --json-path '.file.type' "${resourceUrl}"); then
|
||||
log "ERROR: failed to retrieve file type of resource $resource"
|
||||
exit 1
|
||||
fi
|
||||
if containsPlugin "${outfile}"; then
|
||||
log "Moving resource ${resource} into plugins"
|
||||
mv "${tmpfile}" "/data/plugins/${resource}.jar"
|
||||
mv "$outfile" /data/plugins
|
||||
elif containsJars "${outfile}"; then
|
||||
log "Extracting contents of resource ${resource} into plugins"
|
||||
extract "$outfile" /data/plugins
|
||||
else
|
||||
log "ERROR downloaded resource '${resource}' seems to be not a valid plugin"
|
||||
log "ERROR: file for resource ${resource} has an unexpected file type: ${fileType}"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
rm -rf "$tempDir"
|
||||
}
|
||||
|
||||
if [[ ${SPIGET_RESOURCES} ]]; then
|
||||
if isTrue ${REMOVE_OLD_MODS:-false}; then
|
||||
if isTrue "${REMOVE_OLD_MODS:-false}"; then
|
||||
removeOldMods /data/plugins
|
||||
REMOVE_OLD_MODS=false
|
||||
fi
|
||||
@@ -118,4 +129,4 @@ if [[ ${SPIGET_RESOURCES} ]]; then
|
||||
done
|
||||
fi
|
||||
|
||||
exec ${SCRIPTS:-/}start-setupWorld $@
|
||||
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||
|
||||
@@ -8,6 +8,11 @@ function join_by() {
|
||||
printf "%s" "${@/#/$d}"
|
||||
}
|
||||
|
||||
function get_major_version() {
|
||||
version=$1
|
||||
echo "$version" | cut -d. -f 1-2
|
||||
}
|
||||
|
||||
function isURL() {
|
||||
local value=$1
|
||||
|
||||
@@ -61,6 +66,28 @@ function isTrue() {
|
||||
return ${result}
|
||||
}
|
||||
|
||||
function isFalse() {
|
||||
local oldState
|
||||
oldState=$(shopt -po xtrace)
|
||||
shopt -u -o xtrace
|
||||
|
||||
local value=${1,,}
|
||||
|
||||
result=
|
||||
|
||||
case ${value} in
|
||||
false | off)
|
||||
result=0
|
||||
;;
|
||||
*)
|
||||
result=1
|
||||
;;
|
||||
esac
|
||||
|
||||
eval "$oldState"
|
||||
return ${result}
|
||||
}
|
||||
|
||||
function isDebugging() {
|
||||
if isTrue "${DEBUG:-false}"; then
|
||||
return 0
|
||||
@@ -117,6 +144,10 @@ function logAutostopAction() {
|
||||
echo "[$(date -Iseconds)] [Autostop] $*"
|
||||
}
|
||||
|
||||
function logRcon() {
|
||||
echo "[Rcon loop] $*"
|
||||
}
|
||||
|
||||
function normalizeMemSize() {
|
||||
local scale=1
|
||||
case ${1,,} in
|
||||
@@ -181,7 +212,11 @@ function removeOldMods {
|
||||
}
|
||||
|
||||
function get() {
|
||||
local flags=()
|
||||
mc-image-helper get "$@"
|
||||
}
|
||||
|
||||
function get_silent() {
|
||||
local flags=(-s)
|
||||
if isTrue "${DEBUG_GET:-false}"; then
|
||||
flags+=("--debug")
|
||||
fi
|
||||
@@ -225,11 +260,14 @@ function extract() {
|
||||
type=$(file -b --mime-type "${src}")
|
||||
case "${type}" in
|
||||
application/zip)
|
||||
unzip -q -d "${destDir}" "${src}"
|
||||
unzip -o -q -d "${destDir}" "${src}"
|
||||
;;
|
||||
application/x-tar|application/gzip|application/x-gzip|application/x-bzip2|application/zstd|application/x-zstd)
|
||||
application/x-tar|application/gzip|application/x-gzip|application/x-bzip2)
|
||||
tar -C "${destDir}" -xf "${src}"
|
||||
;;
|
||||
application/zstd|application/x-zstd)
|
||||
tar -C "${destDir}" --use-compress-program=unzstd -xf "${src}"
|
||||
;;
|
||||
*)
|
||||
log "ERROR: unsupported archive type: $type"
|
||||
return 1
|
||||
@@ -253,6 +291,8 @@ function checkSum() {
|
||||
return 0
|
||||
elif [ "${distro}" == "alpine" ] && sha1sum -c "${sum_file}" -s 2> /dev/null; then
|
||||
return 0
|
||||
elif [ "${distro}" == "ol" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -5,7 +5,7 @@ services:
|
||||
depends_on:
|
||||
- mc
|
||||
image: itzg/mc-monitor:${MC_MONITOR_VERSION:-0.10.4}
|
||||
command: status --host mc --retry-interval 1s --timeout 1s --retry-limit 240
|
||||
command: status --host mc --retry-interval 1s --timeout 1s --retry-limit 300
|
||||
mc:
|
||||
restart: "no"
|
||||
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||
|
||||
@@ -7,8 +7,13 @@ services:
|
||||
environment:
|
||||
EULA: "TRUE"
|
||||
SETUP_ONLY: "TRUE"
|
||||
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||
WORLD: /worlds/world-for-testing.zip
|
||||
# the following are only used to speed up test execution
|
||||
TYPE: CUSTOM
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
VERSION: 1.18.1
|
||||
volumes:
|
||||
- ./worlds:/worlds:ro
|
||||
- ./data:/data
|
||||
# the following are only used to speed up test execution
|
||||
- ./verify.sh:/servers/fake.jar
|
||||
|
||||
16
tests/setuponlytests/curseforge/docker-compose.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
mc:
|
||||
image: ${IMAGE_TO_TEST:-itzg/minecraft-server:java8-multiarch}
|
||||
environment:
|
||||
EULA: "true"
|
||||
SETUP_ONLY: "TRUE"
|
||||
TYPE: CURSEFORGE
|
||||
CF_SERVER_MOD: /modpacks/pack.zip
|
||||
INIT_MEMORY: 2G
|
||||
MAX_MEMORY: 6G
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./modpacks:/modpacks:ro
|
||||
|
||||
BIN
tests/setuponlytests/curseforge/modpacks/pack.zip
Normal file
1
tests/setuponlytests/curseforge/require.sh
Normal file
@@ -0,0 +1 @@
|
||||
[[ $VARIANT == java8* ]] || exit 1
|
||||
2
tests/setuponlytests/curseforge/verify.sh
Normal file
@@ -0,0 +1,2 @@
|
||||
mc-image-helper assert fileExists "/data/FeedTheBeast/forge-installer.jar"
|
||||
mc-image-helper assert fileExists "/data/FeedTheBeast/forge.jar"
|
||||
11
tests/setuponlytests/defaults/docker-compose.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
mc:
|
||||
restart: "no"
|
||||
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||
environment:
|
||||
EULA: "TRUE"
|
||||
SETUP_ONLY: "TRUE"
|
||||
volumes:
|
||||
- ./data:/data
|
||||
3
tests/setuponlytests/defaults/verify.sh
Normal file
@@ -0,0 +1,3 @@
|
||||
mc-image-helper assert propertyEquals --file=server.properties --property=rcon.password --expect=minecraft
|
||||
mc-image-helper assert propertyEquals --file=server.properties --property=rcon.port --expect=25575
|
||||
mc-image-helper assert propertyEquals --file=server.properties --property=enable-rcon --expect=true
|
||||
@@ -7,14 +7,15 @@ services:
|
||||
environment:
|
||||
EULA: "TRUE"
|
||||
SETUP_ONLY: "TRUE"
|
||||
DEBUG: "FALSE"
|
||||
# Using custom to bypass Fabric setup
|
||||
TYPE: CUSTOM
|
||||
# Using family to test FORGEAPI Family filter.
|
||||
FAMILY: FABRIC
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||
VERSION: 1.18.2
|
||||
MODS_FORGEAPI_FILE: /config/forgeapi_mods.json
|
||||
# Key is defined in .github/workflows/pr.yml and ci.yml
|
||||
# Key is passed by Github Workflow
|
||||
# This should be coming from github secrets.
|
||||
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
|
||||
REMOVE_OLD_FORGEAPI_MODS: "TRUE"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[{
|
||||
"name": "On A Stick [FABRIC]",
|
||||
"projectId": "550544",
|
||||
"releaseType": "release"
|
||||
},
|
||||
{
|
||||
"name": "Fabric Voice Mod",
|
||||
"projectId": "416089",
|
||||
"releaseType": "beta"
|
||||
}
|
||||
[
|
||||
{
|
||||
"name": "Flan (Land Claim Tool)",
|
||||
"projectId": "404578"
|
||||
},
|
||||
{
|
||||
"name": "Fabric Voice Mod",
|
||||
"projectId": "416089",
|
||||
"releaseType": "beta"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
[[ $MODS_FORGEAPI_KEY ]] || exit 1
|
||||
[[ $MINECRAFT_VERSION == LATEST ]] || exit 1
|
||||
[[ $MODS_FORGEAPI_KEY ]] || exit 1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Validates specific beta call out for specific mod:
|
||||
mc-image-helper assert fileExists "/data/mods/voicechat-fabric*"
|
||||
mc-image-helper assert fileExists "/data/mods/onastick-fabric*"
|
||||
# Dependent of on a stick:
|
||||
mc-image-helper assert fileExists "/data/mods/flan*"
|
||||
# Dependent of flan:
|
||||
mc-image-helper assert fileExists "/data/mods/fabric-api*"
|
||||
|
||||
@@ -7,23 +7,24 @@ services:
|
||||
environment:
|
||||
EULA: "TRUE"
|
||||
SETUP_ONLY: "TRUE"
|
||||
DEBUG: "FALSE"
|
||||
# Using custom to bypass Fabric setup
|
||||
TYPE: CUSTOM
|
||||
# Using family to test FORGEAPI Family filter.
|
||||
FAMILY: FABRIC
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||
VERSION: 1.18.2
|
||||
# Validate Skip Gametype Filter:
|
||||
MODS_FORGEAPI_IGNORE_GAMETYPE: "TRUE"
|
||||
# Validates that Biomes does not download terrablender
|
||||
# Using default false for testing:
|
||||
# MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "FALSE"
|
||||
MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "FALSE"
|
||||
# Contains mix of Forge and Fabric mods
|
||||
MODS_FORGEAPI_PROJECTIDS: 306612,416089,220318
|
||||
MODS_FORGEAPI_PROJECTIDS: 416089,493246
|
||||
# Allows for Beta releases of 416089 the Fabric Voice Mod
|
||||
MODS_FORGEAPI_RELEASES: BETA
|
||||
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
|
||||
REMOVE_OLD_FORGEAPI_MODS: "FALSE"
|
||||
REMOVE_OLD_FORGEAPI_MODS: "TRUE"
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./fake.jar:/servers/fake.jar
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
[[ $MODS_FORGEAPI_KEY ]] || exit 1
|
||||
[[ $MINECRAFT_VERSION == LATEST ]] || exit 1
|
||||
[[ $MODS_FORGEAPI_KEY ]] || exit 1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
mc-image-helper assert fileExists "/data/mods/BiomesOPlenty*"
|
||||
# testing dependencies don't get downloaded when download dependencies is set to false.
|
||||
! mc-image-helper assert fileExists "/data/mods/TerraBlender*"
|
||||
mc-image-helper assert fileExists "/data/mods/voicechat-fabric*"
|
||||
mc-image-helper assert fileExists "/data/mods/fabric-api*"
|
||||
mc-image-helper assert fileExists "/data/mods/flan*"
|
||||
# Dependent of flan, but dependencies are set to false:
|
||||
! mc-image-helper assert fileExists "/data/mods/fabric-api*"
|
||||
|
||||
@@ -13,10 +13,10 @@ services:
|
||||
# - Currently we do not support filtering on vanilla.
|
||||
FAMILY: VANILLA
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||
VERSION: 1.18.2
|
||||
MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "TRUE"
|
||||
# Contains mix of Forge and Fabric mods
|
||||
MODS_FORGEAPI_PROJECTIDS: 306612,416089,220318
|
||||
MODS_FORGEAPI_PROJECTIDS: 416089,419697
|
||||
# Allows for Beta releases of 416089 the Fabric Voice Mod
|
||||
MODS_FORGEAPI_RELEASES: BETA
|
||||
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
[[ $MODS_FORGEAPI_KEY ]] || exit 1
|
||||
[[ $MINECRAFT_VERSION == LATEST ]] || exit 1
|
||||
[[ $MODS_FORGEAPI_KEY ]] || exit 1
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
mc-image-helper assert fileExists "/data/mods/BiomesOPlenty*"
|
||||
mc-image-helper assert fileExists "/data/mods/TerraBlender*"
|
||||
mc-image-helper assert fileExists "/data/mods/voicechat-fabric*"
|
||||
# No family filter applied, DO NOT use Fabric or Forge specific name validation as it may cause random breakage.
|
||||
mc-image-helper assert fileExists "/data/mods/voicechat-fabric-1*"
|
||||
# Should be pull v4 and higher for 1.18.2:
|
||||
mc-image-helper assert fileExists "/data/mods/architectury-4*"
|
||||
mc-image-helper assert fileExists "/data/mods/fabric-api*"
|
||||
|
||||
|
||||
@@ -9,6 +9,13 @@ services:
|
||||
GENERIC_PACKS: testing
|
||||
GENERIC_PACKS_PREFIX: /packs/
|
||||
GENERIC_PACKS_SUFFIX: .zip
|
||||
DEBUG: "true"
|
||||
# the following are only used to speed up test execution
|
||||
TYPE: CUSTOM
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
VERSION: 1.18.1
|
||||
volumes:
|
||||
- ./packs:/packs
|
||||
- ./data:/data
|
||||
# the following are only used to speed up test execution
|
||||
- ./verify.sh:/servers/fake.jar
|
||||
|
||||
@@ -18,6 +18,7 @@ services:
|
||||
TYPE: CUSTOM
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
VERSION: 1.18.1
|
||||
DEBUG: "true"
|
||||
volumes:
|
||||
- ./packs:/packs
|
||||
- ./data:/data
|
||||
|
||||
17
tests/setuponlytests/icon-file-exact/docker-compose.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
mc:
|
||||
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||
environment:
|
||||
EULA: "true"
|
||||
SETUP_ONLY: "true"
|
||||
ICON: /extra/4737386_minecraft_squircle_icon_64x64.png
|
||||
# the following are only used to speed up test execution
|
||||
TYPE: CUSTOM
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
VERSION: 1.18.1
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./extra:/extra
|
||||
- ./fake.jar:/servers/fake.jar
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
0
tests/setuponlytests/icon-file-exact/fake.jar
Normal file
1
tests/setuponlytests/icon-file-exact/verify.sh
Normal file
@@ -0,0 +1 @@
|
||||
mc-image-helper assert fileExists server-icon.png
|
||||
17
tests/setuponlytests/icon-file-scale/docker-compose.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
mc:
|
||||
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||
environment:
|
||||
EULA: "true"
|
||||
SETUP_ONLY: "true"
|
||||
ICON: /extra/4737386_minecraft_squircle_icon.png
|
||||
# the following are only used to speed up test execution
|
||||
TYPE: CUSTOM
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
VERSION: 1.18.1
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./extra:/extra
|
||||
- ./fake.jar:/servers/fake.jar
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
0
tests/setuponlytests/icon-file-scale/fake.jar
Normal file
1
tests/setuponlytests/icon-file-scale/verify.sh
Normal file
@@ -0,0 +1 @@
|
||||
mc-image-helper assert fileExists server-icon.png
|
||||
22
tests/setuponlytests/icon-gif-multiframe/docker-compose.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
web:
|
||||
image: nginx
|
||||
volumes:
|
||||
- ./web:/usr/share/nginx/html
|
||||
mc:
|
||||
depends_on:
|
||||
- web
|
||||
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||
environment:
|
||||
EULA: "true"
|
||||
SETUP_ONLY: "true"
|
||||
ICON: http://web/motion-tween-example.gif
|
||||
# the following are only used to speed up test execution
|
||||
TYPE: CUSTOM
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
VERSION: 1.18.1
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./fake.jar:/servers/fake.jar
|
||||
0
tests/setuponlytests/icon-gif-multiframe/fake.jar
Normal file
1
tests/setuponlytests/icon-gif-multiframe/verify.sh
Normal file
@@ -0,0 +1 @@
|
||||
mc-image-helper assert fileExists server-icon.png
|
||||
|
After Width: | Height: | Size: 61 KiB |
22
tests/setuponlytests/icon-png-atscale/docker-compose.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
web:
|
||||
image: nginx
|
||||
volumes:
|
||||
- ./web:/usr/share/nginx/html
|
||||
mc:
|
||||
depends_on:
|
||||
- web
|
||||
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||
environment:
|
||||
EULA: "true"
|
||||
SETUP_ONLY: "true"
|
||||
ICON: http://web/4737386_minecraft_squircle_icon.png
|
||||
# the following are only used to speed up test execution
|
||||
TYPE: CUSTOM
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
VERSION: 1.18.1
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./fake.jar:/servers/fake.jar
|
||||
0
tests/setuponlytests/icon-png-atscale/fake.jar
Normal file
1
tests/setuponlytests/icon-png-atscale/verify.sh
Normal file
@@ -0,0 +1 @@
|
||||
mc-image-helper assert fileExists server-icon.png
|
||||
|
After Width: | Height: | Size: 592 B |
22
tests/setuponlytests/icon-png-scale/docker-compose.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
web:
|
||||
image: nginx
|
||||
volumes:
|
||||
- ./web:/usr/share/nginx/html
|
||||
mc:
|
||||
depends_on:
|
||||
- web
|
||||
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||
environment:
|
||||
EULA: "true"
|
||||
SETUP_ONLY: "true"
|
||||
ICON: http://web/4737386_minecraft_squircle_icon.png
|
||||
# the following are only used to speed up test execution
|
||||
TYPE: CUSTOM
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
VERSION: 1.18.1
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./fake.jar:/servers/fake.jar
|
||||
0
tests/setuponlytests/icon-png-scale/fake.jar
Normal file
1
tests/setuponlytests/icon-png-scale/verify.sh
Normal file
@@ -0,0 +1 @@
|
||||
mc-image-helper assert fileExists server-icon.png
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
15
tests/setuponlytests/modrinth/docker-compose.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
mc:
|
||||
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||
environment:
|
||||
EULA: "true"
|
||||
SETUP_ONLY: "true"
|
||||
TYPE: FABRIC
|
||||
FABRIC_LAUNCHER: /servers/fake.jar
|
||||
CUSTOM_SERVER: /servers/fake.jar
|
||||
MODRINTH_PROJECTS: fabric-api,cloth-config
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- ./fake.jar:/servers/fake.jar
|
||||