Compare commits

..

63 Commits

Author SHA1 Message Date
Geoff Bourne
3b89f143c2 Track latest from master 2021-11-16 19:02:45 -06:00
Geoff Bourne
788f61c693 Auto-merging via docker-versions-create 2021-11-16 18:52:29 -06:00
Geoff Bourne
7651f3da07 Auto-merging via docker-versions-create 2021-11-15 20:49:10 -06:00
Geoff Bourne
0bf77c18b0 Auto-merging via docker-versions-create 2021-11-13 19:18:27 -06:00
Geoff Bourne
55d272141d Auto-merging via docker-versions-create 2021-11-13 18:53:00 -06:00
Geoff Bourne
b8b5fba660 Auto-merging via docker-versions-create 2021-11-12 21:24:49 -06:00
Geoff Bourne
8a8ec9e52e Auto-merging via docker-versions-create 2021-11-06 21:39:58 -05:00
Geoff Bourne
1ee8ad87ba Auto-merging via docker-versions-create 2021-11-04 21:06:45 -05:00
Geoff Bourne
d8f256954c Auto-merging via docker-versions-create 2021-10-31 09:48:08 -05:00
Geoff Bourne
e741bf325d Merge branch 'master' into java16 2021-10-27 21:13:08 -05:00
Geoff Bourne
583574281b Auto-merging via docker-versions-create 2021-10-25 19:25:36 -05:00
Geoff Bourne
235646840c Auto-merging via docker-versions-create 2021-10-24 20:30:30 -05:00
Geoff Bourne
60b26f02ec Auto-merging via docker-versions-create 2021-10-23 09:46:14 -05:00
Geoff Bourne
c7a4f87e8e Auto-merging via docker-versions-create 2021-10-22 15:56:28 -05:00
Geoff Bourne
70b56c3e28 Merge branch 'master' into java16 2021-10-20 15:36:45 -05:00
Geoff Bourne
87949bf7c1 Auto-merging via docker-versions-create 2021-10-18 22:16:14 -05:00
Geoff Bourne
0e39351ba8 Auto-merging via docker-versions-create 2021-10-17 14:55:03 -05:00
Geoff Bourne
f85673a72e Auto-merging via docker-versions-create 2021-10-15 18:59:36 -05:00
Geoff Bourne
56a00aa416 Auto-merging via docker-versions-create 2021-10-15 18:50:33 -05:00
Geoff Bourne
e6a420036d Auto-merging via docker-versions-create 2021-10-10 09:58:30 -05:00
Geoff Bourne
52f5660e72 Auto-merging via docker-versions-create 2021-10-09 15:27:38 -05:00
Geoff Bourne
fb949d2fdd Auto-merging via docker-versions-create 2021-10-09 12:06:13 -05:00
Geoff Bourne
79714cd6c7 Auto-merging via docker-versions-create 2021-10-02 19:24:10 -05:00
Geoff Bourne
a2f61da686 Auto-merging via docker-versions-create 2021-09-29 10:27:09 -05:00
Geoff Bourne
332b5b3eb9 Auto-merging via docker-versions-create 2021-09-27 20:42:51 -05:00
Geoff Bourne
45a85c83b0 Auto-merging via docker-versions-create 2021-09-20 12:32:17 -05:00
Geoff Bourne
c046a5855e Auto-merging via docker-versions-create 2021-09-15 21:32:54 -05:00
Geoff Bourne
19eebae327 Auto-merging via docker-versions-create 2021-09-15 21:10:23 -05:00
Geoff Bourne
088bc53010 Auto-merging via docker-versions-create 2021-09-15 20:39:04 -05:00
Geoff Bourne
19c5626085 Auto-merging via docker-versions-create 2021-08-30 21:39:28 -05:00
Geoff Bourne
03cbbd465a Auto-merging via docker-versions-create 2021-08-10 12:57:46 -05:00
Geoff Bourne
592f18358a Auto-merging via docker-versions-create 2021-08-01 12:15:02 -05:00
Geoff Bourne
905906fa6c Auto-merging via docker-versions-create 2021-07-31 09:29:16 -05:00
Geoff Bourne
c862745534 Auto-merging via docker-versions-create 2021-07-26 19:37:13 -05:00
Geoff Bourne
ead8543b48 Merge branch 'master' into java16 2021-07-25 18:21:54 -05:00
Geoff Bourne
d34ae9d57d Auto-merging via docker-versions-create 2021-07-25 09:38:47 -05:00
Geoff Bourne
b6e53249f9 Auto-merging via docker-versions-create 2021-07-23 21:29:14 -05:00
Geoff Bourne
8020f83c3d Auto-merging via docker-versions-create 2021-07-17 21:16:18 -05:00
Geoff Bourne
fe01df78c4 Auto-merging via docker-versions-create 2021-07-17 20:59:03 -05:00
Geoff Bourne
afd0865d33 Auto-merging via docker-versions-create 2021-07-17 18:06:02 -05:00
Geoff Bourne
bcf408fb44 Auto-merging via docker-versions-create 2021-07-14 18:43:28 -05:00
Geoff Bourne
37f59eecd9 Auto-merging via docker-versions-create 2021-07-12 19:11:17 -05:00
Geoff Bourne
4ae2e5592f Auto-merging via docker-versions-create 2021-07-09 20:00:00 -05:00
Geoff Bourne
8fc44e0071 Auto-merging via docker-versions-create 2021-07-08 18:01:28 -05:00
Geoff Bourne
f3fa90b700 Auto-merging via docker-versions-create 2021-07-08 08:05:30 -05:00
itzg
c1322a23ea Auto-merging via docker-versions-create 2021-07-08 12:56:09 +00:00
Geoff Bourne
4cbf481441 Auto-merging via docker-versions-create 2021-07-08 07:40:33 -05:00
itzg
1cd8ec83ef Auto-merging via docker-versions-create 2021-07-04 19:54:08 +00:00
Geoff Bourne
9778bddd4f Auto-merging from master 2021-07-03 14:27:40 -05:00
Geoff Bourne
a03a1a8eff ci: auto-merge from master 2021-07-02 16:03:37 -05:00
itzg
408af32fbe Auto-merging via docker-versions-create 2021-07-02 16:56:04 +00:00
itzg
141d6c7125 Auto-merging via docker-versions-create 2021-06-28 12:14:14 +00:00
itzg
ddd4712ea0 Auto-merging via docker-versions-create 2021-06-27 13:13:19 +00:00
itzg
680987a385 Auto-merging via docker-versions-create 2021-06-24 12:47:13 +00:00
Geoff Bourne
655ae04abb Auto-merging via docker-versions-create 2021-06-23 22:35:33 -05:00
Geoff Bourne
f62dd55300 Auto-merging via docker-versions-create 2021-06-20 12:50:41 -05:00
Geoff Bourne
b5877f6208 Auto-merging via docker-versions-create 2021-06-05 17:54:18 -05:00
Geoff Bourne
d561c026c6 Auto-merging via docker-versions-create 2021-05-24 20:52:34 -05:00
Geoff Bourne
3cd3ca9d88 Merge branch 'master' into java16 2021-05-23 12:27:27 -05:00
Geoff Bourne
b9ef9a46b6 Merge from master 2021-05-22 13:47:15 -05:00
Geoff Bourne
275863f04c Auto-merging via docker-versions-create 2021-05-21 23:03:45 -05:00
Geoff Bourne
ae94a6be3a Auto-merging via docker-versions-create 2021-05-21 22:52:46 -05:00
Geoff Bourne
d08c6e2c46 ci: updated CACHE_NAME 2021-05-21 22:13:59 -05:00
205 changed files with 1418 additions and 3930 deletions

19
.gitattributes vendored
View File

@@ -1,2 +1,17 @@
# Auto detect text files and perform LF normalization
* text=lf
# 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

3
.github/FUNDING.yml vendored
View File

@@ -1,4 +1,5 @@
github: itzg
#github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
custom:
- https://www.buymeacoffee.com/itzg
- https://paypal.me/itzg

4
.github/release.yml vendored
View File

@@ -1,4 +0,0 @@
changelog:
exclude:
authors:
- dependabot

View File

