Compare commits

..

113 Commits

Author SHA1 Message Date
Geoff Bourne
df1dac4b3a Auto-merging via docker-versions-create 2022-01-06 21:58:10 -06:00
Geoff Bourne
4f149f8f40 Auto-merging via docker-versions-create 2021-12-23 16:08:38 -06:00
Geoff Bourne
88e5b7e135 Auto-merging via docker-versions-create 2021-12-13 21:28:30 -06:00
Geoff Bourne
86190eafc7 Auto-merging via docker-versions-create 2021-12-12 19:51:45 -06:00
Geoff Bourne
6729ba462e Merge branch 'master' of github.com:itzg/docker-minecraft-server 2021-12-12 15:35:14 -06:00
Geoff Bourne
4b28d5e472 fix: qualify Fabric server jar by installer version
Fixes #1191
2021-12-12 15:28:30 -06:00
Geoff Bourne
7983a4a3a2 Merging latest from master 2021-12-12 09:15:05 -06:00
Geoff Bourne
52ac180c77 Auto-merging via docker-versions-create 2021-12-11 16:24:32 -06:00
Geoff Bourne
3f2022da40 Merge branch 'master' of github.com:itzg/docker-minecraft-server 2021-12-11 16:23:25 -06:00
Geoff Bourne
0f7464403c build: added github release creation step to docker-versions-create.sh 2021-12-11 16:09:15 -06:00
Geoff Bourne
32195e71c5 Auto-merging via docker-versions-create 2021-12-10 21:04:32 -06:00
Geoff Bourne
a0a578f452 Auto-merging via docker-versions-create 2021-12-10 10:42:16 -06:00
Geoff Bourne
ca0ddc80aa Auto-merging via docker-versions-create 2021-12-10 07:57:27 -06:00
Geoff Bourne
1a625f09bb Auto-merging via docker-versions-create 2021-12-06 22:05:02 -06:00
Geoff Bourne
9ab345a727 Auto-merging via docker-versions-create 2021-12-04 10:00:12 -06:00
Geoff Bourne
4e3031cff8 Auto-merging via docker-versions-create 2021-12-02 19:46:55 -06:00
Geoff Bourne
466e1728f6 Auto-merging via docker-versions-create 2021-11-24 15:57:45 -06:00
Geoff Bourne
8dddbc4120 Auto-merging via docker-versions-create 2021-11-24 14:34:30 -06:00
Geoff Bourne
53e9d36a05 Track latest from master 2021-11-16 19:02:30 -06:00
Geoff Bourne
275c2d0c54 Auto-merging via docker-versions-create 2021-11-16 18:52:01 -06:00
Geoff Bourne
cf9c40f331 Auto-merging via docker-versions-create 2021-11-15 20:48:30 -06:00
Geoff Bourne
491ffe49bf Auto-merging via docker-versions-create 2021-11-13 19:18:03 -06:00
Geoff Bourne
d4a9b367c7 Auto-merging via docker-versions-create 2021-11-13 18:52:36 -06:00
Geoff Bourne
032d94a30f Auto-merging via docker-versions-create 2021-11-12 21:24:26 -06:00
Geoff Bourne
3784d2df54 Auto-merging via docker-versions-create 2021-11-06 21:38:11 -05:00
Geoff Bourne
8a36823843 Auto-merging via docker-versions-create 2021-11-04 21:04:41 -05:00
Geoff Bourne
78c520572a Auto-merging via docker-versions-create 2021-10-31 09:46:11 -05:00
Geoff Bourne
5303105265 Switched base image to JDK
#1064
2021-10-27 21:25:24 -05:00
Geoff Bourne
1f120c5fa4 Auto-merging via docker-versions-create 2021-10-25 19:23:56 -05:00
Geoff Bourne
70ec3b838d Auto-merging via docker-versions-create 2021-10-24 20:28:03 -05:00
Geoff Bourne
b248ed342f Auto-merging via docker-versions-create 2021-10-23 09:43:19 -05:00
Geoff Bourne
4c70184804 Merged latest from master 2021-10-22 15:53:10 -05:00
Geoff Bourne
b9ba062add Auto-merged latest from master 2021-10-18 22:13:11 -05:00
Geoff Bourne
cbb1d0ea52 Added support for Crucible server type
#1052
2021-10-18 22:02:23 -05:00
Geoff Bourne
bbad3a3e7a Auto-merging via docker-versions-create 2021-10-17 14:53:04 -05:00
Geoff Bourne
8965397a5a Auto-merging via docker-versions-create 2021-10-15 18:57:28 -05:00
Geoff Bourne
c661fe7318 Auto-merging via docker-versions-create 2021-10-15 18:47:46 -05:00
Geoff Bourne
bae1feb750 Auto-merging via docker-versions-create 2021-10-10 09:56:39 -05:00
Geoff Bourne
edbcf80a70 Auto-merging via docker-versions-create 2021-10-09 15:25:44 -05:00
Geoff Bourne
fb23e12680 Auto-merging via docker-versions-create 2021-10-09 12:04:28 -05:00
Geoff Bourne
e30a2e6448 Auto-merging via docker-versions-create 2021-10-02 19:22:34 -05:00
Geoff Bourne
03d7babd68 Auto-merging via docker-versions-create 2021-09-29 10:26:54 -05:00
Geoff Bourne
332b929a6d Auto-merging via docker-versions-create 2021-09-27 20:41:23 -05:00
Geoff Bourne
c138cabc65 Auto-merging via docker-versions-create 2021-09-20 12:30:46 -05:00
Geoff Bourne
41631e35e8 Auto-merging via docker-versions-create 2021-09-15 21:31:13 -05:00
Geoff Bourne
6f95fa6175 Auto-merging via docker-versions-create 2021-09-15 21:06:58 -05:00
Geoff Bourne
6f16da8309 Auto-merging via docker-versions-create 2021-09-15 20:37:01 -05:00
Geoff Bourne
8cee8d5618 Auto-merging via docker-versions-create 2021-08-30 21:37:26 -05:00
Geoff Bourne
8b76b5776a Auto-merging via docker-versions-create 2021-08-10 12:56:12 -05:00
Geoff Bourne
e3af06d2e4 Auto-merging via docker-versions-create 2021-08-01 12:12:49 -05:00
Geoff Bourne
0ac583514c Auto-merging via docker-versions-create 2021-07-31 09:27:29 -05:00
Geoff Bourne
bf3f15f5fb Auto-merging via docker-versions-create 2021-07-26 19:35:26 -05:00
Geoff Bourne
4aec2322b5 Merge branch 'master' into java8-openj9 2021-07-25 18:20:13 -05:00
Geoff Bourne
51b2eb6851 Auto-merging via docker-versions-create 2021-07-25 09:36:44 -05:00
Geoff Bourne
846050f41a Auto-merging via docker-versions-create 2021-07-23 21:27:37 -05:00
Geoff Bourne
485ec6a141 Auto-merging via docker-versions-create 2021-07-17 21:14:44 -05:00
Geoff Bourne
0096e41882 Auto-merging via docker-versions-create 2021-07-17 20:57:29 -05:00
Geoff Bourne
d45610723a Auto-merging via docker-versions-create 2021-07-17 18:03:56 -05:00
Geoff Bourne
072704b54d Auto-merging via docker-versions-create 2021-07-14 18:43:15 -05:00
Geoff Bourne
0f08e88c5b Auto-merging via docker-versions-create 2021-07-12 19:09:42 -05:00
Geoff Bourne
89604c8d13 Auto-merging via docker-versions-create 2021-07-09 19:58:27 -05:00
Geoff Bourne
58842d444b Auto-merging via docker-versions-create 2021-07-08 17:59:28 -05:00
Geoff Bourne
457d09e14d Auto-merging via docker-versions-create 2021-07-08 08:03:47 -05:00
itzg
7210e81f47 Auto-merging via docker-versions-create 2021-07-08 12:56:00 +00:00
Geoff Bourne
ba86534e6e Auto-merging via docker-versions-create 2021-07-08 07:38:39 -05:00
itzg
44bafbff09 Auto-merging via docker-versions-create 2021-07-04 19:54:01 +00:00
Geoff Bourne
75c51bf0c7 Merge branch 'master' into java8-openj9 2021-07-03 14:19:04 -05:00
Geoff Bourne
cf651f2279 ci: restored limited image platforms for java8-openj9 2021-07-02 16:23:42 -05:00
Geoff Bourne
6d0d7fe19c ci: auto-merge from master 2021-07-02 15:56:54 -05:00
itzg
bb58d7a4c9 Auto-merging via docker-versions-create 2021-07-02 16:55:54 +00:00
itzg
6efaac2861 Auto-merging via docker-versions-create 2021-06-28 12:14:05 +00:00
itzg
806342d74b Auto-merging via docker-versions-create 2021-06-27 13:13:11 +00:00
itzg
926e302595 Auto-merging via docker-versions-create 2021-06-24 12:47:05 +00:00
Geoff Bourne
10e85140ad Auto-merging via docker-versions-create 2021-06-23 22:33:45 -05:00
Geoff Bourne
fc2ed9e612 Auto-merging via docker-versions-create 2021-06-20 12:48:15 -05:00
Geoff Bourne
edfe58079a Auto-merging via docker-versions-create 2021-06-05 17:51:25 -05:00
Geoff Bourne
d423cc3b8d Auto-merging via docker-versions-create 2021-05-24 20:50:52 -05:00
Geoff Bourne
1537e48e29 Merge branch 'master' into java8-openj9 2021-05-23 12:26:56 -05:00
Geoff Bourne
62473771dc Merge from master 2021-05-22 13:00:01 -05:00
Geoff Bourne
c4528e8f79 Auto-merging via docker-versions-create 2021-05-21 23:02:00 -05:00
Geoff Bourne
0f797487ab Auto-merging via docker-versions-create 2021-05-21 22:48:32 -05:00
Geoff Bourne
9511e3cc80 Merge branch 'master' into java8-openj9 2021-05-21 22:35:00 -05:00
Geoff Bourne
3aa4dd6c85 ci: added java8-openj9 branch 2021-05-21 22:31:40 -05:00
Geoff Bourne
27571999b2 Merge branch 'master' into java8-multiarch 2021-05-21 17:28:44 -05:00
Geoff Bourne
bbd7d9e39a ci: introduced CACHE_NAME 2021-05-21 17:26:42 -05:00
Geoff Bourne
ef6f308229 Auto-merging via docker-versions-create 2021-05-19 20:27:42 -05:00
Geoff Bourne
49d89d3e73 Auto-merging via docker-versions-create 2021-05-19 20:25:00 -05:00
Geoff Bourne
74203b23f4 Auto-merging via docker-versions-create 2021-05-15 12:41:22 -05:00
Geoff Bourne
4fb791b490 Merge branch 'multiarch' into java8-multiarch
# Conflicts:
#	Dockerfile
#	start-configuration
2021-05-14 17:59:49 -05:00
Geoff Bourne
ced25ad50a Auto-merging via docker-versions-create 2021-05-06 20:12:55 -05:00
Geoff Bourne
48efc224ba Auto-merging via docker-versions-create 2021-04-30 14:28:07 -05:00
Geoff Bourne
467c1d9954 Auto-merging via docker-versions-create 2021-04-30 11:11:46 -05:00
Geoff Bourne
9ced230f55 Auto-merging via docker-versions-create 2021-04-28 16:51:29 -05:00
Geoff Bourne
f3a8276362 Auto-merging via docker-versions-create 2021-04-26 08:21:06 -05:00
Geoff Bourne
b91d63716e Auto-merging via docker-versions-create 2021-04-24 13:42:37 -05:00
Geoff Bourne
46cccfd531 Auto-merging via docker-versions-create 2021-04-23 21:03:21 -05:00
Geoff Bourne
9fe1cb4a0d ci: Switched multiarch-java8 to be based on adoptopenjdk:8-jre-hotspot 2021-04-21 20:13:22 -05:00
Geoff Bourne
076038b470 Auto-merging via docker-versions-create 2021-04-18 13:29:46 -05:00
Geoff Bourne
aa416729ea Auto-merging via docker-versions-create 2021-04-11 10:09:19 -05:00
Geoff Bourne
812c6365ec Merged latest from master 2021-04-08 19:14:45 -05:00
Geoff Bourne
42a5131b19 Merging latest from master 2021-04-01 16:32:55 -05:00
Geoff Bourne
624f6a210f Added git
#819
2021-04-01 16:28:32 -05:00
Geoff Bourne
1c63cd18b7 Merge branch 'master' into java8-multiarch
# Conflicts:
#	start-configuration
2021-03-06 16:24:55 -06:00
Geoff Bourne
6266a7e3cc Shifted PATH-fix earlier in startup 2021-03-06 16:04:31 -06:00
Geoff Bourne
871ecd4d9d Merge branch 'master' into java8-multiarch
# Conflicts:
#	start-minecraftFinalSetup
2021-02-27 20:52:36 -06:00
Geoff Bourne
c572c95161 Ensure FTBA version.json is readable
#784
2021-02-27 16:58:25 -06:00
Geoff Bourne
f7b58fbbb1 Fix PATH to include java when needed 2021-02-10 14:51:24 -06:00
Geoff Bourne
eccfa444a9 Auto-merging via docker-versions-create 2021-02-10 14:02:05 -06:00
Geoff Bourne
e831d25706 Merged latest from master 2021-02-08 21:18:28 -06:00
Geoff Bourne
12e931332b Auto-merging via docker-versions-create
CONFLICT (content): Merge conflict in Dockerfile
2021-02-07 18:06:06 -06:00
Geoff Bourne
ceee9eddc9 ci: restored base image to ubuntu and install openjdk-8 2021-02-06 15:53:59 -06:00
Geoff Bourne
60ba668743 Merge branch 'master' into java8-multiarch
# Conflicts:
#	Dockerfile
2021-02-06 15:49:16 -06:00
Geoff Bourne
fd1b15e01f ci: Added java8 variant of multiarch 2021-02-06 15:44:02 -06:00
150 changed files with 891 additions and 2362 deletions

