mirror of
https://github.com/itzg/docker-minecraft-server.git
synced 2026-02-17 15:13:55 +00:00
Compare commits
63 Commits
2022.4.1
...
2021.18.0-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b0b8f8a62 | ||
|
|
e94b40bddf | ||
|
|
2dabf34349 | ||
|
|
eb864c0fb8 | ||
|
|
2e0f469748 | ||
|
|
aa95dc291b | ||
|
|
d22280fae7 | ||
|
|
aac3c1c77a | ||
|
|
61b0eff4ca | ||
|
|
8c5f0a53bf | ||
|
|
fffeb7bb9c | ||
|
|
a060cc88d1 | ||
|
|
4421aaa22d | ||
|
|
3a51db6d24 | ||
|
|
969a23ae27 | ||
|
|
1a62592fe2 | ||
|
|
c316dbb5d2 | ||
|
|
bb64135c9b | ||
|
|
ef98de154c | ||
|
|
3d00077ef8 | ||
|
|
0d3ab75683 | ||
|
|
87681e64bb | ||
|
|
8ce986d3d7 | ||
|
|
67fda61de4 | ||
|
|
7c6ec41822 | ||
|
|
93af2025a2 | ||
|
|
c1b040af77 | ||
|
|
4148325787 | ||
|
|
7083cd15e8 | ||
|
|
7418dab476 | ||
|
|
94bbc8e649 | ||
|
|
3e5e62229a | ||
|
|
fe2a9d56ed | ||
|
|
27571999b2 | ||
|
|
bbd7d9e39a | ||
|
|
ef6f308229 | ||
|
|
49d89d3e73 | ||
|
|
74203b23f4 | ||
|
|
4fb791b490 | ||
|
|
ced25ad50a | ||
|
|
48efc224ba | ||
|
|
467c1d9954 | ||
|
|
9ced230f55 | ||
|
|
f3a8276362 | ||
|
|
b91d63716e | ||
|
|
46cccfd531 | ||
|
|
9fe1cb4a0d | ||
|
|
076038b470 | ||
|
|
aa416729ea | ||
|
|
812c6365ec | ||
|
|
42a5131b19 | ||
|
|
624f6a210f | ||
|
|
1c63cd18b7 | ||
|
|
6266a7e3cc | ||
|
|
871ecd4d9d | ||
|
|
c572c95161 | ||
|
|
f7b58fbbb1 | ||
|
|
eccfa444a9 | ||
|
|
e831d25706 | ||
|
|
12e931332b | ||
|
|
ceee9eddc9 | ||
|
|
60ba668743 | ||
|
|
fd1b15e01f |
5
.github/FUNDING.yml
vendored
5
.github/FUNDING.yml
vendored
@@ -1,5 +0,0 @@
|
||||
|
||||
#github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
custom:
|
||||
- https://www.buymeacoffee.com/itzg
|
||||
- https://paypal.me/itzg
|
||||
40
.github/ISSUE_TEMPLATE/bug.yml
vendored
40
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -1,40 +0,0 @@
|
||||
name: Bug Report
|
||||
description: File a bug report
|
||||
labels:
|
||||
- bug
|
||||
- status/needs triage
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to report a bug.
|
||||
|
||||
Please double check some things first:
|
||||
- Do you just have a question about something? If so, asking in the [Q&A Discussions](https://github.com/itzg/docker-minecraft-server/discussions/categories/q-a) or asking on [the Discord server](https://discord.gg/DXfKpjB) would be best.
|
||||
- Is this bug happening after the `[init]` prefixed logs and after the log that says "Starting the Minecraft server"? If so, please report the bug with Mojang or the respective server provider.
|
||||
- Are you seeing a performance problem? If so, that is typically outside the scope of the image setup mechanims. Ask a question as above or contact the respective server provider.
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: Describe the problem
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: container
|
||||
attributes:
|
||||
label: Container definition
|
||||
description: Please provide the compose file or run command used to create the container
|
||||
value: |
|
||||
```
|
||||
Paste run command or compose file here
|
||||
```
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Container logs
|
||||
description: |
|
||||
Please provide container logs from the start of the container, which will be the ones prefixed with `[init]`. It is even better if you can set the variable `DEBUG` to "true" and provide those debug container logs.
|
||||
value: |
|
||||
```
|
||||
Paste logs here
|
||||
```
|
||||
7
.github/ISSUE_TEMPLATE/config.yml
vendored
7
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,7 +0,0 @@
|
||||
contact_links:
|
||||
- name: Ask a question in discussions
|
||||
url: https://github.com/itzg/docker-minecraft-server/discussions
|
||||
about: Please ask questions here
|
||||
- name: Ask a question on Discord
|
||||
url: https://discord.gg/DXfKpjB
|
||||
about: Please ask questions here
|
||||
29
.github/ISSUE_TEMPLATE/enhancement.yml
vendored
29
.github/ISSUE_TEMPLATE/enhancement.yml
vendored
@@ -1,29 +0,0 @@
|
||||
name: Enhancement Request
|
||||
description: Request an enhancement
|
||||
labels:
|
||||
- enhancement
|
||||
- status/needs triage
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to request an enhancement.
|
||||
|
||||
Even if you plan on submitting a pull request with a contributed enhancement it is best to describe the enhancement here first. Somebody might already be working on a similar thing and could use your help.
|
||||
- type: dropdown
|
||||
id: type
|
||||
attributes:
|
||||
label: Enhancement Type
|
||||
options:
|
||||
- Improve an existing feature
|
||||
- A completely new feature
|
||||
- New server type
|
||||
- Not sure
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the enhancement
|
||||
validations:
|
||||
required: true
|
||||
6
.github/no-response.yml
vendored
Normal file
6
.github/no-response.yml
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
daysUntilClose: 14
|
||||
responseRequiredLabel: "status/waiting on feedback"
|
||||
closeComment: >
|
||||
This issue has been automatically closed because there has been no response
|
||||
after requesting feedback. Please feel free to re-open this issue if the
|
||||
scenario still exists and provide a comment with more information.
|
||||
4
.github/release.yml
vendored
4
.github/release.yml
vendored
@@ -1,4 +0,0 @@
|
||||
changelog:
|
||||
exclude:
|
||||
authors:
|
||||
- dependabot
|
||||
134
.github/workflows/build-multiarch.yml
vendored
134
.github/workflows/build-multiarch.yml
vendored
@@ -3,91 +3,55 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- test/**
|
||||
- "*-multiarch"
|
||||
- "multiarch*"
|
||||
- java8-openj9
|
||||
- java11*
|
||||
- java16*
|
||||
- test/multiarch/*
|
||||
tags:
|
||||
- "[0-9]+.[0-9]+.[0-9]+"
|
||||
- "[0-9]+.[0-9]+.[0-9]+-multiarch*"
|
||||
- "[0-9]+.[0-9]+.[0-9]+-*multiarch"
|
||||
- "[0-9]+.[0-9]+.[0-9]+-java8-openj9"
|
||||
- "[0-9]+.[0-9]+.[0-9]+-java11*"
|
||||
- "[0-9]+.[0-9]+.[0-9]+-java16*"
|
||||
paths-ignore:
|
||||
- "*.md"
|
||||
- "docs/**"
|
||||
- "examples/**"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
variant:
|
||||
- java17
|
||||
- java17-openj9
|
||||
- java17-alpine
|
||||
- java8
|
||||
- java8-multiarch
|
||||
- java8-openj9
|
||||
- java11
|
||||
- java11-openj9
|
||||
include:
|
||||
- variant: java17
|
||||
baseImage: eclipse-temurin:17
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
mcVersion: LATEST
|
||||
- variant: java17-openj9
|
||||
baseImage: ibm-semeru-runtimes:open-17-jdk
|
||||
platforms: linux/amd64,linux/arm64
|
||||
mcVersion: LATEST
|
||||
- variant: java17-alpine
|
||||
baseImage: eclipse-temurin:17-jdk-alpine
|
||||
platforms: linux/amd64
|
||||
mcVersion: LATEST
|
||||
- variant: java8
|
||||
baseImage: openjdk:8-jdk-alpine3.8
|
||||
platforms: linux/amd64
|
||||
mcVersion: 1.12.2
|
||||
- variant: java8-multiarch
|
||||
baseImage: eclipse-temurin:8-jdk
|
||||
platforms: linux/amd64,linux/arm64
|
||||
mcVersion: 1.12.2
|
||||
- variant: java8-openj9
|
||||
baseImage: ibm-semeru-runtimes:open-8-jdk
|
||||
platforms: linux/amd64,linux/arm64
|
||||
mcVersion: 1.12.2
|
||||
- variant: java11
|
||||
baseImage: adoptopenjdk:11-jdk-hotspot
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
mcVersion: 1.16.5
|
||||
- variant: java11-openj9
|
||||
baseImage: ibm-semeru-runtimes:open-11-jdk
|
||||
platforms: linux/amd64,linux/arm64
|
||||
mcVersion: 1.16.5
|
||||
env:
|
||||
IMAGE_TO_TEST: ${{ github.repository_owner }}/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }}
|
||||
docker-buildx:
|
||||
if: github.repository == 'itzg/docker-minecraft-server'
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2.4.0
|
||||
with:
|
||||
# for build-files step
|
||||
fetch-depth: 0
|
||||
uses: actions/checkout@v2.3.4
|
||||
|
||||
- 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
|
||||
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v2.1.6
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1.2.0
|
||||
|
||||
@@ -97,39 +61,27 @@ jobs:
|
||||
username: ${{ secrets.DOCKER_USER }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build for test
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
tags: ${{ env.IMAGE_TO_TEST }}
|
||||
# ensure latest base image is used
|
||||
pull: true
|
||||
# load into daemon for test usage in next step
|
||||
load: true
|
||||
push: false
|
||||
build-args: |
|
||||
BASE_IMAGE=${{ matrix.baseImage }}
|
||||
cache-from: type=gha,scope=${{ matrix.variant }}
|
||||
# no cache-to to avoid cross-cache update from next build step
|
||||
|
||||
- name: Run tests
|
||||
env:
|
||||
MINECRAFT_VERSION: ${{ matrix.mcVersion }}
|
||||
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.6.1
|
||||
with:
|
||||
platforms: ${{ matrix.platforms }}
|
||||
push: ${{ github.ref_type == 'tag' || github.ref_name == 'master' }}
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
# ensure latest base image is used
|
||||
pull: true
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache-new
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
BASE_IMAGE=${{ matrix.baseImage }}
|
||||
BUILD_FILES_REV=${{ steps.build-files-rev.outputs.REV }}
|
||||
cache-from: type=gha,scope=${{ matrix.variant }}
|
||||
cache-to: type=gha,mode=max,scope=${{ matrix.variant }}
|
||||
|
||||
- name: Image digest
|
||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
||||
|
||||
- # Temp fix
|
||||
# https://github.com/docker/build-push-action/issues/252
|
||||
# https://github.com/moby/buildkit/issues/1896
|
||||
name: Move cache
|
||||
run: |
|
||||
rm -rf /tmp/.buildx-cache
|
||||
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||
43
.github/workflows/ci.yml
vendored
43
.github/workflows/ci.yml
vendored
@@ -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@v2.4.0
|
||||
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64
|
||||
tags: ${{ env.IMAGE_TO_TEST }}
|
||||
load: true
|
||||
cache-from: type=gha
|
||||
|
||||
- name: Run Setup Only Tests
|
||||
run: bash tests/setuponlytests/test.sh
|
||||
|
||||
# - name: Run Full Minecraft Service Tests
|
||||
# run: |
|
||||
# tests/fulltests/test.sh
|
||||
26
.github/workflows/discord.yml
vendored
26
.github/workflows/discord.yml
vendored
@@ -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 }} 💣💥"
|
||||
4
.github/workflows/generate-toc.yml
vendored
4
.github/workflows/generate-toc.yml
vendored
@@ -11,11 +11,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- run: |
|
||||
curl https://raw.githubusercontent.com/ekalinin/github-markdown-toc/master/gh-md-toc -o gh-md-toc
|
||||
chmod a+x gh-md-toc
|
||||
./gh-md-toc --insert --no-backup README.md
|
||||
- uses: stefanzweifel/git-auto-commit-action@v4.13.1
|
||||
- uses: stefanzweifel/git-auto-commit-action@v4.11.0
|
||||
with:
|
||||
commit_message: "docs: Auto update markdown TOC"
|
||||
33
.github/workflows/issue-label.yml
vendored
33
.github/workflows/issue-label.yml
vendored
@@ -1,33 +0,0 @@
|
||||
name: Issue labels
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled, reopened, closed, deleted]
|
||||
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_ISSUES_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
labelNotify:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- name: notify on label
|
||||
if: >
|
||||
github.event.label.name == 'enhancement'
|
||||
|| github.event.label.name == 'bug'
|
||||
|| github.event.label.name == 'help wanted'
|
||||
|| github.event.label.name == 'priority/high'
|
||||
|| github.event.label.name == 'question'
|
||||
|| github.event.label.name == 'status/waiting on upstream'
|
||||
uses: Ilshidur/action-discord@master
|
||||
with:
|
||||
args: "[${{ github.event.issue.title }} (#${{ github.event.issue.number }})](<${{ github.event.issue.html_url }}>) added `${{ github.event.label.name }}` label"
|
||||
- name: notify on action change
|
||||
if: >
|
||||
github.event.action == 'closed'
|
||||
|| github.event.action == 'reopened'
|
||||
|| github.event.action == 'deleted'
|
||||
uses: Ilshidur/action-discord@master
|
||||
with:
|
||||
args: "[${{ github.event.issue.title }} (#${{ github.event.issue.number }})](<${{ github.event.issue.html_url }}>) has been `${{ github.event.action }}` by `${{ github.event.sender.login }}`"
|
||||
100
.github/workflows/main.yml
vendored
Normal file
100
.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
name: Build and Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- java8
|
||||
- openj9
|
||||
- openj9-11
|
||||
- adopt11
|
||||
- test/*
|
||||
tags:
|
||||
- "[0-9]+.[0-9]+.[0-9]+-java8"
|
||||
- "[0-9]+.[0-9]+.[0-9]+-openj9"
|
||||
- "[0-9]+.[0-9]+.[0-9]+-openj9-11"
|
||||
- "[0-9]+.[0-9]+.[0-9]+-openj9-nightly"
|
||||
- "[0-9]+.[0-9]+.[0-9]+-adopt11"
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
tests/test.sh
|
||||
build:
|
||||
needs:
|
||||
- test
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
|
||||
- name: Prepare
|
||||
id: prep
|
||||
run: |
|
||||
DOCKER_IMAGE=itzg/minecraft-server
|
||||
VERSION=edge
|
||||
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
fi
|
||||
if [[ $GITHUB_REF == refs/heads/* ]]; then
|
||||
VERSION=${GITHUB_REF#refs/heads/}
|
||||
if [[ $VERSION == master ]]; then
|
||||
VERSION=latest
|
||||
fi
|
||||
fi
|
||||
TAGS="${DOCKER_IMAGE}:${VERSION//\//-}"
|
||||
echo ::set-output name=tags::${TAGS}
|
||||
echo ::set-output name=version::${VERSION//\//-}
|
||||
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v2.1.6
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USER }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build and push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2.6.1
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
# ensure latest base image is used
|
||||
pull: true
|
||||
# publish
|
||||
push: true
|
||||
# tags determined by prep step
|
||||
tags: ${{ steps.prep.outputs.tags }}
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache-new
|
||||
labels: |
|
||||
org.opencontainers.image.documentation=https://github.com/itzg/docker-minecraft-server
|
||||
org.opencontainers.image.version=${{ steps.prep.outputs.version }}
|
||||
org.opencontainers.image.source=https://github.com/itzg/docker-minecraft-server
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
|
||||
- name: Image digest
|
||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
||||
|
||||
- # Temp fix
|
||||
# https://github.com/docker/build-push-action/issues/252
|
||||
# https://github.com/moby/buildkit/issues/1896
|
||||
name: Move cache
|
||||
run: |
|
||||
rm -rf /tmp/.buildx-cache
|
||||
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||
54
.github/workflows/pr.yml
vendored
54
.github/workflows/pr.yml
vendored
@@ -1,64 +1,16 @@
|
||||
name: PullRequest
|
||||
name: Validate PR
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
types: [assigned, opened, synchronize, labeled]
|
||||
paths-ignore:
|
||||
- "*.md"
|
||||
- "docs/**"
|
||||
- "examples/**"
|
||||
|
||||
env:
|
||||
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
|
||||
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64
|
||||
tags: ${{ env.IMAGE_TO_TEST }}
|
||||
load: true
|
||||
cache-from: type=gha
|
||||
- uses: actions/checkout@v2.3.4
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
tests/test.sh
|
||||
|
||||
- name: Gather Docker metadata
|
||||
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: |
|
||||
itzg/minecraft-server
|
||||
|
||||
- name: Login to DockerHub
|
||||
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USER }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Push
|
||||
if: contains(github.event.pull_request.labels.*.name, 'ci/push-image')
|
||||
uses: docker/build-push-action@v2.9.0
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
pull: true
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
25
.github/workflows/stale-check.yml
vendored
25
.github/workflows/stale-check.yml
vendored
@@ -1,25 +0,0 @@
|
||||
name: Stale Check
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: 0 2 * * *
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-20.04
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Process Stale Issues
|
||||
uses: actions/stale@v4.1.0
|
||||
with:
|
||||
stale-issue-label: status/stale
|
||||
stale-pr-label: status/stale
|
||||
stale-issue-message: >
|
||||
This issue is stale because it has been open 30 days with no activity.
|
||||
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'
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,5 +1,4 @@
|
||||
.vscode
|
||||
/data/
|
||||
/.idea/
|
||||
*.iml
|
||||
/gh-md-toc
|
||||
/gh-md-toc
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
Adding a new server `TYPE` can vary due to the complexity of obtaining and configuring each type; however, the addition of any server type includes at least the following steps:
|
||||
|
||||
1. Copy an existing "start-deploy*" script, such as [start-deployMohist](scripts/start-deployMohist) and rename it accordingly making sure to retain the "start-deploy" prefix
|
||||
2. Modify the type-specific behavior between the "start-utils" preamble and the hand-off to `start-setupWorld` at the end of the script
|
||||
1. Copy an existing "start-deploy*" script, such as [start-deployMohist](start-deployMohist) and rename it accordingly making sure to retain the "start-deploy" prefix
|
||||
2. Modify the type-specific behavior between the "start-utils" preamble and the hand-off to `start-finalSetupWorld` at the end of the script
|
||||
3. Develop and test the changes using the [iterative process described below](#iterative-script-development)
|
||||
4. Add a case-entry to the `case "${TYPE^^}"` in [start-configuration](scripts/start-configuration)
|
||||
4. Add a case-entry to the `case "${TYPE^^}"` in [start-configuration](start-configuration)
|
||||
5. Add a section to the [README](README.md). It is recommended to copy-modify an existing section to retain a similar wording and level of detail
|
||||
6. [Submit a pull request](https://github.com/itzg/docker-minecraft-server/pulls)
|
||||
|
||||
@@ -15,28 +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 --remove-orphans
|
||||
popd
|
||||
```
|
||||
|
||||
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 --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.
|
||||
@@ -60,33 +40,35 @@ VANILLA_VERSION=1.12.2 /scripts/start-magma
|
||||
|
||||
> NOTE: You may want to temporarily add an `exit` statement near the end of your script to isolate execution to just the script you're developing.
|
||||
|
||||
## Using development copy of mc-image-helper
|
||||
## Multi-base-image variants
|
||||
|
||||
In the cloned copy of [`mc-image-helper`](https://github.com/itzg/mc-image-helper), create an up-to-date snapshot build of the tgz distribution using:
|
||||
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
|
||||
|
||||
```shell
|
||||
./gradlew distTar
|
||||
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
|
||||
```
|
||||
|
||||
Assuming [http-server](https://www.npmjs.com/package/http-server) is installed globally, start a static web server using:
|
||||
> 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.
|
||||
|
||||
```shell
|
||||
http-server ./build/distributions -p 0
|
||||
```
|
||||
> The build and publishing of those branches and their tags is currently performed within Docker Hub.
|
||||
|
||||
Note the port that was selected by http-server and pass the build arguments, such as:
|
||||
## multiarch support
|
||||
|
||||
```shell
|
||||
--build-arg MC_HELPER_VERSION=1.8.1-SNAPSHOT \
|
||||
--build-arg MC_HELPER_BASE_URL=http://host.docker.internal:8080
|
||||
```
|
||||
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.
|
||||
|
||||
Now the image can be built like normal and it will install mc-image-helper from the locally built copy.
|
||||
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:
|
||||
|
||||
```shell script
|
||||
git log --invert-grep --grep "^ci:" --grep "^misc:" --grep "^docs:" --pretty="* %s" 1.1.0..1.2.0
|
||||
git log --invert-grep --grep "^ci:" --grep "^misc:" --grep "^docs:" --pretty="- %s" 1.1.0..1.2.0
|
||||
```
|
||||
|
||||
80
Dockerfile
80
Dockerfile
@@ -1,18 +1,31 @@
|
||||
# syntax = docker/dockerfile:1.3
|
||||
FROM adoptopenjdk:8-jre-hotspot
|
||||
|
||||
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 \
|
||||
curl wget \
|
||||
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
|
||||
COPY files/sudoers* /etc/sudoers.d
|
||||
|
||||
EXPOSE 25565 25575
|
||||
|
||||
@@ -31,28 +44,26 @@ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=1.5.1 --var app=rcon-cli --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
--var version=1.4.7 --var app=rcon-cli --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=0.10.3 --var app=mc-monitor --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
--var version=0.7.1 --var app=mc-monitor --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=1.8.0 --var app=mc-server-runner --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
--var version=1.6.0 --var app=mc-server-runner --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
|
||||
--var version=0.1.1 --var app=maven-metadata-release --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
--var version=0.1.1 --var app=maven-metadata-release --file {{.app}} \
|
||||
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
|
||||
|
||||
ARG MC_HELPER_VERSION=1.16.6
|
||||
ARG MC_HELPER_BASE_URL=https://github.com/itzg/mc-image-helper/releases/download/v${MC_HELPER_VERSION}
|
||||
RUN curl -fsSL ${MC_HELPER_BASE_URL}/mc-image-helper-${MC_HELPER_VERSION}.tgz \
|
||||
| tar -C /usr/share -zxf - \
|
||||
&& ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/bin/mc-image-helper /usr/bin
|
||||
COPY mcstatus /usr/local/bin
|
||||
|
||||
VOLUME ["/data"]
|
||||
COPY server.properties /tmp/server.properties
|
||||
COPY log4j2.xml /tmp/log4j2.xml
|
||||
WORKDIR /data
|
||||
|
||||
STOPSIGNAL SIGTERM
|
||||
@@ -61,19 +72,18 @@ ENV UID=1000 GID=1000 \
|
||||
MEMORY="1G" \
|
||||
TYPE=VANILLA VERSION=LATEST \
|
||||
ENABLE_RCON=true RCON_PORT=25575 RCON_PASSWORD=minecraft \
|
||||
SERVER_PORT=25565 ONLINE_MODE=TRUE SERVER_NAME="Dedicated Server" \
|
||||
ENABLE_AUTOPAUSE=false AUTOPAUSE_TIMEOUT_EST=3600 AUTOPAUSE_TIMEOUT_KN=120 AUTOPAUSE_TIMEOUT_INIT=600 \
|
||||
AUTOPAUSE_PERIOD=10 AUTOPAUSE_KNOCK_INTERFACE=eth0 \
|
||||
ENABLE_AUTOSTOP=false AUTOSTOP_TIMEOUT_EST=3600 AUTOSTOP_TIMEOUT_INIT=1800 AUTOSTOP_PERIOD=10
|
||||
AUTOPAUSE_PERIOD=10 AUTOPAUSE_KNOCK_INTERFACE=eth0
|
||||
|
||||
COPY --chmod=755 scripts/start* /
|
||||
COPY --chmod=755 bin/ /usr/local/bin/
|
||||
COPY --chmod=755 bin/mc-health /health.sh
|
||||
COPY --chmod=644 files/server.properties /tmp/server.properties
|
||||
COPY --chmod=644 files/log4j2.xml /tmp/log4j2.xml
|
||||
COPY --chmod=755 files/autopause /autopause
|
||||
COPY --chmod=755 files/autostop /autostop
|
||||
COPY start* /
|
||||
COPY health.sh /
|
||||
ADD files/autopause /autopause
|
||||
|
||||
RUN dos2unix /start* && chmod +x /start*
|
||||
RUN dos2unix /health.sh && chmod +x /health.sh
|
||||
RUN dos2unix /autopause/* && chmod +x /autopause/*.sh
|
||||
|
||||
RUN dos2unix /start* /autopause/* /autostop/*
|
||||
|
||||
ENTRYPOINT [ "/start" ]
|
||||
HEALTHCHECK --start-period=1m CMD mc-health
|
||||
HEALTHCHECK --start-period=1m CMD /health.sh
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
: "${CONSOLE_IN_NAMED_PIPE:=/tmp/minecraft-console-in}"
|
||||
|
||||
if [ $# = 0 ]; then
|
||||
echo "ERROR: pass console commands as arguments"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -p "${CONSOLE_IN_NAMED_PIPE}" ]; then
|
||||
echo "ERROR: named pipe ${CONSOLE_IN_NAMED_PIPE} is missing"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
gosu minecraft bash -c "echo $* > '${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}'"
|
||||
@@ -1,27 +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 \
|
||||
ttf-dejavu \
|
||||
tar \
|
||||
zstd
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
addgroup -g 1000 minecraft
|
||||
adduser -Ss /bin/false -u 1000 -G minecraft -h /home/minecraft minecraft
|
||||
@@ -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
|
||||
@@ -1,28 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
apt-get update
|
||||
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
apt-get install -y \
|
||||
imagemagick \
|
||||
file \
|
||||
gosu \
|
||||
sudo \
|
||||
net-tools \
|
||||
iputils-ping \
|
||||
curl \
|
||||
git \
|
||||
jq \
|
||||
dos2unix \
|
||||
mysql-client \
|
||||
tzdata \
|
||||
rsync \
|
||||
nano \
|
||||
unzip \
|
||||
zstd \
|
||||
knockd \
|
||||
ttf-dejavu
|
||||
|
||||
apt-get clean
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
addgroup --gid 1000 minecraft
|
||||
adduser --system --shell /bin/false --uid 1000 --ingroup minecraft --home /data minecraft
|
||||
133
docker-versions-create.sh
Executable file
133
docker-versions-create.sh
Executable file
@@ -0,0 +1,133 @@
|
||||
#!/bin/bash
|
||||
#set -x
|
||||
# Use this variable to indicate a list of branches that docker hub is watching
|
||||
branches_list=(
|
||||
'java8'
|
||||
'java8-multiarch'
|
||||
'java8-openj9'
|
||||
'java11'
|
||||
'java11-openj9'
|
||||
'java16'
|
||||
'java16-openj9'
|
||||
'multiarch-latest'
|
||||
)
|
||||
|
||||
function TrapExit {
|
||||
echo "Checking out back in master"
|
||||
git checkout master
|
||||
}
|
||||
|
||||
batchMode=false
|
||||
|
||||
while getopts "hbt:s" arg
|
||||
do
|
||||
case $arg in
|
||||
b)
|
||||
batchMode=true
|
||||
;;
|
||||
t)
|
||||
tag=${OPTARG}
|
||||
;;
|
||||
s)
|
||||
tagArgs="-s -m 'Signed during docker-versions-create"
|
||||
;;
|
||||
h)
|
||||
echo "
|
||||
Usage $0 [options]
|
||||
|
||||
Options:
|
||||
-b enable batch mode, which avoids interactive prompts and causes script to fail immediately
|
||||
when any merge fails
|
||||
-t TAG tag and push the current revision on master with the given tag
|
||||
and apply respective tags to each branch
|
||||
-s enable signed tags
|
||||
-h display this help and exit
|
||||
"
|
||||
exit
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported arg $arg"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
${batchMode} && echo "Using batch mode"
|
||||
|
||||
trap TrapExit EXIT SIGTERM
|
||||
|
||||
test -d ./.git || { echo ".git folder was not found. Please start this script from root directory of the project!";
|
||||
exit 1; }
|
||||
|
||||
# Making sure we are in master
|
||||
git checkout master
|
||||
git pull --all || { echo "Can't pull the repo!"; \
|
||||
exit 1; }
|
||||
if [[ $tag ]]; then
|
||||
git tag $tag
|
||||
git push origin $tag
|
||||
fi
|
||||
|
||||
git_branches=$(git branch -a)
|
||||
|
||||
for branch in "${branches_list[@]}"; do
|
||||
if [[ "$git_branches" != *"$branch"* ]]; then
|
||||
echo "Can't update $branch because I can't find it in the list of branches."
|
||||
exit 1
|
||||
else
|
||||
echo "Branch $branch found. Working with it."
|
||||
git checkout "$branch" || { echo "Can't checkout into the branch. Don't know the cause."; \
|
||||
exit 1; }
|
||||
proceed='False'
|
||||
while [[ "$proceed" == "False" ]]; do
|
||||
# Ensure local branch is aligned with remote since docker-versions-create may have been run elsewhere
|
||||
git pull
|
||||
|
||||
if git merge -m 'Auto-merging via docker-versions-create' master; then
|
||||
proceed="True"
|
||||
echo "Branch $branch updated to current master successfully"
|
||||
# pushing changes to remote for this branch
|
||||
git commit -m "Auto merge branch with master" -a
|
||||
# push may fail if remote doesn't have this branch yet. In this case - sending branch
|
||||
git push || git push -u origin "$branch" || { echo "Can't push changes to the origin."; exit 1; }
|
||||
if [[ $tag ]]; then
|
||||
git tag "$tag-$branch"
|
||||
git push origin "$tag-$branch"
|
||||
fi
|
||||
elif ${batchMode}; then
|
||||
status=$?
|
||||
echo "Git merge failed in batch mode"
|
||||
exit ${status}
|
||||
# and trap exit gets us back to master
|
||||
else
|
||||
cat<<EOL
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
Master merge in the branch $branch encountered an error!
|
||||
You may try to fix the error and merge again. (Commit changes)
|
||||
Or skip this branch merge completely.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
EOL
|
||||
printf "Should we try again? (y):"
|
||||
read -r answer
|
||||
if [[ "$answer" == '' ]] || [[ "$answer" == 'y' ]] || [[ "$answer" == 'Y' ]]; then
|
||||
# If you use non-local editor or files are changed in repo
|
||||
cat <<EOL
|
||||
|
||||
The following commands may encounter an error!
|
||||
This is completely fine if the changes were made locally and remote branch doesn't know about them.
|
||||
|
||||
EOL
|
||||
# Updating branch from remote before trying again
|
||||
git checkout master
|
||||
git fetch --all
|
||||
git pull -a
|
||||
git checkout "$branch"
|
||||
continue
|
||||
else
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
done
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 985 B |
1
examples/.gitignore
vendored
1
examples/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/data/
|
||||
@@ -12,10 +12,7 @@ services:
|
||||
ENABLE_AUTOPAUSE: "TRUE"
|
||||
OVERRIDE_SERVER_PROPERTIES: "TRUE"
|
||||
MAX_TICK_TIME: "-1"
|
||||
# More aggressive settings for demo purposes
|
||||
AUTOPAUSE_TIMEOUT_INIT: "30"
|
||||
AUTOPAUSE_TIMEOUT_EST: "10"
|
||||
restart: unless-stopped
|
||||
restart: always
|
||||
|
||||
volumes:
|
||||
mc: {}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
minecraft:
|
||||
image: itzg/minecraft-server
|
||||
ports:
|
||||
- "25565:25565"
|
||||
volumes:
|
||||
- "mc:/data"
|
||||
environment:
|
||||
EULA: "TRUE"
|
||||
ENABLE_AUTOSTOP: "TRUE"
|
||||
# More aggressive settings for demo purposes
|
||||
AUTOSTOP_TIMEOUT_INIT: "30"
|
||||
AUTOSTOP_TIMEOUT_EST: "20"
|
||||
# Important not to auto-restart the server!!!
|
||||
restart: "no"
|
||||
|
||||
volumes:
|
||||
mc: {}
|
||||
@@ -2,18 +2,12 @@ version: '3.8'
|
||||
|
||||
services:
|
||||
mc:
|
||||
image: itzg/minecraft-server:${IMAGE_TAG:-java8}
|
||||
image: itzg/minecraft-server:java8
|
||||
volumes:
|
||||
- ./modpacks:/modpacks:ro
|
||||
- data:/data
|
||||
environment:
|
||||
EULA: "true"
|
||||
TYPE: CURSEFORGE
|
||||
CF_SERVER_MOD: https://media.forgecdn.net/files/3482/169/Valhelsia+3-3.4.4-SERVER.zip
|
||||
# CF_SERVER_MOD: https://media.forgecdn.net/files/3012/800/SkyFactory-4_Server_4.2.2.zip
|
||||
# CF_SERVER_MOD: /modpacks/${MODPACK:-SkyFactory_4_Server_4.1.0.zip}
|
||||
CF_SERVER_MOD: /modpacks/SkyFactory_4_Server_4.1.0.zip
|
||||
ports:
|
||||
- "25565:25565"
|
||||
|
||||
volumes:
|
||||
data: {}
|
||||
- 25565:25565
|
||||
|
||||
@@ -2,16 +2,15 @@ version: "3.8"
|
||||
|
||||
services:
|
||||
mc:
|
||||
image: itzg/minecraft-server
|
||||
image: itzg/minecraft-server:java8
|
||||
ports:
|
||||
# expose the Minecraft server port outside of container
|
||||
- "25565:25565"
|
||||
- 25565:25565
|
||||
environment:
|
||||
# REQUIRED for all types
|
||||
EULA: "TRUE"
|
||||
# Set server type (vs the default of vanilla)
|
||||
TYPE: FORGE
|
||||
DEBUG: "true"
|
||||
volumes:
|
||||
# use a named, managed volume for data volume
|
||||
- mc_forge:/data
|
||||
|
||||
@@ -3,7 +3,7 @@ version: "3.8"
|
||||
services:
|
||||
mc:
|
||||
# FTBA support is only available in non-Alpine images
|
||||
image: itzg/minecraft-server:${IMAGE_TAG:-java8-multiarch}
|
||||
image: itzg/minecraft-server:java8-multiarch
|
||||
ports:
|
||||
# expose the Minecraft server port outside of container
|
||||
- 25565:25565
|
||||
@@ -14,11 +14,10 @@ services:
|
||||
TYPE: FTBA
|
||||
# Use Pack ID from https://ftb.neptunepowered.org/pack/ftb-presents-direwolf20-1-12/
|
||||
FTB_MODPACK_ID: "31"
|
||||
FTB_MODPACK_VERSION_ID: ""
|
||||
volumes:
|
||||
# use a named, managed volume for data volume
|
||||
- ftba:/data
|
||||
- mc_ftb:/data
|
||||
|
||||
volumes:
|
||||
# declared the named volume, but use default/local storage engine
|
||||
ftba: {}
|
||||
mc_ftb: {}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
mc:
|
||||
image: itzg/minecraft-server:${IMAGE_TAG:-latest}
|
||||
volumes:
|
||||
- data:/data
|
||||
- ./modpacks:/modpacks:ro
|
||||
environment:
|
||||
EULA: "true"
|
||||
TYPE: FORGE
|
||||
DEBUG: "${DEBUG:-false}"
|
||||
VERSION: ${VERSION:-1.17.1}
|
||||
FORGEVERSION: ${FORGEVERSION:-37.0.90}
|
||||
GENERIC_PACK: /modpacks/${MODPACK:-Server-Files-0.0.21.zip}
|
||||
REMOVE_OLD_MODS: "${REMOVE_OLD_MODS:-false}"
|
||||
ports:
|
||||
- "25565:25565"
|
||||
|
||||
volumes:
|
||||
data: {}
|
||||
@@ -1,19 +0,0 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
mc:
|
||||
image: itzg/minecraft-server
|
||||
environment:
|
||||
EULA: "true"
|
||||
TYPE: FORGE
|
||||
VERSION: 1.15.2
|
||||
MODS_FILE: /extras/mods.txt
|
||||
REMOVE_OLD_MODS: "true"
|
||||
ports:
|
||||
- 25565:25565
|
||||
volumes:
|
||||
- data:/data
|
||||
- ./mods.txt:/extras/mods.txt:ro
|
||||
|
||||
volumes:
|
||||
data:
|
||||
@@ -1,17 +0,0 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
mc:
|
||||
image: itzg/minecraft-server
|
||||
ports:
|
||||
- "25565:25565"
|
||||
environment:
|
||||
EULA: "TRUE"
|
||||
TYPE: MOHIST
|
||||
VERSION: 1.12.2
|
||||
DEBUG: "true"
|
||||
volumes:
|
||||
- data:/data
|
||||
|
||||
volumes:
|
||||
data: {}
|
||||
@@ -1,19 +1,18 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
mc:
|
||||
image: itzg/minecraft-server
|
||||
container_name: paper
|
||||
environment:
|
||||
EULA: "true"
|
||||
ENABLE_RCON: "true"
|
||||
TYPE: PAPER
|
||||
VIEW_DISTANCE: 10
|
||||
MEMORY: 2G
|
||||
VERSION: 1.9.4
|
||||
# needed for Paper versions before 1.14
|
||||
CONSOLE: "false"
|
||||
ports:
|
||||
- 25565:25565
|
||||
volumes:
|
||||
- mc-paper:/data
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
mc-paper:
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
rlcraft:
|
||||
image: itzg/minecraft-server:java8
|
||||
container_name: rlcraft
|
||||
volumes:
|
||||
- rlcraft-modpack:/modpacks:ro
|
||||
- rlcraft-data:/data
|
||||
environment:
|
||||
EULA: "true"
|
||||
TYPE: "FORGE"
|
||||
VERSION: "1.12.2"
|
||||
FORGEVERSION: "14.23.5.2855"
|
||||
DIFFICULTY: "hard"
|
||||
MAX_TICK_TIME: "-1"
|
||||
VIEW_DISTANCE: "6"
|
||||
ALLOW_FLIGHT: "true"
|
||||
MEMORY: "4G"
|
||||
GENERIC_PACK: "/modpacks/RLCraft_Server_Pack_1.12.2_Beta_v2.8.2.zip"
|
||||
ports:
|
||||
- 25565:25565
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
rlcraft-data:
|
||||
rlcraft-modpack:
|
||||
@@ -3,18 +3,18 @@ apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
labels:
|
||||
app: mc-example
|
||||
name: mc-example
|
||||
app: example
|
||||
name: example
|
||||
spec:
|
||||
replicas: 1
|
||||
serviceName: mc-example
|
||||
serviceName: example
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mc-example
|
||||
app: example
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mc-example
|
||||
app: example
|
||||
spec:
|
||||
containers:
|
||||
- name: mc
|
||||
@@ -25,18 +25,6 @@ spec:
|
||||
volumeMounts:
|
||||
- mountPath: /data
|
||||
name: data
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- mc-monitor
|
||||
- status
|
||||
- --host
|
||||
- localhost
|
||||
- --port
|
||||
- "25565"
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 5
|
||||
failureThreshold: 18
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: data
|
||||
@@ -51,12 +39,12 @@ apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
service: mc-example
|
||||
name: mc-example
|
||||
service: example
|
||||
name: example
|
||||
spec:
|
||||
ports:
|
||||
- port: 25565
|
||||
targetPort: 25565
|
||||
selector:
|
||||
app: mc-example
|
||||
type: NodePort
|
||||
app: example
|
||||
type: LoadBalancer
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
https://edge.forgecdn.net/files/2965/233/Bookshelf-1.15.2-5.6.40.jar
|
||||
https://edge.forgecdn.net/files/2926/27/ProgressiveBosses-2.1.5-mc1.15.2.jar
|
||||
https://edge.forgecdn.net/files/3248/905/goblintraders-1.3.1-1.15.2.jar
|
||||
https://edge.forgecdn.net/files/3272/32/jei-1.15.2-6.0.3.16.jar
|
||||
https://edge.forgecdn.net/files/2871/647/ToastControl-1.15.2-3.0.1.jar
|
||||
https://edge.forgecdn.net/files/3101/903/Druidcraft-1.15-0.4.45.jar
|
||||
https://edge.forgecdn.net/files/2880/426/DefaultOptions_1.15.2-11.0.1.jar
|
||||
https://edge.forgecdn.net/files/2996/535/MekanismAdditions-1.15.2-9.10.9.422.jar
|
||||
https://edge.forgecdn.net/files/3147/275/blockcarpentry-1.15-0.8.2.jar
|
||||
https://edge.forgecdn.net/files/3005/715/refinedstorageaddons-0.6.3.jar
|
||||
https://edge.forgecdn.net/files/3140/146/rftoolsbase-1.15-1.1.10.jar
|
||||
https://edge.forgecdn.net/files/3236/649/cc-tweaked-1.15.2-1.95.3.jar
|
||||
https://edge.forgecdn.net/files/3048/970/light-overlay-4.7.2.jar
|
||||
https://edge.forgecdn.net/files/3015/904/randompatches-1.15.2-1.22.1.1.jar
|
||||
https://edge.forgecdn.net/files/3131/439/engineersdecor-1.15.2-1.1.4.jar
|
||||
https://edge.forgecdn.net/files/3051/255/carryon-1.15.2-1.13.0.5.jar
|
||||
https://edge.forgecdn.net/files/3175/752/EnderStorage-1.15.2-2.5.2.164-universal.jar
|
||||
https://edge.forgecdn.net/files/2997/84/Savage-and-Ravage-1.15.2-1.1.4.jar
|
||||
https://edge.forgecdn.net/files/3053/840/PackMenu-1.15.2-1.2.8.jar
|
||||
https://edge.forgecdn.net/files/3003/397/JEITweaker-1.15.2-1.0.1.3.jar
|
||||
https://edge.forgecdn.net/files/3069/489/absentbydesign-1.15.2-1.1.1.jar
|
||||
https://edge.forgecdn.net/files/2997/601/Upgrade-Aquatic-1.15.2-1.7.1.jar
|
||||
https://edge.forgecdn.net/files/2950/766/ReAuth-1.14-1.15-3.8.1.jar
|
||||
https://edge.forgecdn.net/files/3024/179/Powah-1.15.2-1.1.15.jar
|
||||
https://edge.forgecdn.net/files/3092/975/StorageDrawers-1.15.2-7.0.3.jar
|
||||
https://edge.forgecdn.net/files/2853/267/furniture-7.0.0-pre16-1.15.1.jar
|
||||
https://edge.forgecdn.net/files/2987/251/AppleSkin-mc1.15.2-forge-1.0.14.jar
|
||||
https://edge.forgecdn.net/files/2980/323/industrial-foregoing-1.15.2-2.3.3-e356e61.jar
|
||||
https://edge.forgecdn.net/files/3024/178/Lollipop-1.15.2-1.0.16.jar
|
||||
https://edge.forgecdn.net/files/3210/106/tablechair-1.4.jar
|
||||
https://edge.forgecdn.net/files/3047/358/xercapaint-1.15.2-3.3.jar
|
||||
https://edge.forgecdn.net/files/2873/657/BonsaiTrees-2.1.2.6.jar
|
||||
https://edge.forgecdn.net/files/2938/583/config-2-3.0.jar
|
||||
https://edge.forgecdn.net/files/2991/235/Waystones_1.15.2-6.0.2.jar
|
||||
https://edge.forgecdn.net/files/2957/23/OpenLoader-1.15.2-4.0.5.jar
|
||||
https://edge.forgecdn.net/files/3275/718/XaerosWorldMap_1.13.2_Forge_1.15.2.jar
|
||||
https://edge.forgecdn.net/files/2876/104/AI-Improvements-1.15.2-0.3.0.jar
|
||||
https://edge.forgecdn.net/files/3005/515/mysticallib-1.15.2-2.0.1.jar
|
||||
https://edge.forgecdn.net/files/3008/867/WAWLA-1.15.2-3.0.4.jar
|
||||
https://edge.forgecdn.net/files/2964/474/WailaHarvestability-mc1.15.2-1.1.12.jar
|
||||
https://edge.forgecdn.net/files/3103/508/Kiwi-1.15.2-2.8.5.jar
|
||||
https://edge.forgecdn.net/files/3128/662/Atum-1.15.2-2.1.12.jar
|
||||
https://edge.forgecdn.net/files/2988/910/Buzzier-Bees-1.15.2-1.5.2.jar
|
||||
https://edge.forgecdn.net/files/3030/627/u_team_core-1.15.2-3.0.2.169.jar
|
||||
https://edge.forgecdn.net/files/3003/984/SilentLib-1.15.2-4.6.6+59.jar
|
||||
https://edge.forgecdn.net/files/2968/353/refinedpipes-0.4.2.jar
|
||||
https://edge.forgecdn.net/files/3140/149/rftoolsbuilder-1.15-2.1.16.jar
|
||||
https://edge.forgecdn.net/files/3067/203/mightyarchitect-mc1.15.2_v0.5.jar
|
||||
https://edge.forgecdn.net/files/2980/153/EquipmentTooltips-1.15.2-1.4.3+14.jar
|
||||
https://edge.forgecdn.net/files/3103/510/FruitTrees-1.15.2-1.7.0.jar
|
||||
https://edge.forgecdn.net/files/2989/38/Atmospheric-1.15.2-1.4.1.jar
|
||||
https://edge.forgecdn.net/files/3096/836/rftoolscontrol-1.15-3.0.9.jar
|
||||
https://edge.forgecdn.net/files/2989/662/Enhanced-Mushrooms-1.15.2-v1.2.2.jar
|
||||
https://edge.forgecdn.net/files/3227/891/SimpleStorageNetwork-1.15.2-1.0.2.jar
|
||||
https://edge.forgecdn.net/files/3217/290/minecolonies-0.13.645-RELEASE-universal.jar
|
||||
https://edge.forgecdn.net/files/2935/384/SnowRealMagic-1.15.2-1.7.5.jar
|
||||
https://edge.forgecdn.net/files/2988/584/aiotbotania-1.15.2-1.2.3.jar
|
||||
https://edge.forgecdn.net/files/3255/408/mowziesmobs-1.5.15.jar
|
||||
https://edge.forgecdn.net/files/3062/510/HealthOverlay-1.15.2-1.0.2.jar
|
||||
https://edge.forgecdn.net/files/3023/121/neoncraft-1.1.jar
|
||||
https://edge.forgecdn.net/files/2997/617/Swamp-Expansion-1.15.2-1.7.3.jar
|
||||
https://edge.forgecdn.net/files/2980/252/titanium-1.15.2-2.4.2.jar
|
||||
https://edge.forgecdn.net/files/3152/946/rftoolsutility-1.15-2.1.20.jar
|
||||
https://edge.forgecdn.net/files/3083/277/swingthroughgrass-1.15.2-1.4.1.jar
|
||||
https://edge.forgecdn.net/files/3138/530/SilentGear-1.15.2-1.11.4+187.jar
|
||||
https://edge.forgecdn.net/files/3105/429/DarkUtilities-1.15.2-3.1.9.jar
|
||||
https://edge.forgecdn.net/files/3099/23/ImmersiveEngineering-1.15.2-4.1.1-125.jar
|
||||
https://edge.forgecdn.net/files/2856/529/FastFurnace-1.15.1-3.0.0.jar
|
||||
https://edge.forgecdn.net/files/2988/999/BiomesOPlenty-1.15.2-10.0.0.366-universal.jar
|
||||
https://edge.forgecdn.net/files/2989/95/The-Endergetic-Expansion-1.15.2-v1.3.2.jar
|
||||
https://edge.forgecdn.net/files/2993/960/FluxNetworks-1.15.2-5.0.3-4.jar
|
||||
https://edge.forgecdn.net/files/3028/611/ServerTabInfo-1.15.2-1.2.8.jar
|
||||
https://edge.forgecdn.net/files/3134/277/fairylights-3.0.15-1.15.2.jar
|
||||
https://edge.forgecdn.net/files/3048/54/useful_backpacks-1.15.2-1.10.3.77.jar
|
||||
https://edge.forgecdn.net/files/3273/515/mcw-trapdoors-1.0.2-mc1.15.2.jar
|
||||
https://edge.forgecdn.net/files/2986/639/CraftingTweaks_1.15.2-11.0.1.jar
|
||||
https://edge.forgecdn.net/files/3261/454/create-mc1.15.2_v0.3.1a.jar
|
||||
https://edge.forgecdn.net/files/3211/10/supermartijn642configlib-1.0.5-mc1.15.jar
|
||||
https://edge.forgecdn.net/files/2995/786/TerraForged-1.15.2-0.0.15.jar
|
||||
https://edge.forgecdn.net/files/2892/562/leavesdecayonotherleaves-1.1.jar
|
||||
@@ -1,27 +0,0 @@
|
||||
version: "3.3"
|
||||
|
||||
services:
|
||||
vanillatweaks_file:
|
||||
restart: "no"
|
||||
image: itzg/minecraft-server
|
||||
ports:
|
||||
- "25565:25565/tcp"
|
||||
environment:
|
||||
EULA: "TRUE"
|
||||
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||
VANILLATWEAKS_FILE: /config/vanillatweaks-datapacks.json
|
||||
REMOVE_OLD_VANILLATWEAKS: "TRUE"
|
||||
volumes:
|
||||
- data:/data
|
||||
- ./vanillatweaks-datapacks.json:/config/vanillatweaks-datapacks.json:ro
|
||||
vanillatweaks_sharecode:
|
||||
# port is set to 25566 to not conflict with vanillatweaks_file example
|
||||
ports:
|
||||
- "25566:25565/tcp"
|
||||
restart: "no"
|
||||
image: itzg/minecraft-server
|
||||
environment:
|
||||
EULA: "TRUE"
|
||||
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||
VANILLATWEAKS_SHARECODE: MGr52E
|
||||
REMOVE_OLD_VANILLATWEAKS: "TRUE"
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"version": "1.18",
|
||||
"packs": {
|
||||
"survival": [
|
||||
"graves",
|
||||
"multiplayer sleep",
|
||||
"afk display",
|
||||
"armor statues",
|
||||
"unlock all recipes",
|
||||
"fast leaf decay",
|
||||
"coordinates hud"
|
||||
],
|
||||
"items": ["armored elytra"]
|
||||
}
|
||||
}
|
||||
0
files/autopause/autopause-daemon.sh
Executable file → Normal file
0
files/autopause/autopause-daemon.sh
Executable file → Normal file
25
files/autopause/autopause-fcns.sh
Executable file → Normal file
25
files/autopause/autopause-fcns.sh
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
current_uptime() {
|
||||
awk '{print $1}' /proc/uptime | cut -d . -f 1
|
||||
echo $(awk '{print $1}' /proc/uptime | cut -d . -f 1)
|
||||
}
|
||||
|
||||
java_running() {
|
||||
@@ -17,15 +17,26 @@ rcon_client_exists() {
|
||||
}
|
||||
|
||||
mc_server_listening() {
|
||||
mc-monitor status --host localhost --port "$SERVER_PORT" --timeout 10s >& /dev/null
|
||||
[[ -n $(netstat -tln | grep -e "0.0.0.0:$SERVER_PORT" -e ":::$SERVER_PORT" | grep LISTEN) ]]
|
||||
}
|
||||
|
||||
java_clients_connected() {
|
||||
local connections
|
||||
if java_running ; then
|
||||
connections=$(mc-monitor status --host localhost --port "$SERVER_PORT" --show-player-count)
|
||||
else
|
||||
connections=0
|
||||
connections=$(netstat -tn | grep ":$SERVER_PORT" | grep ESTABLISHED)
|
||||
if [[ -z "$connections" ]] ; then
|
||||
return 1
|
||||
fi
|
||||
(( connections > 0 ))
|
||||
IFS=$'\n'
|
||||
connections=($connections)
|
||||
unset IFS
|
||||
# check that at least one external address is not localhost
|
||||
# remember, that the host network mode does not work with autopause because of the knockd utility
|
||||
for (( i=0; i<${#connections[@]}; i++ ))
|
||||
do
|
||||
if [[ ! $(echo "${connections[$i]}" | awk '{print $5}') =~ ^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$ ]] ; then
|
||||
# not localhost
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -10,6 +10,3 @@
|
||||
seq_timeout = 1
|
||||
command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh
|
||||
tcpflags = syn
|
||||
[unpauseMCServer-bedrock]
|
||||
sequence = 19132:udp
|
||||
command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# needed for the clients connected function residing in autopause
|
||||
. /autopause/autopause-fcns.sh
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
|
||||
# wait for java process to be started
|
||||
while :
|
||||
do
|
||||
if java_process_exists ; then
|
||||
break
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
STATE=INIT
|
||||
|
||||
while :
|
||||
do
|
||||
case X$STATE in
|
||||
XINIT)
|
||||
# Server startup
|
||||
if mc_server_listening ; then
|
||||
TIME_THRESH=$(($(current_uptime)+$AUTOSTOP_TIMEOUT_INIT))
|
||||
logAutostop "MC Server listening for connections - stopping in $AUTOSTOP_TIMEOUT_INIT seconds"
|
||||
STATE=II
|
||||
fi
|
||||
;;
|
||||
XII)
|
||||
# Initial idle
|
||||
if java_clients_connected ; then
|
||||
logAutostop "Client connected - waiting for disconnect"
|
||||
STATE=E
|
||||
else
|
||||
if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then
|
||||
logAutostop "No client connected since startup - stopping server"
|
||||
/autostop/stop.sh
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
XE)
|
||||
# Established
|
||||
if ! java_clients_connected ; then
|
||||
TIME_THRESH=$(($(current_uptime)+$AUTOSTOP_TIMEOUT_EST))
|
||||
logAutostop "All clients disconnected - stopping in $AUTOSTOP_TIMEOUT_EST seconds"
|
||||
STATE=I
|
||||
fi
|
||||
;;
|
||||
XI)
|
||||
# Idle
|
||||
if java_clients_connected ; then
|
||||
logAutostop "Client reconnected - waiting for disconnect"
|
||||
STATE=E
|
||||
else
|
||||
if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then
|
||||
logAutostop "No client reconnected - stopping"
|
||||
/autostop/stop.sh
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
logAutostop "Error: invalid state: $STATE"
|
||||
;;
|
||||
esac
|
||||
sleep $AUTOSTOP_PERIOD
|
||||
done
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
. /start-utils
|
||||
|
||||
logAutostopAction "Stopping Java process"
|
||||
kill -SIGTERM 1
|
||||
8
bin/mc-health → health.sh
Executable file → Normal file
8
bin/mc-health → health.sh
Executable file → Normal file
@@ -1,10 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck source=../scripts/start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
if [ -f /data/.mc-health.env ]; then
|
||||
. /data/.mc-health.env
|
||||
fi
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
|
||||
if isTrue "${DISABLE_HEALTHCHECK}"; then
|
||||
echo "Healthcheck disabled"
|
||||
@@ -13,6 +9,6 @@ elif isTrue "${ENABLE_AUTOPAUSE}" && [[ "$( ps -ax -o stat,comm | grep 'java' |
|
||||
echo "Java process suspended by Autopause function"
|
||||
exit 0
|
||||
else
|
||||
mc-monitor status "${MC_HEALTH_EXTRA_ARGS[@]}" --host localhost --port "${SERVER_PORT:-25565}"
|
||||
mc-monitor status --host localhost --port $SERVER_PORT
|
||||
exit $?
|
||||
fi
|
||||
@@ -4,7 +4,7 @@
|
||||
<Console name="SysOut" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
||||
</Console>
|
||||
<Queue name="TerminalConsole">
|
||||
<Queue name="ServerGuiConsole">
|
||||
<PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg%n" />
|
||||
</Queue>
|
||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
||||
@@ -28,7 +28,7 @@
|
||||
</filters>
|
||||
<AppenderRef ref="SysOut"/>
|
||||
<AppenderRef ref="File"/>
|
||||
<AppenderRef ref="TerminalConsole"/>
|
||||
<AppenderRef ref="ServerGuiConsole"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
4
minecraft-server/README.md
Normal file
4
minecraft-server/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# Moved to top-level
|
||||
|
||||
The contents of this directory have now been moved to the top level of
|
||||
[itzg/docker-minecraft-server](https://github.com/itzg/docker-minecraft-server).
|
||||
@@ -1,34 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
|
||||
: "${SERVER_PORT:=25565}"
|
||||
export SERVER_PORT
|
||||
|
||||
log "Autostop functionality enabled"
|
||||
|
||||
isDebugging && set -x
|
||||
|
||||
if ! [[ $AUTOSTOP_PERIOD =~ ^[0-9]+$ ]]; then
|
||||
AUTOSTOP_PERIOD=10
|
||||
export AUTOSTOP_PERIOD
|
||||
log "Warning: AUTOSTOP_PERIOD is not numeric, set to 10 (seconds)"
|
||||
fi
|
||||
if [ "$AUTOSTOP_PERIOD" -eq "0" ] ; then
|
||||
AUTOSTOP_PERIOD=10
|
||||
export AUTOSTOP_PERIOD
|
||||
log "Warning: AUTOSTOP_PERIOD must not be 0, set to 10 (seconds)"
|
||||
fi
|
||||
if ! [[ $AUTOSTOP_TIMEOUT_EST =~ ^[0-9]+$ ]] ; then
|
||||
AUTOSTOP_TIMEOUT_EST=3600
|
||||
export AUTOSTOP_TIMEOUT_EST
|
||||
log "Warning: AUTOSTOP_TIMEOUT_EST is not numeric, set to 3600 (seconds)"
|
||||
fi
|
||||
if ! [[ $AUTOSTOP_TIMEOUT_INIT =~ ^[0-9]+$ ]] ; then
|
||||
AUTOSTOP_TIMEOUT_INIT=1800
|
||||
export AUTOSTOP_TIMEOUT_INIT
|
||||
log "Warning: AUTOSTOP_TIMEOUT_INIT is not numeric, set to 1800 (seconds)"
|
||||
fi
|
||||
|
||||
/autostop/autostop-daemon.sh &
|
||||
@@ -1,214 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
|
||||
: "${EULA:=}"
|
||||
: "${PROXY:=}"
|
||||
: "${RCON_PASSWORD_FILE:=}"
|
||||
|
||||
shopt -s nullglob
|
||||
|
||||
isDebugging && set -x
|
||||
|
||||
#umask 002
|
||||
export HOME=/data
|
||||
|
||||
log "Running as uid=$(id -u) gid=$(id -g) with /data as '$(ls -lnd /data)'"
|
||||
|
||||
if [ ! -e /data/eula.txt ]; then
|
||||
if ! isTrue "$EULA"; then
|
||||
log ""
|
||||
log "Please accept the Minecraft EULA at"
|
||||
log " https://account.mojang.com/documents/minecraft_eula"
|
||||
log "by adding the following immediately after 'docker run':"
|
||||
log " -e EULA=TRUE"
|
||||
log ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
writeEula
|
||||
fi
|
||||
|
||||
if isTrue "${ENABLE_AUTOPAUSE}" && isTrue "${EXEC_DIRECTLY:-false}"; then
|
||||
log "EXEC_DIRECTLY=true is incompatible with ENABLE_AUTOPAUSE=true"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if isTrue "${ENABLE_AUTOPAUSE}" && isTrue "${ENABLE_AUTOSTOP}"; then
|
||||
log "ENABLE_AUTOPAUSE=true is incompatible with ENABLE_AUTOSTOP=true"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $PROXY ]]; then
|
||||
export http_proxy="$PROXY"
|
||||
export https_proxy="$PROXY"
|
||||
export JAVA_TOOL_OPTIONS+="-Djava.net.useSystemProxies=true"
|
||||
log "INFO: Giving proxy time to startup..."
|
||||
sleep 5
|
||||
fi
|
||||
|
||||
if [[ $RCON_PASSWORD_FILE ]]; then
|
||||
log ""
|
||||
if [ ! -e ${RCON_PASSWORD_FILE} ]; then
|
||||
log "Initial RCON password file ${RCON_PASSWORD_FILE} does not seems to exist."
|
||||
log "Please ensure your configuration."
|
||||
log "If you are using Docker Secrets feature, please check this for further information: "
|
||||
log " https://docs.docker.com/engine/swarm/secrets"
|
||||
log ""
|
||||
exit 1
|
||||
else
|
||||
RCON_PASSWORD=$(cat ${RCON_PASSWORD_FILE})
|
||||
export RCON_PASSWORD
|
||||
fi
|
||||
log ""
|
||||
fi
|
||||
|
||||
# Some Docker management UIs grab all the image declared variables and present them for configuration.
|
||||
# When upgrading images across Java versions, that creates a mismatch in PATH's expected by base image.
|
||||
if ! which java > /dev/null; then
|
||||
log "ERROR: PATH should not be explicitly passed into the container"
|
||||
log " Remove configuration of that variable."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export VERSIONS_JSON=https://launchermeta.mojang.com/mc/game/version_manifest.json
|
||||
|
||||
case "X$VERSION" in
|
||||
X|XLATEST|Xlatest)
|
||||
if ! VANILLA_VERSION=$(get --json-path '$.latest.release' "$VERSIONS_JSON"); then
|
||||
log "ERROR: version lookup failed: $VANILLA_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
XSNAPSHOT|Xsnapshot)
|
||||
if ! VANILLA_VERSION=$(get --json-path '$.latest.snapshot' "$VERSIONS_JSON"); then
|
||||
log "ERROR: version lookup failed: $VANILLA_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
VANILLA_VERSION=$VERSION
|
||||
;;
|
||||
esac
|
||||
export VANILLA_VERSION
|
||||
log "Resolved version given ${VERSION} into ${VANILLA_VERSION}"
|
||||
|
||||
cd /data || exit 1
|
||||
|
||||
export ORIGINAL_TYPE=${TYPE^^}
|
||||
|
||||
if isTrue "${ENABLE_AUTOPAUSE}"; then
|
||||
${SCRIPTS:-/}start-autopause
|
||||
fi
|
||||
|
||||
if isTrue "${ENABLE_AUTOSTOP}"; then
|
||||
${SCRIPTS:-/}start-autostop
|
||||
fi
|
||||
|
||||
if versionLessThan 1.7; then
|
||||
echo "
|
||||
MC_HEALTH_EXTRA_ARGS=(
|
||||
--use-server-list-ping
|
||||
)
|
||||
" > /data/.mc-health.env
|
||||
fi
|
||||
|
||||
log "Resolving type given ${TYPE}"
|
||||
case "${TYPE^^}" in
|
||||
*BUKKIT|SPIGOT)
|
||||
exec "${SCRIPTS:-/}start-deployBukkitSpigot" "$@"
|
||||
;;
|
||||
|
||||
PAPER)
|
||||
exec "${SCRIPTS:-/}start-deployPaper" "$@"
|
||||
;;
|
||||
|
||||
FORGE)
|
||||
evaluateJavaCompatibilityForForge
|
||||
exec "${SCRIPTS:-/}start-deployForge" "$@"
|
||||
;;
|
||||
|
||||
FABRIC)
|
||||
exec "${SCRIPTS:-/}start-deployFabric" "$@"
|
||||
;;
|
||||
|
||||
FTBA)
|
||||
evaluateJavaCompatibilityForForge
|
||||
exec "${SCRIPTS:-/}start-deployFTBA" "$@"
|
||||
;;
|
||||
|
||||
FTB|CURSEFORGE)
|
||||
evaluateJavaCompatibilityForForge
|
||||
exec "${SCRIPTS:-/}start-deployCF" "$@"
|
||||
;;
|
||||
|
||||
VANILLA)
|
||||
exec "${SCRIPTS:-/}start-deployVanilla" "$@"
|
||||
;;
|
||||
|
||||
SPONGEVANILLA)
|
||||
exec "${SCRIPTS:-/}start-deploySpongeVanilla" "$@"
|
||||
;;
|
||||
|
||||
CUSTOM)
|
||||
evaluateJavaCompatibilityForForge
|
||||
exec "${SCRIPTS:-/}start-deployCustom" "$@"
|
||||
;;
|
||||
|
||||
MAGMA)
|
||||
evaluateJavaCompatibilityForForge
|
||||
exec "${SCRIPTS:-/}start-deployMagma" "$@"
|
||||
;;
|
||||
|
||||
MOHIST)
|
||||
evaluateJavaCompatibilityForForge
|
||||
exec "${SCRIPTS:-/}start-deployMohist" "$@"
|
||||
;;
|
||||
|
||||
CATSERVER)
|
||||
evaluateJavaCompatibilityForForge
|
||||
exec "${SCRIPTS:-/}start-deployCatserver" "$@"
|
||||
;;
|
||||
|
||||
PURPUR)
|
||||
exec "${SCRIPTS:-/}start-deployPurpur" "$@"
|
||||
;;
|
||||
|
||||
AIRPLANE)
|
||||
exec "${SCRIPTS:-/}start-deployAirplane" "$@"
|
||||
;;
|
||||
|
||||
PUFFERFISH)
|
||||
exec "${SCRIPTS:-/}start-deployPufferfish" "$@"
|
||||
;;
|
||||
|
||||
CANYON)
|
||||
exec "${SCRIPTS:-/}start-deployCanyon" "$@"
|
||||
;;
|
||||
|
||||
LIMBO)
|
||||
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" "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
log "Invalid type: '$TYPE'"
|
||||
log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTBA (multiarch-only),"
|
||||
log " CURSEFORGE, SPONGEVANILLA, PURPUR, CUSTOM,"
|
||||
log " MAGMA, MOHIST, CATSERVER, AIRPLANE, PUFFERFISH, CANYON, LIMBO, CRUCIBLE"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
set -euo pipefail
|
||||
isDebugging && set -x
|
||||
|
||||
IFS=$'\n\t'
|
||||
|
||||
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "PURPUR" ] ; then
|
||||
log "ERROR: Airplane server type only supports VERSION=LATEST, VERSION=PURPUR."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
: ${AIRPLANE_TYPE:=airplane}
|
||||
|
||||
if [ "${VERSION}" = "LATEST" ] ; then
|
||||
AIRPLANE_TYPE="airplane"
|
||||
fi
|
||||
|
||||
if [ "${VERSION}" = "PURPUR" ]; then
|
||||
AIRPLANE_TYPE="airplanepurpur"
|
||||
fi
|
||||
|
||||
log "Using ${AIRPLANE_TYPE} 1.17.1 (1.18 unsupported - use Paper/Pufferfish/Purpur for newer versions)"
|
||||
|
||||
export SERVER=${AIRPLANE_TYPE}-1.17.1.jar
|
||||
|
||||
log "Removing old Airplane versions ..."
|
||||
shopt -s nullglob
|
||||
for f in airplane*.jar; do
|
||||
[[ $f != $SERVER ]] && rm $f
|
||||
done
|
||||
|
||||
if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
|
||||
downloadUrl="https://airplane.gg/dl/launcher-${AIRPLANE_TYPE}1.17.1.jar"
|
||||
log "Downloading Airplane from $downloadUrl ..."
|
||||
if ! get -o "$SERVER" "$downloadUrl"; then
|
||||
log "ERROR: failed to download from $downloadUrl (status=$?)"
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
|
||||
# Normalize on Spigot for later operations
|
||||
export FAMILY=SPIGOT
|
||||
|
||||
exec "${SCRIPTS:-/}start-spiget" "$@"
|
||||
@@ -1,60 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-$(dirname "$0")}/start-utils"
|
||||
set -o pipefail
|
||||
set -e
|
||||
isDebugging && set -x
|
||||
|
||||
requireVar VANILLA_VERSION
|
||||
: "${CRUCIBLE_RELEASE:=latest}"
|
||||
|
||||
crucibleReleasesUrl=https://api.github.com/repos/CrucibleMC/Crucible/releases
|
||||
if [[ ${CRUCIBLE_RELEASE^^} = LATEST ]]; then
|
||||
crucibleReleaseUrl=${crucibleReleasesUrl}/latest
|
||||
else
|
||||
crucibleReleaseUrl=${crucibleReleasesUrl}/tags/${CRUCIBLE_RELEASE}
|
||||
fi
|
||||
|
||||
if ! downloadUrl=$(get --json-path "$.assets[?(@.name =~ /Crucible-${VANILLA_VERSION}-.*\.jar/)].browser_download_url" \
|
||||
--accept "application/vnd.github.v3+json" "$crucibleReleaseUrl"); then
|
||||
log "ERROR: failed to access ${CRUCIBLE_RELEASE} release of Crucible"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $downloadUrl = null ]]; then
|
||||
log "ERROR: failed to locate Crucible jar for $VANILLA_VERSION from ${CRUCIBLE_RELEASE}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Downloading Crucible from $downloadUrl"
|
||||
if ! SERVER=$(get --skip-existing --output-filename -o /data "$downloadUrl"); then
|
||||
log "ERROR: failed to download Crucible jar from $downloadUrl"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
librariesDir=/data/libraries
|
||||
if [ ! -d "$librariesDir" ]; then
|
||||
if ! librariesUrl=$(get --json-path "$.assets[?(@.name == 'libraries.zip')].browser_download_url" \
|
||||
--accept "application/vnd.github.v3+json" "$crucibleReleaseUrl"); then
|
||||
log "ERROR: failed to access ${CRUCIBLE_RELEASE} release of Crucible for libraries"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Downloading Crucible libraries"
|
||||
if ! get -o /tmp/libraries.zip "$librariesUrl"; then
|
||||
log "ERROR: failed to download Crucible libraries from $librariesUrl"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! unzip /tmp/libraries.zip -d "$librariesDir"; then
|
||||
log "ERROR: failed to unzip Crucible libraries"
|
||||
exit 1
|
||||
fi
|
||||
rm /tmp/libraries.zip
|
||||
fi
|
||||
|
||||
export SERVER
|
||||
export FAMILY=HYBRID
|
||||
|
||||
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"
|
||||
@@ -1,50 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
|
||||
requireVar VANILLA_VERSION
|
||||
export TYPE=FABRIC
|
||||
: "${FABRIC_LAUNCHER_VERSION:=${FABRIC_INSTALLER_VERSION:-LATEST}}"
|
||||
: "${FABRIC_LAUNCHER:=}"
|
||||
: "${FABRIC_LAUNCHER_URL:=}"
|
||||
: "${FABRIC_LOADER_VERSION:=LATEST}"
|
||||
|
||||
isDebugging && set -x
|
||||
|
||||
# Custom fabric jar
|
||||
if [[ $FABRIC_LAUNCHER ]]; then
|
||||
export SERVER=${FABRIC_LAUNCHER}
|
||||
# Custom fabric jar url
|
||||
elif [[ $FABRIC_LAUNCHER_URL ]]; then
|
||||
export SERVER=fabric-server-$(echo -n "$FABRIC_LAUNCHER_URL" | mc-image-helper hash)
|
||||
# Official fabric launcher
|
||||
else
|
||||
if [[ ${FABRIC_LAUNCHER_VERSION^^} = LATEST ]]; then
|
||||
log "Checking Fabric Launcher version information."
|
||||
FABRIC_LAUNCHER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-installer/maven-metadata.xml)
|
||||
fi
|
||||
if [[ ${FABRIC_LOADER_VERSION^^} = LATEST ]]; then
|
||||
log "Checking Fabric Loader version information."
|
||||
FABRIC_LOADER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-loader/maven-metadata.xml)
|
||||
fi
|
||||
export SERVER=fabric-server-mc.${VANILLA_VERSION}-loader.${FABRIC_LOADER_VERSION}-launcher.${FABRIC_LAUNCHER_VERSION}.jar
|
||||
export FABRIC_LAUNCHER_URL="https://meta.fabricmc.net/v2/versions/loader/${VANILLA_VERSION}/${FABRIC_LOADER_VERSION}/${FABRIC_LAUNCHER_VERSION}/server/jar"
|
||||
fi
|
||||
|
||||
if [[ ! -e ${SERVER} && ! -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"
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! -e ${SERVER} ]]; then
|
||||
log "$SERVER does not exist, cannot launch server!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export FAMILY=FABRIC
|
||||
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||
@@ -1,157 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
: "${FORGEVERSION:=RECOMMENDED}"
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-$(dirname "$0")}/start-utils"
|
||||
isDebugging && set -x
|
||||
|
||||
get_installer() {
|
||||
if [[ -z $FORGE_INSTALLER_URL ]]; then
|
||||
log "Downloading $normForgeVersion"
|
||||
|
||||
forgeFileNames="
|
||||
$shortForgeVersion/forge-$shortForgeVersion-installer.jar
|
||||
$normForgeVersion/forge-$normForgeVersion-installer.jar
|
||||
"
|
||||
|
||||
for fn in $forgeFileNames; do
|
||||
downloadUrl=https://maven.minecraftforge.net/net/minecraftforge/forge/$fn
|
||||
log "...trying $downloadUrl"
|
||||
if get -o "$FORGE_INSTALLER" "$downloadUrl"; then
|
||||
return
|
||||
fi
|
||||
done
|
||||
log "Unable to locate usable URL for $normForgeVersion"
|
||||
exit 2
|
||||
else
|
||||
log "Downloading $FORGE_INSTALLER_URL ..."
|
||||
if ! get -o "$FORGE_INSTALLER" "$FORGE_INSTALLER_URL"; then
|
||||
log "Failed to download from given location $FORGE_INSTALLER_URL"
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
install() {
|
||||
if [ ! -e "$FORGE_INSTALLER" ]; then
|
||||
get_installer "$normForgeVersion" "$shortForgeVersion"
|
||||
fi
|
||||
|
||||
log "Installing Forge $shortForgeVersion. This might take a minute or two..."
|
||||
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
|
||||
fi
|
||||
done
|
||||
# NOTE $shortForgeVersion will be empty if installer location was given to us
|
||||
log "Finding installed server jar..."
|
||||
unset -v latest
|
||||
# 1.17+ ?
|
||||
if [ -f /data/run.sh ]; then
|
||||
latest=/data/run.sh
|
||||
# else pre 1.17
|
||||
else
|
||||
for file in *forge*.jar; do
|
||||
if ! [[ $file =~ installer ]]; then
|
||||
if [[ -z $latest ]] || [[ $file -nt $latest ]]; then
|
||||
latest=$file
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ -z $latest ]]; then
|
||||
log "Unable to derive server jar for Forge"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
export SERVER=$latest
|
||||
log "Using server $SERVER"
|
||||
debug "Writing install marker at $installMarker"
|
||||
echo "$SERVER" > "$installMarker"
|
||||
}
|
||||
|
||||
resolve_versions() {
|
||||
if [[ -z $FORGE_INSTALLER && -z $FORGE_INSTALLER_URL ]]; then
|
||||
norm=$VANILLA_VERSION
|
||||
|
||||
case $VANILLA_VERSION in
|
||||
*.*.*)
|
||||
norm=$VANILLA_VERSION ;;
|
||||
*.*)
|
||||
norm=${VANILLA_VERSION}.0 ;;
|
||||
esac
|
||||
|
||||
#################################################################################
|
||||
promosUrl=http://files.minecraftforge.net/maven/net/minecraftforge/forge/promotions_slim.json
|
||||
|
||||
log "Checking Forge version information."
|
||||
case $FORGEVERSION in
|
||||
LATEST)
|
||||
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
|
||||
fi
|
||||
;;
|
||||
|
||||
RECOMMENDED)
|
||||
if ! FORGE_VERSION=$(get -s --json-path ".promos['$VANILLA_VERSION-recommended']" "$promosUrl"); then
|
||||
if ! FORGE_VERSION=$(get --json-path ".promos['$VANILLA_VERSION-latest']" "$promosUrl"); then
|
||||
log "ERROR: Version $VANILLA_VERSION is not supported by Forge"
|
||||
log " Refer to http://files.minecraftforge.net/ for supported versions"
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
FORGE_VERSION=$FORGEVERSION
|
||||
;;
|
||||
esac
|
||||
|
||||
normForgeVersion=$VANILLA_VERSION-$FORGE_VERSION-$norm
|
||||
shortForgeVersion=$VANILLA_VERSION-$FORGE_VERSION
|
||||
|
||||
FORGE_INSTALLER="/tmp/forge-$shortForgeVersion-installer.jar"
|
||||
elif [[ -z $FORGE_INSTALLER ]]; then
|
||||
FORGE_INSTALLER="/tmp/forge-installer.jar"
|
||||
elif [[ ! -e $FORGE_INSTALLER ]]; then
|
||||
log "ERROR: the given Forge installer doesn't exist : $FORGE_INSTALLER"
|
||||
exit 2
|
||||
else
|
||||
shortForgeVersion=$VANILLA_VERSION-${FORGE_INSTALLER_CUSTOM_VERSION:-custom}
|
||||
fi
|
||||
}
|
||||
|
||||
### main
|
||||
|
||||
resolve_versions
|
||||
|
||||
installMarker="/data/.forge-installed-$shortForgeVersion"
|
||||
|
||||
if [ ! -e "$installMarker" ] || isTrue "${FORCE_REINSTALL:-false}"; then
|
||||
install
|
||||
else
|
||||
SERVER=$(cat "$installMarker")
|
||||
export SERVER
|
||||
if [ ! -e "$SERVER" ]; then
|
||||
rm "$installMarker"
|
||||
install
|
||||
fi
|
||||
fi
|
||||
|
||||
export FAMILY=FORGE
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||
@@ -1,62 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
isDebugging && set -x
|
||||
|
||||
: ${LIMBO_BUILD:=LATEST}
|
||||
: ${FORCE_REDOWNLOAD:=false}
|
||||
: ${LIMBO_SCHEMA_FILENAME:=default.schem}
|
||||
: ${LEVEL:=Default;${LIMBO_SCHEMA_FILENAME}}
|
||||
# defaults to localhost, if this is not set
|
||||
: ${SERVER_IP:=0.0.0.0}
|
||||
|
||||
export LEVEL SERVER_IP
|
||||
|
||||
if [[ ${LIMBO_BUILD^^} == LATEST ]]; then
|
||||
LIMBO_BUILD=lastStableBuild
|
||||
fi
|
||||
|
||||
baseUrl="https://ci.loohpjames.com/job/Limbo/${LIMBO_BUILD}"
|
||||
buildInfoUrl="${baseUrl}/api/json"
|
||||
buildJson=$(curl -fsSL "${buildInfoUrl}")
|
||||
if [ $? != 0 ]; then
|
||||
log "ERROR failed to get build info from ${buildInfoUrl} (status=$?)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ${LIMBO_BUILD} = lastStableBuild ]]; then
|
||||
LIMBO_BUILD=$(jq -r '.number' <<<${buildJson})
|
||||
log "Resolved latest Limbo build to ${LIMBO_BUILD}"
|
||||
fi
|
||||
artifactPath=$(jq -r '.artifacts[] | select(.fileName|test("^Limbo-")) | .relativePath' <<<${buildJson})
|
||||
defaultSchemaPath=$(jq -r '.artifacts[] | select(.fileName|test(".*\\.schem")) | .relativePath' <<<${buildJson})
|
||||
|
||||
export SERVER="limbo-${LIMBO_BUILD}.jar"
|
||||
|
||||
if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
|
||||
downloadUrl="${baseUrl}/artifact/${artifactPath}"
|
||||
log "Downloading Limbo from $downloadUrl ..."
|
||||
if ! curl -fsSL -o "$SERVER" "$downloadUrl"; then
|
||||
log "ERROR: failed to download from $downloadUrl (status=$?)"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if [ ! -f "${LIMBO_SCHEMA_FILENAME}" ]; then
|
||||
log "Downloading default schem file"
|
||||
if ! curl -o "${LIMBO_SCHEMA_FILENAME}" -fsSL "${baseUrl}/artifact/${defaultSchemaPath}"; then
|
||||
log "ERROR: failed to download schema file $baseUrl (status=$?)"
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ${LEVEL} != *\;* ]]; then
|
||||
LEVEL="${LEVEL};${LIMBO_SCHEMA_FILENAME}"
|
||||
fi
|
||||
export LEVEL
|
||||
|
||||
export FAMILY=LIMBO
|
||||
exec ${SCRIPTS:-/}start-setupWorld $@
|
||||
@@ -1,44 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
set -euo pipefail
|
||||
isDebugging && set -x
|
||||
|
||||
IFS=$'\n\t'
|
||||
|
||||
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "1.18" ] ; then
|
||||
log "ERROR: Pufferfish server type only supports VERSION=LATEST, VERSION=1.18. Note that these are branches, not #.#.# versions."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
: ${PUFFERFISH_BUILD:=lastSuccessfulBuild}
|
||||
|
||||
if [ "${VERSION}" = "LATEST" ] || [ "${VERSION}" = "1.18" ]; then
|
||||
PUFFERFISH_BRANCH="1.18"
|
||||
PUFFERFISH_VERSION="1.18.1-R0.1"
|
||||
fi
|
||||
|
||||
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
|
||||
done
|
||||
|
||||
if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
|
||||
artifact="build/libs/pufferfish-paperclip-${PUFFERFISH_VERSION}-SNAPSHOT-reobf.jar"
|
||||
downloadUrl="https://ci.pufferfish.host/job/Pufferfish-${PUFFERFISH_BRANCH}/${PUFFERFISH_BUILD}/artifact/${artifact}"
|
||||
log "Downloading Pufferfish from $downloadUrl ..."
|
||||
if ! get -o "$SERVER" "$downloadUrl"; then
|
||||
log "ERROR: failed to download from $downloadUrl (status=$?)"
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
|
||||
# Normalize on Spigot for later operations
|
||||
export FAMILY=SPIGOT
|
||||
|
||||
exec ${SCRIPTS:-/}start-spiget "$@"
|
||||
@@ -1,56 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
isDebugging && set -x
|
||||
set -o pipefail
|
||||
|
||||
export SERVER="minecraft_server.${VANILLA_VERSION// /_}.jar"
|
||||
|
||||
if [ ! -e "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
|
||||
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)"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$versionManifestUrl" = "null" ]; then
|
||||
log "ERROR couldn't find a matching manifest entry for $VANILLA_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
debug "Found version manifest at $versionManifestUrl"
|
||||
|
||||
serverDownloadUrl=$(get --json-path '$.downloads.server.url' "${versionManifestUrl}")
|
||||
result=$?
|
||||
if [ $result != 0 ]; then
|
||||
log "ERROR failed to obtain version manifest from $versionManifestUrl ($result)"
|
||||
exit 1
|
||||
elif [ "$serverDownloadUrl" = "null" ]; then
|
||||
log "ERROR version $VANILLA_VERSION does not provide a server download"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
debug "Downloading server from $serverDownloadUrl"
|
||||
get -o "$SERVER" "$serverDownloadUrl"
|
||||
result=$?
|
||||
if [ $result != 0 ]; then
|
||||
log "ERROR failed to download server from $serverDownloadUrl ($result)"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if versionLessThan 1.6; then
|
||||
if ! [[ -L /data/minecraft_server.jar && /data/minecraft_server.jar -ef "/data/$SERVER" ]]; then
|
||||
rm -f /data/minecraft_server.jar
|
||||
ln -s "/data/$SERVER" /data/minecraft_server.jar
|
||||
fi
|
||||
SERVER=minecraft_server.jar
|
||||
elif [[ -L /data/minecraft_server.jar ]]; then
|
||||
rm -f /data/minecraft_server.jar
|
||||
fi
|
||||
|
||||
isDebugging && ls -l
|
||||
export FAMILY=VANILLA
|
||||
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||
@@ -1,77 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e -o pipefail
|
||||
|
||||
: "${REMOVE_OLD_DATAPACKS:=false}"
|
||||
: "${DATAPACKS_FILE:=}"
|
||||
: "${REMOVE_OLD_DATAPACKS_DEPTH:=1} "
|
||||
: "${REMOVE_OLD_DATAPACKS_INCLUDE:=*.zip}"
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
isDebugging && set -x
|
||||
|
||||
out_dir=/data/${LEVEL:-world}/datapacks
|
||||
|
||||
# Remove old datapacks
|
||||
if isTrue "${REMOVE_OLD_DATAPACKS}" && [ -z "${DATAPACKS_FILE}" ]; then
|
||||
if [ -d "$out_dir" ]; then
|
||||
find "$out_dir" -mindepth 1 -maxdepth ${REMOVE_OLD_DATAPACKS_DEPTH:-16} -wholename "${REMOVE_OLD_DATAPACKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_DATAPACKS_EXCLUDE:-}" -delete
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$DATAPACKS" ]]; then
|
||||
mkdir -p "$out_dir"
|
||||
|
||||
for i in ${DATAPACKS//,/ }
|
||||
do
|
||||
if isURL "$i"; then
|
||||
log "Downloading datapack $i ..."
|
||||
if ! get -o "${out_dir}" "$i"; then
|
||||
log "ERROR: failed to download from $i into $out_dir"
|
||||
exit 2
|
||||
fi
|
||||
elif [[ -f "$i" && "$i" =~ .*\.zip ]]; then
|
||||
log "Copying datapack located at $i ..."
|
||||
out_file=$(basename "$i")
|
||||
if ! cp "$i" "${out_dir}/$out_file"; then
|
||||
log "ERROR: failed to copy from $i into $out_dir"
|
||||
exit 2
|
||||
fi
|
||||
elif [[ -d "$i" ]]; then
|
||||
log "Copying datapacks from $i ..."
|
||||
cp "$i"/*.zip "${out_dir}"
|
||||
else
|
||||
log "ERROR Invalid URL or path given in DATAPACKS: $i"
|
||||
exit 2
|
||||
fi
|
||||
done
|
||||
|
||||
elif [[ "$DATAPACKS_FILE" ]]; then
|
||||
if [ ! -f "$DATAPACKS_FILE" ]; then
|
||||
log "ERROR: given DATAPACKS_FILE file does not exist"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
mkdir -p "$out_dir"
|
||||
|
||||
args=(
|
||||
-o "${out_dir}"
|
||||
--log-progress-each
|
||||
--skip-existing
|
||||
--uris-file "${DATAPACKS_FILE}"
|
||||
)
|
||||
if isTrue "${REMOVE_OLD_DATAPACKS}"; then
|
||||
args+=(
|
||||
--prune-others "${REMOVE_OLD_DATAPACKS_INCLUDE}"
|
||||
--prune-depth "${REMOVE_OLD_DATAPACKS_DEPTH}"
|
||||
)
|
||||
fi
|
||||
|
||||
if ! get "${args[@]}" ; then
|
||||
log "ERROR: failed to retrieve one or more datapacks"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupForgeApiMods" "$@"
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
|
||||
set -e
|
||||
|
||||
: "${REPLACE_ENV_IN_PLACE:=${REPLACE_ENV_VARIABLES:-false}}"
|
||||
: "${REPLACE_ENV_PATHS:=/data}"
|
||||
: "${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:=}"
|
||||
: "${PATCH_DEFINITIONS:=}"
|
||||
: "${DEBUG:=false}"
|
||||
|
||||
if isTrue "${REPLACE_ENV_IN_PLACE}"; then
|
||||
log "Replacing env variables in ${REPLACE_ENV_PATHS} that match the prefix $REPLACE_ENV_VARIABLE_PREFIX ..."
|
||||
|
||||
mc-image-helper --debug=${DEBUG} interpolate \
|
||||
--replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \
|
||||
--replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \
|
||||
--replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \
|
||||
--replace-env-prefix="${REPLACE_ENV_VARIABLE_PREFIX}" \
|
||||
"${REPLACE_ENV_PATHS[@]}"
|
||||
fi
|
||||
|
||||
if [[ ${PATCH_DEFINITIONS} ]]; then
|
||||
log "Applying patch definitions from ${PATCH_DEFINITIONS}"
|
||||
mc-image-helper --debug=${DEBUG} patch \
|
||||
--patch-env-prefix="${REPLACE_ENV_VARIABLE_PREFIX}" \
|
||||
"${PATCH_DEFINITIONS}"
|
||||
fi
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupRbac" "$@"
|
||||
@@ -1,245 +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
|
||||
out_dir=/data/mods
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
isDebugging && set -x
|
||||
|
||||
# Remove old mods/plugins
|
||||
if isTrue "${REMOVE_OLD_FORGEAPI_MODS}" && [ -z "${MODS_FORGEAPI_KEY}" ]; 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' )
|
||||
PROJECT_FILE_ID=$(jq -n "$PROJECT_FILE" | jq -jc '.id' )
|
||||
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
|
||||
|
||||
# grabs needed values from our json return
|
||||
file_name=$(jq -n "$PROJECT_FILE" | jq -jc '.fileName' )
|
||||
download_url=$(jq -n "$PROJECT_FILE" | jq -jc '.downloadUrl' )
|
||||
|
||||
# trys to make the output directory incase it doesnt exist.
|
||||
mkdir -p "$out_dir"
|
||||
echo "Downloading ${download_url}"
|
||||
if ! get --skip-up-to-date -o "${out_dir}/${file_name}" $download_url ; then
|
||||
log "ERROR: failed to download from ${download_url}"
|
||||
exit 2
|
||||
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
|
||||
jq -n "$required_dependencies" | jq -c '.[]?' | while read current_dependency; do
|
||||
mod_id=$(jq -n "$current_dependency" | jq -jc '.modId' )
|
||||
|
||||
# BROKEN: Example Voice mod keeps returning the voice mod file id instead of the mod file id.
|
||||
# file_id=$(jq -n "$current_dependency" | jq -jc '.fileId' )
|
||||
# dependency_data=$(curl -X GET -s \
|
||||
# "${FORGEAPI_BASE_URL}/mods/${mod_id}/files/${file_id}/download-url" \
|
||||
# -H 'Accept: application/json' -H 'x-api-key: '${MODS_FORGEAPI_KEY}'')
|
||||
# if [ ! "$dependency_data" ]; then
|
||||
# log "ERROR: unable to retrieve dependency data files for ${project_id} from ForgeAPI"
|
||||
# exit 2
|
||||
# fi
|
||||
# dependency_download_url=$(jq -n "$dependency_data" | jq -jc '.data' )
|
||||
# echo "Downloading dependency ${dependency_download_url}"
|
||||
# if ! get -o "${out_dir}/" $dependency_download_url ; then
|
||||
# log "ERROR: failed to download dependency from ${dependency_download_url}"
|
||||
# exit 2
|
||||
# fi
|
||||
|
||||
# Using current mod path and release to go get the REQUIRED DEPENDENCY
|
||||
# NOTE: we are ASUMING it will be release.
|
||||
modFileByProjectID $mod_id "release"
|
||||
downloadModPackfromModFile
|
||||
done
|
||||
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.
|
||||
jq -c '.[]?' $MODS_FORGEAPI_FILE | while read 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' )
|
||||
|
||||
modFileByProjectID $project_id $current_release_type $current_file_name
|
||||
downloadModPackfromModFile
|
||||
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then
|
||||
downloadDependencies
|
||||
fi
|
||||
done
|
||||
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
|
||||
modFileByProjectID $project_id
|
||||
downloadModPackfromModFile
|
||||
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then
|
||||
downloadDependencies
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupModpack" "$@"
|
||||
@@ -1,259 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e -o pipefail
|
||||
|
||||
: "${REMOVE_OLD_MODS:=false}"
|
||||
: "${MODS_FILE:=}"
|
||||
: "${REMOVE_OLD_MODS_DEPTH:=1} "
|
||||
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar}"
|
||||
sum_file=/data/.generic_pack.sum
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
isDebugging && set -x
|
||||
|
||||
# CURSE_URL_BASE used in manifest downloads below
|
||||
CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects}
|
||||
|
||||
# Remove old mods/plugins
|
||||
if isTrue "${REMOVE_OLD_MODS}" && [ -z "${MODS_FILE}" ]; then
|
||||
removeOldMods /data/mods
|
||||
removeOldMods /data/plugins
|
||||
rm -f "$sum_file"
|
||||
fi
|
||||
|
||||
# If packwiz url passed, bootstrap packwiz and update mods before other modpack processing
|
||||
if [[ "${PACKWIZ_URL}" ]]; then
|
||||
# Ensure we have the latest packwiz bootstrap installer
|
||||
latestPackwiz=$(curl -fsSL https://api.github.com/repos/packwiz/packwiz-installer-bootstrap/releases/latest)
|
||||
if [[ -z "${latestPackwiz}" ]]; then
|
||||
log "WARNING: Could not retrieve Packwiz bootstrap installer release information"
|
||||
else
|
||||
isDebugging && log "Latest packwiz ${latestPackwiz}"
|
||||
latestPackwizVer=$(echo ${latestPackwiz} | jq --raw-output '.tag_name')
|
||||
latestPackwizUrl=$(echo ${latestPackwiz} | jq --raw-output '.assets[] | select(.name | match("packwiz-installer-bootstrap.jar")) | .url')
|
||||
: "${PACKWIZ_JAR:=packwiz-installer-bootstrap_${latestPackwizVer}.jar}"
|
||||
if [[ ! -e $PACKWIZ_JAR ]]; then
|
||||
log "Downloading Packwiz ${latestPackwizVer}"
|
||||
curl -H "Accept:application/octet-stream" -o "$PACKWIZ_JAR" -fsSL ${latestPackwizUrl}
|
||||
ln -sf "${PACKWIZ_JAR}" packwiz-installer-bootstrap.jar
|
||||
fi
|
||||
fi
|
||||
if [[ ! -e packwiz-installer-bootstrap.jar ]]; then
|
||||
log "ERROR: Packwiz not available or could not be downloaded from Github!"
|
||||
exit 1
|
||||
fi
|
||||
if isURL "${PACKWIZ_URL}"; then
|
||||
log "Running packwiz against URL: ${PACKWIZ_URL}"
|
||||
java -jar packwiz-installer-bootstrap.jar -g -s server "${PACKWIZ_URL}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If supplied with a URL for a modpack (simple zip of jars), download it and unpack
|
||||
if [[ "$MODPACK" ]]; then
|
||||
if isURL "${MODPACK}"; then
|
||||
log "Downloading mod/plugin pack"
|
||||
if ! get -o /tmp/modpack.zip "${MODPACK}"; then
|
||||
log "ERROR: failed to download from ${MODPACK}"
|
||||
exit 2
|
||||
fi
|
||||
elif [[ "$MODPACK" =~ .*\.zip ]]; then
|
||||
if ! cp "$MODPACK" /tmp/modpack.zip; then
|
||||
log "ERROR: failed to copy from $MODPACK"
|
||||
exit 2
|
||||
fi
|
||||
else
|
||||
log "ERROR Invalid URL or Path given for MODPACK: $MODPACK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$FAMILY" = "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}"
|
||||
fi
|
||||
else
|
||||
mkdir -p /data/mods
|
||||
if ! unzip -o -d /data/mods /tmp/modpack.zip; then
|
||||
log "ERROR: failed to unzip the modpack from ${MODPACK}"
|
||||
fi
|
||||
fi
|
||||
rm -f /tmp/modpack.zip
|
||||
|
||||
elif [[ "$MODS" ]]; then
|
||||
if [ "$FAMILY" = "SPIGOT" ]; then
|
||||
out_dir=/data/plugins
|
||||
else
|
||||
out_dir=/data/mods
|
||||
fi
|
||||
mkdir -p "$out_dir"
|
||||
|
||||
for i in ${MODS//,/ }
|
||||
do
|
||||
if isURL "$i"; then
|
||||
log "Downloading mod/plugin $i ..."
|
||||
if ! get --skip-up-to-date -o "${out_dir}" "$i"; then
|
||||
log "ERROR: failed to download from $i into $out_dir"
|
||||
exit 2
|
||||
fi
|
||||
elif [[ -f "$i" && "$i" =~ .*\.jar ]]; then
|
||||
log "Copying plugin located at $i ..."
|
||||
out_file=$(basename "$i")
|
||||
if ! cp "$i" "${out_dir}/$out_file"; then
|
||||
log "ERROR: failed to copy from $i into $out_dir"
|
||||
exit 2
|
||||
fi
|
||||
elif [[ -d "$i" ]]; then
|
||||
log "Copying plugin jars from $i ..."
|
||||
cp "$i"/*.jar "${out_dir}"
|
||||
else
|
||||
log "ERROR Invalid URL or path given in MODS: $i"
|
||||
exit 2
|
||||
fi
|
||||
done
|
||||
|
||||
elif [[ "$MODS_FILE" ]]; then
|
||||
if [ ! -f "$MODS_FILE" ]; then
|
||||
log "ERROR: given MODS_FILE file does not exist"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [ "$FAMILY" = "SPIGOT" ]; then
|
||||
out_dir=/data/plugins
|
||||
else
|
||||
out_dir=/data/mods
|
||||
fi
|
||||
mkdir -p "$out_dir"
|
||||
|
||||
args=(
|
||||
-o "${out_dir}"
|
||||
--log-progress-each
|
||||
--skip-up-to-date
|
||||
--uris-file "${MODS_FILE}"
|
||||
)
|
||||
if isTrue "${REMOVE_OLD_MODS}"; then
|
||||
args+=(
|
||||
--prune-others "${REMOVE_OLD_MODS_INCLUDE}"
|
||||
--prune-depth "${REMOVE_OLD_MODS_DEPTH}"
|
||||
)
|
||||
fi
|
||||
|
||||
if ! get "${args[@]}" ; then
|
||||
log "ERROR: failed to retrieve one or more mods"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$MANIFEST" ]]; then
|
||||
if [[ -e "$MANIFEST" ]]; then
|
||||
EFFECTIVE_MANIFEST_FILE=$MANIFEST
|
||||
elif isURL "$MANIFEST"; then
|
||||
EFFECTIVE_MANIFEST_FILE=/tmp/manifest.json
|
||||
EFFECTIVE_MANIFEST_URL=$(curl -Ls -o /dev/null -w %{effective_url} $MANIFEST)
|
||||
curl -Ls -o $EFFECTIVE_MANIFEST_FILE "$EFFECTIVE_MANIFEST_URL"
|
||||
else
|
||||
log "MANIFEST='$MANIFEST' is not a valid manifest url or location"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
case "X$EFFECTIVE_MANIFEST_FILE" in
|
||||
X*.json)
|
||||
if [ -f "${EFFECTIVE_MANIFEST_FILE}" ]; then
|
||||
MOD_DIR=${FTB_BASE_DIR:-/data}/mods
|
||||
if [ ! -d "$MOD_DIR" ]
|
||||
then
|
||||
log "Creating mods dir $MOD_DIR"
|
||||
mkdir -p "$MOD_DIR"
|
||||
fi
|
||||
log "Starting manifest download..."
|
||||
cat "${EFFECTIVE_MANIFEST_FILE}" | jq -r '.files[] | (.projectID|tostring) + " " + (.fileID|tostring)'| while read -r p f
|
||||
do
|
||||
if [ ! -f $MOD_DIR/${p}_${f}.jar ]
|
||||
then
|
||||
redirect_url="$(curl -Ls -o /dev/null -w %{effective_url} ${CURSE_URL_BASE}/${p})"
|
||||
url="$redirect_url/download/${f}/file"
|
||||
log Downloading curseforge mod $url
|
||||
# Manifest usually doesn't have mod names. Using id should be fine, tho
|
||||
curl -sSL "${url}" -o $MOD_DIR/${p}_${f}.jar
|
||||
fi
|
||||
done
|
||||
else
|
||||
log "Could not find manifest file, insufficient privileges, or malformed path."
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log "Invalid manifest file for modpack. Please make sure it is a .json file."
|
||||
;;
|
||||
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
|
||||
mkdir -p /data/packs
|
||||
log "Downloading generic pack from $pack"
|
||||
if ! outfile=$(get -o /data/packs --output-filename --skip-up-to-date "$pack"); then
|
||||
log "ERROR: failed to download $pack"
|
||||
exit 2
|
||||
fi
|
||||
packFiles+=("$outfile")
|
||||
else
|
||||
packFiles+=("$pack")
|
||||
fi
|
||||
done
|
||||
|
||||
isDebugging && [ -f "$sum_file}" ] && cat "$sum_file"
|
||||
|
||||
log "Checking if generic packs are up to date"
|
||||
if isTrue "${SKIP_GENERIC_PACK_UPDATE_CHECK:-false}" && [ -f "$sum_file" ]; then
|
||||
log "Skipping generic pack update check"
|
||||
elif isTrue "${FORCE_GENERIC_PACK_UPDATE}" || ! checkSum "${sum_file}"; then
|
||||
log "Generic pack(s) are out of date. Re-applying..."
|
||||
|
||||
base_dir=/tmp/generic_pack_base
|
||||
mkdir -p ${base_dir}
|
||||
for pack in "${packFiles[@]}"; do
|
||||
isDebugging && ls -l "${pack}"
|
||||
extract "${pack}" "${base_dir}"
|
||||
done
|
||||
|
||||
# recalculate the actual base directory of content
|
||||
base_dir=$(find "$base_dir" -type d \( -name mods -o -name plugins -o -name config \) -printf '%h' -quit)
|
||||
if [[ ! $base_dir ]]; then
|
||||
log "ERROR: Unable to find content base of generic packs ${GENERIC_PACKS}. Directories:"
|
||||
find /tmp/generic_pack_base -type d -printf ' - %P\n'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f /data/manifest.txt ]; then
|
||||
log "Manifest exists from older generic pack, cleaning up ..."
|
||||
while read -r f; do
|
||||
rm -rf "/data/${f}"
|
||||
done < /data/manifest.txt
|
||||
# prune empty dirs
|
||||
find /data -mindepth 1 -depth -type d -empty -delete
|
||||
rm -f /data/manifest.txt
|
||||
fi
|
||||
|
||||
log "Writing generic pack manifest ... "
|
||||
find "${base_dir}" -type f -printf "%P\n" > /data/manifest.txt
|
||||
|
||||
log "Applying generic pack ..."
|
||||
cp -R -f "${base_dir}"/* /data
|
||||
rm -rf /tmp/generic_pack_base
|
||||
|
||||
log "Saving generic pack(s) checksum"
|
||||
sha1sum "${packFiles[@]}" > "${sum_file}"
|
||||
isDebugging && cat "$sum_file"
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupModconfig" "$@"
|
||||
@@ -1,70 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck source=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}"
|
||||
|
||||
set -e
|
||||
isDebugging && set -x
|
||||
|
||||
if isTrue ${SYNC_SKIP_NEWER_IN_DESTINATION}; then
|
||||
updateArg="--skip-newer-in-destination"
|
||||
fi
|
||||
|
||||
if isTrue ${REPLACE_ENV_DURING_SYNC}; then
|
||||
subcommand=sync-and-interpolate
|
||||
else
|
||||
subcommand=sync
|
||||
fi
|
||||
|
||||
if [ -d /plugins ]; then
|
||||
case ${FAMILY} in
|
||||
SPIGOT|HYBRID)
|
||||
mkdir -p /data/plugins
|
||||
log "Copying plugins over..."
|
||||
mc-image-helper \
|
||||
--debug=${DEBUG} ${subcommand} $updateArg \
|
||||
--replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \
|
||||
--replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \
|
||||
--replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \
|
||||
--replace-env-prefix=${REPLACE_ENV_VARIABLE_PREFIX} \
|
||||
/plugins /data/plugins
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# If any modules have been provided, copy them over
|
||||
: "${COPY_MODS_DEST:="/data/mods"}"
|
||||
|
||||
if [ -d /mods ]; then
|
||||
log "Copying any mods over..."
|
||||
mc-image-helper \
|
||||
--debug=${DEBUG} ${subcommand} $updateArg \
|
||||
--replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \
|
||||
--replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \
|
||||
--replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \
|
||||
--replace-env-prefix=${REPLACE_ENV_VARIABLE_PREFIX} \
|
||||
/mods "${COPY_MODS_DEST}"
|
||||
fi
|
||||
|
||||
: "${COPY_CONFIG_DEST:="/data/config"}"
|
||||
|
||||
if [ -d /config ]; then
|
||||
log "Copying any configs from /config to ${COPY_CONFIG_DEST}"
|
||||
mc-image-helper \
|
||||
--debug=${DEBUG} ${subcommand} $updateArg \
|
||||
--replace-env-file-suffixes="${REPLACE_ENV_SUFFIXES}" \
|
||||
--replace-env-excludes="${REPLACE_ENV_VARIABLES_EXCLUDES}" \
|
||||
--replace-env-exclude-paths="${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS}" \
|
||||
--replace-env-prefix=${REPLACE_ENV_VARIABLE_PREFIX} \
|
||||
/config "${COPY_CONFIG_DEST}"
|
||||
fi
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupServerProperties" "$@"
|
||||
@@ -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" "$@"
|
||||
@@ -1,240 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
|
||||
: "${SERVER_PROPERTIES:=/data/server.properties}"
|
||||
|
||||
# FUNCTIONS
|
||||
function setServerPropValue {
|
||||
local prop=$1
|
||||
local value=$2
|
||||
# normalize booleans
|
||||
case ${value^^} in
|
||||
TRUE|FALSE)
|
||||
value=${value,,} ;;
|
||||
esac
|
||||
if grep "${prop}" "$SERVER_PROPERTIES" > /dev/null; then
|
||||
log "Setting ${prop} to '${value}' in ${SERVER_PROPERTIES}"
|
||||
sed -i "/^${prop}\s*=/ c ${prop}=${value//\\/\\\\}" "$SERVER_PROPERTIES"
|
||||
else
|
||||
log "Adding ${prop} with '${value}' in ${SERVER_PROPERTIES}"
|
||||
echo "${prop}=${value}" >> "$SERVER_PROPERTIES"
|
||||
fi
|
||||
}
|
||||
|
||||
function setServerProp {
|
||||
local prop=$1
|
||||
local varName=$2
|
||||
|
||||
if [ -v $varName ]; then
|
||||
setServerPropValue "$prop" "${!varName}"
|
||||
fi
|
||||
}
|
||||
|
||||
function customizeServerProps {
|
||||
# Whitelist processing
|
||||
if [ -n "$WHITELIST" ] || [ -n "$WHITELIST_FILE" ] || isTrue "${ENABLE_WHITELIST:-false}"; then
|
||||
log "Enabling whitelist functionality"
|
||||
setServerPropValue "white-list" "true"
|
||||
else
|
||||
log "Disabling whitelist functionality"
|
||||
setServerPropValue "white-list" "false"
|
||||
fi
|
||||
setServerProp "enforce-whitelist" ENFORCE_WHITELIST
|
||||
if [[ $(grep "enforce-whitelist" $SERVER_PROPERTIES) != *true ]]; then
|
||||
log "WARNING: whitelist enabled but not enforced. Set ENFORCE_WHITELIST=TRUE or update 'enforce-whitelist' in server.properties to enforce the whitelist."
|
||||
fi
|
||||
|
||||
# If not provided, generate a reasonable default message-of-the-day,
|
||||
# which shows up in the server listing in the client
|
||||
if ! [ -v MOTD ]; then
|
||||
# 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
|
||||
else
|
||||
label=${ORIGINAL_TYPE}
|
||||
fi
|
||||
|
||||
# Convert label to title-case
|
||||
label=${label,,}
|
||||
label=${label^}
|
||||
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
|
||||
setServerProp "allow-nether" ALLOW_NETHER
|
||||
setServerProp "announce-player-achievements" ANNOUNCE_PLAYER_ACHIEVEMENTS
|
||||
setServerProp "enable-command-block" ENABLE_COMMAND_BLOCK
|
||||
setServerProp "spawn-animals" SPAWN_ANIMALS
|
||||
setServerProp "spawn-monsters" SPAWN_MONSTERS
|
||||
setServerProp "spawn-npcs" SPAWN_NPCS
|
||||
setServerProp "spawn-protection" SPAWN_PROTECTION
|
||||
setServerProp "generate-structures" GENERATE_STRUCTURES
|
||||
setServerProp "view-distance" VIEW_DISTANCE
|
||||
setServerProp "hardcore" HARDCORE
|
||||
setServerProp "snooper-enabled" SNOOPER_ENABLED
|
||||
setServerProp "max-build-height" MAX_BUILD_HEIGHT
|
||||
setServerProp "force-gamemode" FORCE_GAMEMODE
|
||||
setServerProp "max-tick-time" MAX_TICK_TIME
|
||||
setServerProp "enable-query" ENABLE_QUERY
|
||||
setServerProp "query.port" QUERY_PORT
|
||||
setServerProp "enable-rcon" ENABLE_RCON
|
||||
setServerProp "rcon.password" RCON_PASSWORD
|
||||
setServerProp "rcon.port" RCON_PORT
|
||||
setServerProp "max-players" MAX_PLAYERS
|
||||
setServerProp "max-world-size" MAX_WORLD_SIZE
|
||||
setServerProp "level-name" LEVEL
|
||||
setServerProp "level-seed" SEED
|
||||
setServerProp "pvp" PVP
|
||||
setServerProp "generator-settings" GENERATOR_SETTINGS
|
||||
setServerProp "online-mode" ONLINE_MODE
|
||||
setServerProp "allow-flight" ALLOW_FLIGHT
|
||||
setServerProp "resource-pack" RESOURCE_PACK
|
||||
setServerProp "resource-pack-sha1" RESOURCE_PACK_SHA1
|
||||
setServerProp "require-resource-pack" RESOURCE_PACK_ENFORCE
|
||||
setServerProp "player-idle-timeout" PLAYER_IDLE_TIMEOUT
|
||||
setServerProp "broadcast-console-to-ops" BROADCAST_CONSOLE_TO_OPS
|
||||
setServerProp "broadcast-rcon-to-ops" BROADCAST_RCON_TO_OPS
|
||||
setServerProp "enable-jmx-monitoring" ENABLE_JMX
|
||||
setServerProp "sync-chunk-writes" SYNC_CHUNK_WRITES
|
||||
setServerProp "enable-status" ENABLE_STATUS
|
||||
setServerProp "entity-broadcast-range-percentage" ENTITY_BROADCAST_RANGE_PERCENTAGE
|
||||
setServerProp "function-permission-level" FUNCTION_PERMISSION_LEVEL
|
||||
setServerProp "network-compression-threshold" NETWORK_COMPRESSION_THRESHOLD
|
||||
setServerProp "op-permission-level" OP_PERMISSION_LEVEL
|
||||
setServerProp "prevent-proxy-connections" PREVENT_PROXY_CONNECTIONS
|
||||
setServerProp "use-native-transport" USE_NATIVE_TRANSPORT
|
||||
setServerProp "simulation-distance" SIMULATION_DISTANCE
|
||||
setServerPropValue "motd" "$(echo "$MOTD" | mc-image-helper asciify)"
|
||||
[[ $LEVEL_TYPE ]] && setServerPropValue "level-type" "${LEVEL_TYPE^^}"
|
||||
|
||||
if [ -n "$DIFFICULTY" ]; then
|
||||
case ${DIFFICULTY,,} in
|
||||
peaceful|0)
|
||||
if versionLessThan 1.13; then
|
||||
DIFFICULTY=0
|
||||
else
|
||||
DIFFICULTY=peaceful
|
||||
fi
|
||||
;;
|
||||
easy|1)
|
||||
if versionLessThan 1.13; then
|
||||
DIFFICULTY=1
|
||||
else
|
||||
DIFFICULTY=easy
|
||||
fi
|
||||
;;
|
||||
normal|2)
|
||||
if versionLessThan 1.13; then
|
||||
DIFFICULTY=2
|
||||
else
|
||||
DIFFICULTY=normal
|
||||
fi
|
||||
;;
|
||||
hard|3)
|
||||
if versionLessThan 1.13; then
|
||||
DIFFICULTY=3
|
||||
else
|
||||
DIFFICULTY=hard
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log "DIFFICULTY must be peaceful, easy, normal, or hard."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
setServerPropValue "difficulty" "$DIFFICULTY"
|
||||
fi
|
||||
|
||||
if [ -n "$MODE" ]; then
|
||||
log "Setting mode"
|
||||
case ${MODE,,} in
|
||||
su*|0)
|
||||
if versionLessThan 1.13; then
|
||||
MODE=0
|
||||
else
|
||||
MODE=survival
|
||||
fi
|
||||
;;
|
||||
c*|1)
|
||||
if versionLessThan 1.13; then
|
||||
MODE=1
|
||||
else
|
||||
MODE=creative
|
||||
fi
|
||||
;;
|
||||
a*|2)
|
||||
if versionLessThan 1.13; then
|
||||
MODE=2
|
||||
else
|
||||
MODE=adventure
|
||||
fi
|
||||
;;
|
||||
sp*|3)
|
||||
if versionLessThan 1.13; then
|
||||
MODE=3
|
||||
else
|
||||
MODE=spectator
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log "ERROR: Invalid game mode: $MODE"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
setServerPropValue "gamemode" "$MODE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Deploy server.properties file
|
||||
if [[ ${TYPE} == "CURSEFORGE" ]]; then
|
||||
export SERVER_PROPERTIES="${FTB_DIR}/server.properties"
|
||||
log "detected FTB, changing properties path to ${SERVER_PROPERTIES}"
|
||||
fi
|
||||
|
||||
if ! isTrue "${SKIP_SERVER_PROPERTIES:-false}"; then
|
||||
if [ ! -e "$SERVER_PROPERTIES" ]; then
|
||||
log "Creating server.properties in ${SERVER_PROPERTIES}"
|
||||
cp /tmp/server.properties "$SERVER_PROPERTIES"
|
||||
customizeServerProps
|
||||
elif [ -n "${OVERRIDE_SERVER_PROPERTIES}" ]; then
|
||||
case ${OVERRIDE_SERVER_PROPERTIES^^} in
|
||||
TRUE|1)
|
||||
customizeServerProps
|
||||
;;
|
||||
*)
|
||||
log "server.properties already created, skipping"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
log "server.properties already created, skipping"
|
||||
fi
|
||||
else
|
||||
log "Skipping setup of server.properties"
|
||||
fi
|
||||
|
||||
if isTrue "${ENABLE_AUTOPAUSE}"; then
|
||||
current_max_tick=$( grep 'max-tick-time' "$SERVER_PROPERTIES" | sed -r 's/( )+//g' | awk -F= '{print $2}' )
|
||||
if (( current_max_tick > 0 && current_max_tick < 86400000 )); then
|
||||
log "Warning: The server.properties for the server doesn't have the Server Watchdog (effectively) disabled."
|
||||
log "Warning (cont): Autopause functionality resuming the process might trigger the Watchdog and restart the server completely."
|
||||
log "Warning (cont): Set the max-tick-time property to a high value (or disable the Watchdog with value -1 for versions 1.8.1+)."
|
||||
fi
|
||||
fi
|
||||
|
||||
if isDebugging && [ -f "${SERVER_PROPERTIES}" ]; then
|
||||
log "DEBUG Dumping server.properties"
|
||||
cat "${SERVER_PROPERTIES}"
|
||||
fi
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupEnvVariables" "$@"
|
||||
@@ -1,126 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e -o pipefail
|
||||
|
||||
: "${REMOVE_OLD_VANILLATWEAKS:=false}"
|
||||
: "${VANILLATWEAKS_FILE:=}"
|
||||
: "${VANILLATWEAKS_SHARECODE:=}"
|
||||
: "${REMOVE_OLD_VANILLATWEAKS_DEPTH:=1} "
|
||||
: "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:=*.zip}"
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
isDebugging && set -x
|
||||
|
||||
VT_VERSION=""
|
||||
DATAPACKS_DIR="/data/${LEVEL:-world}/datapacks"
|
||||
RESOURCEPACKS_DIR="/data/resourcepacks"
|
||||
|
||||
# Remove old VANILLATWEAKS
|
||||
if isTrue "${REMOVE_OLD_VANILLATWEAKS}"; then
|
||||
# NOTE: datapacks include crafting tweaks.
|
||||
if [ -d "$DATAPACKS_DIR" ]; then
|
||||
find "$DATAPACKS_DIR" -mindepth 1 -maxdepth ${REMOVE_OLD_VANILLATWEAKS_DEPTH:-16} -wholename "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_VANILLATWEAKS_EXCLUDE:-}" -delete
|
||||
fi
|
||||
if [ -d "$RESOURCEPACKS_DIR" ]; then
|
||||
find "$RESOURCEPACKS_DIR" -mindepth 1 -maxdepth ${REMOVE_OLD_VANILLATWEAKS_DEPTH:-16} -wholename "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_VANILLATWEAKS_EXCLUDE:-}" -delete
|
||||
fi
|
||||
fi
|
||||
|
||||
# Gets the download url and downloads the actual files.
|
||||
getUrlAndDownload(){
|
||||
VT_FILE=$1
|
||||
URL_SUFFIX=$2
|
||||
OUTPUT_FILE=$3
|
||||
PACKS=$(jq -jc '.packs // empty' $VT_FILE)
|
||||
if [ ! "$PACKS" ]; then
|
||||
log "ERROR: unable to retrieve ${URL_SUFFIX} from ${VT_FILE}"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
ZIPDATA_URL="https://vanillatweaks.net/assets/server/zip${URL_SUFFIX}.php"
|
||||
DOWNLOAD_URL=$(curl -X POST -F "packs=${PACKS}" -F "version=${VT_VERSION}" $ZIPDATA_URL | jq -r '.link // empty')
|
||||
if [ ! "$DOWNLOAD_URL" ]; then
|
||||
log "ERROR: unable to retrieve ${URL_SUFFIX} packs from vanillatweaks.net!"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if ! get -o $OUTPUT_FILE "https://vanillatweaks.net${DOWNLOAD_URL}"; then
|
||||
log "ERROR: failed to download ${URL_SUFFIX} from ${DOWNLOAD_URL}"
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
# Datapacks Handler
|
||||
downloadDatapacks(){
|
||||
VT_FILE=$1
|
||||
URL_SUFFIX="datapacks"
|
||||
OUTPUT_FILE="/tmp/vanillatweaks.zip"
|
||||
getUrlAndDownload $VT_FILE $URL_SUFFIX $OUTPUT_FILE
|
||||
mkdir -p "$DATAPACKS_DIR"
|
||||
if ! unzip -o -d "$DATAPACKS_DIR" $OUTPUT_FILE; then
|
||||
log "ERROR: failed to unzip the datapacks ${DATAPACKS} from ${OUTPUT_FILE}"
|
||||
fi
|
||||
rm -f $OUTPUT_FILE
|
||||
}
|
||||
|
||||
# Crafting Tweaks Handler
|
||||
downloadCraftingtweaks(){
|
||||
VT_FILE=$1
|
||||
mkdir -p "$DATAPACKS_DIR"
|
||||
getUrlAndDownload $VT_FILE "craftingtweaks" "${DATAPACKS_DIR}/craftingtweaks.zip"
|
||||
}
|
||||
|
||||
# Resourcepacks Handler
|
||||
downloadResourcepacks(){
|
||||
VT_FILE=$1
|
||||
mkdir -p "$RESOURCEPACKS_DIR"
|
||||
getUrlAndDownload $VT_FILE "resourcepacks" "${RESOURCEPACKS_DIR}/resourcepacks.zip"
|
||||
}
|
||||
|
||||
# Example: VANILLATWEAKS_SHARECODE=MGr52E
|
||||
# Code generated from the UI website, typically a alphanumeric 6 digit code.
|
||||
if [[ "$VANILLATWEAKS_SHARECODE" ]]; then
|
||||
VANILLATWEAKS_FILE=()
|
||||
for SHARECODE in ${VANILLATWEAKS_SHARECODE//,/ }; do
|
||||
TMP_FILE="/tmp/${SHARECODE}.json"
|
||||
SHARECODE_LOOKUP_URL="https://vanillatweaks.net/assets/server/sharecode.php?code=${SHARECODE}"
|
||||
if ! get -o "$TMP_FILE" "$SHARECODE_LOOKUP_URL"; then
|
||||
log "ERROR: Unable to use ${SHARECODE} share code provided to retrieve vanillatweaks file"
|
||||
exit 2
|
||||
fi
|
||||
VANILLATWEAKS_FILE+="${TMP_FILE},"
|
||||
done
|
||||
fi
|
||||
|
||||
# Use vanillatweaks file to specify VT and datapacks and crafting tweaks
|
||||
if [[ "$VANILLATWEAKS_FILE" ]]; then
|
||||
for VT_FILE in ${VANILLATWEAKS_FILE//,/ }; do
|
||||
if [ ! -f "$VT_FILE" ]; then
|
||||
log "ERROR: given VANILLATWEAKS_FILE file does not exist"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
VT_VERSION=$(jq -jc '.version // empty' $VT_FILE)
|
||||
if [ ! "$VT_VERSION" ]; then
|
||||
log "ERROR: unable to retrieve version from $VT_FILE"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
TYPE=$(jq -jc '.type // empty' $VT_FILE)
|
||||
if [[ "$TYPE" = "datapacks" ]]; then
|
||||
downloadDatapacks $VT_FILE
|
||||
elif [[ "$TYPE" = "craftingtweaks" ]]; then
|
||||
downloadCraftingtweaks $VT_FILE
|
||||
elif [[ "$TYPE" = "resourcepacks" ]]; then
|
||||
downloadResourcepacks $VT_FILE
|
||||
fi
|
||||
|
||||
# cleans up temp vanilla tweaks file download to get stored packs
|
||||
if [[ "$VANILLATWEAKS_SHARECODE" ]]; then
|
||||
rm -f $VT_FILE
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupDatapack" "$@"
|
||||
@@ -1,126 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
set -e
|
||||
isDebugging && set -x
|
||||
|
||||
if [ "$TYPE" = "CURSEFORGE" ]; then
|
||||
worldDest=$FTB_DIR/${LEVEL:-world}
|
||||
else
|
||||
worldDest=/data/${LEVEL:-world}
|
||||
fi
|
||||
|
||||
if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] ); then
|
||||
if isTrue "${FORCE_WORLD_COPY}"; then
|
||||
log "Removing existing world data in $worldDest ${worldDest}_nether ${worldDest}_the_end"
|
||||
rm -rf "$worldDest" \
|
||||
"${worldDest}_nether" \
|
||||
"${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
|
||||
fi
|
||||
|
||||
if [ -f "$WORLD" ]; then
|
||||
log "Extracting 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
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
fi
|
||||
elif [ -d "$WORLD" ]; then
|
||||
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
|
||||
# Reorganise if a Spigot server
|
||||
log "Moving End and Nether maps to Spigot location"
|
||||
[ -d "$worldDest/DIM1" ] && mv -f "$worldDest/DIM1" "${worldDest}_the_end"
|
||||
[ -d "$worldDest/DIM-1" ] && mv -f "$worldDest/DIM-1" "${worldDest}_nether"
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupVanillaTweaks" "$@"
|
||||
18
scripts/start → start
Executable file → Normal file
18
scripts/start → start
Executable file → Normal 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
|
||||
@@ -1,15 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
|
||||
: "${SERVER_PORT:=25565}"
|
||||
export SERVER_PORT
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
|
||||
log "Autopause functionality enabled"
|
||||
|
||||
isDebugging && set -x
|
||||
|
||||
cp /autopause/knockd-config.cfg /tmp/knockd-config.cfg
|
||||
|
||||
# update server port to listen to
|
||||
168
start-configuration
Normal file
168
start-configuration
Normal file
@@ -0,0 +1,168 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
|
||||
: ${EULA:=}
|
||||
: ${PROXY:=}
|
||||
: ${RCON_PASSWORD_FILE:=}
|
||||
|
||||
shopt -s nullglob
|
||||
|
||||
#umask 002
|
||||
export HOME=/data
|
||||
|
||||
log "Running as uid=$(id -u) gid=$(id -g) with /data as '$(ls -lnd /data)'"
|
||||
|
||||
if [ ! -e /data/eula.txt ]; then
|
||||
if ! isTrue "$EULA"; then
|
||||
log ""
|
||||
log "Please accept the Minecraft EULA at"
|
||||
log " https://account.mojang.com/documents/minecraft_eula"
|
||||
log "by adding the following immediately after 'docker run':"
|
||||
log " -e EULA=TRUE"
|
||||
log ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
writeEula
|
||||
fi
|
||||
|
||||
|
||||
if [[ $PROXY ]]; then
|
||||
export http_proxy="$PROXY"
|
||||
export https_proxy="$PROXY"
|
||||
export JAVA_TOOL_OPTIONS+="-Djava.net.useSystemProxies=true"
|
||||
log "INFO: Giving proxy time to startup..."
|
||||
sleep 5
|
||||
fi
|
||||
|
||||
if [[ $RCON_PASSWORD_FILE ]]; then
|
||||
log ""
|
||||
if [ ! -e ${RCON_PASSWORD_FILE} ]; then
|
||||
log "Initial RCON password file ${RCON_PASSWORD_FILE} does not seems to exist."
|
||||
log "Please ensure your configuration."
|
||||
log "If you are using Docker Secrets feature, please check this for further information: "
|
||||
log " https://docs.docker.com/engine/swarm/secrets"
|
||||
log ""
|
||||
exit 1
|
||||
else
|
||||
RCON_PASSWORD=$(cat ${RCON_PASSWORD_FILE})
|
||||
export RCON_PASSWORD
|
||||
fi
|
||||
log ""
|
||||
fi
|
||||
|
||||
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
|
||||
|
||||
case "X$VERSION" in
|
||||
X|XLATEST|Xlatest)
|
||||
VANILLA_VERSION=$(curl -fsSL $VERSIONS_JSON | jq -r '.latest.release')
|
||||
;;
|
||||
XSNAPSHOT|Xsnapshot)
|
||||
VANILLA_VERSION=$(curl -fsSL $VERSIONS_JSON | jq -r '.latest.snapshot')
|
||||
;;
|
||||
*)
|
||||
VANILLA_VERSION=$VERSION
|
||||
;;
|
||||
esac
|
||||
export VANILLA_VERSION
|
||||
log "Resolved version given ${VERSION} into ${VANILLA_VERSION}"
|
||||
|
||||
cd /data || exit 1
|
||||
|
||||
export ORIGINAL_TYPE=${TYPE^^}
|
||||
|
||||
if isTrue "${ENABLE_AUTOPAUSE}"; then
|
||||
${SCRIPTS:-/}start-autopause
|
||||
fi
|
||||
|
||||
log "Resolving type given ${TYPE}"
|
||||
case "${TYPE^^}" in
|
||||
*BUKKIT|SPIGOT)
|
||||
exec ${SCRIPTS:-/}start-deployBukkitSpigot "$@"
|
||||
;;
|
||||
|
||||
PAPER)
|
||||
exec ${SCRIPTS:-/}start-deployPaper "$@"
|
||||
;;
|
||||
|
||||
TUINITY)
|
||||
exec ${SCRIPTS:-/}start-deployTuinity "$@"
|
||||
;;
|
||||
|
||||
FORGE)
|
||||
exec ${SCRIPTS:-/}start-deployForge "$@"
|
||||
;;
|
||||
|
||||
FABRIC)
|
||||
exec ${SCRIPTS:-/}start-deployFabric "$@"
|
||||
;;
|
||||
|
||||
FTBA)
|
||||
exec ${SCRIPTS:-/}start-deployFTBA "$@"
|
||||
;;
|
||||
|
||||
FTB|CURSEFORGE)
|
||||
exec ${SCRIPTS:-/}start-deployCF "$@"
|
||||
;;
|
||||
|
||||
VANILLA)
|
||||
exec ${SCRIPTS:-/}start-deployVanilla "$@"
|
||||
;;
|
||||
|
||||
SPONGEVANILLA)
|
||||
exec ${SCRIPTS:-/}start-deploySpongeVanilla "$@"
|
||||
;;
|
||||
|
||||
CUSTOM)
|
||||
exec ${SCRIPTS:-/}start-deployCustom "$@"
|
||||
;;
|
||||
|
||||
CURSE_INSTANCE)
|
||||
exec ${SCRIPTS:-/}start-validateCurseInstance "$@"
|
||||
;;
|
||||
|
||||
MAGMA)
|
||||
exec ${SCRIPTS:-/}start-deployMagma "$@"
|
||||
;;
|
||||
|
||||
MOHIST)
|
||||
exec ${SCRIPTS:-/}start-deployMohist "$@"
|
||||
;;
|
||||
|
||||
CATSERVER)
|
||||
exec ${SCRIPTS:-/}start-deployCatserver "$@"
|
||||
;;
|
||||
|
||||
PURPUR)
|
||||
exec ${SCRIPTS:-/}start-deployPurpur "$@"
|
||||
;;
|
||||
|
||||
YATOPIA)
|
||||
exec ${SCRIPTS:-/}start-deployYatopia "$@"
|
||||
;;
|
||||
|
||||
AIRPLANE)
|
||||
exec ${SCRIPTS:-/}start-deployAirplane "$@"
|
||||
;;
|
||||
|
||||
CANYON)
|
||||
exec ${SCRIPTS:-/}start-deployCanyon "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
log "Invalid type: '$TYPE'"
|
||||
log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTBA (multiarch-only),"
|
||||
log " CURSE_INSTANCE, CURSEFORGE, SPONGEVANILLA, TUINITY, PURPUR"
|
||||
log " CUSTOM, MAGMA, MOHIST, CATSERVER, YATOPIA, AIRPLANE, CANYON"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
52
start-deployAirplane
Normal file
52
start-deployAirplane
Normal file
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
isDebugging && set -x
|
||||
|
||||
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "1.16" ] && [ "${VERSION}" != "1.17" ] && [ "${VERSION}" != "PURPUR" ] && [ "${VERSION}" != "PURPUR-1.16" ] ; then
|
||||
log "ERROR: Airplane server type only supports VERSION=LATEST, VERSION=1.17, VERSION=1.16, VERSION=PURPUR or VERSION=PURPUR-1.16. Note that these are branches, not #.#.# versions."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
: ${AIRPLANE_BUILD:=lastSuccessfulBuild}
|
||||
: ${AIRPLANE_TYPE:=airplane}
|
||||
|
||||
if [ "${VERSION}" = "LATEST" ] || [ "${VERSION}" = "1.17" ]; then
|
||||
AIRPLANE_BRANCH="1.17"
|
||||
fi
|
||||
|
||||
if [ "${VERSION}" = "1.16" ]; then
|
||||
AIRPLANE_BRANCH="1.16"
|
||||
fi
|
||||
|
||||
if [ "${VERSION}" = "PURPUR" ]; then
|
||||
AIRPLANE_BRANCH="Purpur-1.17"
|
||||
AIRPLANE_TYPE="airplanepurpur"
|
||||
fi
|
||||
|
||||
if [ "${VERSION}" = "PURPUR-1.16" ]; then
|
||||
AIRPLANE_BRANCH="Purpur-1.16"
|
||||
AIRPLANE_TYPE="airplanepurpur"
|
||||
fi
|
||||
|
||||
log "Using Airplane-${AIRPLANE_BRANCH} branch"
|
||||
|
||||
export SERVER=airplane-${AIRPLANE_BRANCH}-${AIRPLANE_BUILD}.jar
|
||||
|
||||
if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
|
||||
downloadUrl="https://ci.tivy.ca/job/Airplane-${AIRPLANE_BRANCH}/${AIRPLANE_BUILD}/artifact/launcher-${AIRPLANE_TYPE}.jar"
|
||||
log "Downloading Airplane from $downloadUrl ..."
|
||||
curl -fsSL -o "$SERVER" "$downloadUrl"
|
||||
if [ ! -f "$SERVER" ]; then
|
||||
log "ERROR: failed to download from $downloadUrl (status=$?)"
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
|
||||
# Normalize on Spigot for later operations
|
||||
export TYPE=SPIGOT
|
||||
export SKIP_LOG4J_CONFIG=true
|
||||
|
||||
exec ${SCRIPTS:-/}start-spiget "$@"
|
||||
5
scripts/start-deployBukkitSpigot → start-deployBukkitSpigot
Executable file → Normal file
5
scripts/start-deployBukkitSpigot → start-deployBukkitSpigot
Executable file → Normal file
@@ -64,7 +64,7 @@ function downloadSpigot {
|
||||
fi
|
||||
|
||||
if [[ -z $downloadUrl ]]; then
|
||||
if versionLessThan 1.16.5 || ([[ ${getbukkitFlavor} = "craftbukkit" ]] && [[ ${VANILLA_VERSION} = "1.16.5" ]]); then
|
||||
if versionLessThan 1.16.5; then
|
||||
downloadUrl="https://cdn.getbukkit.org/${getbukkitFlavor}/${getbukkitFlavor}-${VANILLA_VERSION}.jar"
|
||||
else
|
||||
downloadUrl="https://download.getbukkit.org/${getbukkitFlavor}/${getbukkitFlavor}-${VANILLA_VERSION}.jar"
|
||||
@@ -126,6 +126,7 @@ else
|
||||
fi
|
||||
|
||||
# Normalize on Spigot for operations below
|
||||
export FAMILY=SPIGOT
|
||||
export TYPE=SPIGOT
|
||||
export SKIP_LOG4J_CONFIG=true
|
||||
|
||||
exec ${SCRIPTS:-/}start-spiget "$@"
|
||||
138
scripts/start-deployCF → start-deployCF
Executable file → Normal file
138
scripts/start-deployCF → start-deployCF
Executable file → Normal file
@@ -2,8 +2,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
|
||||
loadForgeVars() {
|
||||
cfgFile=${1?}
|
||||
@@ -24,7 +23,7 @@ loadForgeVars() {
|
||||
|
||||
isDebugging && set -x
|
||||
|
||||
: "${FTB_BASE_DIR:=${CF_BASE_DIR:-/data/FeedTheBeast}}"
|
||||
: ${FTB_BASE_DIR:=${CF_BASE_DIR:-/data/FeedTheBeast}}
|
||||
export FTB_BASE_DIR
|
||||
|
||||
legacyJavaFixerUrl=https://ftb.forgecdn.net/FTB2/maven/net/minecraftforge/lex/legacyjavafixer/1.0/legacyjavafixer-1.0.jar
|
||||
@@ -35,37 +34,11 @@ FTB_SERVER_MOD=${FTB_SERVER_MOD:-$CF_SERVER_MOD}
|
||||
log "Looking for Feed-The-Beast / CurseForge server modpack."
|
||||
requireVar FTB_SERVER_MOD
|
||||
|
||||
downloadModpack() {
|
||||
srv_modpack=${FTB_SERVER_MOD}
|
||||
if isURL "${srv_modpack}"; then
|
||||
log "Downloading modpack from ${srv_modpack}..."
|
||||
if ! srv_modpack=$(get -o /data --output-filename --skip-existing "${srv_modpack}"); then
|
||||
log "ERROR: failed to download modpack"
|
||||
exit 1
|
||||
fi
|
||||
if ! isTrue ${USE_MODPACK_START_SCRIPT:-true}; then
|
||||
if ! [ -f "${FTB_SERVER_MOD}" ]; then
|
||||
log "ERROR unable to find requested modpack file ${FTB_SERVER_MOD}"
|
||||
exit 2
|
||||
fi
|
||||
if [[ "${srv_modpack:0:5}" == "data/" ]]; then
|
||||
# Prepend with "/"
|
||||
srv_modpack="/${srv_modpack}"
|
||||
fi
|
||||
if [[ ! "${srv_modpack:0:1}" == "/" ]]; then
|
||||
# If not an absolute path, assume file is in "/data"
|
||||
srv_modpack=/data/${srv_modpack}
|
||||
fi
|
||||
if [[ ! -f "${srv_modpack}" ]]; then
|
||||
log "FTB server modpack ${srv_modpack} not found."
|
||||
exit 2
|
||||
fi
|
||||
if [[ ! "${srv_modpack: -4}" == ".zip" ]]; then
|
||||
log "FTB server modpack ${srv_modpack} is not a zip archive."
|
||||
log "Please set FTB_SERVER_MOD to a file with a .zip extension."
|
||||
exit 2
|
||||
fi
|
||||
FTB_SERVER_MOD=${srv_modpack}
|
||||
}
|
||||
|
||||
if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
|
||||
downloadModpack
|
||||
|
||||
needsInstall=true
|
||||
installMarker=/data/.curseforge-installed
|
||||
@@ -73,9 +46,9 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
|
||||
if [ "$(cat $installMarker)" != "${FTB_SERVER_MOD}" ]; then
|
||||
log "Upgrading modpack"
|
||||
|
||||
serverJar=$(find "${FTB_BASE_DIR}" -type f \( -path "*/libraries/*" -o -path "*/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
|
||||
serverJar=$(find ${FTB_BASE_DIR} -not -name "forge*installer.jar" -name "forge*.jar")
|
||||
if [[ "${serverJar}" ]]; then
|
||||
rm -rf "$(dirname "${serverJar}")"/{mods,*.jar,libraries,resources,scripts,config}
|
||||
rm -rf $(dirname "${serverJar}")/{mods,*.jar,libraries,resources,scripts,config}
|
||||
fi
|
||||
else
|
||||
needsInstall=false
|
||||
@@ -84,10 +57,10 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
|
||||
|
||||
if $needsInstall; then
|
||||
log "Unpacking FTB server modpack ${FTB_SERVER_MOD} ..."
|
||||
mkdir -p "${FTB_BASE_DIR}"
|
||||
unzip -o "${FTB_SERVER_MOD}" -d "${FTB_BASE_DIR}" | awk '{printf "."} END {print ""}'
|
||||
mkdir -p ${FTB_BASE_DIR}
|
||||
unzip -o "${FTB_SERVER_MOD}" -d ${FTB_BASE_DIR} | awk '{printf "."} END {print ""}'
|
||||
|
||||
serverJar=$(find "${FTB_BASE_DIR}" -type f \( -path "*/libraries/*" -o -path "*/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
|
||||
serverJar=$(find ${FTB_BASE_DIR} -type f \( -path "*/libraries/*" -o -path "*/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
|
||||
if [[ -z "$serverJar" ]]; then
|
||||
|
||||
if [ -f "${FTB_BASE_DIR}/settings.cfg" ]; then
|
||||
@@ -113,24 +86,22 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
|
||||
|
||||
log "Installing forge server"
|
||||
dirOfInstaller=$(dirname "${forgeInstallerJar}")
|
||||
(cd "${dirOfInstaller}"; java -jar "$(basename "${forgeInstallerJar}")" --installServer)
|
||||
(cd "${dirOfInstaller}"; java -jar $(basename "${forgeInstallerJar}") --installServer)
|
||||
fi
|
||||
|
||||
echo "${FTB_SERVER_MOD}" > $installMarker
|
||||
fi
|
||||
|
||||
SERVER=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( -path "/libraries/*" -o -path "/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
|
||||
export SERVER=$(find ${FTB_BASE_DIR} -type f \( -path "/libraries/*" -o -path "/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -maxdepth 2 -print)
|
||||
if [[ -z "${SERVER}" || ! -f "${SERVER}" ]]; then
|
||||
log "ERROR unable to locate installed forge server jar"
|
||||
isDebugging && find "${FTB_BASE_DIR}" -name "forge*.jar"
|
||||
isDebugging && find ${FTB_BASE_DIR} -name "forge*.jar"
|
||||
exit 2
|
||||
fi
|
||||
export SERVER
|
||||
|
||||
FTB_DIR=$(dirname "${SERVER}")
|
||||
export FTB_DIR
|
||||
export FTB_DIR=$(dirname "${SERVER}")
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||
exec ${SCRIPTS:-/}start-finalSetupWorld $@
|
||||
fi
|
||||
|
||||
entryScriptExpr="
|
||||
@@ -145,8 +116,8 @@ entryScriptExpr="
|
||||
"
|
||||
|
||||
if [[ -d ${FTB_BASE_DIR} ]]; then
|
||||
startScriptCount=$(find "${FTB_BASE_DIR}" $entryScriptExpr |wc -l)
|
||||
if (( startScriptCount > 1 )); then
|
||||
startScriptCount=$(find ${FTB_BASE_DIR} $entryScriptExpr |wc -l)
|
||||
if [[ $startScriptCount > 1 ]]; then
|
||||
log "Conflicting FTB/CurseForge packages have been installed. Please cleanup ${FTB_BASE_DIR}"
|
||||
exit 2
|
||||
fi
|
||||
@@ -158,12 +129,46 @@ fi
|
||||
# also check for the start script rather than just the folder
|
||||
# this allows saving just the world separate from the rest of the data directory
|
||||
if [[ $startScriptCount = 0 ]]; then
|
||||
downloadModpack
|
||||
srv_modpack=${FTB_SERVER_MOD}
|
||||
|
||||
if isURL "${srv_modpack}"; then
|
||||
case $srv_modpack in
|
||||
https://www.feed-the-beast.com/*/download|https://www.curseforge.com/minecraft/modpacks/*/download/*/file)
|
||||
;;
|
||||
https://www.curseforge.com/minecraft/modpacks/*/download/*)
|
||||
srv_modpack=${srv_modpack}/file;;
|
||||
https://www.feed-the-beast.com/*)
|
||||
srv_modpack=${srv_modpack}/download;;
|
||||
esac
|
||||
file=$(basename $(dirname $srv_modpack))
|
||||
downloaded=/data/${file}.zip
|
||||
if [ ! -e $downloaded ]; then
|
||||
log "Downloading FTB modpack...
|
||||
$srv_modpack -> $downloaded"
|
||||
curl -sSL -o $downloaded $srv_modpack
|
||||
fi
|
||||
srv_modpack=$downloaded
|
||||
fi
|
||||
if [[ "${srv_modpack:0:5}" == "data/" ]]; then
|
||||
# Prepend with "/"
|
||||
srv_modpack="/${srv_modpack}"
|
||||
fi
|
||||
if [[ ! "${srv_modpack:0:1}" == "/" ]]; then
|
||||
# If not an absolute path, assume file is in "/data"
|
||||
srv_modpack=/data/${srv_modpack}
|
||||
fi
|
||||
if [[ ! -f "${srv_modpack}" ]]; then
|
||||
log "FTB server modpack ${srv_modpack} not found."
|
||||
exit 2
|
||||
fi
|
||||
if [[ ! "${srv_modpack: -4}" == ".zip" ]]; then
|
||||
log "FTB server modpack ${srv_modpack} is not a zip archive."
|
||||
log "Please set FTB_SERVER_MOD to a file with a .zip extension."
|
||||
exit 2
|
||||
fi
|
||||
|
||||
log "Unpacking FTB server modpack ${srv_modpack} ..."
|
||||
mkdir -p "${FTB_BASE_DIR}"
|
||||
unzip -o "${srv_modpack}" -d "${FTB_BASE_DIR}" | awk '{printf "."} END {print ""}'
|
||||
mkdir -p ${FTB_BASE_DIR}
|
||||
unzip -o "${srv_modpack}" -d ${FTB_BASE_DIR} | awk '{printf "."} END {print ""}'
|
||||
|
||||
installScript=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f -name install.sh)
|
||||
if [[ "$installScript" ]]; then
|
||||
@@ -176,14 +181,13 @@ if [[ $startScriptCount = 0 ]]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $(find "${FTB_BASE_DIR}" $entryScriptExpr | wc -l) = 0 ]]; then
|
||||
if [[ $(find ${FTB_BASE_DIR} $entryScriptExpr | wc -l) = 0 ]]; then
|
||||
|
||||
# Allow up to 2 levels since some modpacks have a top-level directory named
|
||||
# for the modpack
|
||||
forgeJar=$(find "${FTB_BASE_DIR}" -maxdepth 2 -type f \( -path "/libraries/*" -o -path "/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
|
||||
forgeJar=$(find ${FTB_BASE_DIR} -type f \( -path "/libraries/*" -o -path "/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -maxdepth 2 -print)
|
||||
if [[ "$forgeJar" ]]; then
|
||||
FTB_BASE_DIR=$(dirname "${forgeJar}")
|
||||
export FTB_BASE_DIR
|
||||
export FTB_BASE_DIR=$(dirname "${forgeJar}")
|
||||
log "No entry script found, so building one for ${forgeJar}"
|
||||
cat > "${FTB_BASE_DIR}/ServerStart.sh" <<EOF
|
||||
#!/bin/sh
|
||||
@@ -201,29 +205,25 @@ scriptCount=$(find "${FTB_BASE_DIR}" $entryScriptExpr | wc -l)
|
||||
if [[ $scriptCount = 0 ]]; then
|
||||
log "Please make sure you are using the server version of the FTB modpack!"
|
||||
exit 2
|
||||
elif (( scriptCount > 1 )); then
|
||||
log "Ambiguous startup scripts in FTB modpack! Found:"
|
||||
find "${FTB_BASE_DIR}" $entryScriptExpr
|
||||
elif [[ $scriptCount > 1 ]]; then
|
||||
log "Ambigous startup scripts in FTB modpack!"
|
||||
log "found:"
|
||||
find ${FTB_BASE_DIR} $entryScriptExpr
|
||||
exit 2
|
||||
fi
|
||||
|
||||
FTB_SERVER_START=$(find "${FTB_BASE_DIR}" $entryScriptExpr)
|
||||
export FTB_SERVER_START
|
||||
export FTB_SERVER_START=$(find "${FTB_BASE_DIR}" $entryScriptExpr)
|
||||
|
||||
FTB_DIR=$(dirname "${FTB_SERVER_START}")
|
||||
export FTB_DIR
|
||||
export FTB_DIR=$(dirname "${FTB_SERVER_START}")
|
||||
chmod a+x "${FTB_SERVER_START}"
|
||||
grep fml.queryResult=confirm "${FTB_SERVER_START}" > /dev/null || \
|
||||
sed -i 's/-jar/-Dfml.queryResult=confirm -jar/' "${FTB_SERVER_START}"
|
||||
sed -i 's/.*read.*Restart now/#\0/' "${FTB_SERVER_START}"
|
||||
legacyJavaFixerPath="${FTB_DIR}/mods/legacyjavafixer.jar"
|
||||
|
||||
if isTrue "${FTB_LEGACYJAVAFIXER}" && [ ! -e "${legacyJavaFixerPath}" ]; then
|
||||
if isTrue ${FTB_LEGACYJAVAFIXER} && [ ! -e "${legacyJavaFixerPath}" ]; then
|
||||
log "Installing legacy java fixer to ${legacyJavaFixerPath}"
|
||||
if ! get -o "${legacyJavaFixerPath}" ${legacyJavaFixerUrl}; then
|
||||
log "ERROR failed to download legacy java fixer from ${legacyJavaFixerUrl}"
|
||||
exit 1
|
||||
fi
|
||||
curl -sSL -o "${legacyJavaFixerPath}" ${legacyJavaFixerUrl}
|
||||
fi
|
||||
|
||||
if [ -e "${FTB_DIR}/FTBInstall.sh" ]; then
|
||||
@@ -236,5 +236,5 @@ elif [ -e "${FTB_DIR}/Install.sh" ]; then
|
||||
popd
|
||||
fi
|
||||
|
||||
export FAMILY=FORGE
|
||||
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||
# Continue to Final Setup
|
||||
exec ${SCRIPTS:-/}start-finalSetupWorld $@
|
||||
14
scripts/start-deployCanyon → start-deployCanyon
Executable file → Normal file
14
scripts/start-deployCanyon → start-deployCanyon
Executable file → Normal file
@@ -2,11 +2,16 @@
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
isDebugging && set -x
|
||||
|
||||
: "${CANYON_BUILD:=lastSuccessfulBuild}"
|
||||
: ${CANYON_BUILD:=lastSuccessfulBuild}
|
||||
JAVA_VER=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1)
|
||||
|
||||
if [ "${JAVA_VER}" != "8" ]; then
|
||||
log "ERROR: Canyon server type only supports Java version 8"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${VERSION}" != "b1.7.3" ]; then
|
||||
log "ERROR: Canyon server type only supports VERSION=b1.7.3"
|
||||
@@ -43,6 +48,7 @@ if [ ! -f "$SERVER" ]; then
|
||||
fi
|
||||
|
||||
# Normalize on Spigot for later operations
|
||||
export FAMILY=SPIGOT
|
||||
export TYPE=SPIGOT
|
||||
export SKIP_LOG4J_CONFIG=true
|
||||
|
||||
exec ${SCRIPTS:-/}start-spiget "$@"
|
||||
8
scripts/start-deployCatserver → start-deployCatserver
Executable file → Normal file
8
scripts/start-deployCatserver → start-deployCatserver
Executable file → Normal file
@@ -1,7 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
set -o pipefail
|
||||
set -e
|
||||
|
||||
@@ -27,6 +26,7 @@ if [ ! -f ${SERVER} ]; then
|
||||
curl -H "Accept:application/octet-stream" -o "$SERVER" -fsSL https://api.github.com/repos/Luohuayu/CatServer/releases/assets/${latestJarId}
|
||||
fi
|
||||
|
||||
export FAMILY=HYBRID
|
||||
export SKIP_LOG4J_CONFIG=true
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||
# Continue to Final Setup
|
||||
exec ${SCRIPTS:-/}start-finalSetupWorld "$@"
|
||||
9
scripts/start-deployCustom → start-deployCustom
Executable file → Normal file
9
scripts/start-deployCustom → start-deployCustom
Executable file → Normal 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,7 @@ else
|
||||
|
||||
fi
|
||||
|
||||
# Allow for overriding Family on custom for testing.
|
||||
export FAMILY="${FAMILY:-HYBRID}"
|
||||
export SKIP_LOG4J_CONFIG=true
|
||||
|
||||
exec ${SCRIPTS:-/}start-setupWorld $@
|
||||
# Continue to Final Setup
|
||||
exec ${SCRIPTS:-/}start-finalSetupWorld $@
|
||||
20
scripts/start-deployFTBA → start-deployFTBA
Executable file → Normal file
20
scripts/start-deployFTBA → start-deployFTBA
Executable file → Normal file
@@ -2,8 +2,7 @@
|
||||
|
||||
ftbInstallMarker=".ftb-installed"
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
isDebugging && set -x
|
||||
set -e
|
||||
|
||||
@@ -17,7 +16,7 @@ if ! [[ ${FTB_MODPACK_ID} =~ [0-9]+ ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! $FTB_MODPACK_VERSION_ID ]]; then
|
||||
if ! [[ -v FTB_MODPACK_VERSION_ID ]]; then
|
||||
if ! FTB_MODPACK_VERSION_ID=$(curl -fsSL https://api.modpacks.ch/public/modpack/${FTB_MODPACK_ID} | jq -r '.versions | sort_by(.updated)[-1].id'); then
|
||||
log "ERROR unable to resolve latest modpack version ID for modpack ${FTB_MODPACK_ID}"
|
||||
exit 1
|
||||
@@ -31,13 +30,7 @@ if ! [ -f "${ftbInstallMarker}" ] || [ $(cat "${ftbInstallMarker}") != "${FTB_MO
|
||||
ftbInstaller=/data/ftb-installer
|
||||
if ! [[ -f "${ftbInstaller}" ]]; then
|
||||
log "Downloading FTB installer"
|
||||
if [ "$(uname -m)" == "aarch64" ]; then
|
||||
log "Downloading ARM installer"
|
||||
curl -fsSL https://api.modpacks.ch/public/modpack/1/1/server/arm/linux -o "${ftbInstaller}"
|
||||
else
|
||||
log "Downloading x86 installer"
|
||||
curl -fsSL https://api.modpacks.ch/public/modpack/1/1/server/linux -o "${ftbInstaller}"
|
||||
fi
|
||||
curl -fsSL https://api.modpacks.ch/public/modpack/1/1/server/linux -o "${ftbInstaller}"
|
||||
chmod +x "${ftbInstaller}"
|
||||
fi
|
||||
|
||||
@@ -68,7 +61,7 @@ variants=(
|
||||
forge-${mcVersion}-${forgeVersion}-${mcVersion}-universal.jar
|
||||
fabric-${mcVersion}-${fabricVersion}-server-launch.jar
|
||||
)
|
||||
for f in "${variants[@]}"; do
|
||||
for f in ${variants[@]}; do
|
||||
if [ -f $f ]; then
|
||||
export SERVER=$f
|
||||
break
|
||||
@@ -80,6 +73,5 @@ if ! [ -v SERVER ]; then
|
||||
exit 2
|
||||
fi
|
||||
|
||||
export FAMILY=FORGE
|
||||
|
||||
exec ${SCRIPTS:-/}start-setupWorld $@
|
||||
# Continue to Final Setup
|
||||
exec ${SCRIPTS:-/}start-finalSetupWorld $@
|
||||
64
start-deployFabric
Normal file
64
start-deployFabric
Normal file
@@ -0,0 +1,64 @@
|
||||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
|
||||
requireVar VANILLA_VERSION
|
||||
export TYPE=FABRIC
|
||||
export SERVER=fabric-server-${VANILLA_VERSION}.jar
|
||||
|
||||
isDebugging && set -x
|
||||
|
||||
if [[ ! -e ${SERVER} ]]; then
|
||||
|
||||
: ${FABRIC_INSTALLER:=}
|
||||
: ${FABRIC_INSTALLER_URL:=}
|
||||
: ${FABRIC_INSTALLER_VERSION:=${FABRICVERSION:-LATEST}}
|
||||
|
||||
if [[ -z $FABRIC_INSTALLER && -z $FABRIC_INSTALLER_URL ]]; then
|
||||
log "Checking Fabric version information."
|
||||
if [[ ${FABRIC_INSTALLER_VERSION^^} = LATEST ]]; then
|
||||
FABRIC_INSTALLER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-installer/maven-metadata.xml)
|
||||
fi
|
||||
|
||||
FABRIC_INSTALLER="fabric-installer-${FABRIC_INSTALLER_VERSION}.jar"
|
||||
FABRIC_INSTALLER_URL="https://maven.fabricmc.net/net/fabricmc/fabric-installer/${FABRIC_INSTALLER_VERSION}/fabric-installer-${FABRIC_INSTALLER_VERSION}.jar"
|
||||
elif [[ -z $FABRIC_INSTALLER ]]; then
|
||||
FABRIC_INSTALLER="fabric-installer.jar"
|
||||
elif [[ ! -e $FABRIC_INSTALLER ]]; then
|
||||
log "ERROR: the given Fabric installer doesn't exist : $FABRIC_INSTALLER"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [[ ! -e $FABRIC_INSTALLER ]]; then
|
||||
log "Downloading $FABRIC_INSTALLER_URL ..."
|
||||
if ! curl -o $FABRIC_INSTALLER -fsSL $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"
|
||||
|
||||
tries=3
|
||||
set +e
|
||||
while ((--tries >= 0)); do
|
||||
java -jar $FABRIC_INSTALLER server \
|
||||
-mcversion $VANILLA_VERSION \
|
||||
-downloadMinecraft \
|
||||
-dir /data
|
||||
if [[ $? == 0 ]]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
set -e
|
||||
if (($tries < 0)); then
|
||||
log "Fabric failed to install after several tries." >&2
|
||||
exit 10
|
||||
fi
|
||||
|
||||
mv fabric-server-launch.jar ${SERVER}
|
||||
fi
|
||||
|
||||
# Continue to Final Setup
|
||||
exec ${SCRIPTS:-/}start-finalSetupWorld $@
|
||||
122
start-deployForge
Normal file
122
start-deployForge
Normal file
@@ -0,0 +1,122 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
: ${FORGEVERSION:=RECOMMENDED}
|
||||
isDebugging && set -x
|
||||
|
||||
if [[ -z $FORGE_INSTALLER && -z $FORGE_INSTALLER_URL ]]; then
|
||||
norm=$VANILLA_VERSION
|
||||
|
||||
case $VANILLA_VERSION in
|
||||
*.*.*)
|
||||
norm=$VANILLA_VERSION ;;
|
||||
*.*)
|
||||
norm=${VANILLA_VERSION}.0 ;;
|
||||
esac
|
||||
|
||||
#################################################################################
|
||||
|
||||
log "Checking Forge version information."
|
||||
case $FORGEVERSION in
|
||||
RECOMMENDED)
|
||||
curl -fsSL -o /tmp/forge.json http://files.minecraftforge.net/maven/net/minecraftforge/forge/promotions_slim.json
|
||||
FORGE_VERSION=$(cat /tmp/forge.json | jq -r ".promos[\"$VANILLA_VERSION-recommended\"]")
|
||||
if [ $FORGE_VERSION = null ]; then
|
||||
FORGE_VERSION=$(cat /tmp/forge.json | jq -r ".promos[\"$VANILLA_VERSION-latest\"]")
|
||||
if [ $FORGE_VERSION = null ]; then
|
||||
log "ERROR: Version $VANILLA_VERSION is not supported by Forge"
|
||||
log " Refer to http://files.minecraftforge.net/ for supported versions"
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
FORGE_VERSION=$FORGEVERSION
|
||||
;;
|
||||
esac
|
||||
|
||||
normForgeVersion=$VANILLA_VERSION-$FORGE_VERSION-$norm
|
||||
shortForgeVersion=$VANILLA_VERSION-$FORGE_VERSION
|
||||
|
||||
FORGE_INSTALLER="/tmp/forge-$shortForgeVersion-installer.jar"
|
||||
elif [[ -z $FORGE_INSTALLER ]]; then
|
||||
FORGE_INSTALLER="/tmp/forge-installer.jar"
|
||||
elif [[ ! -e $FORGE_INSTALLER ]]; then
|
||||
log "ERROR: the given Forge installer doesn't exist : $FORGE_INSTALLER"
|
||||
exit 2
|
||||
else
|
||||
shortForgeVersion=$VANILLA_VERSION-${FORGE_INSTALLER_CUSTOM_VERSION:-custom}
|
||||
fi
|
||||
|
||||
installMarker="/data/.forge-installed-$shortForgeVersion"
|
||||
|
||||
if [ ! -e $installMarker ]; then
|
||||
if [ ! -e $FORGE_INSTALLER ]; then
|
||||
|
||||
if [[ -z $FORGE_INSTALLER_URL ]]; then
|
||||
log "Downloading $normForgeVersion"
|
||||
|
||||
forgeFileNames="
|
||||
$normForgeVersion/forge-$normForgeVersion-installer.jar
|
||||
$shortForgeVersion/forge-$shortForgeVersion-installer.jar
|
||||
END
|
||||
"
|
||||
for fn in $forgeFileNames; do
|
||||
if [ $fn == END ]; then
|
||||
log "Unable to compute URL for $normForgeVersion"
|
||||
exit 2
|
||||
fi
|
||||
downloadUrl=https://maven.minecraftforge.net/net/minecraftforge/forge/$fn
|
||||
log "...trying $downloadUrl"
|
||||
if curl -o $FORGE_INSTALLER -fsSL $downloadUrl; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
log "Downloading $FORGE_INSTALLER_URL ..."
|
||||
if ! curl -o $FORGE_INSTALLER -fsSL $FORGE_INSTALLER_URL; then
|
||||
log "Failed to download from given location $FORGE_INSTALLER_URL"
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
log "Installing Forge $shortForgeVersion using $FORGE_INSTALLER"
|
||||
mkdir -p mods
|
||||
tries=3
|
||||
while ((--tries >= 0)); do
|
||||
java -jar $FORGE_INSTALLER --installServer
|
||||
if [ $? == 0 ]; 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
|
||||
for file in *forge*.jar; do
|
||||
if ! [[ $file =~ installer ]]; then
|
||||
if [[ -z $latest ]] || [[ $file -nt $latest ]]; then
|
||||
latest=$file
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if [[ -z $latest ]]; then
|
||||
log "Unable to derive server jar for Forge"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
export SERVER=$latest
|
||||
log "Using server $SERVER"
|
||||
echo $SERVER > $installMarker
|
||||
|
||||
else
|
||||
export SERVER=$(cat $installMarker)
|
||||
fi
|
||||
|
||||
# Continue to Final Setup
|
||||
exec ${SCRIPTS:-/}start-finalSetupWorld $@
|
||||
14
scripts/start-deployMagma → start-deployMagma
Executable file → Normal file
14
scripts/start-deployMagma → start-deployMagma
Executable file → Normal 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() {
|
||||
@@ -88,6 +89,5 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
export FAMILY=HYBRID
|
||||
|
||||
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||
# Continue to Final Setup
|
||||
exec ${SCRIPTS:-/}start-finalSetupWorld $@
|
||||
19
scripts/start-deployMohist → start-deployMohist
Executable file → Normal file
19
scripts/start-deployMohist → start-deployMohist
Executable file → Normal file
@@ -1,18 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-$(dirname "$0")}/start-utils"
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
set -o pipefail
|
||||
set -e
|
||||
isDebugging && set -x
|
||||
|
||||
requireVar VANILLA_VERSION
|
||||
: "${MOHIST_BUILD:=lastSuccessfulBuild}"
|
||||
: ${MOHIST_BUILD:=lastSuccessfulBuild}
|
||||
|
||||
mohistJobs=https://ci.codemc.io/job/MohistMC/job/
|
||||
mohistJob=${mohistJobs}Mohist-${VANILLA_VERSION}/
|
||||
|
||||
if ! get --exists "${mohistJob}"; then
|
||||
if ! curl -X HEAD -o /dev/null -fsSL "${mohistJob}"; then
|
||||
log "ERROR: mohist builds do not exist for ${VANILLA_VERSION}"
|
||||
log " check https://ci.codemc.io/job/MohistMC/ for available versions"
|
||||
log " and set VERSION accordingly"
|
||||
@@ -20,7 +19,8 @@ if ! get --exists "${mohistJob}"; then
|
||||
fi
|
||||
|
||||
buildRelPath=$(
|
||||
get --json-path '$.artifacts[0].relativePath' "${mohistJob}${MOHIST_BUILD}/api/json"
|
||||
curl -fsSL "${mohistJob}${MOHIST_BUILD}/api/json" |
|
||||
jq -r '.artifacts[0].relativePath'
|
||||
)
|
||||
|
||||
baseName=$(basename "${buildRelPath}")
|
||||
@@ -33,11 +33,12 @@ fi
|
||||
|
||||
export SERVER="/data/${baseName}"
|
||||
|
||||
if [ ! -f "${SERVER}" ]; then
|
||||
if [ ! -f ${SERVER} ]; then
|
||||
log "Downloading ${baseName}"
|
||||
get -o "${SERVER}" "${mohistJob}${MOHIST_BUILD}/artifact/${buildRelPath}"
|
||||
curl -o "${SERVER}" -fsSL "${mohistJob}${MOHIST_BUILD}/artifact/${buildRelPath}"
|
||||
fi
|
||||
|
||||
export FAMILY=HYBRID
|
||||
export SKIP_LOG4J_CONFIG=true
|
||||
|
||||
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"
|
||||
# Continue to Final Setup
|
||||
exec ${SCRIPTS:-/}start-finalSetupWorld "$@"
|
||||
3
scripts/start-deployPaper → start-deployPaper
Executable file → Normal file
3
scripts/start-deployPaper → start-deployPaper
Executable file → Normal file
@@ -73,6 +73,7 @@ else
|
||||
fi
|
||||
|
||||
# Normalize on Spigot for downstream operations
|
||||
export FAMILY=SPIGOT
|
||||
export TYPE=SPIGOT
|
||||
export SKIP_LOG4J_CONFIG=true
|
||||
|
||||
exec ${SCRIPTS:-/}start-spiget "$@"
|
||||
@@ -2,34 +2,36 @@
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
. ${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
|
||||
PURPUR_BUILD=$(curl -fsSL "https://api.pl3x.net/v2/purpur/${VANILLA_VERSION}" |
|
||||
jq -r '.builds.latest' || echo "")
|
||||
if [[ -z ${PURPUR_BUILD} ]]; then
|
||||
log "ERROR: Failed to locate a Purpur build for ${VANILLA_VERSION}."
|
||||
log " Please check if a download is available at https://purpur.pl3x.net/downloads/"
|
||||
exit 1
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
|
||||
export SERVER="purpur-${VANILLA_VERSION}-${PURPUR_BUILD}.jar"
|
||||
|
||||
if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
|
||||
downloadUrl="https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download"
|
||||
downloadUrl="https://api.pl3x.net/v2/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download"
|
||||
log "Downloading Purpur from $downloadUrl ..."
|
||||
if ! get -o "$SERVER" "$downloadUrl"; then
|
||||
if ! curl -fsSL -o "$SERVER" "$downloadUrl"; then
|
||||
log "ERROR: failed to download from $downloadUrl (status=$?)"
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
|
||||
# Normalize on Spigot for later operations
|
||||
export FAMILY=SPIGOT
|
||||
export TYPE=SPIGOT
|
||||
export SKIP_LOG4J_CONFIG=true
|
||||
|
||||
exec "${SCRIPTS:-/}start-spiget" "$@"
|
||||
exec ${SCRIPTS:-/}start-spiget "$@"
|
||||
4
scripts/start-deploySpongeVanilla → start-deploySpongeVanilla
Executable file → Normal file
4
scripts/start-deploySpongeVanilla → start-deploySpongeVanilla
Executable file → Normal file
@@ -37,5 +37,5 @@ if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then
|
||||
curl -sSL -o $SERVER https://repo.spongepowered.org/maven/org/spongepowered/$TYPE/$SPONGEVERSION/$SERVER
|
||||
fi
|
||||
|
||||
export FAMILY=SPONGE
|
||||
exec ${SCRIPTS:-/}start-setupWorld "$@"
|
||||
# Continue to Final Setup
|
||||
exec ${SCRIPTS:-/}start-finalSetupWorld $@
|
||||
26
start-deployTuinity
Normal file
26
start-deployTuinity
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
|
||||
if [ "${VERSION}" != "LATEST" ]; then
|
||||
log "ERROR: Tuinity server type only supports VERSION=LATEST"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
: ${TUINITY_BUILD:=lastSuccessfulBuild}
|
||||
export SERVER=tuinity-${VANILLA_VERSION}-${TUINITY_BUILD}.jar
|
||||
|
||||
if [ ! -f "$SERVER" ] || [ -n "$FORCE_REDOWNLOAD" ]; then
|
||||
downloadUrl="https://ci.codemc.io/job/Spottedleaf/job/Tuinity/${TUINITY_BUILD}/artifact/tuinity-paperclip.jar"
|
||||
log "Downloading Tuinity (build $TUINITY_BUILD) from $downloadUrl ..."
|
||||
curl -fsSL -o "$SERVER" "$downloadUrl"
|
||||
if [ ! -f "$SERVER" ]; then
|
||||
log "ERROR: failed to download from $downloadUrl (status=$?)"
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
|
||||
# Normalize on Spigot for later operations
|
||||
export TYPE=SPIGOT
|
||||
|
||||
exec ${SCRIPTS:-/}start-spiget "$@"
|
||||
49
start-deployVanilla
Normal file
49
start-deployVanilla
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
isDebugging && set -x
|
||||
set -o pipefail
|
||||
|
||||
export SERVER="minecraft_server.${VANILLA_VERSION// /_}.jar"
|
||||
|
||||
if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then
|
||||
log "Downloading $SERVER ..."
|
||||
debug "Finding version manifest for $VANILLA_VERSION"
|
||||
versionManifestUrl=$(curl -fsSL '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)"
|
||||
exit 1
|
||||
fi
|
||||
if [ $versionManifestUrl = "null" ]; then
|
||||
log "ERROR couldn't find a matching manifest entry for $VANILLA_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
debug "Found version manifest at $versionManifestUrl"
|
||||
|
||||
serverDownloadUrl=$(curl -fsSL ${versionManifestUrl} | jq --raw-output '.downloads.server.url')
|
||||
result=$?
|
||||
if [ $result != 0 ]; then
|
||||
log "ERROR failed to obtain version manifest from $versionManifestUrl ($result)"
|
||||
exit 1
|
||||
elif [ $serverDownloadUrl = null ]; then
|
||||
log "ERROR version $VANILLA_VERSION does not provide a server download"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
debug "Downloading server from $serverDownloadUrl"
|
||||
if isDebugging; then
|
||||
verbose=-v
|
||||
fi
|
||||
curl $verbose -fsSL -o $SERVER $serverDownloadUrl
|
||||
result=$?
|
||||
if [ $result != 0 ]; then
|
||||
log "ERROR failed to download server from $serverDownloadUrl ($result)"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
isDebugging && ls -l
|
||||
|
||||
# Continue to Final Setup
|
||||
exec ${SCRIPTS:-/}start-finalSetupWorld $@
|
||||
30
start-deployYatopia
Normal file
30
start-deployYatopia
Normal file
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
isDebugging && set -x
|
||||
|
||||
: ${VANILLA_VERSION:?}
|
||||
: ${RELEASE:=latest}
|
||||
: ${FORCE_REDOWNLOAD:=false}
|
||||
|
||||
requireEnum RELEASE stable latest
|
||||
|
||||
export SERVER="yatopia-${RELEASE}-${VANILLA_VERSION}.jar"
|
||||
|
||||
if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
|
||||
downloadUrl="https://api.yatopiamc.org/v2/${RELEASE}Build/download?branch=ver/${VANILLA_VERSION}"
|
||||
log "Downloading Yatopia from $downloadUrl ..."
|
||||
if ! curl -fsSL -o "$SERVER" "$downloadUrl"; then
|
||||
log "ERROR: failed to download from $downloadUrl (status=$?)"
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
|
||||
# Normalize on Spigot for later operations
|
||||
export TYPE=SPIGOT
|
||||
export SKIP_LOG4J_CONFIG=true
|
||||
|
||||
# Continue to Final Setup
|
||||
exec ${SCRIPTS:-/}start-finalSetupWorld $@
|
||||
51
start-finalSetupEnvVariables
Normal file
51
start-finalSetupEnvVariables
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
|
||||
: ${ENV_VARIABLE_PREFIX:=CFG_}
|
||||
|
||||
if isTrue "${REPLACE_ENV_VARIABLES}"; then
|
||||
log "Replacing env variables in configs that match the prefix $ENV_VARIABLE_PREFIX ..."
|
||||
|
||||
# File excludes
|
||||
fileExcludes=
|
||||
for f in ${REPLACE_ENV_VARIABLES_EXCLUDES}; do
|
||||
fileExcludes="${fileExcludes} -not -name $f"
|
||||
done
|
||||
|
||||
# Directory excludes (recursive)
|
||||
dirExcludes=$(join_by " -o -path " ${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS})
|
||||
if [[ $dirExcludes ]]; then
|
||||
dirExcludes=" -type d ( -path ${dirExcludes} ) -prune -o"
|
||||
fi
|
||||
|
||||
isDebugging && echo "Using find file exclusions: $fileExcludes"
|
||||
isDebugging && echo "Using find directory exclusions: $dirExcludes"
|
||||
|
||||
for name in $(compgen -v $ENV_VARIABLE_PREFIX); do
|
||||
# check if name of env variable matches the prefix
|
||||
# sanity check environment variables to avoid code injections
|
||||
# Read content from file environment
|
||||
if [[ $name = *"_FILE" ]]; then
|
||||
value=$(<${!name})
|
||||
name="${name%_FILE}"
|
||||
else
|
||||
value=${!name}
|
||||
fi
|
||||
|
||||
log "Replacing $name with $value ..."
|
||||
|
||||
value=${value//\\/\\\\}
|
||||
value=${value//#/\\#}
|
||||
|
||||
find /data/ \
|
||||
$dirExcludes \
|
||||
-type f \
|
||||
\( -name "*.yml" -or -name "*.yaml" -or -name "*.txt" -or -name "*.cfg" \
|
||||
-or -name "*.conf" -or -name "*.properties" -or -name "*.hjson" -or -name "*.json" \) \
|
||||
$fileExcludes \
|
||||
-exec sed -i 's#${'"$name"'}#'"$value"'#g' {} \;
|
||||
done
|
||||
fi
|
||||
|
||||
exec ${SCRIPTS:-/}start-minecraftFinalSetup $@
|
||||
7
scripts/start-setupModconfig → start-finalSetupModconfig
Executable file → Normal file
7
scripts/start-setupModconfig → start-finalSetupModconfig
Executable file → Normal 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-finalSetupMounts $@
|
||||
188
start-finalSetupModpack
Normal file
188
start-finalSetupModpack
Normal file
@@ -0,0 +1,188 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e -o pipefail
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
if isDebugging; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
# CURSE_URL_BASE used in manifest downloads below
|
||||
CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects}
|
||||
|
||||
# Remove old mods/plugins
|
||||
if isTrue ${REMOVE_OLD_MODS:-false}; then
|
||||
removeOldMods /data/mods
|
||||
removeOldMods /data/plugins
|
||||
fi
|
||||
|
||||
# If supplied with a URL for a modpack (simple zip of jars), download it and unpack
|
||||
if [[ "$MODPACK" ]]; then
|
||||
if isURL "${MODPACK}"; then
|
||||
if [[ "${MODPACK}" == *.zip ]]; then
|
||||
downloadUrl="${MODPACK}"
|
||||
else
|
||||
downloadUrl=$(curl -Ls -o /dev/null -w %{effective_url} $MODPACK)
|
||||
if ! [[ $downloadUrl == *.zip ]]; then
|
||||
log "ERROR Invalid URL given for MODPACK: $downloadUrl resolved from $MODPACK"
|
||||
log " Must be HTTP, HTTPS or FTP and a ZIP file"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
log "Downloading mod/plugin pack"
|
||||
log " from $downloadUrl ..."
|
||||
if ! curl -sSL -o /tmp/modpack.zip "$downloadUrl"; then
|
||||
log "ERROR: failed to download from $downloadUrl"
|
||||
exit 2
|
||||
fi
|
||||
elif [[ "$MODPACK" =~ .*\.zip ]]; then
|
||||
if ! cp $MODPACK /tmp/modpack.zip; then
|
||||
log "ERROR: failed to copy from $MODPACK"
|
||||
exit 2
|
||||
fi
|
||||
else
|
||||
log "ERROR Invalid URL or Path given for MODPACK: $MODPACK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
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 $downloadUrl"
|
||||
fi
|
||||
else
|
||||
mkdir -p /data/mods
|
||||
if ! unzip -o -d /data/mods /tmp/modpack.zip; then
|
||||
log "ERROR: failed to unzip the modpack from $downloadUrl"
|
||||
fi
|
||||
fi
|
||||
rm -f /tmp/modpack.zip
|
||||
fi
|
||||
|
||||
# If supplied with a URL for a plugin download it.
|
||||
if [[ "$MODS" ]]; then
|
||||
if [ "$TYPE" = "SPIGOT" ]; then
|
||||
out_dir=/data/plugins
|
||||
else
|
||||
out_dir=/data/mods
|
||||
fi
|
||||
mkdir -p "$out_dir"
|
||||
|
||||
for i in ${MODS//,/ }
|
||||
do
|
||||
if isURL $i; then
|
||||
log "Downloading mod/plugin $i ..."
|
||||
if isValidFileURL jar "$i"; then
|
||||
if ! curl -fsSL -o "${out_dir}/$(getFilenameFromUrl "${i}")" "${i}"; then
|
||||
log "ERROR: failed to download from $i into $out_dir"
|
||||
exit 2
|
||||
fi
|
||||
else
|
||||
effective_url=$(resolveEffectiveUrl "$i")
|
||||
if isValidFileURL jar "${effective_url}"; then
|
||||
out_file=$(getFilenameFromUrl "${effective_url}")
|
||||
if ! curl -fsSL -o "${out_dir}/$out_file" "${effective_url}"; then
|
||||
log "ERROR: failed to download from $i into $out_dir"
|
||||
exit 2
|
||||
fi
|
||||
else
|
||||
log "ERROR: $effective_url resolved from $i is not a valid jar URL"
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
elif [[ -f "$i" && "$i" =~ .*\.jar ]]; then
|
||||
log "Copying plugin located at $i ..."
|
||||
out_file=$(basename "$i")
|
||||
if ! cp "$i" "${out_dir}/$out_file"; then
|
||||
log "ERROR: failed to copy from $i into $out_dir"
|
||||
exit 2
|
||||
fi
|
||||
elif [[ -d "$i" ]]; then
|
||||
log "Copying plugin jars from $i ..."
|
||||
cp "$i"/*.jar "${out_dir}"
|
||||
else
|
||||
log "ERROR Invalid URL or path given in MODS: $i"
|
||||
exit 2
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "$MANIFEST" ]]; then
|
||||
if [[ -e "$MANIFEST" ]]; then
|
||||
EFFECTIVE_MANIFEST_FILE=$MANIFEST
|
||||
elif isURL "$MANIFEST"; then
|
||||
EFFECTIVE_MANIFEST_FILE=/tmp/manifest.json
|
||||
EFFECTIVE_MANIFEST_URL=$(curl -Ls -o /dev/null -w %{effective_url} $MANIFEST)
|
||||
curl -Ls -o $EFFECTIVE_MANIFEST_FILE "$EFFECTIVE_MANIFEST_URL"
|
||||
else
|
||||
log "MANIFEST='$MANIFEST' is not a valid manifest url or location"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
case "X$EFFECTIVE_MANIFEST_FILE" in
|
||||
X*.json)
|
||||
if [ -f "${EFFECTIVE_MANIFEST_FILE}" ]; then
|
||||
MOD_DIR=${FTB_BASE_DIR:-/data}/mods
|
||||
if [ ! -d "$MOD_DIR" ]
|
||||
then
|
||||
log "Creating mods dir $MOD_DIR"
|
||||
mkdir -p "$MOD_DIR"
|
||||
fi
|
||||
log "Starting manifest download..."
|
||||
cat "${EFFECTIVE_MANIFEST_FILE}" | jq -r '.files[] | (.projectID|tostring) + " " + (.fileID|tostring)'| while read -r p f
|
||||
do
|
||||
if [ ! -f $MOD_DIR/${p}_${f}.jar ]
|
||||
then
|
||||
redirect_url="$(curl -Ls -o /dev/null -w %{effective_url} ${CURSE_URL_BASE}/${p})"
|
||||
url="$redirect_url/download/${f}/file"
|
||||
log Downloading curseforge mod $url
|
||||
# Manifest usually doesn't have mod names. Using id should be fine, tho
|
||||
curl -sSL "${url}" -o $MOD_DIR/${p}_${f}.jar
|
||||
fi
|
||||
done
|
||||
else
|
||||
log "Could not find manifest file, unsufficient privs, or malformed path."
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log "Invalid manifest file for modpack. Please make sure it is a .json file."
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [[ "${GENERIC_PACK}" ]]; then
|
||||
if isURL "${GENERIC_PACK}"; then
|
||||
log "Downloading generic pack ..."
|
||||
curl -fsSL -o /tmp/generic_pack.zip "${GENERIC_PACK}"
|
||||
GENERIC_PACK=/tmp/generic_pack.zip
|
||||
fi
|
||||
|
||||
sum_file=/data/.generic_pack.sum
|
||||
if ! sha256sum -c ${sum_file} -s 2> /dev/null; then
|
||||
base_dir=/tmp/generic_pack_base
|
||||
mkdir -p ${base_dir}
|
||||
isDebugging && ls -l "${GENERIC_PACK}"
|
||||
unzip -q -d ${base_dir} "${GENERIC_PACK}"
|
||||
if [ -f /data/manifest.txt ]; then
|
||||
log "Manifest exists from older generic pack, cleaning up ..."
|
||||
while read f; do
|
||||
rm -rf "/data/${f}"
|
||||
done < /data/manifest.txt
|
||||
find /data/* -type d -exec rmdir --ignore-fail-on-non-empty {} +
|
||||
rm -f /data/manifest.txt
|
||||
fi
|
||||
log "Writing generic pack manifest ... "
|
||||
find ${base_dir} -type f -print0 | xargs -0 -I {} echo "{}" | sed "s#${base_dir}/##" > /data/manifest.txt
|
||||
log "Applying generic pack ..."
|
||||
IFS='
|
||||
'
|
||||
set -f
|
||||
for d in $(find ${base_dir} -type d); do mkdir -p "$(sed "s#${base_dir}#/data#" <<< $d)"; done
|
||||
for f in $(find ${base_dir} -type f); do cp -f "$f" "$(sed "s#${base_dir}#/data#" <<< $f)"; done
|
||||
rm -rf ${base_dir}
|
||||
sha256sum "${GENERIC_PACK}" > ${sum_file}
|
||||
fi
|
||||
fi
|
||||
|
||||
exec ${SCRIPTS:-/}start-finalSetupModconfig $@
|
||||
40
start-finalSetupMounts
Executable file
40
start-finalSetupMounts
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
|
||||
: ${PLUGINS_SYNC_UPDATE:=true}
|
||||
|
||||
isDebugging && set -x
|
||||
|
||||
if [ -d /plugins ]; then
|
||||
case ${TYPE} in
|
||||
SPIGOT|BUKKIT|PAPER|MAGMA)
|
||||
mkdir -p /data/plugins
|
||||
log "Copying plugins over..."
|
||||
if isTrue ${PLUGINS_SYNC_UPDATE}; then
|
||||
updateArg="--update"
|
||||
fi
|
||||
# Copy plugins over using rsync to allow deeply nested updates of plugins
|
||||
rsync -a --out-format="update:%f:Last Modified %M" --prune-empty-dirs $updateArg /plugins /data
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# If any modules have been provided, copy them over
|
||||
: ${COPY_MODS_DEST:="/data/mods"}
|
||||
|
||||
if [ -d /mods ]; then
|
||||
log "Copying any mods over..."
|
||||
mkdir -p "${COPY_MODS_DEST}"
|
||||
rsync -a --out-format="update:%f:Last Modified %M" "${rsyncArgs[@]}" --prune-empty-dirs --update /mods/ "${COPY_MODS_DEST}"
|
||||
fi
|
||||
|
||||
: ${COPY_CONFIG_DEST:="/data/config"}
|
||||
|
||||
if [ -d /config ]; then
|
||||
log "Copying any configs from /config to ${COPY_CONFIG_DEST}"
|
||||
mkdir -p "${COPY_CONFIG_DEST}"
|
||||
rsync -a --out-format="update:%f:Last Modified %M" "${rsyncArgs[@]}" --prune-empty-dirs --update /config/ "${COPY_CONFIG_DEST}"
|
||||
fi
|
||||
|
||||
exec ${SCRIPTS:-/}start-finalSetupServerProperties $@
|
||||
220
start-finalSetupServerProperties
Normal file
220
start-finalSetupServerProperties
Normal file
@@ -0,0 +1,220 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
|
||||
: ${SERVER_PROPERTIES:=/data/server.properties}
|
||||
|
||||
# FUNCTIONS
|
||||
function setServerProp {
|
||||
local prop=$1
|
||||
local var=$2
|
||||
if [ -n "$var" ]; then
|
||||
# normalize booleans
|
||||
case ${var^^} in
|
||||
TRUE|FALSE)
|
||||
var=${var,,} ;;
|
||||
esac
|
||||
if grep "${prop}" "$SERVER_PROPERTIES" > /dev/null; then
|
||||
log "Setting ${prop} to '${var}' in ${SERVER_PROPERTIES}"
|
||||
sed -i "/^${prop}\s*=/ c ${prop}=${var//\\/\\\\}" "$SERVER_PROPERTIES"
|
||||
else
|
||||
log "Adding ${prop} with '${var}' in ${SERVER_PROPERTIES}"
|
||||
echo "${prop}=${var}" >> "$SERVER_PROPERTIES"
|
||||
fi
|
||||
else
|
||||
isDebugging && log "Skip setting ${prop}"
|
||||
fi
|
||||
}
|
||||
|
||||
function customizeServerProps {
|
||||
if [ -n "$WHITELIST" ] || isTrue ${ENABLE_WHITELIST:-false}; then
|
||||
log "Creating whitelist"
|
||||
setServerProp "whitelist" "true"
|
||||
setServerProp "white-list" "true"
|
||||
else
|
||||
log "Disabling whitelist"
|
||||
setServerProp "whitelist" "false"
|
||||
setServerProp "white-list" "false"
|
||||
fi
|
||||
|
||||
# If not provided, generate a reasonable default message-of-the-day,
|
||||
# which shows up in the server listing in the client
|
||||
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
|
||||
else
|
||||
label=${ORIGINAL_TYPE}
|
||||
fi
|
||||
|
||||
# Convert label to title-case
|
||||
label=${label,,}
|
||||
label=${label^}
|
||||
MOTD="A ${label} Minecraft Server powered by Docker"
|
||||
fi
|
||||
|
||||
setServerProp "server-name" "$SERVER_NAME"
|
||||
setServerProp "server-ip" "$SERVER_IP"
|
||||
setServerProp "server-port" "$SERVER_PORT"
|
||||
setServerProp "motd" "$MOTD"
|
||||
setServerProp "allow-nether" "$ALLOW_NETHER"
|
||||
setServerProp "announce-player-achievements" "$ANNOUNCE_PLAYER_ACHIEVEMENTS"
|
||||
setServerProp "enable-command-block" "$ENABLE_COMMAND_BLOCK"
|
||||
setServerProp "spawn-animals" "$SPAWN_ANIMALS"
|
||||
setServerProp "spawn-monsters" "$SPAWN_MONSTERS"
|
||||
setServerProp "spawn-npcs" "$SPAWN_NPCS"
|
||||
setServerProp "spawn-protection" "$SPAWN_PROTECTION"
|
||||
setServerProp "generate-structures" "$GENERATE_STRUCTURES"
|
||||
setServerProp "view-distance" "$VIEW_DISTANCE"
|
||||
setServerProp "hardcore" "$HARDCORE"
|
||||
setServerProp "snooper-enabled" "$SNOOPER_ENABLED"
|
||||
setServerProp "max-build-height" "$MAX_BUILD_HEIGHT"
|
||||
setServerProp "force-gamemode" "$FORCE_GAMEMODE"
|
||||
setServerProp "max-tick-time" "$MAX_TICK_TIME"
|
||||
setServerProp "enable-query" "$ENABLE_QUERY"
|
||||
setServerProp "query.port" "$QUERY_PORT"
|
||||
setServerProp "enable-rcon" "$ENABLE_RCON"
|
||||
setServerProp "rcon.password" "$RCON_PASSWORD"
|
||||
setServerProp "rcon.port" "$RCON_PORT"
|
||||
setServerProp "max-players" "$MAX_PLAYERS"
|
||||
setServerProp "max-world-size" "$MAX_WORLD_SIZE"
|
||||
setServerProp "level-name" "$LEVEL"
|
||||
setServerProp "level-seed" "$SEED"
|
||||
setServerProp "pvp" "${PVP}"
|
||||
setServerProp "generator-settings" "$GENERATOR_SETTINGS"
|
||||
setServerProp "online-mode" "$ONLINE_MODE"
|
||||
setServerProp "allow-flight" "$ALLOW_FLIGHT"
|
||||
setServerProp "level-type" "${LEVEL_TYPE^^}"
|
||||
setServerProp "resource-pack" "$RESOURCE_PACK"
|
||||
setServerProp "resource-pack-sha1" "$RESOURCE_PACK_SHA1"
|
||||
setServerProp "player-idle-timeout" "$PLAYER_IDLE_TIMEOUT"
|
||||
setServerProp "broadcast-console-to-ops" "$BROADCAST_CONSOLE_TO_OPS"
|
||||
setServerProp "broadcast-rcon-to-ops" "$BROADCAST_RCON_TO_OPS"
|
||||
setServerProp "enable-jmx-monitoring" "$ENABLE_JMX"
|
||||
setServerProp "sync-chunk-writes" "$SYNC_CHUNK_WRITES"
|
||||
setServerProp "enable-status" "$ENABLE_STATUS"
|
||||
setServerProp "entity-broadcast-range-percentage" "$ENTITY_BROADCAST_RANGE_PERCENTAGE"
|
||||
setServerProp "function-permission-level" "$FUNCTION_PERMISSION_LEVEL"
|
||||
setServerProp "network-compression-threshold" "$NETWORK_COMPRESSION_THRESHOLD"
|
||||
setServerProp "op-permission-level" "$OP_PERMISSION_LEVEL"
|
||||
setServerProp "prevent-proxy-connections" "$PREVENT_PROXY_CONNECTIONS"
|
||||
setServerProp "use-native-transport" "$USE_NATIVE_TRANSPORT"
|
||||
setServerProp "enforce-whitelist" "$ENFORCE_WHITELIST"
|
||||
|
||||
if [ -n "$DIFFICULTY" ]; then
|
||||
case $DIFFICULTY in
|
||||
peaceful|0)
|
||||
if versionLessThan 1.13; then
|
||||
DIFFICULTY=0
|
||||
else
|
||||
DIFFICULTY=peaceful
|
||||
fi
|
||||
;;
|
||||
easy|1)
|
||||
if versionLessThan 1.13; then
|
||||
DIFFICULTY=1
|
||||
else
|
||||
DIFFICULTY=easy
|
||||
fi
|
||||
;;
|
||||
normal|2)
|
||||
if versionLessThan 1.13; then
|
||||
DIFFICULTY=2
|
||||
else
|
||||
DIFFICULTY=normal
|
||||
fi
|
||||
;;
|
||||
hard|3)
|
||||
if versionLessThan 1.13; then
|
||||
DIFFICULTY=3
|
||||
else
|
||||
DIFFICULTY=hard
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log "DIFFICULTY must be peaceful, easy, normal, or hard."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
setServerProp "difficulty" "$DIFFICULTY"
|
||||
fi
|
||||
|
||||
if [ -n "$MODE" ]; then
|
||||
log "Setting mode"
|
||||
MODE_LC=$( echo $MODE | tr '[:upper:]' '[:lower:]' )
|
||||
case $MODE_LC in
|
||||
su*|0)
|
||||
if versionLessThan 1.13; then
|
||||
MODE=0
|
||||
else
|
||||
MODE=survival
|
||||
fi
|
||||
;;
|
||||
c*|1)
|
||||
if versionLessThan 1.13; then
|
||||
MODE=1
|
||||
else
|
||||
MODE=creative
|
||||
fi
|
||||
;;
|
||||
a*|2)
|
||||
if versionLessThan 1.13; then
|
||||
MODE=2
|
||||
else
|
||||
MODE=adventure
|
||||
fi
|
||||
;;
|
||||
sp*|3)
|
||||
if versionLessThan 1.13; then
|
||||
MODE=3
|
||||
else
|
||||
MODE=spectator
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log "ERROR: Invalid game mode: $MODE"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
setServerProp "gamemode" "$MODE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Deploy server.properties file
|
||||
if [[ ${TYPE} == "CURSEFORGE" ]]; then
|
||||
export SERVER_PROPERTIES="${FTB_DIR}/server.properties"
|
||||
log "detected FTB, changing properties path to ${SERVER_PROPERTIES}"
|
||||
fi
|
||||
|
||||
if [ ! -e "$SERVER_PROPERTIES" ]; then
|
||||
log "Creating server.properties in ${SERVER_PROPERTIES}"
|
||||
cp /tmp/server.properties "$SERVER_PROPERTIES"
|
||||
customizeServerProps
|
||||
elif [ -n "${OVERRIDE_SERVER_PROPERTIES}" ]; then
|
||||
case ${OVERRIDE_SERVER_PROPERTIES^^} in
|
||||
TRUE|1)
|
||||
customizeServerProps
|
||||
;;
|
||||
*)
|
||||
log "server.properties already created, skipping"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
log "server.properties already created, skipping"
|
||||
fi
|
||||
|
||||
if isTrue "${ENABLE_AUTOPAUSE}"; then
|
||||
current_max_tick=$( grep 'max-tick-time' "$SERVER_PROPERTIES" | sed -r 's/( )+//g' | awk -F= '{print $2}' )
|
||||
if (( $current_max_tick > 0 && $current_max_tick < 86400000 )); then
|
||||
log "Warning: The server.properties for the server doesn't have the Server Watchdog (effectively) disabled."
|
||||
log "Warning (cont): Autopause functionality resuming the process might trigger the Watchdog and restart the server completely."
|
||||
log "Warning (cont): Set the max-tick-time property to a high value (or disable the Watchdog with value -1 for versions 1.8.1+)."
|
||||
fi
|
||||
fi
|
||||
|
||||
if isDebugging; then
|
||||
log "DEBUG Dumping server.properties"
|
||||
cat "${SERVER_PROPERTIES}"
|
||||
fi
|
||||
|
||||
exec ${SCRIPTS:-/}start-finalSetupEnvVariables $@
|
||||
74
start-finalSetupWorld
Normal file
74
start-finalSetupWorld
Normal file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
set -e
|
||||
isDebugging && set -x
|
||||
|
||||
: ${LEVEL:=world}
|
||||
export LEVEL
|
||||
|
||||
if [ $TYPE = "CURSEFORGE" ]; then
|
||||
worldDest=$FTB_DIR/$LEVEL
|
||||
else
|
||||
worldDest=/data/$LEVEL
|
||||
fi
|
||||
|
||||
if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] ); then
|
||||
if isTrue "${FORCE_WORLD_COPY}"; then
|
||||
log "Removing existing world data in $worldDest ${worldDest}_nether ${worldDest}_the_end"
|
||||
rm -rf "$worldDest" \
|
||||
"${worldDest}_nether" \
|
||||
"${worldDest}_the_end"
|
||||
fi
|
||||
|
||||
if isURL $WORLD; then
|
||||
curl -fsSL "$WORLD" -o /tmp/world.zip
|
||||
zipSrc=/tmp/world.zip
|
||||
elif [[ "$WORLD" =~ .*\.zip ]]; then
|
||||
zipSrc="$WORLD"
|
||||
fi
|
||||
|
||||
if [[ "$zipSrc" ]]; then
|
||||
log "Unzipping world"
|
||||
|
||||
# Stage contents so that the correct subdirectory can be picked off
|
||||
mkdir -p /tmp/world-data
|
||||
(cd /tmp/world-data && unzip -o -q "$zipSrc")
|
||||
|
||||
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
|
||||
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
|
||||
rsync --remove-source-files --recursive --delete "$baseDir/" "$worldDest"
|
||||
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
|
||||
else
|
||||
log "Cloning world directory from $WORLD ..."
|
||||
rsync --recursive --delete "${WORLD%/}"/ "$worldDest"
|
||||
fi
|
||||
|
||||
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"
|
||||
[ -d "$worldDest/DIM-1" ] && mv -f "$worldDest/DIM-1" "${worldDest}_nether"
|
||||
fi
|
||||
fi
|
||||
|
||||
exec ${SCRIPTS:-/}start-finalSetupModpack $@
|
||||
141
scripts/start-finalExec → start-minecraftFinalSetup
Executable file → Normal file
141
scripts/start-finalExec → start-minecraftFinalSetup
Executable file → Normal file
@@ -1,9 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck source=start-utils
|
||||
. "${SCRIPTS:-/}start-utils"
|
||||
. ${SCRIPTS:-/}start-utils
|
||||
isDebugging && set -x
|
||||
|
||||
if [ -n "$OPS" ]; then
|
||||
log "Updating ops"
|
||||
rm -f /data/ops.txt.converted
|
||||
echo $OPS | awk -v RS=, '{print}' > /data/ops.txt
|
||||
fi
|
||||
if isTrue "${OVERRIDE_OPS}"; then
|
||||
log "Recreating ops.json file at server startup"
|
||||
rm -f /data/ops.json
|
||||
fi
|
||||
|
||||
if [ -n "$WHITELIST" ]; then
|
||||
log "Updating whitelist"
|
||||
rm -f /data/white-list.txt.converted
|
||||
echo $WHITELIST | awk -v RS=, '{print}' > /data/white-list.txt
|
||||
fi
|
||||
if isTrue "${OVERRIDE_WHITELIST}"; then
|
||||
log "Recreating whitelist.json file at server startup"
|
||||
rm -f /data/whitelist.json
|
||||
fi
|
||||
|
||||
if [ -n "$ICON" ]; then
|
||||
if [ ! -e server-icon.png ] || [ "${OVERRIDE_ICON}" == "TRUE" ]; then
|
||||
log "Using server icon from $ICON..."
|
||||
@@ -19,47 +38,7 @@ if [ -n "$ICON" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
canUseRollingLogs=true
|
||||
useFallbackJvmFlag=false
|
||||
|
||||
patchLog4jConfig() {
|
||||
file=${1?}
|
||||
url=${2?}
|
||||
if ! get -o "$file" "$url"; then
|
||||
log "ERROR: failed to download corrected log4j config, fallback to JVM flag"
|
||||
useFallbackJvmFlag=true
|
||||
return 1
|
||||
fi
|
||||
JVM_OPTS="-Dlog4j.configurationFile=${file} ${JVM_OPTS}"
|
||||
canUseRollingLogs=false
|
||||
}
|
||||
|
||||
# Patch Log4j remote code execution vulnerability
|
||||
# See https://www.minecraft.net/en-us/article/important-message--security-vulnerability-java-edition
|
||||
if versionLessThan 1.7; then
|
||||
: # No patch required here.
|
||||
elif isFamily VANILLA && versionLessThan 1.12; then
|
||||
patchLog4jConfig log4j2_17-111.xml https://launcher.mojang.com/v1/objects/dd2b723346a8dcd48e7f4d245f6bf09e98db9696/log4j2_17-111.xml
|
||||
elif isFamily VANILLA && versionLessThan 1.17; then
|
||||
patchLog4jConfig log4j2_112-116.xml https://launcher.mojang.com/v1/objects/02937d122c86ce73319ef9975b58896fc1b491d1/log4j2_112-116.xml
|
||||
# See https://purpurmc.org/docs/Log4j/
|
||||
elif isType PURPUR && versionLessThan 1.17; then
|
||||
patchLog4jConfig purpur_log4j2_1141-1165.xml https://purpurmc.org/docs/xml/purpur_log4j2_1141-1165.xml
|
||||
elif isType PURPUR && versionLessThan 1.18.1; then
|
||||
patchLog4jConfig purpur_log4j2_117.xml https://purpurmc.org/docs/xml/purpur_log4j2_117.xml
|
||||
elif versionLessThan 1.18.1; then
|
||||
useFallbackJvmFlag=true
|
||||
fi
|
||||
|
||||
if ${useFallbackJvmFlag}; then
|
||||
JVM_OPTS="-Dlog4j2.formatMsgNoLookups=true ${JVM_OPTS}"
|
||||
fi
|
||||
|
||||
if isTrue ${ENABLE_ROLLING_LOGS:-false}; then
|
||||
if ! ${canUseRollingLogs}; then
|
||||
log "ERROR: Using rolling logs is currently not possible in the selected version due to CVE-2021-44228"
|
||||
exit 1
|
||||
fi
|
||||
# Set up log configuration
|
||||
LOGFILE="/data/log4j2.xml"
|
||||
if [ ! -e "$LOGFILE" ]; then
|
||||
@@ -87,12 +66,12 @@ if versionLessThan 1.14 && [[ ${CONSOLE,,} = false ]]; then
|
||||
fi
|
||||
|
||||
# Optional disable GUI for headless servers
|
||||
if [[ ${GUI,,} = false ]]; then
|
||||
if [[ ${GUI} = false || ${GUI} = FALSE ]]; then
|
||||
EXTRA_ARGS+=" nogui"
|
||||
fi
|
||||
|
||||
: "${INIT_MEMORY:=${MEMORY}}"
|
||||
: "${MAX_MEMORY:=${MEMORY}}"
|
||||
# put these prior JVM_OPTS at the end to give any memory settings there higher precedence
|
||||
log "Setting initial memory to ${INIT_MEMORY:=${MEMORY}} and max to ${MAX_MEMORY:=${MEMORY}}"
|
||||
|
||||
expandedDOpts=
|
||||
if [ -n "$JVM_DD_OPTS" ]; then
|
||||
@@ -159,6 +138,12 @@ if isTrue "${USE_AIKAR_FLAGS}"; then
|
||||
"
|
||||
fi
|
||||
|
||||
if isTrue "${USE_LARGE_PAGES}"; then
|
||||
JVM_XX_OPTS="${JVM_XX_OPTS}
|
||||
-XX:+UseLargePagesInMetaspace
|
||||
"
|
||||
fi
|
||||
|
||||
if isTrue "${USE_FLARE_FLAGS}"; then
|
||||
JVM_XX_OPTS="${JVM_XX_OPTS}
|
||||
-XX:+UnlockDiagnosticVMOptions
|
||||
@@ -172,15 +157,7 @@ if isTrue "${DEBUG_MEMORY}"; then
|
||||
free -m
|
||||
fi
|
||||
|
||||
if [[ ${INIT_MEMORY} || ${MAX_MEMORY} ]]; then
|
||||
log "Setting initial memory to ${INIT_MEMORY:=${MEMORY}} and max to ${MAX_MEMORY:=${MEMORY}}"
|
||||
if [[ ${INIT_MEMORY} ]]; then
|
||||
JVM_OPTS="-Xms${INIT_MEMORY} ${JVM_OPTS}"
|
||||
fi
|
||||
if [[ ${MAX_MEMORY} ]]; then
|
||||
JVM_OPTS="-Xmx${MAX_MEMORY} ${JVM_OPTS}"
|
||||
fi
|
||||
fi
|
||||
JVM_OPTS="-Xms${INIT_MEMORY} -Xmx${MAX_MEMORY} ${JVM_OPTS}"
|
||||
|
||||
function copyFilesForCurseForge() {
|
||||
# copy player modification files unconditionally since their
|
||||
@@ -195,46 +172,52 @@ function copyFilesForCurseForge() {
|
||||
cp -f /data/eula.txt "${FTB_DIR}/"
|
||||
}
|
||||
|
||||
mcServerRunnerArgs=(
|
||||
--stop-duration "${STOP_DURATION:-60}s"
|
||||
--named-pipe "${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}"
|
||||
)
|
||||
mcServerRunnerArgs="--stop-duration ${STOP_DURATION:-60}s"
|
||||
if [[ ${STOP_SERVER_ANNOUNCE_DELAY} ]]; then
|
||||
mcServerRunnerArgs+=(--stop-server-announce-delay "${STOP_SERVER_ANNOUNCE_DELAY}s")
|
||||
mcServerRunnerArgs="${mcServerRunnerArgs} --stop-server-announce-delay ${STOP_SERVER_ANNOUNCE_DELAY}s"
|
||||
fi
|
||||
|
||||
if [[ ${TYPE} == "CURSEFORGE" && "${SERVER}" ]]; then
|
||||
if [[ ${TYPE} == "CURSE_INSTANCE" ]]; then
|
||||
if isTrue ${DEBUG_EXEC}; then
|
||||
set -x
|
||||
fi
|
||||
exec mc-server-runner ${mcServerRunnerArgs} \
|
||||
--cf-instance-file "${CURSE_INSTANCE_JSON}" \
|
||||
java $JVM_XX_OPTS $JVM_OPTS $expandedDOpts -jar _SERVERJAR_ "$@" $EXTRA_ARGS
|
||||
elif [[ ${TYPE} == "CURSEFORGE" && "${SERVER}" ]]; then
|
||||
copyFilesForCurseForge
|
||||
|
||||
cd "${FTB_DIR}" || (log "ERROR: can't go into ${FTB_DIR}"; exit 1)
|
||||
cd "${FTB_DIR}"
|
||||
log "Starting CurseForge server in ${FTB_DIR}..."
|
||||
if isTrue ${DEBUG_EXEC}; then
|
||||
set -x
|
||||
fi
|
||||
exec mc-server-runner ${bootstrapArgs} "${mcServerRunnerArgs[@]}" java $JVM_XX_OPTS $JVM_OPTS $expandedDOpts -jar $(basename "${SERVER}") "$@" $EXTRA_ARGS
|
||||
exec mc-server-runner ${bootstrapArgs} ${mcServerRunnerArgs} java $JVM_XX_OPTS $JVM_OPTS $expandedDOpts -jar $(basename "${SERVER}") "$@" $EXTRA_ARGS
|
||||
elif [[ ${TYPE} == "CURSEFORGE" ]]; then
|
||||
mcServerRunnerArgs+=(--shell bash)
|
||||
mcServerRunnerArgs="${mcServerRunnerArgs} --shell bash"
|
||||
|
||||
copyFilesForCurseForge
|
||||
|
||||
cat > "${FTB_DIR}/settings-local.sh" <<EOF
|
||||
export MIN_RAM="${INIT_MEMORY}"
|
||||
export MAX_RAM="${MAX_MEMORY}"
|
||||
export JAVA_PARAMETERS="${JVM_XX_OPTS} ${JVM_OPTS} $expandedDOpts"
|
||||
export JAVA_PARAMETERS="${JVM_XX_OPTS} -Xms${INIT_MEMORY} ${JVM_OPTS} $expandedDOpts"
|
||||
EOF
|
||||
|
||||
# patch CurseForge cfg file, if present
|
||||
if [ -f "${FTB_DIR}/settings.cfg" ] && [[ ${MAX_MEMORY} ]]; then
|
||||
if [ -f "${FTB_DIR}/settings.cfg" ]; then
|
||||
sed -i "s/MAX_RAM=[^;]*/MAX_RAM=${MAX_MEMORY}/" "${FTB_DIR}/settings.cfg"
|
||||
fi
|
||||
|
||||
cd "${FTB_DIR}" || (log "ERROR: can't go into ${FTB_DIR}"; exit 1)
|
||||
cd "${FTB_DIR}"
|
||||
log "Running FTB ${FTB_SERVER_START} in ${FTB_DIR} ..."
|
||||
|
||||
finalArgs="${FTB_SERVER_START}"
|
||||
finalArgs=(
|
||||
"${FTB_SERVER_START}"
|
||||
)
|
||||
|
||||
if isTrue "${SETUP_ONLY:=false}"; then
|
||||
echo "SETUP_ONLY: ${finalArgs}"
|
||||
if isTrue ${SETUP_ONLY:=false}; then
|
||||
echo "SETUP_ONLY: ${finalArgs[@]}"
|
||||
exit
|
||||
fi
|
||||
|
||||
@@ -244,16 +227,12 @@ EOF
|
||||
if isTrue ${EXEC_DIRECTLY:-false}; then
|
||||
"${finalArgs[@]}"
|
||||
else
|
||||
exec mc-server-runner "${mcServerRunnerArgs[@]}" "${finalArgs[@]}"
|
||||
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
|
||||
@@ -266,23 +245,23 @@ else
|
||||
$JVM_XX_OPTS
|
||||
$JVM_OPTS
|
||||
$expandedDOpts
|
||||
-jar "$SERVER"
|
||||
-jar $SERVER
|
||||
"$@" $EXTRA_ARGS
|
||||
)
|
||||
|
||||
if isTrue ${SETUP_ONLY:=false}; then
|
||||
echo "SETUP_ONLY: java ${finalArgs[*]}"
|
||||
echo "SETUP_ONLY: java ${finalArgs[@]}"
|
||||
exit
|
||||
fi
|
||||
|
||||
if isTrue "${DEBUG_EXEC}"; then
|
||||
if isTrue ${DEBUG_EXEC}; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
if isTrue "${EXEC_DIRECTLY:-false}"; then
|
||||
if isTrue ${EXEC_DIRECTLY:-false}; then
|
||||
exec java "${finalArgs[@]}"
|
||||
else
|
||||
exec mc-server-runner ${bootstrapArgs} "${mcServerRunnerArgs[@]}" java "${finalArgs[@]}"
|
||||
exec mc-server-runner ${bootstrapArgs} ${mcServerRunnerArgs} java "${finalArgs[@]}"
|
||||
fi
|
||||
fi
|
||||
|
||||
22
scripts/start-spiget → start-spiget
Executable file → Normal file
22
scripts/start-spiget → start-spiget
Executable file → Normal file
@@ -22,20 +22,6 @@ containsJars() {
|
||||
return 1
|
||||
}
|
||||
|
||||
containsPlugin() {
|
||||
file=${1?}
|
||||
|
||||
pat='plugin.yml$'
|
||||
|
||||
while read -r line; do
|
||||
if [[ $line =~ $pat ]]; then
|
||||
return 0
|
||||
fi
|
||||
done <<<$(unzip -l "$file")
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
getResourceFromSpiget() {
|
||||
resource=${1?}
|
||||
|
||||
@@ -95,12 +81,9 @@ downloadResourceFromSpiget() {
|
||||
log "Extracting contents of resource ${resource} into plugins"
|
||||
unzip -o -q -d /data/plugins "${tmpfile}"
|
||||
rm "${tmpfile}"
|
||||
elif containsPlugin "${tmpfile}"; then
|
||||
else
|
||||
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
|
||||
|
||||
}
|
||||
@@ -118,4 +101,5 @@ if [[ ${SPIGET_RESOURCES} ]]; then
|
||||
done
|
||||
fi
|
||||
|
||||
exec ${SCRIPTS:-/}start-setupWorld $@
|
||||
# Continue to Final Setup
|
||||
exec ${SCRIPTS:-/}start-finalSetupWorld $@
|
||||
133
scripts/start-utils → start-utils
Executable file → Normal file
133
scripts/start-utils → start-utils
Executable file → Normal file
@@ -40,10 +40,6 @@ function getFilenameFromUrl() {
|
||||
}
|
||||
|
||||
function isTrue() {
|
||||
local oldState
|
||||
oldState=$(shopt -po xtrace)
|
||||
shopt -u -o xtrace
|
||||
|
||||
local value=${1,,}
|
||||
|
||||
result=
|
||||
@@ -57,7 +53,6 @@ function isTrue() {
|
||||
;;
|
||||
esac
|
||||
|
||||
eval "$oldState"
|
||||
return ${result}
|
||||
}
|
||||
|
||||
@@ -87,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() {
|
||||
@@ -109,14 +93,6 @@ function logAutopauseAction() {
|
||||
echo "[$(date -Iseconds)] [Autopause] $*"
|
||||
}
|
||||
|
||||
function logAutostop() {
|
||||
echo "[Autostop loop] $*"
|
||||
}
|
||||
|
||||
function logAutostopAction() {
|
||||
echo "[$(date -Iseconds)] [Autostop] $*"
|
||||
}
|
||||
|
||||
function normalizeMemSize() {
|
||||
local scale=1
|
||||
case ${1,,} in
|
||||
@@ -136,7 +112,32 @@ function normalizeMemSize() {
|
||||
}
|
||||
|
||||
function versionLessThan() {
|
||||
mc-image-helper compare-versions "${VANILLA_VERSION}" lt "${1?}"
|
||||
local activeParts
|
||||
IFS=. read -ra activeParts <<<"${VANILLA_VERSION}"
|
||||
|
||||
local givenParts
|
||||
IFS=. read -ra givenParts <<<"$1"
|
||||
|
||||
if ((${#activeParts[@]} < 2)); then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ((${#activeParts[@]} == 2)); then
|
||||
if ((activeParts[0] < givenParts[0])) ||
|
||||
((activeParts[0] == givenParts[0] && activeParts[1] < givenParts[1])); then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
if ((activeParts[0] < givenParts[0])) ||
|
||||
((activeParts[0] == givenParts[0] && activeParts[1] < givenParts[1])) ||
|
||||
((activeParts[0] == givenParts[0] && activeParts[1] == givenParts[1] && activeParts[2] < givenParts[2])); then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
requireVar() {
|
||||
@@ -160,7 +161,7 @@ requireEnum() {
|
||||
fi
|
||||
done
|
||||
|
||||
log "ERROR: $var must be set to one of $*"
|
||||
log "ERROR: $var must be set to one of $@"
|
||||
# exit 1
|
||||
}
|
||||
|
||||
@@ -179,81 +180,3 @@ function removeOldMods {
|
||||
find "$1" -mindepth 1 -maxdepth ${REMOVE_OLD_MODS_DEPTH:-16} -wholename "${REMOVE_OLD_MODS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_MODS_EXCLUDE:-}" -delete
|
||||
fi
|
||||
}
|
||||
|
||||
function get() {
|
||||
local flags=()
|
||||
if isTrue "${DEBUG_GET:-false}"; then
|
||||
flags+=("--debug")
|
||||
fi
|
||||
mc-image-helper "${flags[@]}" get "$@"
|
||||
}
|
||||
|
||||
function isFamily() {
|
||||
for f in "${@}"; do
|
||||
if [[ ${FAMILY^^} == "${f^^}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
function isType() {
|
||||
for t in "${@}"; do
|
||||
# shellcheck disable=SC2153
|
||||
if [[ $TYPE == "$t" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
function evaluateJavaCompatibilityForForge() {
|
||||
javaRelease=$(mc-image-helper java-release)
|
||||
if versionLessThan 1.18 && (( javaRelease > 8 )); then
|
||||
log "**********************************************************************"
|
||||
log "WARNING: Some mods and modpacks may require Java 8."
|
||||
log " Please use itzg/minecraft-server:java8"
|
||||
log "**********************************************************************"
|
||||
sleep 5
|
||||
fi
|
||||
}
|
||||
|
||||
function extract() {
|
||||
src=${1?}
|
||||
destDir=${2?}
|
||||
|
||||
type=$(file -b --mime-type "${src}")
|
||||
case "${type}" in
|
||||
application/zip)
|
||||
unzip -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
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user