@@ -1,178 +1,86 @@
name: Test and Build multi-architecture
name: Build and publish multiarch
on:
push:
branches:
- master
- test/**
- java8-multiarch
- java8-openj9
- java11*
- java16*
- java17*
- test/*
tags:
- "[0-9]+.[0-9]+.[0-9]+"
paths-ignore:
- "*.md"
- "docs/**"
- "examples/**"
pull_request:
branches: [ master ]
types: [assigned, opened, synchronize, labeled]
- "[0-9]+.[0-9]+.[0-9]+-java8-multiarch"
- "[0-9]+.[0-9]+.[0-9]+-java8-openj9"
- "[0-9]+.[0-9]+.[0-9]+-java11*"
- "[0-9]+.[0-9]+.[0-9]+-java16*"
paths-ignore:
- "*.md"
- "docs/**"
- "examples/**"
jobs:
build:
strategy:
fail-fast: false
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
# 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: 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-jre
platforms: linux/amd64,linux/arm64
mcVersion: 1.18.2
- variant: java17-alpine
baseImage: eclipse-temurin:17-jre-alpine
platforms: linux/amd64
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-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 }}
docker-buildx:
if: github.repository == 'itzg/docker-minecraft-server'
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v3
with:
# for build-files step
fetch-depth: 0
uses: actions/checkout@v2.4.0
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
uses: docker/metadata-action@v3
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.
images: |
${{ github.repository_owner }}/minecraft-server
itzg/minecraft-server
tags: |
type=ref,event=tag,enable=${{ matrix.variant == 'java17' }}
type=ref,event=tag,suffix=-${{ matrix.variant }}
type=raw,value=${{ matrix.variant }}
type=ref,event=branch
type=ref,event=tag
flavor: |
latest=${{ matrix.variant == 'java17' }}
labels: |
org.opencontainers.image.authors=Geoff Bourne <itzgeoff@gmail.com>
latest=${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v1
- name: Cache Docker layers
uses: actions/cache@v2.1.6
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Set up QEMU
uses: docker/setup-qemu-action@v2.0.0
- name: Build for test
uses: docker/build-push-action@v3.0.0
with:
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
# ensure latest base image is used
pull: true
# load into daemon for test usage in next step
load: true
push: false
build-args: |
BASE_IMAGE=${{ matrix.baseImage }}
cache-from: type=gha,scope=${{ matrix.variant }}
# no cache-to to avoid cross-cache update from next build step
- name: Run tests
env:
MINECRAFT_VERSION: ${{ matrix.mcVersion }}
VARIANT: ${{ matrix.variant }}
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
run: |
tests/test.sh
uses: docker/setup-qemu-action@v1.2.0
- name: Login to DockerHub
uses: docker/login-action@v2
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v3.0.0
uses: docker/build-push-action@v2.7.0
with:
platforms: ${{ matrix.platforms }}
push: >
${{
github.ref_type == 'tag'
|| github.ref_name == 'master'
|| ( github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci/push-image') )
}}
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
# ensure latest base image is used
pull: true
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
labels: ${{ steps.meta.outputs.labels }}
build-args: |
BASE_IMAGE=${{ matrix.baseImage }}
BUILD_FILES_REV=${{ steps.build-files-rev.outputs.REV }}
cache-from: type=gha,scope=${{ matrix.variant }}
cache-to: type=gha,mode=max,scope=${{ matrix.variant }}
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
- # Temp fix
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache

View File

@@ -1,43 +0,0 @@
name: ContinuousIntegration
on:
push:
branches:
- 'dev*'
- '!master'
- '!java*'
- '!multi*'
paths-ignore:
- "*.md"
- "docs/**"
- "examples/**"
env:
IMAGE_TO_TEST: ${{ secrets.IMAGE_ORG }}/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@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build
uses: docker/build-push-action@v3.0.0
with:
context: .
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
load: true
cache-from: type=gha
- name: Run Setup Only Tests
run: bash tests/setuponlytests/test.sh
# - name: Run Full Minecraft Service Tests
# run: |
# tests/fulltests/test.sh

View File

@@ -1,26 +0,0 @@
name: Discord notifications
on:
workflow_run:
workflows: ["ContinuousIntegration", "Build and Publish", "Build and publish multiarch" ]
types:
- completed
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
jobs:
discord:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: on-success
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: Ilshidur/action-discord@master
with:
args: "Github repo: ${{ github.repository }}\n- Branch: ${{ github.event.workflow_run.head_branch }}\n- [Link: to Actions](<${{ github.event.workflow_run.html_url }}>)\n- Status: 🎉 ${{ github.event.workflow_run.conclusion }} 🍏"
- name: on-failure
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
uses: Ilshidur/action-discord@master
with:
args: "Github repo: ${{ github.repository }}\n- Branch: ${{ github.event.workflow_run.head_branch }}\n- [Link: to Actions](<${{ github.event.workflow_run.html_url }}>)\n- Status: 🤔 ${{ github.event.workflow_run.conclusion }} 💣💥"

21
.github/workflows/generate-toc.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
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.12.0
with:
commit_message: "docs: Auto update markdown TOC"

View File

@@ -1,33 +0,0 @@
name: Issue labels
on:
issues:
types: [labeled, reopened, closed, deleted]
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_ISSUES_WEBHOOK }}
jobs:
labelNotify:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: notify on label
if: >
github.event.label.name == 'enhancement'
|| github.event.label.name == 'bug'
|| github.event.label.name == 'help wanted'
|| github.event.label.name == 'priority/high'
|| github.event.label.name == 'question'
|| github.event.label.name == 'status/waiting on upstream'
uses: Ilshidur/action-discord@master
with:
args: "[${{ github.event.issue.title }} (#${{ github.event.issue.number }})](<${{ github.event.issue.html_url }}>) added `${{ github.event.label.name }}` label"
- name: notify on action change
if: >
github.event.action == 'closed'
|| github.event.action == 'reopened'
|| github.event.action == 'deleted'
uses: Ilshidur/action-discord@master
with:
args: "[${{ github.event.issue.title }} (#${{ github.event.issue.number }})](<${{ github.event.issue.html_url }}>) has been `${{ github.event.action }}` by `${{ github.event.sender.login }}`"

100
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,100 @@
name: Build and Publish
on:
push:
branches:
- java8
- openj9
- openj9-11
- adopt11
- test/alpine/*
tags:
- "[0-9]+.[0-9]+.[0-9]+-java8"
- "[0-9]+.[0-9]+.[0-9]+-openj9"
- "[0-9]+.[0-9]+.[0-9]+-openj9-11"
- "[0-9]+.[0-9]+.[0-9]+-openj9-nightly"
- "[0-9]+.[0-9]+.[0-9]+-adopt11"
jobs:
test:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2.4.0
- name: Run tests
run: |
tests/test.sh
build:
needs:
- test
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2.4.0
- name: Prepare
id: prep
run: |
DOCKER_IMAGE=itzg/minecraft-server
VERSION=edge
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
fi
if [[ $GITHUB_REF == refs/heads/* ]]; then
VERSION=${GITHUB_REF#refs/heads/}
if [[ $VERSION == master ]]; then
VERSION=latest
fi
fi
TAGS="${DOCKER_IMAGE}:${VERSION//\//-}"
echo ::set-output name=tags::${TAGS}
echo ::set-output name=version::${VERSION//\//-}
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Cache Docker layers
uses: actions/cache@v2.1.6
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2.7.0
with:
context: .
file: ./Dockerfile
# ensure latest base image is used
pull: true
# publish
push: true
# tags determined by prep step
tags: ${{ steps.prep.outputs.tags }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
labels: |
org.opencontainers.image.documentation=https://github.com/itzg/docker-minecraft-server
org.opencontainers.image.version=${{ steps.prep.outputs.version }}
org.opencontainers.image.source=https://github.com/itzg/docker-minecraft-server
org.opencontainers.image.revision=${{ github.sha }}
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
- # Temp fix
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache

16
.github/workflows/pr.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: Validate PR
on:
pull_request:
branches: [ master ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.4.0
- name: Run tests
run: |
tests/test.sh

View File

@@ -1,6 +1,7 @@
name: Stale Check
on:
issue_comment:
schedule:
- cron: 0 2 * * *
@@ -12,7 +13,7 @@ jobs:
pull-requests: write
steps:
- name: Process Stale Issues
uses: actions/stale@v5
uses: actions/stale@v4.0.0
with:
stale-issue-label: status/stale
stale-pr-label: status/stale
@@ -21,5 +22,5 @@ jobs:
Please add a comment describing the reason to keep this issue open.
days-before-stale: 30
days-before-close: 5
exempt-issue-labels: 'enhancement,keep,status/needs triage,priority/high'
exempt-issue-labels: 'enhancement,keep,status/needs triage'

4
.gitignore vendored
View File

@@ -1,6 +1,4 @@
.vscode
/data/
/.idea/
*.iml
/gh-md-toc
personal-build-and-develop.*
/gh-md-toc

View File

@@ -15,35 +15,8 @@ Individual scripts can be iteratively developed, debugged, and tested using the
First, build a baseline of the image to include the packages needed by existing or new scripts:
PowerShell: (Example of building and testing ForgeAPI)
```powershell
$env:MODS_FORGEAPI_KEY='$2a$...'
$env:FOLDER_TO_TEST="forgeapimods_projectids"
$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 -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$...'
export FOLDER_TO_TEST="forgeapimods_file"
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 -v --remove-orphans
popd
```shell script
docker build -t mc-dev .
```
Using the baseline image, an interactive container can be started to iteratively run the scripts to be developed. By attaching the current workspace directory, you can use the local editor of your choice to iteratively modify scripts while using the container to run them.
@@ -78,7 +51,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 8080
http-server ./build/distributions -p 0
```
Note the port that was selected by http-server and pass the build arguments, such as:
@@ -88,7 +61,32 @@ 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.
## Multi-base-image variants
Several base-image variants are maintained in order to offer choices in JDK provider and version. The variants are maintained in their respective branches:
- openj9
- openj9-nightly
- adopt11
- adopt13
- multiarch
The [docker-versions-create.sh](docker-versions-create.sh) script is configured with the branches to maintain and is used to merge changes from the master branch into the mulit-base variant branches. The script also manages git tagging the master branch along with the merged branches. So a typical use of the script would be like:
```shell script
./docker-versions-create.sh -s -t 1.2.0
```
> Most often the major version will be bumped unless a bug or hotfix needs to be published in which case the patch version should be incremented.
> The build and publishing of those branches and their tags is currently performed within Docker Hub.
## multiarch support
The [multiarch branch](https://github.com/itzg/docker-minecraft-server/tree/multiarch) supports running the image on amd64, arm64, and armv7 (aka RaspberryPi). Unlike the mainline branches, it is based on Ubuntu 18.04 since the openjdk package provided by Ubuntu includes full JIT support on all of the processor types.
The multiarch images are built and published by [a Github action](https://github.com/itzg/docker-minecraft-server/actions?query=workflow%3A%22Build+and+publish+multiarch%22), which [is configured in that branch](https://github.com/itzg/docker-minecraft-server/blob/multiarch/.github/workflows/build-multiarch.yml).
## Generating release notes

View File

@@ -1,75 +1,92 @@
# 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
FROM eclipse-temurin:16-jdk
LABEL org.opencontainers.image.authors="Geoff Bourne <itzgeoff@gmail.com>"
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y \
imagemagick \
gosu \
sudo \
net-tools \
iputils-ping \
curl wget \
git \
jq \
dos2unix \
mysql-client \
tzdata \
rsync \
nano \
unzip \
knockd \
ttf-dejavu \
&& apt-get clean
RUN addgroup --gid 1000 minecraft \
&& adduser --system --shell /bin/false --uid 1000 --ingroup minecraft --home /data minecraft
COPY 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.1 --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.9.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
COPY scripts/start* /
COPY bin/ /usr/local/bin/
COPY bin/mc-health /health.sh
COPY files/server.properties /tmp/server.properties
COPY files/log4j2.xml /tmp/log4j2.xml
COPY files/autopause /autopause
RUN dos2unix /start* && chmod +x /start* \
&& dos2unix /autopause/* && chmod +x /autopause/*.sh
ENTRYPOINT [ "/start" ]
HEALTHCHECK --start-period=1m CMD mc-health

770
README.md

File diff suppressed because it is too large Load Diff

View File

@@ -2,9 +2,6 @@
# shellcheck source=../scripts/start-utils
. "${SCRIPTS:-/}start-utils"
if [ -f /data/.mc-health.env ]; then
. /data/.mc-health.env
fi
if isTrue "${DISABLE_HEALTHCHECK}"; then
echo "Healthcheck disabled"
@@ -13,6 +10,6 @@ elif isTrue "${ENABLE_AUTOPAUSE}" && [[ "$( ps -ax -o stat,comm | grep 'java' |
echo "Java process suspended by Autopause function"
exit 0
else
mc-monitor status "${MC_HEALTH_EXTRA_ARGS[@]}" --host localhost --port "${SERVER_PORT:-25565}"
mc-monitor status --host localhost --port "${SERVER_PORT:-25565}"
exit $?
fi

View File

@@ -1,5 +1,5 @@
#!/bin/bash
. "/start-utils"
: "${CONSOLE_IN_NAMED_PIPE:=/tmp/minecraft-console-in}"
if [ $# = 0 ]; then
@@ -12,12 +12,4 @@ if [ ! -p "${CONSOLE_IN_NAMED_PIPE}" ]; then
exit 1
fi
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
echo "$@" > "${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}"

View File

@@ -1,26 +0,0 @@
#!/bin/sh
set -e
apk add --no-cache -U \
openssl \
imagemagick \
file \
lsof \
su-exec \
coreutils \
findutils \
procps \
shadow \
bash \
curl iputils \
git \
jq \
mysql-client \
tzdata \
rsync \
nano \
sudo \
knock \
tar \
zstd

View File

@@ -1,6 +0,0 @@
#!/bin/sh
set -e
addgroup -g 1000 minecraft
adduser -Ss /bin/false -u 1000 -G minecraft -h /home/minecraft minecraft

View File

@@ -1,12 +0,0 @@
#!/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

View File

@@ -1,37 +0,0 @@
#!/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

View File

@@ -1,2 +0,0 @@
groupadd --gid 1000 minecraft
useradd --system --shell /bin/false --uid 1000 -g minecraft --home /data minecraft

View File

@@ -1,7 +0,0 @@
#!/bin/sh
set -e
distro=$(cat /etc/os-release | grep -E "^ID=" | cut -d= -f2 | sed -e 's/"//g')
"$(dirname "$0")/${distro}/$1".sh

View File

@@ -1,28 +0,0 @@
#!/bin/sh
set -e
apt-get update
DEBIAN_FRONTEND=noninteractive \
apt-get install -y \
imagemagick \
file \
gosu \
sudo \
net-tools \
iputils-ping \
curl \
git \
jq \
dos2unix \
mysql-client \
tzdata \
rsync \
nano \
unzip \
zstd \
lbzip2 \
knockd
apt-get clean

View File

@@ -1,6 +0,0 @@
#!/bin/sh
set -e
addgroup --gid 1000 minecraft
adduser --system --shell /bin/false --uid 1000 --ingroup minecraft --home /data minecraft

133
docker-versions-create.sh Executable file
View File

@@ -0,0 +1,133 @@
#!/bin/bash
#set -x
# Use this variable to indicate a list of branches that docker hub is watching
branches_list=(
'java8'
'java8-multiarch'
'java8-openj9'
'java11'
'java11-openj9'
'java16'
'java16-openj9'
'java17'
)
function TrapExit {
echo "Checking out back in master"
git checkout master
}
batchMode=false
while getopts "hbt:s" arg
do
case $arg in
b)
batchMode=true
;;
t)
tag=${OPTARG}
;;
s)
tagArgs="-s -m 'Signed during docker-versions-create"
;;
h)
echo "
Usage $0 [options]
Options:
-b enable batch mode, which avoids interactive prompts and causes script to fail immediately
when any merge fails
-t TAG tag and push the current revision on master with the given tag
and apply respective tags to each branch
-s enable signed tags
-h display this help and exit
"
exit
;;
*)
echo "Unsupported arg $arg"
exit 2
;;
esac
done
${batchMode} && echo "Using batch mode"
trap TrapExit EXIT SIGTERM
test -d ./.git || { echo ".git folder was not found. Please start this script from root directory of the project!";
exit 1; }
# Making sure we are in master
git checkout master
git pull --all || { echo "Can't pull the repo!"; \
exit 1; }
if [[ $tag ]]; then
git tag $tag
git push origin $tag
fi
git_branches=$(git branch -a)
for branch in "${branches_list[@]}"; do
if [[ "$git_branches" != *"$branch"* ]]; then
echo "Can't update $branch because I can't find it in the list of branches."
exit 1
else
echo "Branch $branch found. Working with it."
git checkout "$branch" || { echo "Can't checkout into the branch. Don't know the cause."; \
exit 1; }
proceed='False'
while [[ "$proceed" == "False" ]]; do
# Ensure local branch is aligned with remote since docker-versions-create may have been run elsewhere
git pull
if git merge -m 'Auto-merging via docker-versions-create' master; then
proceed="True"
echo "Branch $branch updated to current master successfully"
# pushing changes to remote for this branch
git commit -m "Auto merge branch with master" -a
# push may fail if remote doesn't have this branch yet. In this case - sending branch
git push || git push -u origin "$branch" || { echo "Can't push changes to the origin."; exit 1; }
if [[ $tag ]]; then
git tag "$tag-$branch"
git push origin "$tag-$branch"
fi
elif ${batchMode}; then
status=$?
echo "Git merge failed in batch mode"
exit ${status}
# and trap exit gets us back to master
else
cat<<EOL
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Master merge in the branch $branch encountered an error!
You may try to fix the error and merge again. (Commit changes)
Or skip this branch merge completely.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
EOL
printf "Should we try again? (y):"
read -r answer
if [[ "$answer" == '' ]] || [[ "$answer" == 'y' ]] || [[ "$answer" == 'Y' ]]; then
# If you use non-local editor or files are changed in repo
cat <<EOL
The following commands may encounter an error!
This is completely fine if the changes were made locally and remote branch doesn't know about them.
EOL
# Updating branch from remote before trying again
git checkout master
git fetch --all
git pull -a
git checkout "$branch"
continue
else
break
fi
fi
done
fi
done

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

View File

@@ -1,20 +0,0 @@
version: '3.8'
services:
minecraft:
image: itzg/minecraft-server
ports:
- "25565:25565"
volumes:
- "mc:/data"
environment:
EULA: "TRUE"
ENABLE_AUTOSTOP: "TRUE"
# More aggressive settings for demo purposes
AUTOSTOP_TIMEOUT_INIT: "30"
AUTOSTOP_TIMEOUT_EST: "20"
# Important not to auto-restart the server!!!
restart: "no"
volumes:
mc: {}

View File

@@ -9,9 +9,7 @@ services:
environment:
EULA: "true"
TYPE: CURSEFORGE
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/3482/169/Valhelsia+3-3.4.4-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:

View File

@@ -1,19 +0,0 @@
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"

View File

@@ -13,7 +13,6 @@ services:
VERSION: ${VERSION:-1.17.1}
FORGEVERSION: ${FORGEVERSION:-37.0.90}
GENERIC_PACK: /modpacks/${MODPACK:-Server-Files-0.0.21.zip}
REMOVE_OLD_MODS: "${REMOVE_OLD_MODS:-false}"
ports:
- "25565:25565"

View File

@@ -1,17 +0,0 @@
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: {}

View File

@@ -1,18 +0,0 @@
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: {}

View File

@@ -1,19 +1,18 @@
version: '3.8'
services:
mc:
image: itzg/minecraft-server
container_name: paper
environment:
EULA: "true"
ENABLE_RCON: "true"
TYPE: PAPER
VIEW_DISTANCE: 10
MEMORY: 2G
VERSION: 1.9.4
# needed for Paper versions before 1.14
CONSOLE: "false"
ports:
- 25565:25565
volumes:
- mc-paper:/data
restart: unless-stopped
volumes:
mc-paper:

View File

@@ -1,36 +0,0 @@
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: {}

View File

@@ -1,27 +1,27 @@
version: '3.8'
services:
mc:
rlcraft:
image: itzg/minecraft-server:java8
container_name: rlcraft
volumes:
- data:/data
- ./modpacks:/modpacks:ro
- rlcraft-modpack:/modpacks:ro
- rlcraft-data:/data
environment:
EULA: "true"
TYPE: "FORGE"
VERSION: "1.12.2"
FORGEVERSION: "14.23.5.2860"
OVERRIDE_SERVER_PROPERTIES: "true"
FORGEVERSION: "14.23.5.2855"
DIFFICULTY: "hard"
MAX_TICK_TIME: "-1"
VIEW_DISTANCE: "6"
ALLOW_FLIGHT: "true"
ENABLE_COMMAND_BLOCK: "true"
VIEW_DISTANCE: "10"
MEMORY: "4G"
# 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"
GENERIC_PACK: "/modpacks/RLCraft_Server_Pack_1.12.2_Beta_v2.8.2.zip"
ports:
- 25565:25565
restart: unless-stopped
volumes:
data:
rlcraft-data:
rlcraft-modpack:

View File

@@ -3,8 +3,6 @@ version: "3.8"
services:
mc:
image: itzg/minecraft-server
tty: true
stdin_open: true
ports:
- 25565:25565
environment:

View File

@@ -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: 34315,3836
SPIGET_RESOURCES: 9089,34315,3836
volumes:
- data:/data

View File

@@ -3,18 +3,18 @@ apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: mc-example
name: mc-example
app: example
name: example
spec:
replicas: 1
serviceName: mc-example
serviceName: example
selector:
matchLabels:
app: mc-example
app: example
template:
metadata:
labels:
app: mc-example
app: example
spec:
containers:
- name: mc
@@ -25,18 +25,6 @@ spec:
volumeMounts:
- mountPath: /data
name: data
readinessProbe:
exec:
command:
- mc-monitor
- status
- --host
- localhost
- --port
- "25565"
initialDelaySeconds: 30
periodSeconds: 5
failureThreshold: 18
volumeClaimTemplates:
- metadata:
name: data
@@ -51,12 +39,12 @@ apiVersion: v1
kind: Service
metadata:
labels:
service: mc-example
name: mc-example
service: example
name: example
spec:
ports:
- port: 25565
targetPort: 25565
selector:
app: mc-example
type: NodePort
app: example
type: LoadBalancer

View File

@@ -35,17 +35,20 @@ spec:
name: main
readinessProbe:
exec:
command: [ "/usr/local/bin/mc-monitor", "status", "--host", "localhost" ]
# Give it i + p * f seconds to be ready, so 120 seconds
initialDelaySeconds: 20
command:
- mcstatus
- localhost
- ping
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 20
# Monitor ongoing liveness
livenessProbe:
exec:
command: ["/usr/local/bin/mc-monitor", "status", "--host", "localhost"]
initialDelaySeconds: 120
periodSeconds: 60
command:
- mcstatus
- localhost
- ping
initialDelaySeconds: 5
periodSeconds: 5
volumeMounts:
- name: mc-data
mountPath: /data

View File

@@ -1,27 +0,0 @@
version: "3.3"
services:
vanillatweaks_file:
restart: "no"
image: itzg/minecraft-server
ports:
- "25565:25565/tcp"
environment:
EULA: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
VANILLATWEAKS_FILE: /config/vanillatweaks-datapacks.json
REMOVE_OLD_VANILLATWEAKS: "TRUE"
volumes:
- data:/data
- ./vanillatweaks-datapacks.json:/config/vanillatweaks-datapacks.json:ro
vanillatweaks_sharecode:
# port is set to 25566 to not conflict with vanillatweaks_file example
ports:
- "25566:25565/tcp"
restart: "no"
image: itzg/minecraft-server
environment:
EULA: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
VANILLATWEAKS_SHARECODE: MGr52E
REMOVE_OLD_VANILLATWEAKS: "TRUE"

View File

@@ -1,15 +0,0 @@
{
"version": "1.18",
"packs": {
"survival": [
"graves",
"multiplayer sleep",
"afk display",
"armor statues",
"unlock all recipes",
"fast leaf decay",
"coordinates hud"
],
"items": ["armored elytra"]
}
}

View File

@@ -20,16 +20,12 @@ mc_server_listening() {
mc-monitor status --host localhost --port "$SERVER_PORT" --timeout 10s >& /dev/null
}
java_clients_connections() {
java_clients_connected() {
local connections
if java_running ; then
connections=$(mc-monitor status --host localhost --port "$SERVER_PORT" --show-player-count)
else
connections=0
fi
echo $connections
}
java_clients_connected() {
(( $(java_clients_connections) > 0 ))
(( connections > 0 ))
}

View File

@@ -3,13 +3,13 @@
[unpauseMCServer-server]
sequence = 25565
seq_timeout = 1
command = /autopause/resume.sh
command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh
tcpflags = syn
[unpauseMCServer-rcon]
sequence = 25575
seq_timeout = 1
command = /autopause/resume.sh
command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh
tcpflags = syn
[unpauseMCServer-bedrock]
sequence = 19132:udp
command = /autopause/resume.sh
command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh

View File

@@ -1,69 +0,0 @@
#!/bin/bash
# needed for the clients connected function residing in autopause
. /autopause/autopause-fcns.sh
. ${SCRIPTS:-/}start-utils
# wait for java process to be started
while :
do
if java_process_exists ; then
break
fi
sleep 0.1
done
STATE=INIT
while :
do
case X$STATE in
XINIT)
# Server startup
if mc_server_listening ; then
TIME_THRESH=$(($(current_uptime)+$AUTOSTOP_TIMEOUT_INIT))
logAutostop "MC Server listening for connections - stopping in $AUTOSTOP_TIMEOUT_INIT seconds"
STATE=II
fi
;;
XII)
# Initial idle
if java_clients_connected ; then
logAutostop "Client connected - waiting for disconnect"
STATE=E
else
if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then
logAutostop "No client connected since startup - stopping server"
/autostop/stop.sh
exit 0
fi
fi
;;
XE)
# Established
if ! java_clients_connected ; then
TIME_THRESH=$(($(current_uptime)+$AUTOSTOP_TIMEOUT_EST))
logAutostop "All clients disconnected - stopping in $AUTOSTOP_TIMEOUT_EST seconds"
STATE=I
fi
;;
XI)
# Idle
if java_clients_connected ; then
logAutostop "Client reconnected - waiting for disconnect"
STATE=E
else
if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then
logAutostop "No client reconnected - stopping"
/autostop/stop.sh
exit 0
fi
fi
;;
*)
logAutostop "Error: invalid state: $STATE"
;;
esac
sleep $AUTOSTOP_PERIOD
done

View File

@@ -1,6 +0,0 @@
#!/bin/bash
. /start-utils
logAutostopAction "Stopping Java process"
kill -SIGTERM 1

View File

@@ -10,16 +10,13 @@
<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>

View File

@@ -1,101 +0,0 @@
#!/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

View File

@@ -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

View File

@@ -1,16 +1,11 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
# The Dockerfile ENVs take precedence here, but defaulting for testing consistency
: "${UID:=1000}"
: "${GID:=1000}"
. ${SCRIPTS:-/}start-utils
umask 0002
chmod g+w /data
if ! isTrue "${SKIP_SUDO:-false}" && [ "$(id -u)" = 0 ]; then
if ! isTrue "${SKIP_SUDO:-false}" && [ $(id -u) = 0 ]; then
runAsUser=minecraft
runAsGroup=minecraft
@@ -29,14 +24,14 @@ if ! isTrue "${SKIP_SUDO:-false}" && [ "$(id -u)" = 0 ]; then
if [[ $GID != 0 ]]; then
if [[ $GID != $(id -g minecraft) ]]; then
log "Changing gid of minecraft to $GID"
groupmod -o -g "$GID" minecraft
groupmod -o -g $GID minecraft
fi
else
runAsGroup=root
fi
fi
if [[ $(stat -c "%u" /data) != "$UID" ]]; then
if [[ $(stat -c "%u" /data) != $UID ]]; then
log "Changing ownership of /data to $UID ..."
chown -R ${runAsUser}:${runAsGroup} /data
fi
@@ -45,12 +40,7 @@ if ! isTrue "${SKIP_SUDO:-false}" && [ "$(id -u)" = 0 ]; then
echo 'hosts: files dns' > /etc/nsswitch.conf
fi
distro=$(getDistro)
if [[ $distro == alpine ]]; then
exec su-exec ${runAsUser}:${runAsGroup} "${SCRIPTS:-/}start-configuration" "$@"
else
exec gosu ${runAsUser}:${runAsGroup} "${SCRIPTS:-/}start-configuration" "$@"
fi
exec gosu ${runAsUser}:${runAsGroup} ${SCRIPTS:-/}start-configuration $@
else
exec "${SCRIPTS:-/}start-configuration" "$@"
exec ${SCRIPTS:-/}start-configuration $@
fi

View File

@@ -4,19 +4,7 @@
. "${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"

View File

@@ -1,42 +0,0 @@
#!/bin/bash
# shellcheck source=start-utils
. "${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"
isDebugging && set -x
if ! [[ $AUTOSTOP_PERIOD =~ ^[0-9]+$ ]]; then
AUTOSTOP_PERIOD=10
export AUTOSTOP_PERIOD
log "Warning: AUTOSTOP_PERIOD is not numeric, set to 10 (seconds)"
fi
if [ "$AUTOSTOP_PERIOD" -eq "0" ] ; then
AUTOSTOP_PERIOD=10
export AUTOSTOP_PERIOD
log "Warning: AUTOSTOP_PERIOD must not be 0, set to 10 (seconds)"
fi
if ! [[ $AUTOSTOP_TIMEOUT_EST =~ ^[0-9]+$ ]] ; then
AUTOSTOP_TIMEOUT_EST=3600
export AUTOSTOP_TIMEOUT_EST
log "Warning: AUTOSTOP_TIMEOUT_EST is not numeric, set to 3600 (seconds)"
fi
if ! [[ $AUTOSTOP_TIMEOUT_INIT =~ ^[0-9]+$ ]] ; then
AUTOSTOP_TIMEOUT_INIT=1800
export AUTOSTOP_TIMEOUT_INIT
log "Warning: AUTOSTOP_TIMEOUT_INIT is not numeric, set to 1800 (seconds)"
fi
/autostop/autostop-daemon.sh &

View File

@@ -3,22 +3,11 @@ set -euo pipefail
IFS=$'\n\t'
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
: "${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
@@ -43,15 +32,6 @@ if [ ! -e /data/eula.txt ]; then
writeEula
fi
if isTrue "${ENABLE_AUTOPAUSE}" && isTrue "${EXEC_DIRECTLY:-false}"; then
log "EXEC_DIRECTLY=true is incompatible with ENABLE_AUTOPAUSE=true"
exit 1
fi
if isTrue "${ENABLE_AUTOPAUSE}" && isTrue "${ENABLE_AUTOSTOP}"; then
log "ENABLE_AUTOPAUSE=true is incompatible with ENABLE_AUTOSTOP=true"
exit 1
fi
if [[ $PROXY ]]; then
export http_proxy="$PROXY"
@@ -77,28 +57,9 @@ if [[ $RCON_PASSWORD_FILE ]]; then
log ""
fi
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
if ! which java > /dev/null; then
log "Fixing PATH to include java"
PATH="${PATH}:/opt/java/openjdk/bin"
fi
export VERSIONS_JSON=https://launchermeta.mojang.com/mc/game/version_manifest.json
@@ -121,9 +82,7 @@ case "X$VERSION" in
;;
esac
export 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}"
log "Resolved version given ${VERSION} into ${VANILLA_VERSION}"
cd /data || exit 1
@@ -133,61 +92,42 @@ if isTrue "${ENABLE_AUTOPAUSE}"; then
${SCRIPTS:-/}start-autopause
fi
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=(
--use-server-list-ping
)
" > /data/.mc-health.env
fi
log "Resolving type given ${TYPE}"
case "${TYPE^^}" in
*BUKKIT|SPIGOT)
exec "${SCRIPTS:-/}start-deployBukkitSpigot" "$@"
exec ${SCRIPTS:-/}start-deployBukkitSpigot "$@"
;;
PAPER)
exec "${SCRIPTS:-/}start-deployPaper" "$@"
exec ${SCRIPTS:-/}start-deployPaper "$@"
;;
FORGE)
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployForge" "$@"
if versionLessThan 1.17; then
log "**********************************************************************"
log "WARNING: The image tag itzg/minecraft-server:java8 is recommended"
log " since some mods require Java 8"
log " Exception traces reporting ClassCastException: class jdk.internal.loader.ClassLoaders\$AppClassLoader"
log " can be fixed with java8"
log "**********************************************************************"
fi
exec ${SCRIPTS:-/}start-deployForge "$@"
;;
FABRIC)
exec "${SCRIPTS:-/}start-deployFabric" "$@"
exec ${SCRIPTS:-/}start-deployFabric "$@"
;;
QUILT)
exec "${SCRIPTS:-/}start-deployQuilt" "$@"
;;
FTBA)
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployFTBA" "$@"
exec ${SCRIPTS:-/}start-deployFTBA "$@"
;;
FTB|CURSEFORGE)
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployCF" "$@"
log "**********************************************************************"
log "NOTE: Some mods and modpacks may require Java 8."
log " If so, use itzg/minecraft-server:java8"
log "**********************************************************************"
exec ${SCRIPTS:-/}start-deployCF "$@"
;;
VANILLA)
@@ -195,48 +135,39 @@ case "${TYPE^^}" in
;;
SPONGEVANILLA)
exec "${SCRIPTS:-/}start-deploySpongeVanilla" "$@"
exec ${SCRIPTS:-/}start-deploySpongeVanilla "$@"
;;
CUSTOM)
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployCustom" "$@"
exec ${SCRIPTS:-/}start-deployCustom "$@"
;;
MAGMA)
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployMagma" "$@"
exec ${SCRIPTS:-/}start-deployMagma "$@"
;;
MOHIST)
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployMohist" "$@"
exec ${SCRIPTS:-/}start-deployMohist "$@"
;;
CATSERVER)
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployCatserver" "$@"
;;
LOLISERVER)
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployLoliserver" "$@"
exec ${SCRIPTS:-/}start-deployCatserver "$@"
;;
PURPUR)
exec "${SCRIPTS:-/}start-deployPurpur" "$@"
exec ${SCRIPTS:-/}start-deployPurpur "$@"
;;
PUFFERFISH)
exec "${SCRIPTS:-/}start-deployPufferfish" "$@"
AIRPLANE)
exec ${SCRIPTS:-/}start-deployAirplane "$@"
;;
CANYON)
exec "${SCRIPTS:-/}start-deployCanyon" "$@"
exec ${SCRIPTS:-/}start-deployCanyon "$@"
;;
LIMBO)
exec "${SCRIPTS:-/}start-deployLimbo" "$@"
exec ${SCRIPTS:-/}start-deployLimbo "$@"
;;
CRUCIBLE)
@@ -253,7 +184,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, LOLISERVER, AIRPLANE, PUFFERFISH, CANYON, LIMBO, CRUCIBLE"
log " MAGMA, MOHIST, CATSERVER, AIRPLANE, CANYON, LIMBO, CRUCIBLE"
exit 1
;;

52
scripts/start-deployAirplane Executable file
View File

@@ -0,0 +1,52 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "1.16" ] && [ "${VERSION}" != "1.17" ] && [ "${VERSION}" != "PURPUR" ] && [ "${VERSION}" != "PURPUR-1.16" ] ; then
log "ERROR: Airplane server type only supports VERSION=LATEST, VERSION=1.17, VERSION=1.16, VERSION=PURPUR or VERSION=PURPUR-1.16. Note that these are branches, not #.#.# versions."
exit 1
fi
: ${AIRPLANE_BUILD:=lastSuccessfulBuild}
: ${AIRPLANE_TYPE:=airplane}
if [ "${VERSION}" = "LATEST" ] || [ "${VERSION}" = "1.17" ]; then
AIRPLANE_BRANCH="1.17"
fi
if [ "${VERSION}" = "1.16" ]; then
AIRPLANE_BRANCH="1.16"
fi
if [ "${VERSION}" = "PURPUR" ]; then
AIRPLANE_BRANCH="Purpur-1.17"
AIRPLANE_TYPE="airplanepurpur"
fi
if [ "${VERSION}" = "PURPUR-1.16" ]; then
AIRPLANE_BRANCH="Purpur-1.16"
AIRPLANE_TYPE="airplanepurpur"
fi
log "Using Airplane-${AIRPLANE_BRANCH} branch"
export SERVER=airplane-${AIRPLANE_BRANCH}-${AIRPLANE_BUILD}.jar
if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
downloadUrl="https://ci.tivy.ca/job/Airplane-${AIRPLANE_BRANCH}/${AIRPLANE_BUILD}/artifact/launcher-${AIRPLANE_TYPE}.jar"
log "Downloading Airplane from $downloadUrl ..."
curl -fsSL -o "$SERVER" "$downloadUrl"
if [ ! -f "$SERVER" ]; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3
fi
fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -64,7 +64,7 @@ function downloadSpigot {
fi
if [[ -z $downloadUrl ]]; then
if versionLessThan 1.16.5 || ([[ ${getbukkitFlavor} = "craftbukkit" ]] && [[ ${VANILLA_VERSION} = "1.16.5" ]]); then
if versionLessThan 1.16.5; then
downloadUrl="https://cdn.getbukkit.org/${getbukkitFlavor}/${getbukkitFlavor}-${VANILLA_VERSION}.jar"
else
downloadUrl="https://download.getbukkit.org/${getbukkitFlavor}/${getbukkitFlavor}-${VANILLA_VERSION}.jar"
@@ -126,6 +126,7 @@ else
fi
# Normalize on Spigot for operations below
export FAMILY=SPIGOT
export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -33,42 +33,13 @@ export TYPE=CURSEFORGE
FTB_SERVER_MOD=${FTB_SERVER_MOD:-$CF_SERVER_MOD}
log "Looking for Feed-The-Beast / CurseForge server modpack."
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}
if isURL "${srv_modpack}"; then
log "Downloading modpack from ${srv_modpack}..."
if ! srv_modpack=$(get -o /data --output-filename --skip-existing "${srv_modpack}"); then
log "ERROR: failed to download modpack"
exit 1
fi
fi
if [[ "${srv_modpack:0:5}" == "data/" ]]; then
# Prepend with "/"
srv_modpack="/${srv_modpack}"
fi
if [[ ! "${srv_modpack:0:1}" == "/" ]]; then
# If not an absolute path, assume file is in "/data"
srv_modpack=/data/${srv_modpack}
fi
if [[ ! -f "${srv_modpack}" ]]; then
log "FTB server modpack ${srv_modpack} not found."
exit 2
fi
if [[ ! "${srv_modpack: -4}" == ".zip" ]]; then
log "FTB server modpack ${srv_modpack} is not a zip archive."
log "Please set FTB_SERVER_MOD to a file with a .zip extension."
exit 2
fi
FTB_SERVER_MOD=${srv_modpack}
}
requireVar FTB_SERVER_MOD
if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
downloadModpack
if ! [ -f "${FTB_SERVER_MOD}" ]; then
log "ERROR unable to find requested modpack file ${FTB_SERVER_MOD}"
exit 2
fi
needsInstall=true
installMarker=/data/.curseforge-installed
@@ -76,7 +47,7 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
if [ "$(cat $installMarker)" != "${FTB_SERVER_MOD}" ]; then
log "Upgrading modpack"
serverJar=$(find "${FTB_BASE_DIR}" -type f \( -path "*/libraries/*" -o -path "*/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
serverJar=$(find "${FTB_BASE_DIR}" -not -name "forge*installer.jar" -name "forge*.jar")
if [[ "${serverJar}" ]]; then
rm -rf "$(dirname "${serverJar}")"/{mods,*.jar,libraries,resources,scripts,config}
fi
@@ -136,94 +107,104 @@ 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
"
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
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
fi
}
startScript=$(findStartScript)
else
startScriptCount=0
fi
# 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 [[ ! $startScript ]]; then
downloadModpack
if [[ $startScriptCount = 0 ]]; then
srv_modpack=${FTB_SERVER_MOD}
if isURL "${srv_modpack}"; then
log "Downloading modpack from ${srv_modpack}..."
if ! srv_modpack=$(get -o /data --output-filename --skip-existing "${srv_modpack}"); then
log "ERROR: failed to download modpack"
exit 1
fi
fi
if [[ "${srv_modpack:0:5}" == "data/" ]]; then
# Prepend with "/"
srv_modpack="/${srv_modpack}"
fi
if [[ ! "${srv_modpack:0:1}" == "/" ]]; then
# If not an absolute path, assume file is in "/data"
srv_modpack=/data/${srv_modpack}
fi
if [[ ! -f "${srv_modpack}" ]]; then
log "FTB server modpack ${srv_modpack} not found."
exit 2
fi
if [[ ! "${srv_modpack: -4}" == ".zip" ]]; then
log "FTB server modpack ${srv_modpack} is not a zip archive."
log "Please set FTB_SERVER_MOD to a file with a .zip extension."
exit 2
fi
log "Unpacking FTB server modpack ${srv_modpack} ..."
mkdir -p "${FTB_BASE_DIR}"
unzip -o "${srv_modpack}" -d "${FTB_BASE_DIR}" | awk '{printf "."} END {print ""}'
installScriptExpr=(
-name install.sh
-o -name FTBInstall.sh
-o -name Install.sh
)
installScript=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( "${installScriptExpr[@]}" \) -print -quit)
installScript=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f -name install.sh)
if [[ "$installScript" ]]; then
(
cd "$(dirname "${installScript}")"
chmod +x "${installScript}"
log "Running included $(basename "${installScript}"). This might take a minute or two..."
"${installScript}" > install.log
chmod +x ./install.sh
log "Running included install.sh"
./install.sh
)
fi
startScript=$(findStartScript)
fi
# start script provided by unzipped+installed modpack?
if [[ ! $startScript ]]; then
# no, then look for a forge jar to run
if [[ $(find "${FTB_BASE_DIR}" $entryScriptExpr | wc -l) = 0 ]]; then
# 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
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"
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
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
fi
fi
# 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="$startScript"
FTB_SERVER_START=$(find "${FTB_BASE_DIR}" $entryScriptExpr)
export FTB_SERVER_START
FTB_DIR=$(dirname "${FTB_SERVER_START}")
@@ -242,5 +223,14 @@ if isTrue "${FTB_LEGACYJAVAFIXER}" && [ ! -e "${legacyJavaFixerPath}" ]; then
fi
fi
export FAMILY=FORGE
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
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -2,11 +2,16 @@
set -euo pipefail
IFS=$'\n\t'
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
: "${CANYON_BUILD:=lastSuccessfulBuild}"
: ${CANYON_BUILD:=lastSuccessfulBuild}
JAVA_VER=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1)
if [ "${JAVA_VER}" != "8" ]; then
log "ERROR: Canyon server type only supports Java version 8"
exit 1
fi
if [ "${VERSION}" != "b1.7.3" ]; then
log "ERROR: Canyon server type only supports VERSION=b1.7.3"
@@ -43,6 +48,7 @@ if [ ! -f "$SERVER" ]; then
fi
# Normalize on Spigot for later operations
export FAMILY=SPIGOT
export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -1,7 +1,6 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
set -o pipefail
set -e
@@ -27,6 +26,7 @@ if [ ! -f ${SERVER} ]; then
curl -H "Accept:application/octet-stream" -o "$SERVER" -fsSL https://api.github.com/repos/Luohuayu/CatServer/releases/assets/${latestJarId}
fi
export FAMILY=HYBRID
export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-/}start-setupWorld" "$@"
# Continue to Final Setup
exec ${SCRIPTS:-/}start-setupWorld "$@"