View File

@@ -3,105 +3,44 @@ on:
push:
branches:
- master
- test/**
- java8-multiarch
- java8-openj9
- java11*
- java16*
- java17*
tags:
- "[0-9]+.[0-9]+.[0-9]+"
- "[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/**"
env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
jobs:
build:
strategy:
fail-fast: false
matrix:
variant:
- java17
- java17-jdk
- java17-openj9
- java17-alpine
- java8
- java8-multiarch
- java8-openj9
- java8-jdk
- java11
- java11-openj9
- java11-jdk
include:
# JAVA 17:
- variant: java17
baseImage: eclipse-temurin:17-jre
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: LATEST
- variant: java17-jdk
baseImage: eclipse-temurin:17
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: LATEST
- variant: java17-openj9
baseImage: ibm-semeru-runtimes:open-17-jre
platforms: linux/amd64,linux/arm64
mcVersion: LATEST
- variant: java17-alpine
baseImage: eclipse-temurin:17-jre-alpine
platforms: linux/amd64
mcVersion: LATEST
# 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-multiarch
baseImage: eclipse-temurin:8u312-b07-jre
platforms: linux/amd64,linux/arm64
mcVersion: 1.12.2
- variant: java8-jdk
baseImage: eclipse-temurin:8u312-b07-jdk
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 }}
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@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@v1
@@ -116,40 +55,38 @@ jobs:
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build for test
uses: docker/build-push-action@v2.9.0
uses: docker/build-push-action@v2.7.0
if: github.ref_name == 'master'
with:
context: .
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 }}
cache-from: type=gha
# 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 }}
# It is assumed that image variants are merged from master and tested there
if: github.ref_name == 'master'
run: |
tests/test.sh
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2.9.0
uses: docker/build-push-action@v2.7.0
with:
platforms: ${{ matrix.platforms }}
push: ${{ github.ref_type == 'tag' || github.ref_name == 'master' }}
context: .
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
# ensure latest base image is used
pull: true
cache-from: type=gha
cache-to: type=gha,mode=max
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 }}

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@v1
- name: Build
uses: docker/build-push-action@v2.9.0
with:
context: .
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
load: true
cache-from: type=gha
- name: Run 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 }} 💣💥"

View File

@@ -11,11 +11,11 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v3
- 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.14.0
- 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 }}`"

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

@@ -0,0 +1,97 @@
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"
env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
jobs:
build:
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: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build for test
uses: docker/build-push-action@v2.7.0
if: github.ref_name == 'java8'
with:
context: .
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
# ensure latest base image is used
pull: true
load: true
push: false
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Run tests
if: github.ref_name == 'java8'
run: |
tests/test.sh
env:
MINECRAFT_VERSION: 1.12.2
- 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=gha
cache-to: type=gha,mode=max
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 }}

View File

@@ -1,4 +1,4 @@
name: PullRequest
name: Validate PR
on:
pull_request:
@@ -17,13 +17,13 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v2.4.0
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Build
uses: docker/build-push-action@v2.9.0
uses: docker/build-push-action@v2.7.0
with:
context: .
platforms: linux/amd64
@@ -32,9 +32,6 @@ jobs:
cache-from: type=gha
- name: Run tests
env:
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
MINECRAFT_VERSION: LATEST
run: |
tests/test.sh
@@ -55,7 +52,7 @@ jobs:
- name: Push
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
uses: docker/build-push-action@v2.9.0
uses: docker/build-push-action@v2.7.0
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64

View File

@@ -12,7 +12,7 @@ jobs:
pull-requests: write
steps:
- name: Process Stale Issues
uses: actions/stale@v5
uses: actions/stale@v4.1.0
with:
stale-issue-label: status/stale
stale-pr-label: status/stale
@@ -21,5 +21,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'

2
.gitignore vendored
View File

@@ -2,5 +2,5 @@
/data/
/.idea/
*.iml
*.zip
/gh-md-toc
personal-build-and-develop.*

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.
@@ -90,6 +63,31 @@ Note the port that was selected by http-server and pass the build arguments, suc
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
The following git command can be used to provide the bulk of release notes content:
@@ -97,3 +95,25 @@ The following git command can be used to provide the bulk of release notes conte
```shell script
git log --invert-grep --grep "^ci:" --grep "^misc:" --grep "^docs:" --pretty="* %s" 1.1.0..1.2.0
```
## Tracking changes from master without content
The following script uses the [ours](https://git-scm.com/docs/merge-strategies#Documentation/merge-strategies.txt-ours) merging strategy to track the history from master into the other branches without actually bringing the changes over. It is useful when a change is specific to master only, such as bumping the base Java version for the `latest` image tag.
```shell
branches=(
java8
java8-multiarch
java8-openj9
java11
java11-openj9
java16
java16-openj9
java17
)
for b in "${branches[@]}"; do
git checkout "$b"
git merge -s ours -m "Track latest from master" master
git push origin
done
```

View File

@@ -1,16 +1,30 @@
# syntax = docker/dockerfile:1.3
FROM adoptopenjdk:8-jdk-openj9
ARG BASE_IMAGE=eclipse-temurin:17-jdk
FROM ${BASE_IMAGE}
LABEL org.opencontainers.image.authors="Geoff Bourne <itzgeoff@gmail.com>"
# 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 apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y \
imagemagick \
gosu \
sudo \
net-tools \
iputils-ping \
curl \
git \
jq \
dos2unix \
mysql-client \
tzdata \
rsync \
nano \
unzip \
knockd \
ttf-dejavu \
&& apt-get clean
RUN --mount=target=/build,source=build \
REV=${BUILD_FILES_REV} /build/run.sh setup-user
RUN addgroup --gid 1000 minecraft \
&& adduser --system --shell /bin/false --uid 1000 --ingroup minecraft --home /data minecraft
COPY --chmod=644 files/sudoers* /etc/sudoers.d
@@ -46,7 +60,7 @@ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=0.1.1 --var app=maven-metadata-release --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
ARG MC_HELPER_VERSION=1.16.11
ARG MC_HELPER_VERSION=1.11.0
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 - \
@@ -72,9 +86,8 @@ 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/*
RUN dos2unix /start* /autopause/* /autostop/*
ENTRYPOINT [ "/start" ]
HEALTHCHECK --start-period=1m CMD mc-health

336
README.md
View File

@@ -33,14 +33,6 @@ By default, the container will download the latest version of the "vanilla" [Min
* [Versions](#versions)
* [Running Minecraft server on different Java version](#running-minecraft-server-on-different-java-version)
* [Deprecated Image Tags](#deprecated-image-tags)
* [Related Projects](#related-projects)
* [<a href="https://github.com/itzg/docker-minecraft-bedrock-server">itzg/minecraft-bedrock-server</a>](#itzgminecraft-bedrock-server)
* [<a href="https://github.com/itzg/mc-router">mc-router</a>](#mc-router)
* [<a href="https://github.com/itzg/docker-bungeecord/">itzg/bungeecord</a>](#itzgbungeecord)
* [<a href="https://github.com/itzg/docker-mc-backup">itzg/mc-backup</a>](#itzgmc-backup)
* [<a href="https://github.com/itzg/rcon-cli">rcon-cli</a>](#rcon-cli)
* [<a href="https://github.com/itzg/mc-monitor">mc-monitor</a>](#mc-monitor)
* [<a href="https://github.com/itzg/mc-image-helper">mc-image-helper</a>](#mc-image-helper)
* [Healthcheck](#healthcheck)
* [Deployment Templates and Examples](#deployment-templates-and-examples)
* [Helm Charts](#helm-charts)
@@ -76,8 +68,7 @@ By default, the container will download the latest version of the "vanilla" [Min
* [Optional plugins, mods, and config attach points](#optional-plugins-mods-and-config-attach-points)
* [Auto-downloading SpigotMC/Bukkit/PaperMC plugins](#auto-downloading-spigotmcbukkitpapermc-plugins)
* [Downloadable mod/plugin pack for Forge, Fabric, and Bukkit-like Servers](#downloadable-modplugin-pack-for-forge-fabric-and-bukkit-like-servers)
* [ForgeAPI usage to use non-version specific projects](#forgeapi-usage-to-use-non-version-specific-projects)
* [Generic pack files](#generic-pack-files)
* [Generic pack file](#generic-pack-file)
* [Mod/Plugin URL Listing File](#modplugin-url-listing-file)
* [Remove old mods/plugins](#remove-old-modsplugins)
* [Working with world data](#working-with-world-data)
@@ -141,9 +132,6 @@ By default, the container will download the latest version of the "vanilla" [Min
* [Explicitly disable GUI](#explicitly-disable-gui)
* [Stop Duration](#stop-duration)
* [Setup only](#setup-only)
* [Enable Flare Flags](#enable-flare-flags)
* [Enable timestamps in init logs](#enable-timestamps-in-init-logs)
* [Use RCON commands](#use-rcon-commands)
* [Autopause](#autopause)
* [Description](#description)
* [Enabling Autopause](#enabling-autopause)
@@ -151,7 +139,7 @@ By default, the container will download the latest version of the "vanilla" [Min
* [Running on RaspberryPi](#running-on-raspberrypi)
* [Contributing](#contributing)
<!-- Added by: runner, at: Wed Mar 16 00:48:32 UTC 2022 -->
<!-- Added by: runner, at: Thu Jan 6 12:50:03 UTC 2022 -->
<!--te-->
@@ -254,8 +242,6 @@ If you had used the commands in the first section, without the `-v` volume attac
> In this example, it is assumed the original container was given a `--name` of "mc", so change the container identifier accordingly.
> You can also locate the Docker-managed directory from the `Source` field obtained from `docker inspect <container id or name> -f "{{json .Mounts}}"`
First, stop the existing container:
```shell
docker stop mc
@@ -296,17 +282,17 @@ the server jar remain in the `/data` directory. It is safe to remove those._
When using the image `itzg:/minecraft-server` without a tag, the `latest` image tag is implied from the table below. To use a different version of Java, please use an alternate tag to run your Minecraft server container.
| Tag name | Java version | Linux | JVM Type | Architecture |
|-----------------|-------------|--------|----------|-------------------|
| latest | 17 | Debian | Hotspot | amd64,arm64,armv7 |
| java8 | 8 | Alpine | Hotspot | amd64 |
| Tag name | Java version | Linux | JVM Type | Architecture |
| -------------- | -------------|--------|----------|-------------------|
| latest | 16 | Debian | Hotspot | amd64,arm64,armv7 |
| java8 | 8 | Alpine | Hotspot | amd64 |
| java8-multiarch | 8 | Debian | Hotspot | amd64,arm64,armv7 |
| java8-openj9 | 8 | Debian | OpenJ9 | amd64 |
| java11 | 11 | Debian | Hotspot | amd64,arm64,armv7 |
| java11-openj9 | 11 | Debian | OpenJ9 | amd64 |
| java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 |
| java17-openj9 | 17 | Debian | OpenJ9 | amd64 |
| java17-alpine | 17 | Alpine | Hotspot | amd64 |
| java8-openj9 | 8 | Debian | OpenJ9 | amd64 |
| java11 | 11 | Debian | Hotspot | amd64,arm64,armv7 |
| java11-openj9 | 11 | Debian | OpenJ9 | amd64 |
| java16-openj9 | 16 | Debian | OpenJ9 | amd64 |
| java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 |
| java17-openj9 | 17 | Debian | OpenJ9 | amd64 |
For example, to use Java version 8 on any supported architecture:
@@ -324,37 +310,7 @@ The following image tags have been deprecated and are no longer receiving update
- adopt15
- openj9-nightly
- multiarch-latest
- java16/java16-openj9
## Related Projects
### [itzg/minecraft-bedrock-server](https://github.com/itzg/docker-minecraft-bedrock-server)
Docker image that runs a Minecraft Bedrock server.
### [mc-router](https://github.com/itzg/mc-router)
Lightweight multiplexer/proxy for Minecraft Java servers. Provided as a stand-alone application and a Docker image.
### [itzg/bungeecord](https://github.com/itzg/docker-bungeecord/)
Docker image that runs a proxy powered by Bungeecord, Velocity, or Waterfall
### [itzg/mc-backup](https://github.com/itzg/docker-mc-backup)
Docker image that runs as a side-car container to backup world data.
### [rcon-cli](https://github.com/itzg/rcon-cli)
A tool that is bundled with this image to provide CLI access to an RCON endpoint.
### [mc-monitor](https://github.com/itzg/mc-monitor)
A tool that is bundled with this image that provides health checks and metrics reporting, such as a Prometheus exporter or a telegraf data source.
### [mc-image-helper](https://github.com/itzg/mc-image-helper)
A tool that is bundled with this image to provide complex, re-usable preparation operations.
- java16
## Healthcheck
@@ -434,7 +390,7 @@ To troubleshoot any issues with memory allocation reported by the JVM, set the e
### Running a Forge Server
Enable [Forge server](http://www.minecraftforge.net/) mode by adding a `-e TYPE=FORGE` to your command-line.
Enable [Forge server](http://www.minecraftforge.net/wiki/) mode by adding a `-e TYPE=FORGE` to your command-line.
The overall version is specified by `VERSION`, [as described in the section above](#versions) and will run the recommended Forge version by default. You can also choose to run a specific Forge version with `FORGEVERSION`, such as `-e FORGEVERSION=14.23.5.2854`.
@@ -459,7 +415,7 @@ In both of the cases above, there is no need for the `VERSION` or `FORGEVERSION`
### Running a Fabric Server
Enable [Fabric server](https://fabricmc.net/) mode by adding a `-e TYPE=FABRIC` to your command-line.
Enable [Fabric server](https://fabricmc.net/) mode by adding a `-e TYPE=FABRIC` to your command-line. By default, the container will install the latest [fabric-loader](https://fabricmc.net/wiki/documentation:fabric_loader) using the latest [fabric-installer](https://fabricmc.net/use/), against the minecraft server version you have defined with `VERSION` (defaulting to the latest vanilla release of the game).
```
docker run -d -v /path/on/host:/data \
@@ -467,22 +423,19 @@ docker run -d -v /path/on/host:/data \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
```
By default, the container will install the latest [fabric server launcher](https://fabricmc.net/use/server/), using the latest [fabric-loader](https://fabricmc.net/wiki/documentation:fabric_loader) against the minecraft version you have defined with `VERSION` (defaulting to the latest vanilla release of the game).
See the [Working with mods and plugins](#working-with-mods-and-plugins) section to set up Fabric mods and configuration.
A specific loader or launcher version other than the latest can be requested using `FABRIC_LOADER_VERSION` and `FABRIC_LAUNCHER_VERSION` respectively, such as:
A specific loader version other than the latest can be requested using `FABRIC_LOADER_VERSION`, such as:
```
docker run -d -v /path/on/host:/data ... \
-e TYPE=FABRIC \
-e FABRIC_LAUNCHER_VERSION=0.10.2 \
-e FABRIC_LOADER_VERSION=0.13.1
-e FABRIC_LOADER_VERSION=0.12.8
```
> If you wish to use an alternative launcher you can:
> * Provide the path to a custom launcher jar available to the container with `FABRIC_LAUNCHER`, relative to `/data` (such as `-e FABRIC_LAUNCHER=fabric-server-custom.jar`)
> * Provide the URL to a custom launcher jar with `FABRIC_LAUNCHER_URL` (such as `-e FABRIC_LAUNCHER_URL=http://HOST/fabric-server-custom.jar`)
See the [Working with mods and plugins](#working-with-mods-and-plugins) section to set up Fabric mods and configuration.
If you wish to use an alternative installer you can:
* Specify an alternative version using `FABRIC_INSTALLER_VERSION` (such as `-e FABRIC_INSTALLER_VERSION=0.10.2`)
* Provide the path to a custom installer jar available to the container with `FABRIC_INSTALLER`, relative to `/data` (such as `-e FABRIC_INSTALLER=fabric-installer-0.5.0.32.jar`)
* Provide the URL to a custom installer jar with `FABRIC_INSTALLER_URL` (such as `-e FABRIC_INSTALLER_URL=http://HOST/fabric-installer-0.5.0.32.jar`)
### Running a Bukkit/Spigot server
@@ -527,11 +480,12 @@ An [Airplane](https://airplane.gg) server, which is "a stable, optimized, well s
-e TYPE=AIRPLANE
> NOTE: The `VERSION` variable is used to select an Airplane type to download. The available options are "LATEST" and "PURPUR", both 1.17.1. Airplane does not support 1.18 -- use Paper/Pufferfish/Purpur.
> NOTE: The `VERSION` variable is used to select an Airplane branch to download from. The available options are "LATEST" "1.17" and "PURPUR"
Extra variables:
- `AIRPLANE_BUILD=lastSuccessfulBuild` : set a specific Airplane build to use
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [Flare](https://blog.airplane.gg/flare) profiler
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the [Flare](https://blog.airplane.gg/flare) profiler
### Running a Pufferfish server
@@ -539,12 +493,11 @@ A [Pufferfish](https://github.com/pufferfish-gg/Pufferfish) server, which is "a
-e TYPE=PUFFERFISH
> NOTE: The `VERSION` variable is used to select branch latest, 1.18, or 1.17. Use PUFFERFISH_BUILD to really select the SERVER VERSION number.
> NOTE: The `VERSION` variable is used to select a Pufferfish branch to download from. The available options are "LATEST" and "1.18"
Extra variables:
- `PUFFERFISH_BUILD=lastSuccessfulBuild` : set a specific Pufferfish build to use. Example: selecting build 47 => 1.18.1, or build 50 => 1.18.2 etc
- `PUFFERFISH_BUILD=lastSuccessfulBuild` : set a specific Pufferfish build to use
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [Flare](https://blog.airplane.gg/flare) profiler
### Running a Purpur server
@@ -557,7 +510,7 @@ A [Purpur](https://purpur.pl3x.net/) server, which is "drop-in replacement for P
Extra variables:
- `PURPUR_BUILD=LATEST` : set a specific Purpur build to use
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [Flare](https://blog.airplane.gg/flare) profiler
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the [Flare](https://blog.airplane.gg/flare) profiler
### Running a Magma server
@@ -634,8 +587,6 @@ Configuration options with defaults:
- `LIMBO_SCHEMA_FILENAME`=default.schem
- `LEVEL`="Default;${LIMBO_SCHEMA_FILENAME}"
> NOTE: instead of using format codes in the MOTD, Limbo requires [JSON chat content](https://minecraft.fandom.com/wiki/Raw_JSON_text_format#Java_Edition). If a plain string is provided, which is the default, then it gets converted into the required JSON structure.
### Running a Crucible server
A [Crucible](https://github.com/CrucibleMC/Crucible) server can be run by setting `TYPE` to `CRUCIBLE`.
@@ -653,8 +604,8 @@ Crucible is only available for 1.7.10, so be sure to set `VERSION=1.7.10`.
[Feed the Beast application](https://www.feed-the-beast.com/) modpacks are supported by using `-e TYPE=FTBA` (**note** the "A" at the end of the type). This server type will automatically take care of downloading and installing the modpack and appropriate version of Forge, so the `VERSION` does not need to be specified.
### Environment Variables:
- `FTB_MODPACK_ID`: **required**, the numerical ID of the modpack to install. The ID can be located by [finding the modpack](https://www.feed-the-beast.com/modpack) and hovering over the name of the modpack, [as shown here](docs/ftba-identifier-popup.png).
- `FTB_MODPACK_VERSION_ID`: optional, the numerical Id of the version to install. If not specified, the latest version will be installed. The "Version ID" can be obtained by drilling into the Versions tab and hovering over the version name, [as shown here](docs/ftba-version-id-popup.png).
- `FTB_MODPACK_ID`: **required**, the numerical ID of the modpack to install. The ID can be located by [finding the modpack](https://www.feed-the-beast.com/modpack) and using the "ID" displayed next to the name
- `FTB_MODPACK_VERSION_ID`: optional, the numerical Id of the version to install. If not specified, the latest version will be installed. The "Version ID" can be obtained by drilling into the Versions tab and clicking a specific version.
### Upgrading
@@ -790,83 +741,11 @@ You may also download or copy over individual mods using the `MODS` environment
docker run -d -e MODS=https://www.example.com/mods/mod1.jar,/plugins/common,/plugins/special/mod2.jar ...
### ForgeAPI usage to use non-version specific projects
### Generic pack file
**NOTE:** This potentially could lead to unexpected behavior if the Mod receives an update with unexpected behavior.
To install all of the server content (jars, mods, plugins, configs, etc) from a zip file, such as a CurseForge modpack that is missing a server start script, then set `GENERIC_PACK` to the container path of the zip file. That, combined with `TYPE`, allows for custom content along with container managed server download and install.
This is more complicated because you will be pulling/using the latest mod for the release of your game. To get started make sure you have a [CursedForge API Key](https://docs.curseforge.com/#getting-started). Then use the environmental parameters in your docker build.
Please be aware of the following when using these options for your mods:
* Mod Release types: Release, Beta, and Alpha.
* Mod dependencies: Required and Optional
* Mod family: Fabric, Forge, and Bukkit.
Parameters to use the ForgeAPI:
* `MODS_FORGEAPI_KEY` - Required
* `MODS_FORGEAPI_FILE` - Required or use MODS_FORGEAPI_PROJECTIDS (Overrides MODS_FORGEAPI_PROJECTIDS)
* `MODS_FORGEAPI_PROJECTIDS` - Required or use MODS_FORGEAPI_FILE
* `MODS_FORGEAPI_RELEASES` - Default is release, Options: [Release|Beta|Alpha]
* `MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES` - Default is False, attempts to download required mods (releaseType Release) defined in Forge.
* `MODS_FORGEAPI_IGNORE_GAMETYPE` - Default is False, Allows for filtering mods on family type: FORGE, FABRIC, and BUKKIT. (Does not filter for Vanilla or custom)
* `REMOVE_OLD_FORGEAPI_MODS` - Default is False
* `REMOVE_OLD_DATAPACKS_DEPTH` - Default is 1
* `REMOVE_OLD_DATAPACKS_INCLUDE` - Default is *.jar
Example of expected forge api project ids, releases, and key:
```yaml
MODS_FORGEAPI_PROJECTIDS: 306612,256717
MODS_FORGEAPI_RELEASES: Release
MODS_FORGEAPI_KEY: $WRX...
```
Example of expected ForgeAPI file format.
**Field Description**:
* `name` is currently unused, but can be used to document each entry.
* `projectId` id is the id found on the CurseForge website for a particular mod
* `releaseType` Type corresponds to forge's R, B, A icon for each file. Default Release, options are (release|beta|alpha).
* `fileName` is used for version pinning if latest file will not work for you.
```json
[
{
"name": "fabric api",
"projectId": "306612",
"releaseType": "release"
},
{
"name": "fabric voice mod",
"projectId": "416089",
"releaseType": "beta"
},
{
"name": "Biomes o plenty",
"projectId": "220318",
"fileName": "BiomesOPlenty-1.18.1-15.0.0.100-universal.jar",
"releaseType": "release"
}
]
```
### Generic pack files
To install all the server content (jars, mods, plugins, configs, etc.) from a zip or tgz file, then set `GENERIC_PACK` to the container path or URL of the archive file. This can also be used to apply a CurseForge modpack that is missing a server start script and/or Forge installer.
If multiple generic packs need to be applied together, set `GENERIC_PACKS` instead, with a comma separated list of archive file paths and/or URLs to files.
To avoid repetition, each entry will be prefixed by the value of `GENERIC_PACKS_PREFIX` and suffixed by the value of `GENERIC_PACKS_SUFFIX`, both of which are optional. For example, the following variables
```
GENERIC_PACKS=configs-v9.0.1,mods-v4.3.6
GENERIC_PACKS_PREFIX=https://cdn.example.org/
GENERIC_PACKS_SUFFIX=.zip
```
would expand to `https://cdn.example.org/configs-v9.0.1.zip,https://cdn.example.org/mods-v4.3.6.zip`.
If applying large generic packs, the update check can be time-consuming since a SHA1 checksum is compared. To skip the update check set `SKIP_GENERIC_PACK_UPDATE_CHECK` to "true". Conversely, the generic pack(s) can be forced to be applied without comparing the checksum by setting `FORCE_GENERIC_PACK_UPDATE` to "true".
If multiple generic packs need to be applied together, set `GENERIC_PACKS` instead, with a comma separated list of zip file paths and/or URLs to zip files.
### Mod/Plugin URL Listing File
@@ -906,19 +785,23 @@ before unpacking new content from the MODPACK or MODS.
### Downloadable world
Instead of mounting the `/data` volume, you can instead specify the URL of a ZIP or compressed TAR file containing an archived world. It will be searched for a file `level.dat` and the containing subdirectory moved to the directory named by `$LEVEL`. This means that most of the archived Minecraft worlds downloadable from the Internet will already be in the correct format.
Instead of mounting the `/data` volume, you can instead specify the URL of a ZIP file containing an archived world. It will be searched for a file `level.dat` and the containing subdirectory moved to the directory named by `$LEVEL`. This means that most of the archived Minecraft worlds downloadable from the Internet will already be in the correct format.
docker run -d -e WORLD=http://www.example.com/worlds/MySave.zip ...
**NOTE:** This URL must be accessible from inside the container. Therefore, you should use an IP address or a globally resolvable FQDN, or else the name of a linked container.
**NOTE:** This URL must be accessible from inside the container. Therefore,
you should use an IP address or a globally resolvable FQDN, or else the
name of a linked container.
**NOTE:** If the archive contains more than one `level.dat`, then the one to select can be picked with `WORLD_INDEX`, which defaults to 1.
### Cloning world from a container path
The `WORLD` option can also be used to reference a directory, zip file, or compressed tar file that will be used as a source to clone or extract the world directory.
The `WORLD` option can also be used to reference a directory or zip file that will be used as a source to clone or unzip the world directory.
For example, the following would initially clone the world's content from `/worlds/basic`. Also notice in the example that you should use a read-only volume attachment to ensure the clone source remains pristine.
For example, the following would initially clone the world's content
from `/worlds/basic`. Also notice in the example that you can use a
read-only volume attachment to ensure the clone source remains pristine.
```
docker run ... -v $HOME/worlds:/worlds:ro -e WORLD=/worlds/basic
@@ -945,9 +828,6 @@ Datapacks will be placed in `/data/$LEVEL/datapacks`
VanillaTweaks datapacks can be installed with a share code from the website UI **OR** a json file to specify packs to download and install.
Datapacks will be placed in `/data/$LEVEL/datapacks`
Resourcepacks will be placed in `/data/resourcepacks`
Accepted Parameters:
- `VANILLATWEAKS_FILE`
@@ -958,60 +838,32 @@ Accepted Parameters:
- `REMOVE_OLD_VANILLATWEAKS_EXCLUDE`
Example of expected Vanillatweaks sharecode:
**Note**: ResourcePacks, DataPacks, and CraftingTweaks all have separate sharecodes
```yaml
VANILLATWEAKS_SHARECODE: MGr52E,tF1zL2,LnEDwT
VANILLATWEAKS_SHARECODE: MGr52E
```
Example of expected Vanillatweaks file format:
```yaml
VANILLATWEAKS_FILE: /config/vt-datapacks.json,/config/vt-craftingtweaks.json,/config/vt-resourcepacks.json
```
Datapacks Json:
```json
{
"type": "datapacks",
"version": "1.18",
"packs": {
"survival": [
"graves",
"multiplayer sleep",
"afk display",
"armor statues",
"unlock all recipes",
"fast leaf decay",
"coordinates hud"
],
"items": ["armored elytra"]
}
}
```
Resourcepacks Json:
```json
{
"type": "resourcepacks",
"version": "1.18",
"packs": {
"aesthetic": ["CherryPicking", "BlackNetherBricks", "AlternateBlockDestruction"]
},
"result": "ok"
}
```
CraftingTweaks Json:
```json
{
"type": "craftingtweaks",
"version": "1.18",
"packs": {
"quality of life": [
"dropper to dispenser",
"double slabs",
"back to blocks"
]
},
"result": "ok"
}
```
Datapacks will be placed in `/data/$LEVEL/datapacks`
## Server configuration
@@ -1528,9 +1380,6 @@ To let the JVM calculate the heap size from the container declared memory limit,
General JVM options can be passed to the Minecraft Server invocation by passing a `JVM_OPTS`
environment variable. The JVM requires `-XX` options to precede `-X` options, so those can be declared in `JVM_XX_OPTS`. Both variables are space-delimited, raw JVM arguments.
```
-e JVM_OPTS="-someJVMOption someJVMOptionValue"
```
For some cases, if e.g. after removing mods, it could be necessary to startup minecraft with an additional `-D` parameter like `-Dfml.queryResult=confirm`. To address this you can use the environment variable `JVM_DD_OPTS`, which builds the params from a given list of values separated by space, but without the `-D` prefix. To make things running under systems (e.g. Plesk), which doesn't allow `=` inside values, a `:` (colon) could be used instead. The upper example would look like this:
`JVM_DD_OPTS=fml.queryResult:confirm`, and will be converted to `-Dfml.queryResult=confirm`.
@@ -1636,95 +1485,6 @@ When the container is signalled to stop, the Minecraft process wrapper will atte
### Setup only
If you are using a host-attached data directory, then you can have the image setup the Minecraft server files and stop prior to launching the server process by setting `SETUP_ONLY` to `true`.
### Enable Flare Flags
To enable the JVM flags required to fully support the [Flare profiling suite](https://blog.airplane.gg/flare), set the following variable:
-e USE_FLARE_FLAGS=true
Flare is built-in to Airplane/Pufferfish/Purpur, and is available in [plugin form](https://github.com/TECHNOVE/FlarePlugin) for other server types.
### Enable timestamps in init logs
Before the container starts the Minecraft Server its output is prefixed with `[init]`, such as
```
[init] Starting the Minecraft server...
```
To also include the timestamp with each log, set `LOG_TIMESTAMP` to "true". The log output will then look like:
```
[init] 2022-02-05 16:58:33+00:00 Starting the Minecraft server...
```
### Use RCON commands
Feature is used run commands when the server starts, client connects, or client disconnects.
**Notes:**
* On clinet connect we only know there was a connection, and not who connected. RCON commands will need to be used for that.
* Using '|-' is preferred for yaml, this make sure only the correct new lines are in place for the commands.
**On Server Start:**
```yaml
RCON_CMDS_STARTUP: |-
/gamerule doFireTick false
/pregen start 200
```
**On Client Connection:**
```yaml
RCON_CMDS_ON_CONNECT: |-
/team join New @a[team=]
```
**On Client Disconnect:**
```yaml
RCON_CMDS_ON_DISCONNECT: |-
/gamerule doFireTick true
```
**On First Client Connect**
```yaml
RCON_CMDS_FIRST_CONNECT: |-
/pregen stop
```
**On Last Client Disconnect**
```yaml
RCON_CMDS_LAST_DISCONNECT: |-
/kill @e[type=minecraft:boat]
/pregen start 200
```
**Example of rules for new players**
Uses team NEW and team OLD to track players on the server. So move player with no team to NEW, run a command, move them to team OLD.
[Reference Article](https://www.minecraftforum.net/forums/minecraft-java-edition/redstone-discussion-and/2213523-detect-players-first-join)
```yaml
RCON_CMDS_STARTUP: |-
/pregen start 200
/gamerule doFireTick false
/team add New
/team add Old
RCON_CMDS_ON_CONNECT: |-
/team join New @a[team=]
/give @a[team=New] birch_boat
/team join Old @a[team=New]
RCON_CMDS_FIRST_CONNECT: |-
/pregen stop
RCON_CMDS_LAST_DISCONNECT: |-
/kill @e[type=minecraft:boat]
/pregen start 200
```
## Autopause

View File

@@ -12,8 +12,4 @@ if [ ! -p "${CONSOLE_IN_NAMED_PIPE}" ]; then
exit 1
fi
if [ "$(id -u)" = 0 ]; then
gosu minecraft bash -c "echo $* > '${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}'"
else
echo "$@" > "${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}"
fi
gosu minecraft bash -c "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,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,27 +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 \
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

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

@@ -0,0 +1,157 @@
#!/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-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
if [[ $tag ]]; then
if [ -f "$HOME/.github.env" ]; then
source "$HOME/.github.env"
if [[ $GITHUB_TOKEN ]]
then
auth=(-u ":$GITHUB_TOKEN")
base=https://api.github.com
: "${owner:=itzg}"
: "${repo:=docker-minecraft-server}"
read -r -d '' releaseBody << EOF
{
"tag_name": "$tag",
"name": "$tag",
"generate_release_notes": true
}
EOF
if ! curl "${auth[@]}" -H "Accept: application/vnd.github.v3+json" \
"${base}/repos/${owner}/${repo}/releases" -d "$releaseBody"; then
echo "ERROR failed to create github release $tag"
exit 1
fi
fi
fi
fi

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

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

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

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

@@ -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,12 +1,11 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${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
@@ -25,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
@@ -41,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

@@ -3,17 +3,11 @@ set -euo pipefail
IFS=$'\n\t'
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
: "${EULA:=}"
: "${PROXY:=}"
: "${RCON_PASSWORD_FILE:=}"
: "${RCON_CMDS_STARTUP:=}"
: "${RCON_CMDS_ON_CONNECT:=}"
: "${RCON_CMDS_ON_DISCONNECT:=}"
: "${RCON_CMDS_FIRST_CONNECT:=}"
: "${RCON_CMDS_LAST_DISCONNECT:=}"
: "${RCON_CMDS_PERIOD:=10}"
shopt -s nullglob
@@ -72,28 +66,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
@@ -116,9 +91,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
@@ -132,18 +105,6 @@ 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=(
@@ -155,30 +116,27 @@ 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" "$@"
exec ${SCRIPTS:-/}start-deployForge "$@"
;;
FABRIC)
exec "${SCRIPTS:-/}start-deployFabric" "$@"
exec ${SCRIPTS:-/}start-deployFabric "$@"
;;
FTBA)
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployFTBA" "$@"
exec ${SCRIPTS:-/}start-deployFTBA "$@"
;;
FTB|CURSEFORGE)
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployCF" "$@"
exec ${SCRIPTS:-/}start-deployCF "$@"
;;
VANILLA)
@@ -186,56 +144,46 @@ 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" "$@"
exec ${SCRIPTS:-/}start-deployCatserver "$@"
;;
PURPUR)
exec "${SCRIPTS:-/}start-deployPurpur" "$@"
exec ${SCRIPTS:-/}start-deployPurpur "$@"
;;
AIRPLANE)
exec "${SCRIPTS:-/}start-deployAirplane" "$@"
exec ${SCRIPTS:-/}start-deployAirplane "$@"
;;
PUFFERFISH)
exec "${SCRIPTS:-/}start-deployPufferfish" "$@"
exec ${SCRIPTS:-/}start-deployPufferfish "$@"
;;
CANYON)
exec "${SCRIPTS:-/}start-deployCanyon" "$@"
exec ${SCRIPTS:-/}start-deployCanyon "$@"
;;
LIMBO)
exec "${SCRIPTS:-/}start-deployLimbo" "$@"
exec ${SCRIPTS:-/}start-deployLimbo "$@"
;;
CRUCIBLE)
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 "**********************************************************************"
exec "${SCRIPTS:-/}start-deployCrucible" "$@"
;;

View File

@@ -6,33 +6,35 @@ isDebugging && set -x
IFS=$'\n\t'
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "PURPUR" ] ; then
log "ERROR: Airplane server type only supports VERSION=LATEST, VERSION=PURPUR."
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "1.17" ] && [ "${VERSION}" != "PURPUR" ] ; then
log "ERROR: Airplane server type only supports VERSION=LATEST, VERSION=1.17, VERSION=PURPUR. Note that these are branches, not #.#.# versions."
exit 1
fi
: ${AIRPLANE_BUILD:=lastSuccessfulBuild}
: ${AIRPLANE_TYPE:=airplane}
if [ "${VERSION}" = "LATEST" ] ; then
AIRPLANE_TYPE="airplane"
if [ "${VERSION}" = "LATEST" ] || [ "${VERSION}" = "1.17" ]; then
AIRPLANE_BRANCH="1.17"
fi
if [ "${VERSION}" = "PURPUR" ]; then
AIRPLANE_BRANCH="Purpur-1.17"
AIRPLANE_TYPE="airplanepurpur"
fi
log "Using ${AIRPLANE_TYPE} 1.17.1 (1.18 unsupported - use Paper/Pufferfish/Purpur for newer versions)"
log "Using Airplane-${AIRPLANE_BRANCH} branch"
export SERVER=${AIRPLANE_TYPE}-1.17.1.jar
export SERVER=airplane-${AIRPLANE_BRANCH}-${AIRPLANE_BUILD}.jar
log "Removing old Airplane versions ..."
shopt -s nullglob
for f in airplane*.jar; do
for f in airplane-*.jar; do
[[ $f != $SERVER ]] && rm $f
done
if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
downloadUrl="https://airplane.gg/dl/launcher-${AIRPLANE_TYPE}1.17.1.jar"
downloadUrl="https://ci.tivy.ca/job/Airplane-${AIRPLANE_BRANCH}/${AIRPLANE_BUILD}/artifact/launcher-${AIRPLANE_TYPE}.jar"
log "Downloading Airplane from $downloadUrl ..."
if ! get -o "$SERVER" "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
@@ -41,6 +43,8 @@ if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-/}start-spiget" "$@"
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -126,6 +126,8 @@ else
fi
# Normalize on Spigot for operations below
export TYPE=SPIGOT
export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -43,6 +43,8 @@ if [ ! -f "$SERVER" ]; then
fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
export FAMILY=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,8 @@ 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" "$@"
export FAMILY=HYBRID
# Continue to Final Setup
exec ${SCRIPTS:-/}start-setupWorld "$@"

View File

@@ -55,6 +55,7 @@ if [ ! -d "$librariesDir" ]; then
fi
export SERVER
export SKIP_LOG4J_CONFIG=true
export FAMILY=HYBRID
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
export FAMILY=HYBRID
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
@@ -81,5 +80,4 @@ if ! [ -v SERVER ]; then
fi
export FAMILY=FORGE
exec ${SCRIPTS:-/}start-setupWorld $@

View File

@@ -6,45 +6,76 @@ set -eu
requireVar VANILLA_VERSION
export TYPE=FABRIC
: "${FABRIC_LAUNCHER_VERSION:=${FABRIC_INSTALLER_VERSION:-LATEST}}"
: "${FABRIC_LAUNCHER:=}"
: "${FABRIC_LAUNCHER_URL:=}"
: "${FABRIC_INSTALLER_VERSION:=${FABRICVERSION:-LATEST}}"
: "${FABRIC_INSTALLER:=}"
: "${FABRIC_INSTALLER_URL:=}"
: "${FABRIC_LOADER_VERSION:=LATEST}"
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"
log "Checking Fabric version information."
if [[ $FABRIC_INSTALLER ]]; then
FABRIC_INSTALLER_VERSION=$(echo -n "$FABRIC_INSTALLER" | mc-image-helper hash)
elif [[ $FABRIC_INSTALLER_URL ]]; then
FABRIC_INSTALLER_VERSION=$(echo -n "$FABRIC_INSTALLER_URL" | mc-image-helper hash)
elif [[ ${FABRIC_INSTALLER_VERSION^^} = LATEST ]]; then
FABRIC_INSTALLER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-installer/maven-metadata.xml)
fi
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"
export SERVER=fabric-server-${VANILLA_VERSION}-${FABRIC_INSTALLER_VERSION}.jar
if [ ! \( -e ${SERVER} -a -e "server-${VANILLA_VERSION}.jar" \) ]; then
if [[ -z $FABRIC_INSTALLER && -z $FABRIC_INSTALLER_URL ]]; then
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 server.jar "server-${VANILLA_VERSION}.jar"
mv fabric-server-launch.jar "${SERVER}"
fi
if [[ ! -e ${SERVER} ]]; then
log "$SERVER does not exist, cannot launch server!"
exit 1
fi
# Specify which server jar to run
echo "serverJar=server-${VANILLA_VERSION}.jar" > fabric-server-launcher.properties
export FAMILY=FABRIC
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -38,23 +38,18 @@ install() {
get_installer "$normForgeVersion" "$shortForgeVersion"
fi
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
@@ -99,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
@@ -107,8 +102,8 @@ resolve_versions() {
;;
RECOMMENDED)
if ! FORGE_VERSION=$(get -s --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 -s --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
@@ -153,5 +148,4 @@ else
fi
export FAMILY=FORGE
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

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

View File

@@ -1,12 +1,13 @@
#!/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}"
: ${MAGMA_CHANNEL:=stable}
magmaDownloadServer() {
@@ -89,5 +90,4 @@ else
fi
export FAMILY=HYBRID
exec "${SCRIPTS:-/}start-setupWorld" "$@"
exec ${SCRIPTS:-/}start-setupWorld "$@"

View File

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

View File

@@ -73,6 +73,8 @@ else
fi
# Normalize on Spigot for downstream operations
export TYPE=SPIGOT
export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -1,45 +1,46 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
. ${SCRIPTS:-/}start-utils
set -euo pipefail
isDebugging && set -x
IFS=$'\n\t'
if [[ "${MAJOR_VANILLA_VERSION}" != "1.18" ]] && [[ "${MAJOR_VANILLA_VERSION}" != "1.17" ]]; then
log "ERROR: Pufferfish server type only supports versions 1.18 or 1.17, use PUFFERFISH_BUILD to select the the correct build 47 => 1.18.1, 50 => 1.18.2 etc"
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "1.18" ] ; then
log "ERROR: Pufferfish server type only supports VERSION=LATEST, VERSION=1.18. Note that these are branches, not #.#.# versions."
exit 1
fi
: "${PUFFERFISH_BUILD:=lastSuccessfulBuild}"
: ${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}"
if [ "${VERSION}" = "LATEST" ] || [ "${VERSION}" = "1.18" ]; then
PUFFERFISH_BRANCH="1.18"
PUFFERFISH_VERSION="1.18.1-R0.1"
fi
# Setting server to the Jar filename for export.
export SERVER=$PUFFERFISH_BUILD_FILENAME
log "Using Pufferfish-${PUFFERFISH_BRANCH} branch"
export SERVER=pufferfish-${PUFFERFISH_BRANCH}-${PUFFERFISH_BUILD}.jar
log "Removing old Pufferfish versions ..."
shopt -s nullglob
for f in pufferfish-*.jar; do
[[ $f != "$SERVER" ]] && rm "$f"
[[ $f != $SERVER ]] && rm $f
done
if [[ ! -f "$SERVER" ]] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
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=$?)"
if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
artifact="build/libs/pufferfish-paperclip-${PUFFERFISH_VERSION}-SNAPSHOT-reobf.jar"
downloadUrl="https://ci.pufferfish.host/job/Pufferfish-${PUFFERFISH_BRANCH}/${PUFFERFISH_BUILD}/artifact/${artifact}"
log "Downloading Pufferfish from $downloadUrl ..."
if ! get -o "$SERVER" "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3
fi
fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-/}start-spiget" "$@"
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -6,9 +6,9 @@ IFS=$'\n\t'
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x
: "${VANILLA_VERSION:?}"
: "${PURPUR_BUILD:=LATEST}"
: "${FORCE_REDOWNLOAD:=false}"
: ${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
@@ -30,6 +30,8 @@ if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-/}start-spiget" "$@"

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

View File

@@ -1,23 +1,105 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}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
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..."
# 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
read -r -a specs < <(identify /tmp/icon.img | awk 'NR == 1 { print $2, $3 }')
if [ "${specs[0]} ${specs[1]}" = "PNG 64x64" ]; then
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
elif [ "${specs[0]}" = GIF ]; then
log "Converting GIF image to 64x64 PNG..."
convert "/tmp/icon.img[0]" -resize 64x64! /data/server-icon.png
else
log "Converting image to 64x64 PNG..."
convert /tmp/icon.img -resize 64x64! /data/server-icon.png
@@ -26,15 +108,13 @@ if [ -n "$ICON" ]; then
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
log "ERROR: failed to download corrected log4j config"
exit 1
fi
JVM_OPTS="-Dlog4j.configurationFile=${file} ${JVM_OPTS}"
canUseRollingLogs=false
@@ -48,16 +128,7 @@ 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
@@ -93,7 +164,7 @@ 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
@@ -252,14 +323,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

@@ -74,4 +74,4 @@ elif [[ "$DATAPACKS_FILE" ]]; then
fi
fi
exec "${SCRIPTS:-/}start-setupForgeApiMods" "$@"
exec "${SCRIPTS:-/}start-setupModpack" "$@"

View File

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

View File

@@ -1,243 +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 ${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 $( ! isTrue "$MODS_FORGEAPI_IGNORE_GAMETYPE" ) && $FILTER_BY_FAMILY ; then
# Looks for file by version and server type in lowercase
current_project_file=$(jq -n "$project_files" | jq --arg RELEASE_FILTER "$RELEASE_NUMBER_FILTER" --arg GAME_TYPE ${FAMILY,,} -jc '
.data | sort_by(.id) | reverse | map(select(.gameVersions[] | ascii_downcase | contains ($GAME_TYPE))) | map(select(.releaseType<=($RELEASE_FILTER|tonumber))) | .[0] // empty')
else
# Looks for file by version only.
current_project_file=$(jq -n "$project_files" | jq --arg RELEASE_FILTER "$RELEASE_NUMBER_FILTER" -jc '
.data | sort_by(.id) | reverse | map(select(.releaseType<=($RELEASE_FILTER|tonumber))) | .[0] // empty')
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"
# 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
# Needs loop here to look up release types befor calling download.
while read -r current_project; do
# 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

@@ -25,11 +25,11 @@ 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)
latestPackwiz=$(curl -fsSL https://api.github.com/repos/comp500/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}"
isDebugging && log "Latest packwiz ${latestPackWiz}"
latestPackwizVer=$(echo ${latestPackwiz} | jq --raw-output '.tag_name')
latestPackwizUrl=$(echo ${latestPackwiz} | jq --raw-output '.assets[] | select(.name | match("packwiz-installer-bootstrap.jar")) | .url')
: "${PACKWIZ_JAR:=packwiz-installer-bootstrap_${latestPackwizVer}.jar}"
@@ -67,7 +67,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}"
@@ -81,7 +81,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
@@ -92,7 +92,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
@@ -118,7 +118,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
@@ -128,7 +128,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
@@ -188,19 +188,15 @@ esac
fi
: "${GENERIC_PACKS:=${GENERIC_PACK}}"
: "${GENERIC_PACKS_PREFIX:=}"
: "${GENERIC_PACKS_SUFFIX:=}"
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
for pack in "${packs[@]}"; do
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
if ! outfile=$(get -o /data/packs --output-filename --skip-existing "$pack"); then
log "ERROR: failed to download $pack"
exit 2
fi
@@ -211,18 +207,12 @@ if [[ "${GENERIC_PACKS}" ]]; then
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..."
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}"
extract "${pack}" "${base_dir}"
unzip -q -d ${base_dir} "${pack}"
done
# recalculate the actual base directory of content
@@ -250,8 +240,7 @@ if [[ "${GENERIC_PACKS}" ]]; then
cp -R -f "${base_dir}"/* /data
rm -rf /tmp/generic_pack_base
log "Saving generic pack(s) checksum"
sha1sum "${packFiles[@]}" > "${sum_file}"
sha256sum "${packFiles[@]}" > "${sum_file}"
isDebugging && cat "$sum_file"
fi
fi

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

@@ -48,7 +48,7 @@ function customizeServerProps {
# 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
@@ -62,13 +62,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

View File

@@ -12,115 +12,73 @@ set -e -o pipefail
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x
VT_VERSION=""
DATAPACKS_DIR="/data/${LEVEL:-world}/datapacks"
RESOURCEPACKS_DIR="/data/resourcepacks"
out_dir=/data/${LEVEL:-world}/datapacks
# Remove old VANILLATWEAKS
if isTrue "${REMOVE_OLD_VANILLATWEAKS}"; then
# NOTE: datapacks include crafting tweaks.
if [ -d "$DATAPACKS_DIR" ]; then
find "$DATAPACKS_DIR" -mindepth 1 -maxdepth ${REMOVE_OLD_VANILLATWEAKS_DEPTH:-16} -wholename "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_VANILLATWEAKS_EXCLUDE:-}" -delete
fi
if [ -d "$RESOURCEPACKS_DIR" ]; then
find "$RESOURCEPACKS_DIR" -mindepth 1 -maxdepth ${REMOVE_OLD_VANILLATWEAKS_DEPTH:-16} -wholename "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_VANILLATWEAKS_EXCLUDE:-}" -delete
if isTrue "${REMOVE_OLD_VANILLATWEAKS}" && [ -z "${VANILLATWEAKS_FILE}" ]; then
if [ -d "$out_dir" ]; then
find "$out_dir" -mindepth 1 -maxdepth ${REMOVE_OLD_VANILLATWEAKS_DEPTH:-16} -wholename "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_VANILLATWEAKS_EXCLUDE:-}" -delete
fi
fi
# Gets the download url and downloads the actual files.
getUrlAndDownload(){
VT_FILE=$1
URL_SUFFIX=$2
OUTPUT_FILE=$3
PACKS=$(jq -jc '.packs // empty' $VT_FILE)
if [ ! "$PACKS" ]; then
log "ERROR: unable to retrieve ${URL_SUFFIX} from ${VT_FILE}"
exit 2
fi
ZIPDATA_URL="https://vanillatweaks.net/assets/server/zip${URL_SUFFIX}.php"
DOWNLOAD_URL=$(curl -X POST -F "packs=${PACKS}" -F "version=${VT_VERSION}" $ZIPDATA_URL | jq -r '.link // empty')
if [ ! "$DOWNLOAD_URL" ]; then
log "ERROR: unable to retrieve ${URL_SUFFIX} packs from vanillatweaks.net!"
exit 2
fi
if ! get -o $OUTPUT_FILE "https://vanillatweaks.net${DOWNLOAD_URL}"; then
log "ERROR: failed to download ${URL_SUFFIX} from ${DOWNLOAD_URL}"
exit 2
fi
}
# Datapacks Handler
downloadDatapacks(){
VT_FILE=$1
URL_SUFFIX="datapacks"
OUTPUT_FILE="/tmp/vanillatweaks.zip"
getUrlAndDownload $VT_FILE $URL_SUFFIX $OUTPUT_FILE
mkdir -p "$DATAPACKS_DIR"
if ! unzip -o -d "$DATAPACKS_DIR" $OUTPUT_FILE; then
log "ERROR: failed to unzip the datapacks ${DATAPACKS} from ${OUTPUT_FILE}"
fi
rm -f $OUTPUT_FILE
}
# Crafting Tweaks Handler
downloadCraftingtweaks(){
VT_FILE=$1
mkdir -p "$DATAPACKS_DIR"
getUrlAndDownload $VT_FILE "craftingtweaks" "${DATAPACKS_DIR}/craftingtweaks.zip"
}
# Resourcepacks Handler
downloadResourcepacks(){
VT_FILE=$1
mkdir -p "$RESOURCEPACKS_DIR"
getUrlAndDownload $VT_FILE "resourcepacks" "${RESOURCEPACKS_DIR}/resourcepacks.zip"
}
# Example: VANILLATWEAKS_SHARECODE=MGr52E
# Code generated from the UI website, typically a alphanumeric 6 digit code.
if [[ "$VANILLATWEAKS_SHARECODE" ]]; then
VANILLATWEAKS_FILE=()
for SHARECODE in ${VANILLATWEAKS_SHARECODE//,/ }; do
TMP_FILE="/tmp/${SHARECODE}.json"
SHARECODE_LOOKUP_URL="https://vanillatweaks.net/assets/server/sharecode.php?code=${SHARECODE}"
if ! get -o "$TMP_FILE" "$SHARECODE_LOOKUP_URL"; then
log "ERROR: Unable to use ${SHARECODE} share code provided to retrieve vanillatweaks file"
exit 2
fi
VANILLATWEAKS_FILE+="${TMP_FILE},"
done
VANILLATWEAKS_FILE=/tmp/vanillatweaksfile.json
SHARECODE_LOOKUP_URL="https://vanillatweaks.net/assets/server/sharecode.php?code=${VANILLATWEAKS_SHARECODE}"
curl -f $SHARECODE_LOOKUP_URL -o $VANILLATWEAKS_FILE
if [ ! -f "$VANILLATWEAKS_FILE" ]; then
log "ERROR: Unable to use share code provided to retreive vanillatweaks file"
exit 2
fi
fi
# Use vanillatweaks file to specify VT and datapacks and crafting tweaks
# Use vanillatweaks file to specify VT and datapacks
if [[ "$VANILLATWEAKS_FILE" ]]; then
for VT_FILE in ${VANILLATWEAKS_FILE//,/ }; do
if [ ! -f "$VT_FILE" ]; then
log "ERROR: given VANILLATWEAKS_FILE file does not exist"
exit 2
fi
if [ ! -f "$VANILLATWEAKS_FILE" ]; then
log "ERROR: given VANILLATWEAKS_FILE file does not exist"
exit 2
fi
VT_VERSION=$(jq -jc '.version // empty' $VT_FILE)
if [ ! "$VT_VERSION" ]; then
log "ERROR: unable to retrieve version from $VT_FILE"
exit 2
fi
PACKS=$(jq -jc '.packs' $VANILLATWEAKS_FILE)
if [ ! "$PACKS" ]; then
log "ERROR: unable to retrieve packs from $VANILLATWEAKS_FILE"
exit 2
fi
TYPE=$(jq -jc '.type // empty' $VT_FILE)
if [[ "$TYPE" = "datapacks" ]]; then
downloadDatapacks $VT_FILE
elif [[ "$TYPE" = "craftingtweaks" ]]; then
downloadCraftingtweaks $VT_FILE
elif [[ "$TYPE" = "resourcepacks" ]]; then
downloadResourcepacks $VT_FILE
fi
VT_VERSION=$(jq -jc '.version' $VANILLATWEAKS_FILE)
if [ ! "$VT_VERSION" ]; then
log "ERROR: unable to retrieve version from $VANILLATWEAKS_FILE"
exit 2
fi
fi
# cleans up temp vanilla tweaks file download to get stored packs
if [[ "$VANILLATWEAKS_SHARECODE" ]]; then
rm -f $VT_FILE
fi
done
# Download and unzip packs
if [[ "$PACKS" ]] && [[ "$VT_VERSION" ]]; then
VT_ZIPDATA_URL=https://vanillatweaks.net/assets/server/zipdatapacks.php
DOWNLOAD_URL=$(curl -X POST -F "packs=${PACKS}" -F "version=${VT_VERSION}" $VT_ZIPDATA_URL | jq -r '.link')
if [ ! "$DOWNLOAD_URL" ]; then
log "ERROR: unable to retrieve DOWNLOAD_URL from vanillatweaks.net!"
exit 2
fi
TEMPZIP=/tmp/vanillatweaks.zip
if ! get -o $TEMPZIP "https://vanillatweaks.net${DOWNLOAD_URL}"; then
log "ERROR: failed to download from ${DOWNLOAD_URL}"
exit 2
fi
mkdir -p "$out_dir"
if ! unzip -o -d "$out_dir" $TEMPZIP; then
log "ERROR: failed to unzip the ${PACKS} from ${$TEMPZIP}"
fi
# clean up files time!
rm -f $TEMPZIP
# cleans up temp vanilla tweaks file download to get stored packs
if [[ "$VANILLATWEAKS_SHARECODE" ]]; then
rm -f $VANILLATWEAKS_FILE
fi
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"

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,7 +17,7 @@ containsJars() {
if [[ $line =~ $pat ]]; then
return 0
fi
done < <(unzip -l "$file" | tail -n +4)
done <<<$(unzip -l "$file")
return 1
}
@@ -34,7 +31,7 @@ containsPlugin() {
if [[ $line =~ $pat ]]; then
return 0
fi
done < <(unzip -l "$file" | tail -n +4)
done <<<$(unzip -l "$file")
return 1
}
@@ -52,7 +49,7 @@ getResourceFromSpiget() {
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 +71,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,35 +84,29 @@ getResourceFromSpiget() {
downloadResourceFromSpiget() {
resource=${1?}
resourceUrl="https://api.spiget.org/v2/resources/${resource}"
if ! outfile=$(get_silent --output-filename -o /tmp "${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 containsJars "${outfile}"; then
log "Extracting contents of resource ${resource} into plugins"
extract "$outfile" /data/plugins
rm "$outfile"
elif containsPlugin "${outfile}"; then
log "Moving resource ${resource} into plugins"
mv "$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
if containsJars "${tmpfile}"; then
log "Extracting contents of resource ${resource} into plugins"
unzip -o -q -d /data/plugins "${tmpfile}"
rm "${tmpfile}"
elif containsPlugin "${tmpfile}"; then
log "Moving resource ${resource} into plugins"
mv "${tmpfile}" "/data/plugins/${resource}.jar"
else
log "ERROR downloaded resource '${resource}' seems to be not a valid plugin"
exit 2
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
@@ -127,4 +118,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,7 +53,6 @@ function isTrue() {
;;
esac
eval "$oldState"
return ${result}
}
@@ -92,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() {
@@ -122,10 +101,6 @@ function logAutostopAction() {
echo "[$(date -Iseconds)] [Autostop] $*"
}
function logRcon() {
echo "[Rcon loop] $*"
}
function normalizeMemSize() {
local scale=1
case ${1,,} in
@@ -197,80 +172,11 @@ function get() {
mc-image-helper "${flags[@]}" get "$@"
}
function get_silent() {
local flags=(-s)
if isTrue "${DEBUG_GET:-false}"; then
flags+=("--debug")
fi
mc-image-helper "${flags[@]}" get "$@"
}
function isFamily() {
for f in "${@}"; do
if [[ ${FAMILY^^} == "${f^^}" ]]; then
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|application/zstd|application/x-zstd)
tar -C "${destDir}" -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
else
return 1
fi
}
}

1
tests/.gitignore vendored
View File

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

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

@@ -6,9 +6,9 @@ services:
environment:
EULA: "true"
SETUP_ONLY: "TRUE"
GENERIC_PACKS: testing
GENERIC_PACKS_PREFIX: /packs/
GENERIC_PACKS_SUFFIX: .zip
GENERIC_PACKS: https://github.com/itzg/mc-image-helper/releases/download/v1.9.5/mc-image-helper-1.9.5.zip,/packs/testing.zip
volumes:
- ./packs:/packs
- ./data:/data
- 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,14 +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}
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/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

View File

@@ -1,16 +0,0 @@
version: "3"
services:
mc:
image: ${IMAGE_TO_TEST:-itzg/minecraft-server:java8-multiarch}
environment:
EULA: "true"
SETUP_ONLY: "TRUE"
TYPE: CURSEFORGE
CF_SERVER_MOD: /modpacks/pack.zip
INIT_MEMORY: 2G
MAX_MEMORY: 6G
volumes:
- ./data:/data
- ./modpacks:/modpacks:ro

View File

@@ -1 +0,0 @@
[[ $VARIANT == java8* ]] || exit 1

View File

@@ -1,2 +0,0 @@
mc-image-helper assert fileExists "/data/FeedTheBeast/forge-installer.jar"
mc-image-helper assert fileExists "/data/FeedTheBeast/forge.jar"

View File

@@ -1,26 +0,0 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
# Using custom to bypass Fabric setup
TYPE: CUSTOM
# Using family to test FORGEAPI Family filter.
FAMILY: FABRIC
CUSTOM_SERVER: /servers/fake.jar
VERSION: ${MINECRAFT_VERSION:-LATEST}
MODS_FORGEAPI_FILE: /config/forgeapi_mods.json
# Key is defined in .github/workflows/pr.yml and ci.yml
# This should be coming from github secrets.
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
REMOVE_OLD_FORGEAPI_MODS: "TRUE"
# Validates that Fabric API gets download as a dependency.
MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "TRUE"
volumes:
- ./forgeapi_mods.json:/config/forgeapi_mods.json:ro
- ./data:/data
- ./fake.jar:/servers/fake.jar

View File

@@ -1,11 +0,0 @@
[{
"name": "On A Stick [FABRIC]",
"projectId": "550544",
"releaseType": "release"
},
{
"name": "Fabric Voice Mod",
"projectId": "416089",
"releaseType": "beta"
}
]

View File

@@ -1,2 +0,0 @@
[[ $MINECRAFT_VERSION == LATEST ]] || exit 1
[[ $MODS_FORGEAPI_KEY ]] || exit 1

View File

@@ -1,5 +0,0 @@
# Validates specific beta call out for specific mod:
mc-image-helper assert fileExists "/data/mods/voicechat-fabric*"
mc-image-helper assert fileExists "/data/mods/onastick-fabric*"
# Dependent of on a stick:
mc-image-helper assert fileExists "/data/mods/fabric-api*"

View File

@@ -1,29 +0,0 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
# Using custom to bypass Fabric setup
TYPE: CUSTOM
# Using family to test FORGEAPI Family filter.
FAMILY: FABRIC
CUSTOM_SERVER: /servers/fake.jar
VERSION: ${MINECRAFT_VERSION:-LATEST}
# Validate Skip Gametype Filter:
MODS_FORGEAPI_IGNORE_GAMETYPE: "TRUE"
# Validates that Biomes does not download terrablender
# Using default false for testing:
# MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "FALSE"
# Contains mix of Forge and Fabric mods
MODS_FORGEAPI_PROJECTIDS: 306612,416089,220318
# Allows for Beta releases of 416089 the Fabric Voice Mod
MODS_FORGEAPI_RELEASES: BETA
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
REMOVE_OLD_FORGEAPI_MODS: "FALSE"
volumes:
- ./data:/data
- ./fake.jar:/servers/fake.jar

View File

@@ -1,2 +0,0 @@
[[ $MINECRAFT_VERSION == LATEST ]] || exit 1
[[ $MODS_FORGEAPI_KEY ]] || exit 1

View File

@@ -1,5 +0,0 @@
mc-image-helper assert fileExists "/data/mods/BiomesOPlenty*"
# testing dependencies don't get downloaded when download dependencies is set to false.
! mc-image-helper assert fileExists "/data/mods/TerraBlender*"
mc-image-helper assert fileExists "/data/mods/voicechat-fabric*"
mc-image-helper assert fileExists "/data/mods/fabric-api*"

View File

@@ -1,26 +0,0 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
# Using custom to bypass Fabric setup
TYPE: CUSTOM
# Validate Skip Gametype Filter for vanilla
# - Currently we do not support filtering on vanilla.
FAMILY: VANILLA
CUSTOM_SERVER: /servers/fake.jar
VERSION: ${MINECRAFT_VERSION:-LATEST}
MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "TRUE"
# Contains mix of Forge and Fabric mods
MODS_FORGEAPI_PROJECTIDS: 306612,416089,220318
# Allows for Beta releases of 416089 the Fabric Voice Mod
MODS_FORGEAPI_RELEASES: BETA
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
REMOVE_OLD_FORGEAPI_MODS: "TRUE"
volumes:
- ./data:/data
- ./fake.jar:/servers/fake.jar

View File

@@ -1,2 +0,0 @@
[[ $MINECRAFT_VERSION == LATEST ]] || exit 1
[[ $MODS_FORGEAPI_KEY ]] || exit 1

View File

@@ -1,5 +0,0 @@
# No family filter applied, DO NOT use Fabric or Forge specific name validation as it may cause random breakage.
mc-image-helper assert fileExists "/data/mods/BiomesOPlenty*"
mc-image-helper assert fileExists "/data/mods/TerraBlender*"
mc-image-helper assert fileExists "/data/mods/voicechat*"
mc-image-helper assert fileExists "/data/mods/fabric-api*"

View File

@@ -1 +0,0 @@
mc-image-helper assert fileExists one.txt mods/two.txt

View File

@@ -1,24 +0,0 @@
version: "3"
services:
web:
image: nginx
volumes:
- ./web:/usr/share/nginx/html
mc:
depends_on:
- web
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
SETUP_ONLY: "true"
GENERIC_PACKS: http://web/configs.zip,/packs/testing.zip
LOG_TIMESTAMP: "true"
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes:
- ./packs:/packs
- ./data:/data
- ./fake.jar:/servers/fake.jar

View File

@@ -1,2 +0,0 @@
mc-image-helper assert fileExists one.txt mods/two.txt
mc-image-helper assert fileExists config/opt.yml

View File

@@ -1,22 +0,0 @@
version: "3"
services:
web:
image: nginx
volumes:
- ./web:/usr/share/nginx/html
mc:
depends_on:
- web
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
SETUP_ONLY: "true"
ICON: http://web/motion-tween-example.gif
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes:
- ./data:/data
- ./fake.jar:/servers/fake.jar

View File

@@ -1 +0,0 @@
mc-image-helper assert fileExists server-icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -1,22 +0,0 @@
version: "3"
services:
web:
image: nginx
volumes:
- ./web:/usr/share/nginx/html
mc:
depends_on:
- web
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
SETUP_ONLY: "true"
ICON: http://web/4737386_minecraft_squircle_icon.png
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes:
- ./data:/data
- ./fake.jar:/servers/fake.jar

View File

@@ -1 +0,0 @@
mc-image-helper assert fileExists server-icon.png

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