View File

@@ -55,6 +55,6 @@ if [ ! -d "$librariesDir" ]; then
fi
export SERVER
export FAMILY=HYBRID
export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"

View File

@@ -1,7 +1,6 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
if isURL ${CUSTOM_SERVER}; then
@@ -31,7 +30,6 @@ else
fi
# Allow for overriding Family on custom for testing.
export FAMILY="${FAMILY:-HYBRID}"
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-setupWorld $@

View File

@@ -2,8 +2,7 @@
ftbInstallMarker=".ftb-installed"
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
set -e
@@ -67,9 +66,8 @@ 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
for f in ${variants[@]}; do
if [ -f $f ]; then
export SERVER=$f
break
@@ -81,6 +79,4 @@ if ! [ -v SERVER ]; then
exit 2
fi
export FAMILY=FORGE
exec ${SCRIPTS:-/}start-setupWorld $@

View File

@@ -2,49 +2,71 @@
set -eu
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
requireVar VANILLA_VERSION
export TYPE=FABRIC
: "${FABRIC_LAUNCHER_VERSION:=${FABRIC_INSTALLER_VERSION:-LATEST}}"
: "${FABRIC_LAUNCHER:=}"
: "${FABRIC_LAUNCHER_URL:=}"
: "${FABRIC_LOADER_VERSION:=LATEST}"
export SERVER=fabric-server-${VANILLA_VERSION}.jar
isDebugging && set -x
# Custom fabric jar
if [[ $FABRIC_LAUNCHER ]]; then
export SERVER=${FABRIC_LAUNCHER}
# Custom fabric jar url
elif [[ $FABRIC_LAUNCHER_URL ]]; then
export SERVER=fabric-server-$(echo -n "$FABRIC_LAUNCHER_URL" | mc-image-helper hash)
# Official fabric launcher
else
if [[ ${FABRIC_LAUNCHER_VERSION^^} = LATEST ]]; then
log "Checking Fabric Launcher version information."
FABRIC_LAUNCHER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-installer/maven-metadata.xml)
fi
if [[ ${FABRIC_LOADER_VERSION^^} = LATEST ]]; then
log "Checking Fabric Loader version information."
FABRIC_LOADER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-loader/maven-metadata.xml)
fi
export SERVER=fabric-server-mc.${VANILLA_VERSION}-loader.${FABRIC_LOADER_VERSION}-launcher.${FABRIC_LAUNCHER_VERSION}.jar
export FABRIC_LAUNCHER_URL="https://meta.fabricmc.net/v2/versions/loader/${VANILLA_VERSION}/${FABRIC_LOADER_VERSION}/${FABRIC_LAUNCHER_VERSION}/server/jar"
fi
if [[ ! -e ${SERVER} ]]; then
if [[ ! -e ${SERVER} && ! -z ${FABRIC_LAUNCHER_URL} ]]; then
log "Downloading $FABRIC_LAUNCHER_URL ..."
if ! get -o "$SERVER" "$FABRIC_LAUNCHER_URL"; then
log "Failed to download from given location $FABRIC_LAUNCHER_URL"
: ${FABRIC_INSTALLER:=}
: ${FABRIC_INSTALLER_URL:=}
: ${FABRIC_LOADER_VERSION:=LATEST}
: ${FABRIC_INSTALLER_VERSION:=${FABRICVERSION:-LATEST}}
if [[ -z $FABRIC_INSTALLER && -z $FABRIC_INSTALLER_URL ]]; then
log "Checking Fabric version information."
if [[ ${FABRIC_INSTALLER_VERSION^^} = LATEST ]]; then
FABRIC_INSTALLER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-installer/maven-metadata.xml)
fi
FABRIC_INSTALLER="fabric-installer-${FABRIC_INSTALLER_VERSION}.jar"
FABRIC_INSTALLER_URL="https://maven.fabricmc.net/net/fabricmc/fabric-installer/${FABRIC_INSTALLER_VERSION}/fabric-installer-${FABRIC_INSTALLER_VERSION}.jar"
elif [[ -z $FABRIC_INSTALLER ]]; then
FABRIC_INSTALLER="fabric-installer.jar"
elif [[ ! -e $FABRIC_INSTALLER ]]; then
log "ERROR: the given Fabric installer doesn't exist : $FABRIC_INSTALLER"
exit 2
fi
if [[ -z $FABRIC_LOADER_VERSION || ${FABRIC_LOADER_VERSION^^} = LATEST ]]; then
log "Checking Fabric Loader version information."
FABRIC_LOADER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-loader/maven-metadata.xml)
fi
if [[ ! -e $FABRIC_INSTALLER ]]; then
log "Downloading $FABRIC_INSTALLER_URL ..."
if ! get -o "$FABRIC_INSTALLER" "$FABRIC_INSTALLER_URL"; then
log "Failed to download from given location $FABRIC_INSTALLER_URL"
exit 2
fi
fi
log "Installing Fabric ${VANILLA_VERSION} using $FABRIC_INSTALLER with loader version $FABRIC_LOADER_VERSION"
tries=3
set +e
while ((--tries >= 0)); do
java -jar $FABRIC_INSTALLER server \
-mcversion $VANILLA_VERSION \
-loader $FABRIC_LOADER_VERSION \
-downloadMinecraft \
-dir /data
if [[ $? == 0 ]]; then
break
fi
done
set -e
if (($tries < 0)); then
log "Fabric failed to install after several tries." >&2
exit 10
fi
mv fabric-server-launch.jar "${SERVER}"
fi
if [[ ! -e ${SERVER} ]]; then
log "$SERVER does not exist, cannot launch server!"
exit 1
fi
export FAMILY=FABRIC
exec "${SCRIPTS:-/}start-setupWorld" "$@"
exec ${SCRIPTS:-/}start-setupWorld "$@"

View File

@@ -8,11 +8,11 @@ isDebugging && set -x
get_installer() {
if [[ -z $FORGE_INSTALLER_URL ]]; then
log "Downloading Forge Installer $normForgeVersion"
log "Downloading $normForgeVersion"
forgeFileNames="
$shortForgeVersion/forge-$shortForgeVersion-installer.jar
$normForgeVersion/forge-$normForgeVersion-installer.jar
$shortForgeVersion/forge-$shortForgeVersion-installer.jar
"
for fn in $forgeFileNames; do
@@ -25,7 +25,7 @@ get_installer() {
log "Unable to locate usable URL for $normForgeVersion"
exit 2
else
log "Downloading Forge Installer from $FORGE_INSTALLER_URL ..."
log "Downloading $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,26 +38,18 @@ install() {
get_installer "$normForgeVersion" "$shortForgeVersion"
fi
# reference issue #1459
rm -f run.sh
log "Installing Forge $shortForgeVersion. This might take a minute or two..."
log "Installing Forge $shortForgeVersion using $FORGE_INSTALLER"
mkdir -p mods
tries=3
while true; do
if ! java -jar "$FORGE_INSTALLER" --installServer &> forge-installer.log; then
if ((--tries <= 0)); then
cat forge-installer.log
log "
ERROR Forge failed to install after several tries.
"
exit 1
fi
log "Install failed. Trying again..."
else
break # out of this loop
while ((--tries >= 0)); do
if java -jar "$FORGE_INSTALLER" --installServer; then
break
fi
done
if ((tries < 0)); then
log "Forge failed to install after several tries." >&2
exit 10
fi
# NOTE $shortForgeVersion will be empty if installer location was given to us
log "Finding installed server jar..."
unset -v latest
@@ -102,7 +94,7 @@ resolve_versions() {
log "Checking Forge version information."
case $FORGEVERSION in
LATEST)
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" --json-value-when-missing "" "$promosUrl"); then
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" "$promosUrl"); then
log "ERROR: Version $VANILLA_VERSION is not supported by Forge"
log " Refer to http://files.minecraftforge.net/ for supported versions"
exit 2
@@ -110,8 +102,8 @@ resolve_versions() {
;;
RECOMMENDED)
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
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-recommended']" "$promosUrl"); then
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" "$promosUrl"); then
log "ERROR: Version $VANILLA_VERSION is not supported by Forge"
log " Refer to http://files.minecraftforge.net/ for supported versions"
exit 2
@@ -155,6 +147,4 @@ else
fi
fi
export FAMILY=FORGE
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -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}
@@ -58,5 +58,6 @@ if [[ ${LEVEL} != *\;* ]]; then
fi
export LEVEL
export FAMILY=LIMBO
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-setupWorld $@

View File

@@ -1,32 +0,0 @@
#!/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" "$@"

View File

@@ -1,22 +1,92 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
export SKIP_LOG4J_CONFIG=true
isDebugging && set -x
: "${VANILLA_VERSION?}"
: ${VANILLA_VERSION?}
# stable, dev
: ${MAGMA_CHANNEL:=stable}
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?"
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=$?)"
exit 1
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
tagName=$(echo "${latestMeta}" | jq -r '.tag_name')
markerFile=".magma-installed-${VANILLA_VERSION}-${tagName}"
if [ -f "${markerFile}" ]; then
installedTagName=$(cat "${markerFile}")
fi
export SERVER
export FAMILY=HYBRID
if [ ! -f "${markerFile}" ]; then
exec "${SCRIPTS:-/}start-setupWorld" "$@"
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
fi
exec ${SCRIPTS:-/}start-setupWorld $@

View File

@@ -38,6 +38,6 @@ if [ ! -f "${SERVER}" ]; then
get -o "${SERVER}" "${mohistJob}${MOHIST_BUILD}/artifact/${buildRelPath}"
fi
export FAMILY=HYBRID
export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"

View File

@@ -1,39 +1,10 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
set -o pipefail
handleDebugMode
isDebugging && set -x
: "${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
if [[ $PAPER_DOWNLOAD_URL ]]; then
export SERVER=$(getFilenameFromUrl "${PAPER_DOWNLOAD_URL}")
if [ -f "$SERVER" ]; then
@@ -52,16 +23,26 @@ else
0)
;;
22)
handleMissingVersion
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
;;
*)
echo "ERROR: unknown error while looking up PaperMC version=${VANILLA_VERSION}"
exit 1
;;
esac
if [[ $build = null ]]; then
handleMissingVersion
if [ $? != 0 ]; then
echo "ERROR: failed to lookup PaperMC build from version ${VANILLA_VERSION}"
exit 1
fi
export SERVER=$(curl -fsSL "https://papermc.io/api/v2/projects/paper/versions/${VANILLA_VERSION}/builds/${build}" -H "accept: application/json" \
@@ -92,6 +73,7 @@ else
fi
# Normalize on Spigot for downstream operations
export FAMILY=SPIGOT
export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -1,45 +0,0 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
set -euo pipefail
isDebugging && set -x
IFS=$'\n\t'
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_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}"
# 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"
done
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
# Normalize on Spigot for later operations
export FAMILY=SPIGOT
exec "${SCRIPTS:-/}start-spiget" "$@"

View File

@@ -2,54 +2,36 @@
set -euo pipefail
IFS=$'\n\t'
: "${PURPUR_DOWNLOAD_URL:=}"
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
if [[ $PURPUR_DOWNLOAD_URL ]]; then
export SERVER=$(getFilenameFromUrl "${PURPUR_DOWNLOAD_URL}")
: ${VANILLA_VERSION:?}
: ${PURPUR_BUILD:=LATEST}
: ${FORCE_REDOWNLOAD:=false}
if [ -f "$SERVER" ]; then
zarg=(-z "$SERVER")
fi
echo "Preparing custom Purpur jar from $PURPUR_DOWNLOAD_URL"
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
if [[ ${PURPUR_BUILD} == LATEST ]]; then
PURPUR_BUILD=$(curl -fsSL "https://api.pl3x.net/v2/purpur/${VANILLA_VERSION}" |
jq -r '.builds.latest' || echo "")
if [[ -z ${PURPUR_BUILD} ]]; 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 3
fi
fi
# Normalize on Spigot for later operations
export FAMILY=SPIGOT
export SERVER="purpur-${VANILLA_VERSION}-${PURPUR_BUILD}.jar"
exec "${SCRIPTS:-/}start-spiget" "$@"
if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
downloadUrl="https://api.pl3x.net/v2/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download"
log "Downloading Purpur from $downloadUrl ..."
if ! curl -fsSL -o "$SERVER" "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3
fi
fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -1,60 +0,0 @@
#!/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" "$@"

View File

@@ -24,14 +24,12 @@ esac
if [ -z $SPONGEVERSION ]; then
log "Choosing Version for Sponge"
if [ "$SPONGEBRANCH" == "stable" ]; then
SPONGEVERSION=`curl -fsSL https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE | jq -r '.buildTypes.stable.latest.version'`
export SPONGEVERSION=`curl -fsSL https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE | jq -r '.buildTypes.stable.latest.version'`
else
SPONGEVERSION=`curl -fsSL https://dl-api.spongepowered.org/v1/org.spongepowered/$TYPE | jq -r '.buildTypes.bleeding.latest.version'`
export 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
@@ -39,5 +37,4 @@ if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then
curl -sSL -o $SERVER https://repo.spongepowered.org/maven/org/spongepowered/$TYPE/$SPONGEVERSION/$SERVER
fi
export FAMILY=SPONGE
exec ${SCRIPTS:-/}start-setupWorld "$@"
exec ${SCRIPTS:-/}start-setupWorld $@

View File

@@ -8,25 +8,27 @@ set -o pipefail
export SERVER="minecraft_server.${VANILLA_VERSION// /_}.jar"
if [ ! -e "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
log "Locating download for $SERVER ..."
log "Downloading $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"
if ! serverDownloadUrl=$(get --json-path '$.downloads.server.url' "${versionManifestUrl}"); then
log "ERROR: failed to obtain version manifest from $versionManifestUrl ($result)"
serverDownloadUrl=$(get --json-path '$.downloads.server.url' "${versionManifestUrl}")
result=$?
if [ $result != 0 ]; then
log "ERROR failed to obtain version manifest from $versionManifestUrl ($result)"
exit 1
elif [ "$serverDownloadUrl" = "null" ]; then
log "ERROR: there is not a server download for version $VANILLA_VERSION"
log "ERROR version $VANILLA_VERSION does not provide a server download"
exit 1
fi
@@ -34,7 +36,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
@@ -50,5 +52,5 @@ elif [[ -L /data/minecraft_server.jar ]]; then
fi
isDebugging && ls -l
export FAMILY=VANILLA
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -1,84 +1,44 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
isDebugging && set -x
if [ -n "$OPS" ]; then
log "Updating ops"
rm -f /data/ops.txt.converted
echo $OPS | awk -v RS=, '{print}' > /data/ops.txt
fi
if isTrue "${OVERRIDE_OPS}"; then
log "Recreating ops.json file at server startup"
rm -f /data/ops.json
fi
if [ -n "$WHITELIST" ]; then
log "Updating whitelist"
rm -f /data/white-list.txt.converted
echo $WHITELIST | awk -v RS=, '{print}' > /data/white-list.txt
fi
if isTrue "${OVERRIDE_WHITELIST}"; then
log "Recreating whitelist.json file at server startup"
rm -f /data/whitelist.json
fi
if [ -n "$ICON" ]; then
if [ ! -e server-icon.png ] || isTrue "${OVERRIDE_ICON}"; then
if [ ! -e server-icon.png ] || [ "${OVERRIDE_ICON}" == "TRUE" ]; then
log "Using server icon from $ICON..."
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
# 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
else
log "Converting image to 64x64 PNG..."
convert "$ICON" -resize 64x64! /data/server-icon.png
convert /tmp/icon.img -resize 64x64! /data/server-icon.png
fi
fi
fi
canUseRollingLogs=true
useFallbackJvmFlag=false
patchLog4jConfig() {
file=${1?}
url=${2?}
if ! get -o "$file" "$url"; then
log "ERROR: failed to download corrected log4j config, fallback to JVM flag"
useFallbackJvmFlag=true
return 1
fi
JVM_OPTS="-Dlog4j.configurationFile=${file} ${JVM_OPTS}"
canUseRollingLogs=false
}
# Patch Log4j remote code execution vulnerability
# See https://www.minecraft.net/en-us/article/important-message--security-vulnerability-java-edition
if versionLessThan 1.7; then
: # No patch required here.
elif isFamily VANILLA && versionLessThan 1.12; then
patchLog4jConfig log4j2_17-111.xml https://launcher.mojang.com/v1/objects/dd2b723346a8dcd48e7f4d245f6bf09e98db9696/log4j2_17-111.xml
elif isFamily VANILLA && versionLessThan 1.17; then
patchLog4jConfig log4j2_112-116.xml https://launcher.mojang.com/v1/objects/02937d122c86ce73319ef9975b58896fc1b491d1/log4j2_112-116.xml
# See https://purpurmc.org/docs/Log4j/
elif isType PURPUR && versionLessThan 1.17; then
patchLog4jConfig purpur_log4j2_1141-1165.xml https://purpurmc.org/docs/xml/purpur_log4j2_1141-1165.xml
elif isType PURPUR && versionLessThan 1.18.1; then
patchLog4jConfig purpur_log4j2_117.xml https://purpurmc.org/docs/xml/purpur_log4j2_117.xml
elif versionLessThan 1.18.1; then
useFallbackJvmFlag=true
fi
if ${useFallbackJvmFlag}; then
JVM_OPTS="-Dlog4j2.formatMsgNoLookups=true ${JVM_OPTS}"
fi
if isTrue ${ENABLE_ROLLING_LOGS:-false}; then
if ! ${canUseRollingLogs}; then
log "ERROR: Using rolling logs is currently not possible in the selected version due to CVE-2021-44228"
exit 1
fi
# Set up log configuration
LOGFILE="/data/log4j2.xml"
if [ ! -e "$LOGFILE" ]; then
@@ -106,13 +66,12 @@ if versionLessThan 1.14 && [[ ${CONSOLE,,} = false ]]; then
fi
# Optional disable GUI for headless servers
if [[ ${GUI,,} = false ]]; then
if [[ ${GUI} = false || ${GUI} = FALSE ]]; then
EXTRA_ARGS+=" nogui"
fi
: "${MEMORY=1G}"
: "${INIT_MEMORY=${MEMORY}}"
: "${MAX_MEMORY=${MEMORY}}"
: "${INIT_MEMORY:=${MEMORY}}"
: "${MAX_MEMORY:=${MEMORY}}"
expandedDOpts=
if [ -n "$JVM_DD_OPTS" ]; then
@@ -122,8 +81,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}
@@ -179,6 +138,12 @@ if isTrue "${USE_AIKAR_FLAGS}"; then
"
fi
if isTrue "${USE_LARGE_PAGES}"; then
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UseLargePagesInMetaspace
"
fi
if isTrue "${USE_FLARE_FLAGS}"; then
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UnlockDiagnosticVMOptions
@@ -186,12 +151,6 @@ 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
@@ -272,14 +231,10 @@ EOF
else
exec mc-server-runner "${mcServerRunnerArgs[@]}" "${finalArgs[@]}"
fi
elif [[ $SERVER =~ run.sh ]]; then
elif [[ -x run.sh ]]; then
log "Using Forge supplied run.sh script..."
echo $JVM_XX_OPTS $JVM_OPTS $expandedDOpts > user_jvm_args.txt
if isTrue ${SETUP_ONLY:=false}; then
echo "SETUP_ONLY: bash ${SERVER}"
exit
fi
exec mc-server-runner "${mcServerRunnerArgs[@]}" --shell bash "${SERVER}"
exec mc-server-runner "${mcServerRunnerArgs[@]}" --shell bash run.sh
else
# If we have a bootstrap.txt file... feed that in to the server stdin
if [ -f /data/bootstrap.txt ]; then

View File

@@ -1,36 +0,0 @@
#!/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 &

View File

@@ -1,77 +0,0 @@
#!/bin/bash
set -e -o pipefail
: "${REMOVE_OLD_DATAPACKS:=false}"
: "${DATAPACKS_FILE:=}"
: "${REMOVE_OLD_DATAPACKS_DEPTH:=1} "
: "${REMOVE_OLD_DATAPACKS_INCLUDE:=*.zip}"
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x
out_dir=/data/${LEVEL:-world}/datapacks
# Remove old datapacks
if isTrue "${REMOVE_OLD_DATAPACKS}" && [ -z "${DATAPACKS_FILE}" ]; then
if [ -d "$out_dir" ]; then
find "$out_dir" -mindepth 1 -maxdepth ${REMOVE_OLD_DATAPACKS_DEPTH:-16} -wholename "${REMOVE_OLD_DATAPACKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_DATAPACKS_EXCLUDE:-}" -delete
fi
fi
if [[ "$DATAPACKS" ]]; then
mkdir -p "$out_dir"
for i in ${DATAPACKS//,/ }
do
if isURL "$i"; then
log "Downloading datapack $i ..."
if ! get -o "${out_dir}" "$i"; then
log "ERROR: failed to download from $i into $out_dir"
exit 2
fi
elif [[ -f "$i" && "$i" =~ .*\.zip ]]; then
log "Copying datapack located at $i ..."
out_file=$(basename "$i")
if ! cp "$i" "${out_dir}/$out_file"; then
log "ERROR: failed to copy from $i into $out_dir"
exit 2
fi
elif [[ -d "$i" ]]; then
log "Copying datapacks from $i ..."
cp "$i"/*.zip "${out_dir}"
else
log "ERROR Invalid URL or path given in DATAPACKS: $i"
exit 2
fi
done
elif [[ "$DATAPACKS_FILE" ]]; then
if [ ! -f "$DATAPACKS_FILE" ]; then
log "ERROR: given DATAPACKS_FILE file does not exist"
exit 2
fi
mkdir -p "$out_dir"
args=(
-o "${out_dir}"
--log-progress-each
--skip-existing
--uris-file "${DATAPACKS_FILE}"
)
if isTrue "${REMOVE_OLD_DATAPACKS}"; then
args+=(
--prune-others "${REMOVE_OLD_DATAPACKS_INCLUDE}"
--prune-depth "${REMOVE_OLD_DATAPACKS_DEPTH}"
)
fi
if ! get "${args[@]}" ; then
log "ERROR: failed to retrieve one or more datapacks"
exit 1
fi
fi
exec "${SCRIPTS:-/}start-setupForgeApiMods" "$@"

View File

@@ -32,4 +32,4 @@ if [[ ${PATCH_DEFINITIONS} ]]; then
"${PATCH_DEFINITIONS}"
fi
exec "${SCRIPTS:-/}start-setupRbac" "$@"
exec "${SCRIPTS:-/}start-finalExec" "$@"

View File

@@ -1,244 +0,0 @@
#!/bin/bash
set -e -o pipefail
: "${MODS_FORGEAPI_KEY:=}"
: "${REMOVE_OLD_FORGEAPI_MODS:=false}"
: "${MODS_FORGEAPI_PROJECTIDS:=}"
: "${MODS_FORGEAPI_FILE:=}"
: "${MODS_FORGEAPI_RELEASES:=RELEASE}"
: "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES:=false}"
: "${MODS_FORGEAPI_IGNORE_GAMETYPE:=false}"
: "${REMOVE_OLD_MODS_DEPTH:=1} "
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar}"
# FORGEAPI_BASE_URL used in manifest downloads below
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
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x
# Remove old mods/plugins
if isTrue "${REMOVE_OLD_FORGEAPI_MODS}"; then
removeOldMods "/data/mods"
fi
# Family filter is on by default for Forge, Fabric, and Bukkit
updateFamilyFilter(){
if isFamily "FORGE" "FABRIC" "BUKKIT"; then
FILTER_BY_FAMILY=true
fi
}
ensureModKey(){
if [ -z "$MODS_FORGEAPI_KEY" ]; then
log "ERROR: MODS_FORGEAPI_KEY REQUIRED to Connect to FORGE API, you supplied: ${MODS_FORGEAPI_KEY}"
exit 2
fi
}
# Set the global release type per the text.
# NOTE: downcasing release type for comparing types.
updateReleaseNumber(){
releaseType=$1
if [ "release" = "${releaseType,,}" ] || [ 1 = "${releaseType,,}" ]; then
RELEASE_NUMBER_FILTER=1
elif [ "beta" = "${releaseType,,}" ] || [ 2 = "${releaseType,,}" ]; then
RELEASE_NUMBER_FILTER=2
elif [ "alpha" = "${releaseType,,}" ] || [ 3 = "${releaseType,,}" ]; then
RELEASE_NUMBER_FILTER=3
fi
}
retrieveVersionTypeNumber(){
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}'')
if [ ! "$minecraft_types" ]; then
log "ERROR: unable to retrieve version types for ${VERSION_NAME} from ForgeAPI. Check Forge API key or supplied Minecraft version"
exit 2
fi
TYPE_ID=$(jq -n "$minecraft_types" | jq --arg VERSION_NAME "$VERSION_NAME" -jc '
.data[]? | select(.name==$VERSION_NAME) | .id')
if [ ! "$TYPE_ID" ]; then
log "ERROR: unable to retrieve version types for ${VERSION_NAME} from ForgeAPI"
exit 2
fi
}
modFileByProjectID(){
project_id=$(echo "$1" | tr -d '"')
project_id_release_type=$2
project_id_file_name=$3
unset PROJECT_FILE
# if Type id isn't defined use minecraft version to go get it.
if [ ! "$TYPE_ID" ]; then
retrieveVersionTypeNumber
fi
# JQ is struggling with larger page sizes so having to pagination for mods with a lot of releases
pageSize=42
index=0
total_count=1
while [ $index -lt $total_count ]; do
project_files=$(curl -X GET -s \
"${FORGEAPI_BASE_URL}/mods/${project_id}/files?gameVersionTypeId=${TYPE_ID}&index=${index}&pageSize=${pageSize}" \
-H 'Accept: application/json' -H 'x-api-key: '${MODS_FORGEAPI_KEY}'')
if [ ! "$project_files" ]; then
log "ERROR: unable to retrieve any project id files for ${project_id} from ForgeAPI"
exit 2
fi
# Use project files to grab out the total count of mods.
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"
unset project_id_release_type
else
updateReleaseNumber $MODS_FORGEAPI_RELEASES
fi
# 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
# 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 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,,}" --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" --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 // 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
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))
done
if [ ! "$PROJECT_FILE" ]; then
log "ERROR: Unable to retrieve any files for ${project_id}, Release Type: ${RELEASE_NUMBER_FILTER}, FAMILY_TYPE: ${FAMILY,,}"
exit 2
fi
}
downloadModPackfromModFile() {
if [ ! "$PROJECT_FILE" ]; then
log "ERROR: Project File not found from the ForgeAPI"
exit 2
fi
# trys to make the output directory incase it doesnt exist.
mkdir -p "$out_dir"
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
}
downloadDependencies(){
if [ "$PROJECT_FILE" ]; then
dependencies=$(jq -n "$PROJECT_FILE" | jq -jc '.dependencies' )
required_dependencies=$(jq -n "$dependencies" | jq --arg REQUIRED_FILTER "3" -jc '
map(select(.relationType==($REQUIRED_FILTER|tonumber)))')
if [ "$required_dependencies" ]; then
while read -r current_dependency; do
mod_id=$(jq -n "$current_dependency" | jq -jc '.modId' )
# 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
}
# Use forge api json file to filter and download the correct mods
if [ "$MODS_FORGEAPI_FILE" ] && [ -z "$MODS_FORGEAPI_PROJECTIDS" ]; then
ensureModKey
updateFamilyFilter
if [ ! -f "$MODS_FORGEAPI_FILE" ]; 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.
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' )
# 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
# 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.
if [ "$MODS_FORGEAPI_PROJECTIDS" ] && [ -z "$MODS_FORGEAPI_FILE" ]; then
ensureModKey
updateFamilyFilter
for project_id in ${MODS_FORGEAPI_PROJECTIDS//,/ }; do
# 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
exec "${SCRIPTS:-/}start-setupModpack" "$@"

View File

@@ -1,7 +1,6 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
# If supplied with a URL for a config (simple zip of configurations), download it and unpack
if [[ "$MODCONFIG" ]]; then
@@ -10,7 +9,7 @@ case "X$MODCONFIG" in
log "Downloading mod/plugin configs via HTTP"
log " from $MODCONFIG ..."
curl -sSL -o /tmp/modconfig.zip "$MODCONFIG"
if [ "$FAMILY" = "SPIGOT" ]; then
if [ "$TYPE" = "SPIGOT" ]; then
mkdir -p /data/plugins
unzip -o -d /data/plugins /tmp/modconfig.zip
else
@@ -25,4 +24,4 @@ case "X$MODCONFIG" in
esac
fi
exec "${SCRIPTS:-/}start-setupMounts" "$@"
exec ${SCRIPTS:-/}start-setupMounts $@

View File

@@ -6,7 +6,6 @@ set -e -o pipefail
: "${MODS_FILE:=}"
: "${REMOVE_OLD_MODS_DEPTH:=1} "
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar}"
sum_file=/data/.generic_pack.sum
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
@@ -19,40 +18,6 @@ CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects}
if isTrue "${REMOVE_OLD_MODS}" && [ -z "${MODS_FILE}" ]; then
removeOldMods /data/mods
removeOldMods /data/plugins
rm -f "$sum_file"
fi
# If packwiz url passed, bootstrap packwiz and update mods before other modpack processing
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_BOOTSTRAP_JAR:=packwiz-installer-bootstrap_${latestPackwizVer}.jar}"
if [[ ! -e $PACKWIZ_BOOTSTRAP_JAR ]]; then
log "Downloading Packwiz ${latestPackwizVer}"
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
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
# If supplied with a URL for a modpack (simple zip of jars), download it and unpack
@@ -73,7 +38,7 @@ if [[ "$MODPACK" ]]; then
exit 1
fi
if [ "$FAMILY" = "SPIGOT" ]; then
if [ "$TYPE" = "SPIGOT" ]; then
mkdir -p /data/plugins
if ! unzip -o -d /data/plugins /tmp/modpack.zip; then
log "ERROR: failed to unzip the modpack from ${MODPACK}"
@@ -87,7 +52,7 @@ if [[ "$MODPACK" ]]; then
rm -f /tmp/modpack.zip
elif [[ "$MODS" ]]; then
if [ "$FAMILY" = "SPIGOT" ]; then
if [ "$TYPE" = "SPIGOT" ]; then
out_dir=/data/plugins
else
out_dir=/data/mods
@@ -98,7 +63,7 @@ elif [[ "$MODS" ]]; then
do
if isURL "$i"; then
log "Downloading mod/plugin $i ..."
if ! get --skip-up-to-date -o "${out_dir}" "$i"; then
if ! get -o "${out_dir}" "$i"; then
log "ERROR: failed to download from $i into $out_dir"
exit 2
fi
@@ -124,7 +89,7 @@ elif [[ "$MODS_FILE" ]]; then
exit 2
fi
if [ "$FAMILY" = "SPIGOT" ]; then
if [ "$TYPE" = "SPIGOT" ]; then
out_dir=/data/plugins
else
out_dir=/data/mods
@@ -134,7 +99,7 @@ elif [[ "$MODS_FILE" ]]; then
args=(
-o "${out_dir}"
--log-progress-each
--skip-up-to-date
--skip-existing
--uris-file "${MODS_FILE}"
)
if isTrue "${REMOVE_OLD_MODS}"; then
@@ -193,104 +158,63 @@ case "X$EFFECTIVE_MANIFEST_FILE" in
esac
fi
function genericPacks() {
: "${GENERIC_PACKS:=${GENERIC_PACK}}"
: "${GENERIC_PACKS_PREFIX:=}"
: "${GENERIC_PACKS_SUFFIX:=}"
: "${GENERIC_PACKS:=${GENERIC_PACK}}"
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
fi
packFiles+=("$outfile")
else
packFiles+=("$pack")
packFiles=()
for pack in "${packs[@]}"; do
if isURL "$pack"; then
mkdir -p /data/packs
if ! outfile=$(get -o /data/packs --output-filename --skip-existing "$pack"); then
log "ERROR: failed to download $pack"
exit 2
fi
packFiles+=("$outfile")
else
packFiles+=("$pack")
fi
done
sum_file=/data/.generic_pack.sum
isDebugging && [ -f "$sum_file}" ] && cat "$sum_file"
if ! sha256sum -c "${sum_file}" --status 2> /dev/null; then
base_dir=/tmp/generic_pack_base
mkdir -p ${base_dir}
for pack in "${packFiles[@]}"; do
isDebugging && ls -l "${pack}"
unzip -q -d ${base_dir} "${pack}"
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..."
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"
# 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
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,,}"
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
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"
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
sha256sum "${packFiles[@]}" > "${sum_file}"
isDebugging && cat "$sum_file"
fi
}
genericPacks
modrinthProjects
fi
exec "${SCRIPTS:-/}start-setupModconfig" "$@"

View File

@@ -1,15 +1,14 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
: "${SYNC_SKIP_NEWER_IN_DESTINATION:=${PLUGINS_SYNC_UPDATE:-true}}"
: "${REPLACE_ENV_DURING_SYNC:=true}"
: "${REPLACE_ENV_SUFFIXES:=yml,yaml,txt,cfg,conf,properties,hjson,json,tml,toml}"
: "${REPLACE_ENV_VARIABLE_PREFIX:=${ENV_VARIABLE_PREFIX:-CFG_}}"
: "${REPLACE_ENV_VARIABLES_EXCLUDES:=}"
: "${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS:=}"
: "${DEBUG:=false}"
: ${SYNC_SKIP_NEWER_IN_DESTINATION:=${PLUGINS_SYNC_UPDATE:-true}}
: ${REPLACE_ENV_DURING_SYNC:=true}
: ${REPLACE_ENV_SUFFIXES:=yml,yaml,txt,cfg,conf,properties,hjson,json,tml,toml}
: ${REPLACE_ENV_VARIABLE_PREFIX:=${ENV_VARIABLE_PREFIX:-CFG_}}
: ${REPLACE_ENV_VARIABLES_EXCLUDES:=}
: ${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS:=}
: ${DEBUG:=false}
set -e
isDebugging && set -x
@@ -25,8 +24,8 @@ else
fi
if [ -d /plugins ]; then
case ${FAMILY} in
SPIGOT|HYBRID)
case ${TYPE} in
SPIGOT|BUKKIT|PAPER|MAGMA)
mkdir -p /data/plugins
log "Copying plugins over..."
mc-image-helper \
@@ -41,7 +40,7 @@ if [ -d /plugins ]; then
fi
# If any modules have been provided, copy them over
: "${COPY_MODS_DEST:="/data/mods"}"
: ${COPY_MODS_DEST:="/data/mods"}
if [ -d /mods ]; then
log "Copying any mods over..."
@@ -54,7 +53,7 @@ if [ -d /mods ]; then
/mods "${COPY_MODS_DEST}"
fi
: "${COPY_CONFIG_DEST:="/data/config"}"
: ${COPY_CONFIG_DEST:="/data/config"}
if [ -d /config ]; then
log "Copying any configs from /config to ${COPY_CONFIG_DEST}"
@@ -67,4 +66,4 @@ if [ -d /config ]; then
/config "${COPY_CONFIG_DEST}"
fi
exec "${SCRIPTS:-/}start-setupServerProperties" "$@"
exec ${SCRIPTS:-/}start-setupServerProperties $@

View File

@@ -1,98 +0,0 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x
if versionLessThan 1.7.6; then
opsFile=ops.txt
whitelistFile=white-list.txt
else
opsFile=ops.json
whitelistFile=whitelist.json
fi
function process_user_file() {
local output=$1
local source=$2
if isURL "$source"; then
log "Downloading $output from $source"
if ! get -o "/data/$output" "$source"; then
log "ERROR: failed to download from $source"
exit 2
fi
else
log "Copying $output from $source"
if ! cp "$source" "/data/$output"; then
log "ERROR: failed to copy from $source"
exit 1
fi
fi
}
function process_user_csv() {
local output=$1
local list=$2
local playerDataList
if [[ "$output" == *"ops"* ]]; then
# Extra data for ops.json
userData='{"uuid": .id, "name": .username, "level": 4}'
else
userData='{"uuid": .id, "name": .username}'
fi
log "Updating ${output%.*}"
for i in ${list//,/ }
do
if [ -e "$output" ] && grep -q "$i" "$output"; then
log "$i already present in $output, skipping"
continue
fi
if ! playerData=$(get "https://playerdb.co/api/player/minecraft/$i" | jq -re ".data.player"); then
log "WARNING: Could not lookup user $i for ${output} addition"
else
playerDataList=$playerDataList$(echo "$playerData" | jq -r "$userData")
fi
done
local newUsers=$(echo "$playerDataList" | jq -s .)
if [[ $output =~ .*\.txt ]]; then
# username list for txt config (Minecraft <= 1.7.5)
echo $newUsers | jq -r '.[].name' >> "/data/${output}"
sort -u /data/${output} -o /data/${output}
elif [ -e /data/${output} ]; then
# Merge with existing json file
local currentUsers=$(cat "/data/${output}")
jq --argjson current "$currentUsers" --argjson new "$newUsers" -n '$new + $current | unique_by(.uuid)' > "/data/${output}"
else
# New json file
echo $newUsers > "/data/${output}"
fi
}
if isTrue "${OVERRIDE_OPS}"; then
log "Recreating ${opsFile} file at server startup"
rm -f /data/${opsFile}
fi
if [ -n "${OPS_FILE}" ] && [ ! -e "/data/${opsFile}" ]; then
process_user_file ${opsFile} "$OPS_FILE"
fi
if [ -n "${OPS}" ]; then
process_user_csv ${opsFile} "$OPS"
fi
if isTrue "${OVERRIDE_WHITELIST}"; then
log "Recreating ${whitelistFile} file at server startup"
rm -f /data/${whitelistFile}
fi
if [ -n "${WHITELIST_FILE}" ] && [ ! -e "/data/${whitelistFile}" ]; then
process_user_file ${whitelistFile} "$WHITELIST_FILE"
fi
if [ -n "${WHITELIST}" ]; then
process_user_csv ${whitelistFile} "$WHITELIST"
fi
exec "${SCRIPTS:-/}start-finalExec" "$@"

View File

@@ -4,7 +4,6 @@
. "${SCRIPTS:-/}start-utils"
: "${SERVER_PROPERTIES:=/data/server.properties}"
: "${ENABLE_RCON:=true}"
# FUNCTIONS
function setServerPropValue {
@@ -34,22 +33,19 @@ function setServerProp {
}
function customizeServerProps {
# Whitelist processing
if [ -n "$WHITELIST" ] || [ -n "$WHITELIST_FILE" ] || isTrue "${ENABLE_WHITELIST:-false}"; then
log "Enabling whitelist functionality"
if [ -n "$WHITELIST" ] || isTrue "${ENABLE_WHITELIST:-false}"; then
log "Creating whitelist"
setServerPropValue "whitelist" "true"
setServerPropValue "white-list" "true"
else
log "Disabling whitelist functionality"
log "Disabling whitelist"
setServerPropValue "whitelist" "false"
setServerPropValue "white-list" "false"
fi
setServerProp "enforce-whitelist" ENFORCE_WHITELIST
if [[ $(grep "enforce-whitelist" $SERVER_PROPERTIES) != *true ]]; then
log "WARNING: whitelist enabled but not enforced. Set ENFORCE_WHITELIST=TRUE or update 'enforce-whitelist' in server.properties to enforce the whitelist."
fi
# If not provided, generate a reasonable default message-of-the-day,
# which shows up in the server listing in the client
if ! [ -v MOTD ]; then
if [ -z "$MOTD" ]; then
# snapshot is the odd case where we have to look at version to identify that label
if [[ ${ORIGINAL_TYPE} == "VANILLA" && ${VERSION} == "SNAPSHOT" ]]; then
label=SNAPSHOT
@@ -63,13 +59,6 @@ function customizeServerProps {
MOTD="A ${label} Minecraft Server powered by Docker"
fi
# normalize MOTD
if [[ ${TYPE^^} = LIMBO ]]; then
if [[ $MOTD ]] && ! [[ $MOTD =~ ^{ ]]; then
MOTD="{\"text\":\"${MOTD}\"}"
fi
fi
setServerProp "server-name" SERVER_NAME
setServerProp "server-ip" SERVER_IP
setServerProp "server-port" SERVER_PORT
@@ -102,7 +91,6 @@ function customizeServerProps {
setServerProp "allow-flight" ALLOW_FLIGHT
setServerProp "resource-pack" RESOURCE_PACK
setServerProp "resource-pack-sha1" RESOURCE_PACK_SHA1
setServerProp "require-resource-pack" RESOURCE_PACK_ENFORCE
setServerProp "player-idle-timeout" PLAYER_IDLE_TIMEOUT
setServerProp "broadcast-console-to-ops" BROADCAST_CONSOLE_TO_OPS
setServerProp "broadcast-rcon-to-ops" BROADCAST_RCON_TO_OPS
@@ -115,9 +103,8 @@ function customizeServerProps {
setServerProp "op-permission-level" OP_PERMISSION_LEVEL
setServerProp "prevent-proxy-connections" PREVENT_PROXY_CONNECTIONS
setServerProp "use-native-transport" USE_NATIVE_TRANSPORT
setServerProp "enforce-whitelist" ENFORCE_WHITELIST
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^^}"

View File

@@ -1,19 +0,0 @@
#!/bin/bash
set -e -o pipefail
: "${VANILLATWEAKS_FILE:=}"
: "${VANILLATWEAKS_SHARECODE:=}"
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
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" "$@"

View File

@@ -5,7 +5,7 @@
set -e
isDebugging && set -x
if [ "$TYPE" = "CURSEFORGE" ]; then
if [ $TYPE = "CURSEFORGE" ]; then
worldDest=$FTB_DIR/${LEVEL:-world}
else
worldDest=/data/${LEVEL:-world}
@@ -19,103 +19,49 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] );
"${worldDest}_the_end"
fi
if isURL "$WORLD"; then
log "Downloading world from $WORLD"
if ! get -o /tmp/world.bin "$WORLD"; then
log "ERROR: failed to download world from $WORLD"
exit 1
fi
WORLD=/tmp/world.bin
if isURL $WORLD; then
curl -fsSL "$WORLD" -o /tmp/world.zip
zipSrc=/tmp/world.zip
elif [[ "$WORLD" =~ .*\.zip ]]; then
zipSrc="$WORLD"
fi
if [ -f "$WORLD" ]; then
log "Extracting world"
if [[ "$zipSrc" ]]; then
log "Unzipping world"
# Stage contents so that the correct subdirectory can be picked off
mkdir -p /tmp/world-data
if ! extract "$WORLD" /tmp/world-data; then
log "ERROR extracting world from $WORLD"
exit 1
fi
(cd /tmp/world-data && unzip -o -q "$zipSrc")
baseDirs=$(find /tmp/world-data -name "level.dat" -exec dirname "{}" \;)
if ! [[ $baseDirs ]]; then
log "ERROR world content is not valid since level.dat could not be found"
exit 2
if [ "$TYPE" = "SPIGOT" ]; then
baseDirs=$(find /tmp/world-data -name "level.dat" -not -path "*_nether*" -not -path "*_the_end*" -exec dirname "{}" \;)
else
baseDirs=$(find /tmp/world-data -name "level.dat" -exec dirname "{}" \;)
fi
count=$(echo "$baseDirs" | wc -l)
if [[ $count -gt 1 ]]; then
baseDirsNoSpigotSuffix=$(echo "$baseDirs" | sed -re 's:(_nether|_the_end)/?$::' | sort -u)
if [ $(echo "$baseDirsNoSpigotSuffix" | wc -l) -eq 1 ]; then
baseDir="$baseDirsNoSpigotSuffix"
baseName=$(basename "$baseDir")
log "Found Spigot naming conventions, taking $baseName as main dimension"
else
baseDir="$(echo "$baseDirs" | sed -n ${WORLD_INDEX:-1}p)"
baseName=$(basename "$baseDir")
log "WARN multiple levels found, picking: $baseName"
fi
baseDir="$(echo "$baseDirs" | sed -n ${WORLD_INDEX:-1}p)"
baseName=$(basename "$baseDir")
log "WARN multiple levels found, picking: $baseName"
elif [[ $count -gt 0 ]]; then
baseDir="$baseDirs"
else
log "ERROR invalid world content"
exit 1
fi
if [ -d "${baseDir}_nether/DIM-1" ]; then
if [ -d "$baseDir/DIM-1" ]; then
log "WARN found Nether dimension in both $baseDir and ${baseDir}_nether, picking ${baseDir}_nether"
rm -r "$baseDir/DIM-1"
fi
fi
if [ -d "${baseDir}_the_end/DIM1" ]; then
if [ -d "$baseDir/DIM1" ]; then
log "WARN found End dimension in both $baseDir and ${baseDir}_the_end, picking ${baseDir}_the_end"
rm -r "$baseDir/DIM1"
fi
fi
log "Copying world..."
rsync --remove-source-files --recursive --delete "$baseDir/" "$worldDest"
if [ "$FAMILY" = "SPIGOT" ]; then
if [ -d "${baseDir}_nether" ]; then
log "Copying Spigot Nether..."
rsync --remove-source-files --recursive --delete "${baseDir}_nether/" "${worldDest}_nether"
elif [ -d "$worldDest/DIM-1" ]; then
log "Moving Nether to Spigot location..."
mkdir -p "${worldDest}_nether"
mv -f "$worldDest/DIM-1" "${worldDest}_nether/"
fi
if [ -d "${baseDir}_the_end" ]; then
log "Copying Spigot End..."
rsync --remove-source-files --recursive --delete "${baseDir}_the_end/" "${worldDest}_the_end"
elif [ -d "$worldDest/DIM1" ]; then
log "Moving End to Spigot location..."
mkdir -p "${worldDest}_the_end"
mv -f "$worldDest/DIM1" "${worldDest}_the_end/"
fi
else
if [ -d "${baseDir}_nether/DIM-1" ]; then
log "Copying Spigot Nether to vanilla location..."
rsync --remove-source-files --recursive --delete "${baseDir}_nether/DIM-1" "${worldDest}/"
fi
if [ -d "${baseDir}_the_end/DIM1" ]; then
log "Copying Spigot End to vanilla location..."
rsync --remove-source-files --recursive --delete "${baseDir}_the_end/DIM1" "${worldDest}/"
fi
if [ "$TYPE" = "SPIGOT" ]; then
log "Copying end and nether ..."
[ -d "${baseDir}_nether" ] && rsync --remove-source-files --recursive --delete "${baseDir}_nether/" "${worldDest}_nether"
[ -d "${baseDir}_the_end" ] && rsync --remove-source-files --recursive --delete "${baseDir}_the_end/" "${worldDest}_the_end"
fi
elif [ -d "$WORLD" ]; then
else
log "Cloning world directory from $WORLD ..."
rsync --recursive --delete "${WORLD%/}"/ "$worldDest"
else
log "ERROR: world file/directory $WORLD is missing"
exit 1
fi
if [ "$FAMILY" = "SPIGOT" ]; then
if [ "$TYPE" = "SPIGOT" ]; then
# Reorganise if a Spigot server
log "Moving End and Nether maps to Spigot location"
[ -d "$worldDest/DIM1" ] && mv -f "$worldDest/DIM1" "${worldDest}_the_end"
@@ -123,4 +69,4 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] );
fi
fi
exec "${SCRIPTS:-/}start-setupVanillaTweaks" "$@"
exec "${SCRIPTS:-/}start-setupModpack" "$@"

View File

@@ -2,14 +2,11 @@
set -euo pipefail
IFS=$'\n\t'
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
handleDebugMode
: "${SPIGET_RESOURCES:=}"
: "${SPIGET_DOWNLOAD_TOLERANCE:=5}" # in minutes
acceptArgs=(--accept application/zip --accept application/java-archive --accept application/octet-stream)
: ${SPIGET_RESOURCES:=}
: ${SPIGET_DOWNLOAD_TOLERANCE:=5} # in minutes
containsJars() {
file=${1?}
@@ -20,21 +17,7 @@ containsJars() {
if [[ $line =~ $pat ]]; then
return 0
fi
done < <(unzip -l "$file" | tail -n +4)
return 1
}
containsPlugin() {
file=${1?}
pat='plugin.yml$'
while read -r line; do
if [[ $line =~ $pat ]]; then
return 0
fi
done < <(unzip -l "$file" | tail -n +4)
done <<<$(unzip -l "$file")
return 1
}
@@ -47,12 +30,12 @@ getResourceFromSpiget() {
mkdir -p /data/plugins
versionfile="/data/plugins/.${resource}-version.json"
versionfileNew="${versionfile}.tmp"
versionfileNew="/tmp/.${resource}-version.json"
if [ -f "$versionfile" ]; then
if [[ -n $(find "$versionfile" -mmin +${SPIGET_DOWNLOAD_TOLERANCE}) ]]; then
urlVersion="https://api.spiget.org/v2/resources/${resource}/versions/latest"
if ! get -o "${versionfileNew}" "${urlVersion}"; then
if ! curl -o "${versionfileNew}" -fsSL -H "User-Agent: itzg/minecraft-server" "${extraCurlArgs[@]}" "${urlVersion}"; then
log "ERROR failed to download resource version meta data '${resource}' from ${urlVersion}"
exit 2
fi
@@ -74,7 +57,7 @@ getResourceFromSpiget() {
else
if downloadResourceFromSpiget "${resource}"; then
urlVersion="https://api.spiget.org/v2/resources/${resource}/versions/latest"
if ! get -o "${versionfileNew}" "${urlVersion}"; then
if ! curl -o "${versionfileNew}" -fsSL -H "User-Agent: itzg/minecraft-server" "${extraCurlArgs[@]}" "${urlVersion}"; then
log "ERROR failed to download resource version meta data '${resource}' from ${urlVersion}"
exit 2
fi
@@ -87,37 +70,26 @@ getResourceFromSpiget() {
downloadResourceFromSpiget() {
resource=${1?}
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 ! 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 "$outfile" /data/plugins
elif containsJars "${outfile}"; then
log "Extracting contents of resource ${resource} into plugins"
extract "$outfile" /data/plugins
else
log "ERROR: file for resource ${resource} has an unexpected file type: ${fileType}"
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
fi
rm -rf "$tempDir"
if containsJars "${tmpfile}"; then
log "Extracting contents of resource ${resource} into plugins"
unzip -o -q -d /data/plugins "${tmpfile}"
rm "${tmpfile}"
else
log "Moving resource ${resource} into plugins"
mv "${tmpfile}" "/data/plugins/${resource}.jar"
fi
}
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
@@ -129,4 +101,4 @@ if [[ ${SPIGET_RESOURCES} ]]; then
done
fi
exec "${SCRIPTS:-/}start-setupWorld" "$@"
exec ${SCRIPTS:-/}start-setupWorld $@

View File

@@ -8,11 +8,6 @@ function join_by() {
printf "%s" "${@/#/$d}"
}
function get_major_version() {
version=$1
echo "$version" | cut -d. -f 1-2
}
function isURL() {
local value=$1
@@ -45,10 +40,6 @@ function getFilenameFromUrl() {
}
function isTrue() {
local oldState
oldState=$(shopt -po xtrace)
shopt -u -o xtrace
local value=${1,,}
result=
@@ -62,29 +53,6 @@ function isTrue() {
;;
esac
eval "$oldState"
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}
}
@@ -114,18 +82,7 @@ function logn() {
}
function log() {
local oldState
# The return status when listing options is zero if all optnames are enabled, non- zero otherwise.
oldState=$(shopt -po xtrace || true)
shopt -u -o xtrace
if isDebugging || isTrue "${LOG_TIMESTAMP:-false}"; then
ts=" $(date --rfc-3339=seconds)"
else
ts=
fi
echo "[init]${ts} $*"
eval "$oldState"
echo "[init] $*"
}
function logAutopause() {
@@ -136,18 +93,6 @@ function logAutopauseAction() {
echo "[$(date -Iseconds)] [Autopause] $*"
}
function logAutostop() {
echo "[Autostop loop] $*"
}
function logAutostopAction() {
echo "[$(date -Iseconds)] [Autostop] $*"
}
function logRcon() {
echo "[Rcon loop] $*"
}
function normalizeMemSize() {
local scale=1
case ${1,,} in
@@ -167,7 +112,32 @@ function normalizeMemSize() {
}
function versionLessThan() {
mc-image-helper compare-versions "${VANILLA_VERSION}" lt "${1?}"
local activeParts
IFS=. read -ra activeParts <<<"${VANILLA_VERSION}"
local givenParts
IFS=. read -ra givenParts <<<"$1"
if ((${#activeParts[@]} < 2)); then
return 1
fi
if ((${#activeParts[@]} == 2)); then
if ((activeParts[0] < givenParts[0])) ||
((activeParts[0] == givenParts[0] && activeParts[1] < givenParts[1])); then
return 0
else
return 1
fi
else
if ((activeParts[0] < givenParts[0])) ||
((activeParts[0] == givenParts[0] && activeParts[1] < givenParts[1])) ||
((activeParts[0] == givenParts[0] && activeParts[1] == givenParts[1] && activeParts[2] < givenParts[2])); then
return 0
else
return 1
fi
fi
}
requireVar() {
@@ -191,7 +161,7 @@ requireEnum() {
fi
done
log "ERROR: $var must be set to one of $*"
log "ERROR: $var must be set to one of $@"
# exit 1
}
@@ -212,88 +182,9 @@ function removeOldMods {
}
function get() {
mc-image-helper get "$@"
}
function get_silent() {
local flags=(-s)
local flags=()
if isTrue "${DEBUG_GET:-false}"; then
flags+=("--debug")
fi
mc-image-helper "${flags[@]}" get "$@"
}
function isFamily() {
for f in "${@}"; do
if [[ ${FAMILY^^} == "${f^^}" ]]; then
return 0
fi
done
return 1
}
function isType() {
for t in "${@}"; do
# shellcheck disable=SC2153
if [[ $TYPE == "$t" ]]; then
return 0
fi
done
return 1
}
function evaluateJavaCompatibilityForForge() {
javaRelease=$(mc-image-helper java-release)
if versionLessThan 1.18 && (( javaRelease > 8 )); then
log "**********************************************************************"
log "WARNING: Some mods and modpacks may require Java 8."
log " Please use itzg/minecraft-server:java8"
log "**********************************************************************"
sleep 5
fi
}
function extract() {
src=${1?}
destDir=${2?}
type=$(file -b --mime-type "${src}")
case "${type}" in
application/zip)
unzip -o -q -d "${destDir}" "${src}"
;;
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
;;
esac
}
function getDistro() {
cat /etc/os-release | grep -E "^ID=" | cut -d= -f2 | sed -e 's/"//g'
}
function checkSum() {
local sum_file=${1?}
# Get distro
distro=$(getDistro)
if [ "${distro}" == "debian" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
return 0
elif [ "${distro}" == "ubuntu" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
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
}
}

1
tests/.gitignore vendored
View File

@@ -1 +0,0 @@
data/

View File

@@ -0,0 +1,20 @@
version: "3.8"
services:
sut:
depends_on:
- mc
image: itzg/mc-monitor:0.6.0
command: status --host mc --retry-interval 1s --retry-limit 120
mc:
restart: "no"
build:
context: ..
args:
TARGETOS: linux
TARGETARCH: amd64
cache_from:
- itzg/minecraft-server:latest
environment:
EULA: "TRUE"

View File

@@ -1,43 +0,0 @@
#!/bin/bash
# go to script root directory
cd "$(dirname "$0")" || exit 1
# compose down function for reuse
down() {
docker-compose down -v --remove-orphans
}
checkandExitOnFailure(){
failed=$1
# docker-compose logs outputs messages from the specified container
if $failed; then
docker-compose logs mc
down
cd ..
exit 2
fi
}
# tests to completely spin up Minecraft and use the monitor to validate the service is running.
fullMinecraftUpTest(){
folder=$1
cd "$folder"
failed=false
# run the monitor to validate the Minecraft image is healthy
docker-compose run monitor || failed=true
echo "${folder} Result: failed=$failed"
checkandExitOnFailure $failed
down
cd ..
}
# go through each folder in fulltests and run fullbuilds
FOLDERS=$(ls)
for folder in $FOLDERS; do
# If folder is a directory
if [ -d "$folder" ]; then
echo "Starting Tests on ${folder}"
fullMinecraftUpTest $folder
fi
done

View File

@@ -1,15 +0,0 @@
version: "3"
services:
monitor:
depends_on:
- mc
image: itzg/mc-monitor:${MC_MONITOR_VERSION:-0.10.4}
command: status --host mc --retry-interval 1s --timeout 1s --retry-limit 300
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}

View File

@@ -0,0 +1,15 @@
version: "3"
services:
mc:
image: itzg/minecraft-server
environment:
EULA: "true"
GENERIC_PACKS: https://github.com/itzg/mc-image-helper/releases/download/v1.9.5/mc-image-helper-1.9.5.zip,/packs/testing.zip
DEBUG: "true"
volumes:
- ./packs:/packs
- data:/data
volumes:
data: {}

View File

@@ -1,15 +0,0 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
TYPE: "PAPER"
WORLD: /worlds/world-for-testing.zip
volumes:
- ./worlds:/worlds:ro
- ./data:/data

View File

@@ -1,5 +0,0 @@
mc-image-helper assert fileExists world/level.dat && \
mc-image-helper assert fileExists world_nether/DIM-1/some_spigot_nether_file && \
mc-image-helper assert fileExists world_the_end/DIM1/some_spigot_end_file && \
! mc-image-helper assert fileExists world_nether/DIM-1/some_vanilla_nether_file && \
! mc-image-helper assert fileExists world_the_end/DIM1/some_vanilla_end_file

View File

@@ -1,19 +0,0 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
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

View File

@@ -1,5 +0,0 @@
mc-image-helper assert fileExists world/level.dat && \
mc-image-helper assert fileExists world/DIM-1/some_spigot_nether_file && \
mc-image-helper assert fileExists world/DIM1/some_spigot_end_file && \
! mc-image-helper assert fileExists world/DIM-1/some_vanilla_nether_file && \
! mc-image-helper assert fileExists world/DIM1/some_vanilla_end_file

Some files were not shown because too many files have changed in this diff Show More