Compare commits

..

238 Commits

Author SHA1 Message Date
Geoff Bourne
48414b3e87 Auto-merging via docker-versions-create 2022-02-08 19:18:43 -06:00
Jordy Hulck
4cb227629f Distro aware checksum (#1345) 2022-02-08 19:17:26 -06:00
dependabot[bot]
932cd8f89e build(deps): bump docker/build-push-action from 2.8.0 to 2.9.0 (#1339) 2022-02-07 06:54:56 -06:00
Geoff Bourne
f2f8d58d3b Only skip up-to-date files with MODS and MODS_FILE (#1338)
Fixes #1254
2022-02-06 17:46:17 -06:00
Luc Ritchie
b7bbe1b0a6 Support Spigot-style and vanilla-style world zips, for any server type (#1305) 2022-02-06 15:51:28 -06:00
itzg
1dd9a2e6e0 docs: Auto update markdown TOC 2022-02-06 18:45:40 +00:00
chblodg
aa7b997697 Adding support for crafting tweaks and resource packs (#1336)
Co-authored-by: christopher blodgett <christopher.blodgett@gmail.com>
Co-authored-by: Geoff Bourne <itzgeoff@gmail.com>
Co-authored-by: Floyd Everest <me@floydeverest.com>
2022-02-06 12:45:25 -06:00
Geoff Bourne
c2bf2bbcc5 Use rfc-2822 for log timestamp 2022-02-05 22:56:24 -06:00
Geoff Bourne
68b926f2b1 Auto-merging via docker-versions-create 2022-02-05 22:52:42 -06:00
Geoff Bourne
306671ffe7 Disabled world_from_tarzstd test for now 2022-02-05 22:50:12 -06:00
Geoff Bourne
be99d171f5 Added extract detection for application/x-zstd 2022-02-05 22:47:58 -06:00
Geoff Bourne
882f3b1cd8 Added zstd package 2022-02-05 22:44:13 -06:00
Geoff Bourne
eb6c7c98f0 build: adjusted discord workflow name 2022-02-05 22:40:42 -06:00
Geoff Bourne
3472c67ca8 build: give issue-label workflow a name 2022-02-05 16:10:12 -06:00
Geoff Bourne
8995e63b72 build: fixed typo in push condition 2022-02-05 16:03:40 -06:00
Geoff Bourne
b65f108917 build: also push git tag builds 2022-02-05 16:02:27 -06:00
itzg
2b374a2073 docs: Auto update markdown TOC 2022-02-05 18:38:46 +00:00
Geoff Bourne
b5b164d5d3 feat: added SKIP_GENERIC_PACK_UPDATE_CHECK and FORCE_GENERIC_PACK_UPDATE (#1333) 2022-02-05 12:38:33 -06:00
itzg
0cde40604e docs: Auto update markdown TOC 2022-02-05 18:27:33 +00:00
Geoff Bourne
22f2eb7308 feat: add option to include timestamp with init logs (#1332) 2022-02-05 12:27:17 -06:00
Geoff Bourne
4a1d2d2b80 build: adjusted for eclipse-temurin:8-jdk not being on armv7 2022-02-02 22:27:38 -06:00
Geoff Bourne
10922b261b build: build-multiarch tags were too broad 2022-02-02 22:18:54 -06:00
Geoff Bourne
13883b20e7 Auto-merging via docker-versions-create 2022-02-02 22:15:47 -06:00
itzg
de0188de3d docs: Auto update markdown TOC 2022-02-02 02:53:20 +00:00
Geoff Bourne
2b093ad421 docs: fixed Forge homepage link
Fixes #1244
2022-02-01 20:53:05 -06:00
itzg
0ec73b141f docs: Auto update markdown TOC 2022-02-01 21:08:27 +00:00
Geoff Bourne
de0bb14abd docs: added inspect command to see anonymous volume path 2022-02-01 15:08:09 -06:00
Geoff Bourne
26809ef1f0 build: enable exit on failure for verify in setuponlytests
Related to #1305
2022-01-31 21:44:18 -06:00
itzg
dca4f86fa6 docs: Auto update markdown TOC 2022-01-31 01:50:07 +00:00
Geoff Bourne
eb0c30d134 feat: added prefix/suffix support for GENERIC_PACKS (#1321)
For #1315
2022-01-30 19:49:54 -06:00
Geoff Bourne
c55cce628d fix: bumped mc-image-helper to 1.16.3 to use specific user agent (#1320) 2022-01-30 14:05:50 -06:00
Geoff Bourne
c52c3fb04a fix: adjusted extract's file type matching for x-gzip 2022-01-30 13:53:57 -06:00
Alexandre Boucey
240238013b Use Log4J2 JVM flag when file download fail (#1316) 2022-01-30 13:46:09 -06:00
Geoff Bourne
67c8879c6b Merge latest from master 2022-01-30 12:08:38 -06:00
Geoff Bourne
18f0f0ceee fix: speedup generic pack update check (#1317)
#1281
2022-01-30 11:17:21 -06:00
Geoff Bourne
aca8701072 fix: speedup generic pack update check
#1281
2022-01-30 11:09:34 -06:00
Geoff Bourne
c424fe1c7b build: corrected issue-label to use issue.number 2022-01-29 22:09:18 -06:00
Geoff Bourne
eb694463c5 build: switch to matrix builds for Debian based variant builds (#1313) 2022-01-29 14:53:34 -06:00
Geoff Bourne
469afb3200 build: fixed issue.id reference in issue-label workflow 2022-01-28 22:44:37 -06:00
itzg
8f8acc40f5 docs: Auto update markdown TOC 2022-01-28 00:42:48 +00:00
chblodg
7dbd8256ea Adding ForgeAPI version pinning and dependency download. (#1308)
Co-authored-by: christopher blodgett <christopher.blodgett@gmail.com>
Co-authored-by: Geoff Bourne <itzgeoff@gmail.com>
2022-01-27 18:42:33 -06:00
Geoff Bourne
66468975e0 build: added id to labelled issue discord message 2022-01-27 15:03:00 -06:00
Geoff Bourne
6d27ce8461 build: updated issue label workflow with more labels 2022-01-27 14:47:03 -06:00
Geoff Bourne
b0817f2a83 build: updated issues workflow with 'help wanted'
See #1310
2022-01-27 14:44:44 -06:00
Geoff Bourne
21602a79e7 Refactored ops and whitelist processing into its own file (#1306) 2022-01-26 20:25:52 -06:00
Luc Ritchie
8a42dfe232 Fix loading world from compressed tar archives (#1304) 2022-01-25 16:19:15 -06:00
dependabot[bot]
d02bbb798e build(deps): bump docker/build-push-action from 2.7.0 to 2.8.0 (#1300) 2022-01-24 07:35:03 -06:00
Geoff Bourne
d2452ba18f Merge latest from master 2022-01-23 22:22:45 -06:00
itzg
cbbc817279 docs: Auto update markdown TOC 2022-01-24 04:19:38 +00:00
Geoff Bourne
18d8aba20f feat: support WORLD files in compressed tar format (#1297) 2022-01-23 22:19:25 -06:00
itzg
09834c289a docs: Auto update markdown TOC 2022-01-24 00:34:13 +00:00
Jawa_Juice
880dca1ae5 Update Airplane download URL, clarify version support (#1296) 2022-01-23 18:34:00 -06:00
Geoff Bourne
7f940626d8 Auto-merging via docker-versions-create 2022-01-23 10:59:40 -06:00
itzg
b1e33d4049 docs: Auto update markdown TOC 2022-01-23 16:57:49 +00:00
Geoff Bourne
284c260886 Added java17-openj9 to merge system 2022-01-23 10:57:31 -06:00
Nailima
05bbb45046 fix: changed packwiz url to reflect new repo address (#1293) 2022-01-22 10:36:52 -06:00
Geoff Bourne
d11fe229df ci: Reference branch and html URL from completed workflow in discord workflow (#1292) 2022-01-20 20:52:48 -06:00
Geoff Bourne
7246d836ec Auto-merging via docker-versions-create 2022-01-20 23:10:34 +00:00
itzg
b7801565c2 docs: Auto update markdown TOC 2022-01-20 23:09:54 +00:00
chblodg
bd4760e504 Adding MODS_FORGEAPI to auto-download by project ids (#1275)
Co-authored-by: christopher blodgett <christopher.blodgett@gmail.com>
Co-authored-by: Geoff Bourne <itzgeoff@gmail.com>
2022-01-20 17:09:34 -06:00
Geoff Bourne
edc25b216f misc: exclude high priority issues from stale check 2022-01-17 20:23:56 -06:00
Geoff Bourne
c01e97ca94 Auto-merging via docker-versions-create 2022-01-17 13:22:19 -06:00
dependabot[bot]
5499867ae8 build(deps): bump stefanzweifel/git-auto-commit-action (#1288) 2022-01-17 07:14:21 -06:00
Geoff Bourne
e4c575c130 fix(purpur): apply log4j mitigations specific to Purpur (#1280) 2022-01-16 20:49:15 -06:00
itzg
f29f098b26 docs: Auto update markdown TOC 2022-01-11 00:37:32 +00:00
Jawa_Juice
1d751ab2bc Docs: Flare flags (#1270) 2022-01-10 18:37:10 -06:00
Geoff Bourne
b59eefd556 Auto-merging via docker-versions-create 2022-01-10 06:57:20 -06:00
Drew Brown
4f87662664 fix: Set default MOTD if unset (#1265)
Co-authored-by: Geoff Bourne <itzgeoff@gmail.com>
2022-01-10 06:56:28 -06:00
Geoff Bourne
ce6ef7d81c Auto-merging via docker-versions-create 2022-01-08 15:22:09 -06:00
Geoff Bourne
7e2937aa8d fix(forge): improved tracking and use of Forge run.sh (#1264)
Fixes #1260
2022-01-08 13:19:30 -06:00
itzg
529781adda docs: Auto update markdown TOC 2022-01-08 00:32:28 +00:00
Geoff Bourne
977d082638 fix(limbo): convert MOTD to JSON chat format (#1259) 2022-01-07 18:32:10 -06:00
Geoff Bourne
0a2e6721fb Installed GNU-style find package
#1127
2022-01-06 22:11:26 -06:00
Geoff Bourne
5461107b83 Merged latest from master 2022-01-06 21:56:50 -06:00
itzg
c506cf11ac docs: Auto update markdown TOC 2022-01-06 12:50:04 +00:00
Bram
967d5159ea Add Pufferfish support (#1255) 2022-01-06 06:49:46 -06:00
Geoff Bourne
79f978359c fix: ensured GENERIC_PACKS are re-applied with REMOVE_OLD_MODS (#1257)
#1253
2022-01-05 21:38:51 -06:00
itzg
4c7bb313be docs: Auto update markdown TOC 2022-01-04 03:59:33 +00:00
chblodg
83d3555eab Adding Vanilla Tweaks Options (#1246) 2022-01-03 21:59:19 -06:00
Geoff Bourne
e93cc569c6 fix[purpur]: use mc-image-helper for robust Purpur build lookup (#1242) 2022-01-02 10:17:32 -06:00
itzg
5c0cf03548 docs: Auto update markdown TOC 2022-01-01 21:46:38 +00:00
Geoff Bourne
00cae995a7 Removed USE_LARGE_PAGES since its use is removed from Java 17
#1239
2022-01-01 15:46:43 -06:00
Jordy Hulck
4ba0a9c98c Support downloading CurseForge modpack when USE_MODPACK_START_SCRIPT is false (#1229) 2022-01-01 15:23:21 -06:00
itzg
6520655d6c docs: Auto update markdown TOC 2022-01-01 18:28:00 +00:00
Geoff Bourne
6bd722b11b docs: added note about log4jshell mitigation 2022-01-01 12:28:01 -06:00
itzg
4576882f07 docs: Auto update markdown TOC 2022-01-01 17:53:42 +00:00
Geoff Bourne
224553f695 Added java17-openj9 variant
#1209
2022-01-01 11:53:45 -06:00
itzg
cc100fd8bb docs: Auto update markdown TOC 2022-01-01 17:51:22 +00:00
Bartosz Stefańczyk
a7a0e54cb9 docs: Added note about mc-status under autopause section (#1224) 2022-01-01 11:51:07 -06:00
Jordy Hulck
ce32eb8d4f fix [CurseForge]: Fix script not deleting old version files when upgrading (#1230) 2022-01-01 11:05:07 -06:00
Geoff Bourne
39519427bb build: provide option to push image for a PR (#1221) 2021-12-23 18:38:18 -06:00
Geoff Bourne
5356c76dd6 Merged latest from master 2021-12-23 16:07:34 -06:00
itzg
2f1fed822c docs: Auto update markdown TOC 2021-12-22 13:01:44 +00:00
Caden Kriese
bf5824b6e5 Added support for downloading and installing datapacks (#1214) 2021-12-22 07:01:23 -06:00
itzg
52bf2ae094 docs: Auto update markdown TOC 2021-12-21 00:27:44 +00:00
Michael Kirsch
fa4a0e92ce Autostop feature (#1212) 2021-12-20 18:27:27 -06:00
Geoff Bourne
c15e231d7e fix: write to console pipe as minecraft user (#1216) 2021-12-20 07:09:29 -06:00
Daniel Hoffend
cc885276f5 fix: verify that the downloaded resource is a valid plugin (#1210) 2021-12-19 19:24:02 -06:00
Geoff Bourne
9dee47cb6d docs: exclude dependabot from changelog 2021-12-13 21:35:14 -06:00
Geoff Bourne
bd97029446 Auto-merging via docker-versions-create 2021-12-13 21:27:47 -06:00
itzg
39611fa9cb docs: Auto update markdown TOC 2021-12-14 02:14:33 +00:00
Jawa_Juice
bb56de694a Remove Airplane 1.16 as unsupported (#1199) 2021-12-13 20:14:16 -06:00
woeisme
c4d4d2bcc1 Created new template for docker-compose-paper.yml (#1198) 2021-12-13 14:25:21 -06:00
Levy Ehrstein
4e44f33db9 fix: fabric downgrading not working (#1197, #1192)
See #1192 for an in-depth explanation of the problem.

Reported-by: Erik "Coding-Kiwi"
2021-12-13 13:50:20 -06:00
dependabot[bot]
58c085527f build(deps): bump actions/stale from 4.0.0 to 4.1.0 (#1196) 2021-12-13 07:45:16 -06:00
itzg
79fa4b95c3 docs: Auto update markdown TOC 2021-12-13 02:08:27 +00:00
Geoff Bourne
d5f1660c77 docs: Removed docker-compose-paper.yml since it was out of date (#1195) 2021-12-12 20:08:13 -06:00
Geoff Bourne
6537cfb5b5 Auto-merging via docker-versions-create 2021-12-12 19:51:09 -06:00
Geoff Bourne
6729ba462e Merge branch 'master' of github.com:itzg/docker-minecraft-server 2021-12-12 15:35:14 -06:00
Geoff Bourne
3a3b5fc002 fix: qualify Fabric server jar by installer version (#1193) 2021-12-12 15:34:24 -06:00
Geoff Bourne
4b28d5e472 fix: qualify Fabric server jar by installer version
Fixes #1191
2021-12-12 15:28:30 -06:00
Geoff Bourne
51002c956e Merging latest from master 2021-12-12 09:01:39 -06:00
Levy Ehrstein
eccc989887 secruity: Fix CVE-2021-44228 mitigation (#1190) 2021-12-12 08:19:16 -06:00
Brett Randall
c4aa105042 Added --chmod to all COPY instructions in Dockerfile (#1184) 2021-12-12 08:10:18 -06:00
Geoff Bourne
ffcb76f73f build: auto-create github release when docker-versions-create with tag (#1188) 2021-12-11 16:51:01 -06:00
Geoff Bourne
de62cf8dc7 Auto-merging via docker-versions-create 2021-12-11 16:23:55 -06:00
Geoff Bourne
c9d5ad7530 Auto-merging via docker-versions-create 2021-12-10 21:01:24 -06:00
Geoff Bourne
1be933bd63 Auto-merging via docker-versions-create 2021-12-10 10:41:48 -06:00
Geoff Bourne
99b792dec1 Auto-merging via docker-versions-create 2021-12-10 07:56:57 -06:00
Geoff Bourne
ee5267cf41 Merge branch 'master' into java8 2021-12-06 22:20:24 -06:00
Geoff Bourne
0a46d0382e build: also run tests with java8 2021-12-06 22:16:50 -06:00
Geoff Bourne
cc61497f7e build: test 1.12.2 with java8 2021-12-06 22:15:32 -06:00
Geoff Bourne
2c2cbadd9a build: fixed combined test/build jobs 2021-12-06 22:11:43 -06:00
Geoff Bourne
bfc29d289d Auto-merging via docker-versions-create 2021-12-06 22:04:39 -06:00
Geoff Bourne
84a1313261 Auto-merging via docker-versions-create 2021-12-04 09:59:45 -06:00
Geoff Bourne
39bcfddf3c Auto-merging via docker-versions-create 2021-12-02 19:46:33 -06:00
Geoff Bourne
e6ea8197aa Auto-merging via docker-versions-create 2021-11-24 15:57:25 -06:00
Geoff Bourne
0184c095fc Auto-merging via docker-versions-create 2021-11-24 14:34:08 -06:00
Geoff Bourne
524a7e21f3 Merge branch 'master' into java8 2021-11-16 18:57:49 -06:00
Geoff Bourne
f817cae945 Merge latest from master 2021-11-16 18:51:22 -06:00
Geoff Bourne
675d05920b Auto-merging via docker-versions-create 2021-11-15 20:48:02 -06:00
Geoff Bourne
106a7132d4 Auto-merging via docker-versions-create 2021-11-13 19:17:46 -06:00
Geoff Bourne
0e04a10efa Auto-merging via docker-versions-create 2021-11-13 18:52:19 -06:00
Geoff Bourne
0d8df635d6 Auto-merging via docker-versions-create 2021-11-12 21:24:10 -06:00
Geoff Bourne
e0dedc194d Auto-merging via docker-versions-create 2021-11-06 21:36:59 -05:00
Geoff Bourne
ef32e8ed4c Auto-merging via docker-versions-create 2021-11-04 21:03:18 -05:00
Geoff Bourne
489b583ad7 Auto-merging via docker-versions-create 2021-10-31 09:44:37 -05:00
Geoff Bourne
8c4dff22fb Switched base image to JDK
#1064
2021-10-27 21:23:27 -05:00
Geoff Bourne
455f31c9d8 Auto-merging via docker-versions-create 2021-10-25 19:22:48 -05:00
Geoff Bourne
bac1bfb5dc Auto-merging via docker-versions-create 2021-10-24 20:25:05 -05:00
Geoff Bourne
9994c64b51 Auto-merging via docker-versions-create 2021-10-23 09:42:03 -05:00
Geoff Bourne
92079fc01f Merged latest from master 2021-10-21 21:55:29 -05:00
Geoff Bourne
98378130f2 Fixed Crucible libraries unzip for Alpine
#1052
2021-10-19 21:17:54 -05:00
Geoff Bourne
42856da49d Auto-merged latest from master 2021-10-18 22:08:22 -05:00
Geoff Bourne
83b05609d3 Added support for Crucible server type
#1052
2021-10-18 22:01:52 -05:00
Geoff Bourne
21fab1bf41 Auto-merging via docker-versions-create 2021-10-17 14:51:54 -05:00
Geoff Bourne
2849359a11 Auto-merging via docker-versions-create 2021-10-15 18:56:01 -05:00
Geoff Bourne
cd337f34da Auto-merging via docker-versions-create 2021-10-15 18:46:01 -05:00
Geoff Bourne
7a9aa760a2 Auto-merging via docker-versions-create 2021-10-10 09:55:28 -05:00
Geoff Bourne
2fd405ec5b Auto-merging via docker-versions-create 2021-10-09 15:24:22 -05:00
Geoff Bourne
cbfe9a069c Merged latest from master 2021-10-09 12:02:02 -05:00
Geoff Bourne
2db61fd72f Auto-merging via docker-versions-create 2021-10-02 19:21:27 -05:00
Geoff Bourne
6e2073fda5 Auto-merging via docker-versions-create 2021-09-29 10:26:44 -05:00
Geoff Bourne
ae48a8710e Auto-merging via docker-versions-create 2021-09-27 20:40:23 -05:00
Geoff Bourne
3b54a9fd67 Auto-merging via docker-versions-create 2021-09-20 12:29:36 -05:00
Geoff Bourne
a66efb1a4f Auto-merging via docker-versions-create 2021-09-15 21:30:00 -05:00
Geoff Bourne
83938d8989 Auto-merging via docker-versions-create 2021-09-15 21:05:30 -05:00
Geoff Bourne
8335b81bd8 Merged latest from master 2021-09-15 21:01:21 -05:00
Geoff Bourne
b9c379ec6c Auto-merging via docker-versions-create 2021-09-15 20:35:51 -05:00
Geoff Bourne
b9ecbf7497 Auto-merging via docker-versions-create 2021-08-30 21:36:02 -05:00
Geoff Bourne
eca00e88bf Auto-merging via docker-versions-create 2021-08-10 12:55:04 -05:00
Geoff Bourne
2a3169344d Auto-merging via docker-versions-create 2021-08-01 12:11:15 -05:00
Geoff Bourne
8ec4f0d244 Auto-merging via docker-versions-create 2021-07-31 09:26:17 -05:00
Geoff Bourne
d45250ebf2 Auto-merging via docker-versions-create 2021-07-26 19:34:15 -05:00
Geoff Bourne
03110aef99 Merged latest from master 2021-07-25 09:58:03 -05:00
Geoff Bourne
f344e7e823 Auto-merging via docker-versions-create 2021-07-25 09:35:30 -05:00
Geoff Bourne
c7fcaf1ec6 Auto-merging via docker-versions-create 2021-07-23 21:26:32 -05:00
Geoff Bourne
9d700041a7 Auto-merging via docker-versions-create 2021-07-17 21:13:39 -05:00
Geoff Bourne
4af4ed69a5 Auto-merging via docker-versions-create 2021-07-17 20:56:25 -05:00
Geoff Bourne
d215c14996 Auto-merging via docker-versions-create 2021-07-17 18:02:29 -05:00
Geoff Bourne
4716254b5b Auto-merging via docker-versions-create 2021-07-14 18:43:03 -05:00
Geoff Bourne
3c2b7f0718 Auto-merging via docker-versions-create 2021-07-12 19:08:38 -05:00
Geoff Bourne
0fd43f5a05 Auto-merging via docker-versions-create 2021-07-09 19:57:21 -05:00
Geoff Bourne
fae6479453 Auto-merging via docker-versions-create 2021-07-08 17:58:19 -05:00
Geoff Bourne
d9df5bf773 Auto-merging via docker-versions-create 2021-07-08 08:02:40 -05:00
itzg
13d7248c38 Auto-merging via docker-versions-create 2021-07-08 12:55:55 +00:00
Geoff Bourne
3c54954057 Auto merge branch with master 2021-07-08 07:37:23 -05:00
itzg
84823a559d Auto-merging via docker-versions-create 2021-07-07 14:56:34 +00:00
itzg
d543df768b Auto-merging via docker-versions-create 2021-07-06 12:22:19 +00:00
itzg
74968389a2 Auto-merging via docker-versions-create 2021-07-05 12:10:23 +00:00
itzg
1701718515 Auto-merging via docker-versions-create 2021-07-04 19:53:56 +00:00
Geoff Bourne
ed6937654c Auto-merging from master 2021-07-03 14:22:14 -05:00
Geoff Bourne
73eb6e2e45 Auto-merge from master 2021-07-02 15:52:08 -05:00
itzg
8b982472a4 Auto-merging via docker-versions-create 2021-07-02 16:55:49 +00:00
itzg
ab406727d6 Auto-merging via docker-versions-create 2021-06-28 12:13:57 +00:00
itzg
5fc74a45f7 Auto-merging via docker-versions-create 2021-06-27 13:13:05 +00:00
itzg
17ecd48cd8 Auto-merging via docker-versions-create 2021-06-24 12:46:59 +00:00
Geoff Bourne
4732ce27a6 Auto-merging via docker-versions-create 2021-06-23 22:32:34 -05:00
Geoff Bourne
6e10768e7f ci: test java8 with VERSION=1.16.5 2021-06-20 13:49:02 -05:00
Geoff Bourne
bb47a3705d Auto merge branch with master 2021-06-20 12:46:28 -05:00
Geoff Bourne
c3e1e92547 Auto-merging via docker-versions-create 2021-06-20 12:46:25 -05:00
Geoff Bourne
9ddd768f44 Auto-merging via docker-versions-create 2021-06-05 17:49:30 -05:00
Geoff Bourne
62e1ff8ffa Restored correct ps usage for autopause in Alpine
#897
2021-05-27 08:22:17 -05:00
Geoff Bourne
5f95d135f5 Auto-merging via docker-versions-create 2021-05-24 20:49:44 -05:00
Geoff Bourne
8e32d26b0f Merge branch 'master' into java8 2021-05-23 12:26:33 -05:00
Geoff Bourne
573f064970 Merge from master 2021-05-22 12:58:53 -05:00
Geoff Bourne
0bc6f4075b Auto-merging via docker-versions-create 2021-05-21 23:01:07 -05:00
Geoff Bourne
4ebcc0ef48 Auto-merging via docker-versions-create 2021-05-21 22:47:21 -05:00
Geoff Bourne
57720cf394 Merge branch 'master' into java8 2021-05-21 22:15:35 -05:00
Geoff Bourne
64b2783f19 ci: restored changes for java8 2021-05-21 17:18:57 -05:00
Geoff Bourne
1dbdd7628a Merge branch 'master' into java8 2021-05-21 17:04:24 -05:00
Geoff Bourne
4252ec710f ci: use CACHE_NAME in main.yml 2021-05-21 17:04:11 -05:00
Geoff Bourne
11d455c284 Merge branch 'master' into java8
# Conflicts:
#	Dockerfile
2021-05-21 17:02:17 -05:00
Geoff Bourne
08bc419dc8 Auto-merging via docker-versions-create 2021-05-19 20:27:11 -05:00
Geoff Bourne
67c23017d0 Auto-merging via docker-versions-create 2021-05-19 20:24:31 -05:00
Geoff Bourne
6e1ba3667c Auto-merging via docker-versions-create 2021-05-19 20:18:57 -05:00
Geoff Bourne
0c2f8b903b Auto-merging via docker-versions-create 2021-05-15 12:40:56 -05:00
Geoff Bourne
b9335d9cd6 Auto-merging via docker-versions-create 2021-05-06 20:12:25 -05:00
Geoff Bourne
0d92092b90 Auto-merging via docker-versions-create 2021-04-30 14:27:40 -05:00
Geoff Bourne
e653a41b3f Auto-merging via docker-versions-create 2021-04-30 11:11:19 -05:00
Geoff Bourne
82e63c54c4 Auto-merging via docker-versions-create 2021-04-28 16:50:55 -05:00
Geoff Bourne
f9c573f598 Auto-merging via docker-versions-create 2021-04-26 08:20:41 -05:00
Geoff Bourne
bf8b9cf20d Auto-merging via docker-versions-create 2021-04-24 13:42:07 -05:00
Geoff Bourne
0dd5a412d9 Auto-merging via docker-versions-create 2021-04-23 21:02:46 -05:00
Geoff Bourne
b389561091 Auto-merging via docker-versions-create 2021-04-18 13:29:12 -05:00
Geoff Bourne
6ee055761d Merge branch 'master' into java8 2021-04-11 10:41:32 -05:00
Geoff Bourne
49f9ff645e Auto-merging via docker-versions-create 2021-04-11 10:08:47 -05:00
Geoff Bourne
004cbdb9f7 Auto-merging via docker-versions-create 2021-04-08 19:12:56 -05:00
Geoff Bourne
45856a1a81 Auto-merging via docker-versions-create 2021-04-01 16:30:55 -05:00
Geoff Bourne
1e615e76e8 Merge branch 'master' into java8
# Conflicts:
#	start-configuration
#	start-deployCF
2021-03-18 19:58:16 -05:00
Geoff Bourne
1c85a685de Added support for CF modpacks using settings.cfg
#772 #800
2021-03-14 15:02:40 -05:00
Geoff Bourne
7cd207f40b docs: Added more info about getbukkit's weird 1.8 file naming
#103
2021-03-13 16:54:56 -06:00
Geoff Bourne
140a8aa90c Merge branch 'master' into java8 2021-03-11 19:40:26 -06:00
Geoff Bourne
76dcff9d18 Merge branch 'master' into java8 2021-03-11 17:23:48 -06:00
Geoff Bourne
a9a86d249b Merge branch 'master' into java8
# Conflicts:
#	start-configuration
2021-03-06 16:23:07 -06:00
Geoff Bourne
595760d301 Shifted PATH-fix earlier in startup 2021-03-06 16:04:06 -06:00
Geoff Bourne
6d3f194ce3 Merge from master 2021-02-27 20:47:00 -06:00
Geoff Bourne
21c1620f0c misc: java is actually found in /usr/bin by default 2021-02-11 15:05:45 -06:00
Geoff Bourne
e78e5af96d Fix PATH to include java when needed 2021-02-10 14:49:13 -06:00
Geoff Bourne
0fb9700fc7 Auto-merging via docker-versions-create 2021-02-10 14:01:35 -06:00
Geoff Bourne
18925ef32c Merged latest from master 2021-02-08 21:16:50 -06:00
Geoff Bourne
f06b990f8a Auto-merging via docker-versions-create 2021-02-07 18:03:40 -06:00
Geoff Bourne
75844ae81a Fix java8 base image to actually be Java 8
#753
2021-02-07 11:10:38 -06:00
Geoff Bourne
6bb2323c46 Auto-merging docker-versions-create.sh
CONFLICT (content): Merge conflict in docker-versions-create.sh
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
2021-02-07 09:07:30 -06:00
Geoff Bourne
7814ca21b5 Merge branch 'master' into java8
# Conflicts:
#	README.md
#	start-configuration
2021-01-30 18:56:33 -06:00
Geoff Bourne
b8806629ec Merged latest from master 2021-01-30 16:48:11 -06:00
Geoff Bourne
4a7f838a0f Upgraded mainline/latest to Java 11 2021-01-30 16:16:36 -06:00
Geoff Bourne
2d07dee4df Prepared forge branch's Dockerfile 2021-01-30 15:58:03 -06:00
121 changed files with 2201 additions and 513 deletions

4
.github/release.yml vendored Normal file
View File

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

View File

@@ -3,30 +3,60 @@ on:
push:
branches:
- master
- java8-multiarch
- java8-openj9
- java11*
- java16*
- java17*
- test/*
- fix/*
- test/**
tags:
- "[0-9]+.[0-9]+.[0-9]+"
- "[0-9]+.[0-9]+.[0-9]+-java8-multiarch"
- "[0-9]+.[0-9]+.[0-9]+-java8-openj9"
- "[0-9]+.[0-9]+.[0-9]+-java11*"
- "[0-9]+.[0-9]+.[0-9]+-java16*"
paths-ignore:
- "*.md"
- "docs/**"
- "examples/**"
env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
jobs:
build:
if: github.repository == 'itzg/docker-minecraft-server'
strategy:
fail-fast: false
matrix:
variant:
- java17
- java17-openj9
- java8-multiarch
- java8-openj9
- java11
- java11-openj9
include:
- variant: java17
baseImage: eclipse-temurin:17
tagPrefix: java17-
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: LATEST
- variant: java17-openj9
baseImage: ibm-semeru-runtimes:open-17-jdk
tagPrefix: java17-openj9-
platforms: linux/amd64,linux/arm64
mcVersion: LATEST
- variant: java8-multiarch
baseImage: eclipse-temurin:8-jdk
tagPrefix: java8-
platforms: linux/amd64,linux/arm64
mcVersion: 1.12.2
- variant: java8-openj9
baseImage: ibm-semeru-runtimes:open-8-jdk
tagPrefix: java8-openj9-
platforms: linux/amd64,linux/arm64
mcVersion: 1.12.2
- variant: java11
baseImage: adoptopenjdk:11-jdk-hotspot
tagPrefix: java11-
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: 1.16.5
- variant: java11-openj9
baseImage: ibm-semeru-runtimes:open-11-jdk
tagPrefix: java11-openj9-
platforms: linux/amd64,linux/arm64
mcVersion: 1.16.5
env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }}
runs-on: ubuntu-20.04
steps:
- name: Checkout
@@ -39,10 +69,13 @@ jobs:
images: |
itzg/minecraft-server
tags: |
type=ref,event=branch
type=ref,event=tag
type=ref,event=tag,enable=${{ matrix.variant == 'java17' }}
type=ref,event=tag,suffix=-${{ matrix.variant }}
type=raw,value=${{ matrix.variant }}
flavor: |
latest=${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
latest=${{ matrix.variant == 'java17' }}
labels: |
org.opencontainers.image.authors=Geoff Bourne <itzgeoff@gmail.com>
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
@@ -57,38 +90,37 @@ jobs:
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build for test
uses: docker/build-push-action@v2.7.0
if: github.ref_name == 'master'
uses: docker/build-push-action@v2.9.0
with:
context: .
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
# ensure latest base image is used
pull: true
# load into daemon for test usage in next step
load: true
push: false
cache-from: type=gha
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
# It is assumed that image variants are merged from master and tested there
if: github.ref_name == 'master'
env:
MINECRAFT_VERSION: ${{ matrix.mcVersion }}
run: |
tests/test.sh
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2.7.0
uses: docker/build-push-action@v2.9.0
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
platforms: ${{ matrix.platforms }}
push: ${{ github.ref_type == 'tag' || github.ref_name == 'master' }}
tags: ${{ steps.meta.outputs.tags }}
# ensure latest base image is used
pull: true
cache-from: type=gha
cache-to: type=gha,mode=max
labels: ${{ steps.meta.outputs.labels }}
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
build-args: |
BASE_IMAGE=${{ matrix.baseImage }}
cache-from: type=gha,scope=${{ matrix.variant }}
cache-to: type=gha,mode=max,scope=${{ matrix.variant }}

43
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
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 Normal file
View File

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

View File

@@ -16,6 +16,6 @@ jobs:
curl https://raw.githubusercontent.com/ekalinin/github-markdown-toc/master/gh-md-toc -o gh-md-toc
chmod a+x gh-md-toc
./gh-md-toc --insert --no-backup README.md
- uses: stefanzweifel/git-auto-commit-action@v4.12.0
- uses: stefanzweifel/git-auto-commit-action@v4.13.1
with:
commit_message: "docs: Auto update markdown TOC"

25
.github/workflows/issue-label.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: Issue labels
on:
issues:
types: [labeled]
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_ISSUES_WEBHOOK }}
jobs:
labelNotify:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: notify
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"

View File

@@ -4,16 +4,9 @@ on:
push:
branches:
- java8
- openj9
- openj9-11
- adopt11
- test/alpine/*
tags:
- "[0-9]+.[0-9]+.[0-9]+-java8"
- "[0-9]+.[0-9]+.[0-9]+-openj9"
- "[0-9]+.[0-9]+.[0-9]+-openj9-11"
- "[0-9]+.[0-9]+.[0-9]+-openj9-nightly"
- "[0-9]+.[0-9]+.[0-9]+-adopt11"
env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
@@ -53,7 +46,7 @@ jobs:
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build for test
uses: docker/build-push-action@v2.7.0
uses: docker/build-push-action@v2.9.0
if: github.ref_name == 'java8'
with:
context: .
@@ -75,7 +68,7 @@ jobs:
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2.7.0
uses: docker/build-push-action@v2.9.0
with:
context: .
file: ./Dockerfile
@@ -92,6 +85,4 @@ jobs:
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 }}
org.opencontainers.image.authors=Geoff Bourne <itzgeoff@gmail.com>

View File

@@ -1,15 +1,21 @@
name: Validate PR
name: PullRequest
on:
pull_request:
branches: [ master ]
types: [assigned, opened, synchronize, labeled]
paths-ignore:
- "*.md"
- "docs/**"
- "examples/**"
env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
jobs:
test:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2.4.0
@@ -18,15 +24,41 @@ jobs:
uses: docker/setup-buildx-action@v1
- name: Build
uses: docker/build-push-action@v2.7.0
uses: docker/build-push-action@v2.9.0
with:
context: .
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
load: true
cache-from: type=gha
cache-to: type=gha,mode=max
- 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 }}

View File

@@ -12,7 +12,7 @@ jobs:
pull-requests: write
steps:
- name: Process Stale Issues
uses: actions/stale@v4.0.0
uses: actions/stale@v4.1.0
with:
stale-issue-label: status/stale
stale-pr-label: status/stale
@@ -21,5 +21,5 @@ jobs:
Please add a comment describing the reason to keep this issue open.
days-before-stale: 30
days-before-close: 5
exempt-issue-labels: 'enhancement,keep,status/needs triage'
exempt-issue-labels: 'enhancement,keep,status/needs triage,priority/high'

3
.gitignore vendored
View File

@@ -1,4 +1,5 @@
.vscode
/data/
/.idea/
*.iml
/gh-md-toc
/gh-md-toc

View File

@@ -15,8 +15,24 @@ 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:
```shell script
docker build -t mc-dev .
PowerShell:
```powershell
$env:IMAGE_TO_TEST="mc-dev"
docker build -t $env:IMAGE_TO_TEST .
pushd tests/setuponlytests/vanillatweaks_file/
docker-compose run mc
docker-compose down --remove-orphans
popd
```
Bash:
```bash
export IMAGE_TO_TEST=mc-dev
docker build -t $IMAGE_TO_TEST .
pushd tests/setuponlytests/vanillatweaks_file/
docker-compose run mc
docker-compose down --remove-orphans
popd
```
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.
@@ -116,4 +132,4 @@ for b in "${branches[@]}"; do
git merge -s ours -m "Track latest from master" master
git push origin
done
```
```

View File

@@ -1,40 +1,42 @@
FROM eclipse-temurin:17-jdk
ARG BASE_IMAGE=openjdk:8-jdk-alpine
FROM ${BASE_IMAGE}
LABEL org.opencontainers.image.authors="Geoff Bourne <itzgeoff@gmail.com>"
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y \
RUN apk add --no-cache -U \
openssl \
imagemagick \
gosu \
sudo \
net-tools \
iputils-ping \
curl wget \
file \
lsof \
su-exec \
# GNU compatible 'find'
findutils \
shadow \
bash \
curl iputils \
git \
jq \
dos2unix \
mysql-client \
tzdata \
rsync \
nano \
unzip \
knockd \
sudo \
knock \
ttf-dejavu \
&& apt-get clean
zstd
RUN addgroup --gid 1000 minecraft \
&& adduser --system --shell /bin/false --uid 1000 --ingroup minecraft --home /data minecraft
RUN addgroup -g 1000 minecraft \
&& adduser -Ss /bin/false -u 1000 -G minecraft -h /home/minecraft minecraft \
&& mkdir -m 777 /data \
&& chown minecraft:minecraft /data /home/minecraft
COPY files/sudoers* /etc/sudoers.d
COPY --chmod=644 files/sudoers* /etc/sudoers.d
EXPOSE 25565 25575
# hook into docker BuildKit --platform support
# see https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
ARG TARGETOS
ARG TARGETARCH
ARG TARGETVARIANT
ARG TARGETOS=linux
ARG TARGETARCH=amd64
ARG TARGETVARIANT=""
ARG EASY_ADD_VER=0.7.1
ADD https://github.com/itzg/easy-add/releases/download/${EASY_ADD_VER}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add
@@ -45,26 +47,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.5.1 --var app=rcon-cli --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=0.10.3 --var app=mc-monitor --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
--var version=0.10.3 --var app=mc-monitor --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=1.8.0 --var app=mc-server-runner --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
--var version=1.8.0 --var app=mc-server-runner --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=0.1.1 --var app=maven-metadata-release --file {{.app}} \
--from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
--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.10.0
ARG MC_HELPER_VERSION=1.16.5
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
| tar -C /usr/share -zxf - \
&& ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/bin/mc-image-helper /usr/bin
VOLUME ["/data"]
WORKDIR /data
@@ -72,21 +74,22 @@ WORKDIR /data
STOPSIGNAL SIGTERM
ENV UID=1000 GID=1000 \
MEMORY="1G" \
JVM_XX_OPTS="-XX:+UseG1GC" MEMORY="1G" \
TYPE=VANILLA VERSION=LATEST \
ENABLE_RCON=true RCON_PORT=25575 RCON_PASSWORD=minecraft \
ENABLE_AUTOPAUSE=false AUTOPAUSE_TIMEOUT_EST=3600 AUTOPAUSE_TIMEOUT_KN=120 AUTOPAUSE_TIMEOUT_INIT=600 \
AUTOPAUSE_PERIOD=10 AUTOPAUSE_KNOCK_INTERFACE=eth0
AUTOPAUSE_PERIOD=10 AUTOPAUSE_KNOCK_INTERFACE=eth0 \
ENABLE_AUTOSTOP=false AUTOSTOP_TIMEOUT_EST=3600 AUTOSTOP_TIMEOUT_INIT=1800 AUTOSTOP_PERIOD=10
COPY scripts/start* /
COPY bin/ /usr/local/bin/
COPY bin/mc-health /health.sh
COPY files/server.properties /tmp/server.properties
COPY files/log4j2.xml /tmp/log4j2.xml
COPY files/autopause /autopause
COPY --chmod=755 scripts/start* /
COPY --chmod=755 bin/ /usr/local/bin/
COPY --chmod=755 bin/mc-health /health.sh
COPY --chmod=644 files/server.properties /tmp/server.properties
COPY --chmod=644 files/log4j2.xml /tmp/log4j2.xml
COPY --chmod=755 files/autopause /autopause
COPY --chmod=755 files/autostop /autostop
RUN dos2unix /start* && chmod +x /start* \
&& dos2unix /autopause/* && chmod +x /autopause/*.sh
RUN dos2unix /start* /autopause/* /autostop/*
ENTRYPOINT [ "/start" ]
HEALTHCHECK --start-period=1m CMD mc-health

271
README.md
View File

@@ -24,6 +24,7 @@ By default, the container will download the latest version of the "vanilla" [Min
**TABLE OF CONTENTS**
<!--ts-->
* [Mitigated Log4jShell Vulnerability](#mitigated-log4jshell-vulnerability)
* [Looking for a Bedrock Dedicated Server](#looking-for-a-bedrock-dedicated-server)
* [Interacting with the server](#interacting-with-the-server)
* [Data Directory](#data-directory)
@@ -45,6 +46,7 @@ By default, the container will download the latest version of the "vanilla" [Min
* [Running a Bukkit/Spigot server](#running-a-bukkitspigot-server)
* [Running a Paper server](#running-a-paper-server)
* [Running an Airplane server](#running-an-airplane-server)
* [Running a Pufferfish server](#running-a-pufferfish-server)
* [Running a Purpur server](#running-a-purpur-server)
* [Running a Magma server](#running-a-magma-server)
* [Running a Mohist server](#running-a-mohist-server)
@@ -66,13 +68,16 @@ By default, the container will download the latest version of the "vanilla" [Min
* [Optional plugins, mods, and config attach points](#optional-plugins-mods-and-config-attach-points)
* [Auto-downloading SpigotMC/Bukkit/PaperMC plugins](#auto-downloading-spigotmcbukkitpapermc-plugins)
* [Downloadable mod/plugin pack for Forge, Fabric, and Bukkit-like Servers](#downloadable-modplugin-pack-for-forge-fabric-and-bukkit-like-servers)
* [Generic pack file](#generic-pack-file)
* [ForgeAPI usage to use non-version specific projects](#forgeapi-usage-to-use-non-version-specific-projects)
* [Generic pack files](#generic-pack-files)
* [Mod/Plugin URL Listing File](#modplugin-url-listing-file)
* [Remove old mods/plugins](#remove-old-modsplugins)
* [Working with world data](#working-with-world-data)
* [Downloadable world](#downloadable-world)
* [Cloning world from a container path](#cloning-world-from-a-container-path)
* [Overwrite world on start](#overwrite-world-on-start)
* [Datapacks](#datapacks)
* [VanillaTweaks](#vanillatweaks)
* [Server configuration](#server-configuration)
* [Message of the Day](#message-of-the-day)
* [Difficulty](#difficulty)
@@ -128,16 +133,23 @@ By default, the container will download the latest version of the "vanilla" [Min
* [Explicitly disable GUI](#explicitly-disable-gui)
* [Stop Duration](#stop-duration)
* [Setup only](#setup-only)
* [Enable Flare Flags](#enable-flare-flags)
* [Enable timestamps in init logs](#enable-timestamps-in-init-logs)
* [Autopause](#autopause)
* [Description](#description)
* [Enabling Autopause](#enabling-autopause)
* [Autostop](#autostop)
* [Running on RaspberryPi](#running-on-raspberrypi)
* [Contributing](#contributing)
<!-- Added by: runner, at: Sat Dec 11 22:09:10 UTC 2021 -->
<!-- Added by: runner, at: Sun Feb 6 18:45:39 UTC 2022 -->
<!--te-->
## Mitigated Log4jShell Vulnerability
**Please ensure you have pulled the latest image** since [all official mitigations](https://www.minecraft.net/en-us/article/important-message--security-vulnerability-java-edition) are automatically applied by the container startup process.
## Looking for a Bedrock Dedicated Server
For Minecraft clients running on consoles, mobile, or native Windows, you'll need to
@@ -233,6 +245,8 @@ If you had used the commands in the first section, without the `-v` volume attac
> In this example, it is assumed the original container was given a `--name` of "mc", so change the container identifier accordingly.
> You can also locate the Docker-managed directory from the `Source` field obtained from `docker inspect <container id or name> -f "{{json .Mounts}}"`
First, stop the existing container:
```shell
docker stop mc
@@ -281,8 +295,8 @@ When using the image `itzg:/minecraft-server` without a tag, the `latest` image
| java8-openj9 | 8 | Debian | OpenJ9 | amd64 |
| java11 | 11 | Debian | Hotspot | amd64,arm64,armv7 |
| java11-openj9 | 11 | Debian | OpenJ9 | amd64 |
| java16-openj9 | 16 | Debian | OpenJ9 | amd64 |
| java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 |
| java17-openj9 | 17 | Debian | OpenJ9 | amd64 |
For example, to use Java version 8 on any supported architecture:
@@ -300,7 +314,7 @@ The following image tags have been deprecated and are no longer receiving update
- adopt15
- openj9-nightly
- multiarch-latest
- java16
- java16/java16-openj9
## Healthcheck
@@ -380,7 +394,7 @@ To troubleshoot any issues with memory allocation reported by the JVM, set the e
### Running a Forge Server
Enable [Forge server](http://www.minecraftforge.net/wiki/) mode by adding a `-e TYPE=FORGE` to your command-line.
Enable [Forge server](http://www.minecraftforge.net/) mode by adding a `-e TYPE=FORGE` to your command-line.
The overall version is specified by `VERSION`, [as described in the section above](#versions) and will run the recommended Forge version by default. You can also choose to run a specific Forge version with `FORGEVERSION`, such as `-e FORGEVERSION=14.23.5.2854`.
@@ -452,19 +466,13 @@ Plugins can either be managed within the `plugins` subdirectory of the [data dir
Enable Paper server mode by adding a `-e TYPE=PAPER` to your command-line.
By default the container will run the latest build of [Paper server](https://papermc.io/downloads)
but you can also choose to run a specific build with `-e PAPERBUILD=205`.
By default, the container will run the latest build of [Paper server](https://papermc.io/downloads) but you can also choose to run a specific build with `-e PAPERBUILD=205`.
docker run -d -v /path/on/host:/data \
-e TYPE=PAPER \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
If you are hosting your own copy of Paper you can override the download URL with:
- -e PAPER_DOWNLOAD_URL=<url>
An example compose file is provided at
[examples/docker-compose-paper.yml](examples/docker-compose-paper.yml).
If you are hosting your own copy of Paper you can override the download URL with `PAPER_DOWNLOAD_URL=<url>`.
If you have attached a host directory to the `/data` volume, then you can install plugins via the `plugins` subdirectory. You can also [attach a `/plugins` volume](#optional-plugins-mods-and-config-attach-points). If you add plugins while the container is running, you'll need to restart it to pick those up.
@@ -476,12 +484,24 @@ An [Airplane](https://airplane.gg) server, which is "a stable, optimized, well s
-e TYPE=AIRPLANE
> NOTE: The `VERSION` variable is used to select an Airplane branch to download from. The available options are "LATEST" "1.17" "1.16" "PURPUR" and "PURPUR-1.16"
> NOTE: The `VERSION` variable is used to select an Airplane type to download. The available options are "LATEST" and "PURPUR", both 1.17.1. Airplane does not support 1.18 -- use Paper/Pufferfish/Purpur.
Extra variables:
- `AIRPLANE_BUILD=lastSuccessfulBuild` : set a specific Airplane build to use
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the [Flare](https://blog.airplane.gg/flare) profiler
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [Flare](https://blog.airplane.gg/flare) profiler
### Running a Pufferfish server
A [Pufferfish](https://github.com/pufferfish-gg/Pufferfish) server, which is "a highly optimized Paper fork designed for large servers requiring both maximum performance, stability, and "enterprise" features."
-e TYPE=PUFFERFISH
> NOTE: The `VERSION` variable is used to select a Pufferfish branch to download from. The available options are "LATEST" and "1.18"
Extra variables:
- `PUFFERFISH_BUILD=lastSuccessfulBuild` : set a specific Pufferfish build to use
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [Flare](https://blog.airplane.gg/flare) profiler
### Running a Purpur server
@@ -494,7 +514,7 @@ A [Purpur](https://purpur.pl3x.net/) server, which is "drop-in replacement for P
Extra variables:
- `PURPUR_BUILD=LATEST` : set a specific Purpur build to use
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the [Flare](https://blog.airplane.gg/flare) profiler
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [Flare](https://blog.airplane.gg/flare) profiler
### Running a Magma server
@@ -571,6 +591,8 @@ Configuration options with defaults:
- `LIMBO_SCHEMA_FILENAME`=default.schem
- `LEVEL`="Default;${LIMBO_SCHEMA_FILENAME}"
> NOTE: instead of using format codes in the MOTD, Limbo requires [JSON chat content](https://minecraft.fandom.com/wiki/Raw_JSON_text_format#Java_Edition). If a plain string is provided, which is the default, then it gets converted into the required JSON structure.
### Running a Crucible server
A [Crucible](https://github.com/CrucibleMC/Crucible) server can be run by setting `TYPE` to `CRUCIBLE`.
@@ -725,11 +747,77 @@ You may also download or copy over individual mods using the `MODS` environment
docker run -d -e MODS=https://www.example.com/mods/mod1.jar,/plugins/common,/plugins/special/mod2.jar ...
### Generic pack file
### ForgeAPI usage to use non-version specific projects
To install all of the server content (jars, mods, plugins, configs, etc) from a zip file, such as a CurseForge modpack that is missing a server start script, then set `GENERIC_PACK` to the container path of the zip file. That, combined with `TYPE`, allows for custom content along with container managed server download and install.
**NOTE:** This potentially could lead to unexpected behavior if the Mod receives an update with unexpected behavior.
If multiple generic packs need to be applied together, set `GENERIC_PACKS` instead, with a comma separated list of zip file paths and/or URLs to zip files.
This is more complicated because you will be pulling/using the latest mod for the release of your game. To get started make sure you have a [CursedForge API Key](https://docs.curseforge.com/#getting-started). Then use the environmental parameters in your docker build.
Parameters to use the ForgeAPI:
* `MODS_FORGEAPI_KEY` - Required
* `MODS_FORGEAPI_FILE` - Required or use MODS_FORGEAPI_PROJECTIDS (Overrides MODS_FORGEAPI_PROJECTIDS)
* `MODS_FORGEAPI_PROJECTIDS` - Required or use MODS_FORGEAPI_FILE
* `MODS_FORGEAPI_RELEASES` - Default is release, Options: [Release|Beta|Alpha]
* `MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES` - Default is False, attempts to download required mods (releaseType Release) defined in Forge.
* `REMOVE_OLD_FORGEAPI_MODS` - Default is False
* `REMOVE_OLD_DATAPACKS_DEPTH` - Default is 1
* `REMOVE_OLD_DATAPACKS_INCLUDE` - Default is *.jar
Example of expected forge api project ids, releases, and key:
```yaml
MODS_FORGEAPI_PROJECTIDS: 306612,256717
MODS_FORGEAPI_RELEASES: Release
MODS_FORGEAPI_KEY: $WRX...
```
Example of expected ForgeAPI file format.
**Field Description**:
* `name` is currently unused, but can be used to document each entry.
* `projectId` id is the id found on the CurseForge website for a particular mod
* `releaseType` Type corresponds to forge's R, B, A icon for each file. Default Release, options are (release|beta|alpha).
* `fileName` is used for version pinning if latest file will not work for you.
```json
[
{
"name": "fabric api",
"projectId": "306612",
"releaseType": "release"
},
{
"name": "fabric voice mod",
"projectId": "416089",
"releaseType": "beta"
},
{
"name": "Biomes o plenty",
"projectId": "220318",
"fileName": "BiomesOPlenty-1.18.1-15.0.0.100-universal.jar",
"releaseType": "release"
}
]
```
### Generic pack files
To install all the server content (jars, mods, plugins, configs, etc.) from a zip or tgz file, then set `GENERIC_PACK` to the container path or URL of the archive file. This can also be used to apply a CurseForge modpack that is missing a server start script and/or Forge installer.
If multiple generic packs need to be applied together, set `GENERIC_PACKS` instead, with a comma separated list of archive file paths and/or URLs to files.
To avoid repetition, each entry will be prefixed by the value of `GENERIC_PACKS_PREFIX` and suffixed by the value of `GENERIC_PACKS_SUFFIX`, both of which are optional. For example, the following variables
```
GENERIC_PACKS=configs-v9.0.1,mods-v4.3.6
GENERIC_PACKS_PREFIX=https://cdn.example.org/
GENERIC_PACKS_SUFFIX=.zip
```
would expand to `https://cdn.example.org/configs-v9.0.1.zip,https://cdn.example.org/mods-v4.3.6.zip`.
If applying large generic packs, the update check can be time-consuming since a SHA1 checksum is compared. To skip the update check set `SKIP_GENERIC_PACK_UPDATE_CHECK` to "true". Conversely, the generic pack(s) can be forced to be applied without comparing the checksum by setting `FORCE_GENERIC_PACK_UPDATE` to "true".
### Mod/Plugin URL Listing File
@@ -769,23 +857,19 @@ before unpacking new content from the MODPACK or MODS.
### Downloadable world
Instead of mounting the `/data` volume, you can instead specify the URL of a ZIP file containing an archived world. It will be searched for a file `level.dat` and the containing subdirectory moved to the directory named by `$LEVEL`. This means that most of the archived Minecraft worlds downloadable from the Internet will already be in the correct format.
Instead of mounting the `/data` volume, you can instead specify the URL of a ZIP or compressed TAR file containing an archived world. It will be searched for a file `level.dat` and the containing subdirectory moved to the directory named by `$LEVEL`. This means that most of the archived Minecraft worlds downloadable from the Internet will already be in the correct format.
docker run -d -e WORLD=http://www.example.com/worlds/MySave.zip ...
**NOTE:** This URL must be accessible from inside the container. Therefore,
you should use an IP address or a globally resolvable FQDN, or else the
name of a linked container.
**NOTE:** This URL must be accessible from inside the container. Therefore, you should use an IP address or a globally resolvable FQDN, or else the name of a linked container.
**NOTE:** If the archive contains more than one `level.dat`, then the one to select can be picked with `WORLD_INDEX`, which defaults to 1.
### Cloning world from a container path
The `WORLD` option can also be used to reference a directory or zip file that will be used as a source to clone or unzip the world directory.
The `WORLD` option can also be used to reference a directory, zip file, or compressed tar file that will be used as a source to clone or extract the world directory.
For example, the following would initially clone the world's content
from `/worlds/basic`. Also notice in the example that you can use a
read-only volume attachment to ensure the clone source remains pristine.
For example, the following would initially clone the world's content from `/worlds/basic`. Also notice in the example that you should use a read-only volume attachment to ensure the clone source remains pristine.
```
docker run ... -v $HOME/worlds:/worlds:ro -e WORLD=/worlds/basic
@@ -798,6 +882,87 @@ The following diagram shows how this option can be used in a compose deployment
### Overwrite world on start
The world will only be downloaded or copied if it doesn't exist already. Set `FORCE_WORLD_COPY=TRUE` to force overwrite the world on every server start.
### Datapacks
Datapacks can be installed in a similar manner to mods/plugins. There are many environment variables which function in the same way they do for [mods](#working-with-mods-and-plugins):
* `DATAPACKS`
* `DATAPACKS_FILE`
* `REMOVE_OLD_DATAPACKS`
* `REMOVE_OLD_DATAPACKS_DEPTH`
* `REMOVE_OLD_DATAPACKS_INCLUDE`
* `REMOVE_OLD_DATAPACKS_EXCLUDE`
Datapacks will be placed in `/data/$LEVEL/datapacks`
### VanillaTweaks
VanillaTweaks datapacks can be installed with a share code from the website UI **OR** a json file to specify packs to download and install.
Datapacks will be placed in `/data/$LEVEL/datapacks`
Resourcepacks will be placed in `/data/resourcepacks`
Accepted Parameters:
- `VANILLATWEAKS_FILE`
- `VANILLATWEAKS_SHARECODE`
- `REMOVE_OLD_VANILLATWEAKS`
- `REMOVE_OLD_VANILLATWEAKS_DEPTH`
- `REMOVE_OLD_VANILLATWEAKS_INCLUDE`
- `REMOVE_OLD_VANILLATWEAKS_EXCLUDE`
Example of expected Vanillatweaks sharecode:
**Note**: ResourcePacks, DataPacks, and CraftingTweaks all have separate sharecodes
```yaml
VANILLATWEAKS_SHARECODE: MGr52E,tF1zL2,LnEDwT
```
Example of expected Vanillatweaks file format:
```yaml
VANILLATWEAKS_FILE: /config/vt-datapacks.json,/config/vt-craftingtweaks.json,/config/vt-resourcepacks.json
```
Datapacks Json:
```json
{
"version": "1.18",
"packs": {
"survival": [
"graves",
"multiplayer sleep",
],
"items": ["armored elytra"]
}
}
```
Resourcepacks Json:
```json
{
"type": "resourcepacks",
"version": "1.18",
"packs": {
"aesthetic": ["CherryPicking", "BlackNetherBricks", "AlternateBlockDestruction"]
},
"result": "ok"
}
```
CraftingTweaks Json:
```json
{
"type": "craftingtweaks",
"version": "1.18",
"packs": {
"quality of life": [
"dropper to dispenser",
"double slabs",
"back to blocks"
]
},
"result": "ok"
}
```
## Server configuration
By default, the server configuration will be created and set based on the following environment variables, but only the first time the server is started. If the `server.properties` file already exists, the values in them will not be changed.
@@ -1394,10 +1559,6 @@ To enable remote JMX, such as for profiling with VisualVM or JMC, add the enviro
When `MEMORY` is greater than or equal to 12G, then the Aikar flags will be adjusted according to the article.
Large page support can also be enabled by adding
-e USE_LARGE_PAGES=true
### HTTP Proxy
You may configure the use of an HTTP/HTTPS proxy by passing the proxy's URL via the `PROXY`
@@ -1422,6 +1583,28 @@ When the container is signalled to stop, the Minecraft process wrapper will atte
### Setup only
If you are using a host-attached data directory, then you can have the image setup the Minecraft server files and stop prior to launching the server process by setting `SETUP_ONLY` to `true`.
### Enable Flare Flags
To enable the JVM flags required to fully support the [Flare profiling suite](https://blog.airplane.gg/flare), set the following variable:
-e USE_FLARE_FLAGS=true
Flare is built-in to Airplane/Pufferfish/Purpur, and is available in [plugin form](https://github.com/TECHNOVE/FlarePlugin) for other server types.
### Enable timestamps in init logs
Before the container starts the Minecraft Server its output is prefixed with `[init]`, such as
```
[init] Starting the Minecraft server...
```
To also include the timestamp with each log, set `LOG_TIMESTAMP` to "true". The log output will then look like:
```
[init] 2022-02-05 16:58:33+00:00 Starting the Minecraft server...
```
## Autopause
@@ -1453,6 +1636,8 @@ Enable the Autopause functionality by setting:
Autopause is not compatible with `EXEC_DIRECTLY=true` and the two cannot be set together.
> When configuring kubernetes readiness/liveness health checks with auto-pause enabled, be sure to reference the `mc-health` wrapper script rather than `mc-status` directly.
The following environment variables define the behaviour of auto-pausing:
* `AUTOPAUSE_TIMEOUT_EST`, default `3600` (seconds)
describes the time between the last client disconnect and the pausing of the process (read as timeout established)
@@ -1465,6 +1650,28 @@ The following environment variables define the behaviour of auto-pausing:
* `AUTOPAUSE_KNOCK_INTERFACE`, default `eth0`
<br>Describes the interface passed to the `knockd` daemon. If the default interface does not work, run the `ifconfig` command inside the container and derive the interface receiving the incoming connection from its output. The passed interface must exist inside the container. Using the loopback interface (`lo`) does likely not yield the desired results.
## Autostop
An option to stop the server after a specified time has been added for niche applications (e.g. billing saving on AWS Fargate). The function is incompatible with the Autopause functionality, as they basically cancel out each other.
Note that the docker container variables have to be set accordingly (restart policy set to "no") and that the container has to be manually restarted.
A starting, example compose file has been provided in [examples/docker-compose-autostop.yml](examples/docker-compose-autostop.yml).
Enable the Autostop functionality by setting:
```
-e ENABLE_AUTOSTOP=TRUE
```
The following environment variables define the behaviour of auto-stopping:
* `AUTOSTOP_TIMEOUT_EST`, default `3600` (seconds)
describes the time between the last client disconnect and the stopping of the server (read as timeout established)
* `AUTOSTOP_TIMEOUT_INIT`, default `1800` (seconds)
describes the time between server start and the stopping of the server, when no client connects inbetween (read as timeout initialized)
* `AUTOSTOP_PERIOD`, default `10` (seconds)
describes period of the daemonized state machine, that handles the stopping of the server
## Running on RaspberryPi
To run this image on a RaspberryPi 3 B+, 4, or newer, use any of the image tags [list in the Java version section](#running-minecraft-server-on-different-java-version) that specify `armv7` for the architecture, which includes `itzg/minecraft-server:latest`.

View File

@@ -12,4 +12,4 @@ if [ ! -p "${CONSOLE_IN_NAMED_PIPE}" ]; then
exit 1
fi
echo "$@" > "${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}"
gosu minecraft bash -c "echo $* > '${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}'"

View File

@@ -3,12 +3,6 @@
# Use this variable to indicate a list of branches that docker hub is watching
branches_list=(
'java8'
'java8-multiarch'
'java8-openj9'
'java11'
'java11-openj9'
'java16-openj9'
'java17'
)
function TrapExit {
@@ -147,7 +141,7 @@ if [[ $tag ]]; then
"generate_release_notes": true
}
EOF
if ! echo curl "${auth[@]}" -H "Accept: application/vnd.github.v3+json" \
if ! curl "${auth[@]}" -H "Accept: application/vnd.github.v3+json" \
"${base}/repos/${owner}/${repo}/releases" -d "$releaseBody"; then
echo "ERROR failed to create github release $tag"
exit 1

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -5,15 +5,15 @@ current_uptime() {
}
java_running() {
[[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]]
[[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]]
}
java_process_exists() {
[[ -n "$(ps -ax -o comm | grep 'java')" ]]
[[ -n "$(ps -a -o comm | grep 'java')" ]]
}
rcon_client_exists() {
[[ -n "$(ps -ax -o comm | grep 'rcon-cli')" ]]
[[ -n "$(ps -a -o comm | grep 'rcon-cli')" ]]
}
mc_server_listening() {

View File

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

View File

@@ -2,7 +2,7 @@
. /start-utils
if [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] ; then
if [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] ; then
# save world
rcon-cli save-all >/dev/null

View File

@@ -2,7 +2,7 @@
. /start-utils
if [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^T.*$ ]] ; then
if [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^T.*$ ]] ; then
logAutopauseAction "Knocked, resuming Java process"
pkill -CONT java
fi

View File

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

6
files/autostop/stop.sh Executable file
View File

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

View File

@@ -40,7 +40,7 @@ if ! isTrue "${SKIP_SUDO:-false}" && [ $(id -u) = 0 ]; then
echo 'hosts: files dns' > /etc/nsswitch.conf
fi
exec gosu ${runAsUser}:${runAsGroup} ${SCRIPTS:-/}start-configuration $@
exec su-exec ${runAsUser}:${runAsGroup} ${SCRIPTS:-/}start-configuration "$@"
else
exec ${SCRIPTS:-/}start-configuration $@
exec ${SCRIPTS:-/}start-configuration "$@"
fi

34
scripts/start-autostop Executable file
View File

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

View File

@@ -3,7 +3,7 @@ set -euo pipefail
IFS=$'\n\t'
# shellcheck source=start-utils
. ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
: "${EULA:=}"
: "${PROXY:=}"
@@ -37,6 +37,11 @@ if isTrue "${ENABLE_AUTOPAUSE}" && isTrue "${EXEC_DIRECTLY:-false}"; then
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"
@@ -61,9 +66,12 @@ if [[ $RCON_PASSWORD_FILE ]]; then
log ""
fi
# Some Docker management UIs grab all the image declared variables and present them for configuration.
# When upgrading images across Java versions, that creates a mismatch in PATH's expected by base image.
if ! which java > /dev/null; then
log "Fixing PATH to include java"
PATH="${PATH}:/opt/java/openjdk/bin"
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
@@ -96,6 +104,10 @@ 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=(
@@ -107,39 +119,31 @@ fi
log "Resolving type given ${TYPE}"
case "${TYPE^^}" in
*BUKKIT|SPIGOT)
exec ${SCRIPTS:-/}start-deployBukkitSpigot "$@"
exec "${SCRIPTS:-/}start-deployBukkitSpigot" "$@"
;;
PAPER)
exec ${SCRIPTS:-/}start-deployPaper "$@"
exec "${SCRIPTS:-/}start-deployPaper" "$@"
;;
FORGE)
if versionLessThan 1.17; then
log "**********************************************************************"
log "WARNING: The image tag itzg/minecraft-server:java8 is recommended"
log " since some mods require Java 8"
log " Exception traces reporting ClassCastException: class jdk.internal.loader.ClassLoaders\$AppClassLoader"
log " can be fixed with java8"
log "**********************************************************************"
fi
exec ${SCRIPTS:-/}start-deployForge "$@"
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployForge" "$@"
;;
FABRIC)
exec ${SCRIPTS:-/}start-deployFabric "$@"
exec "${SCRIPTS:-/}start-deployFabric" "$@"
;;
FTBA)
exec ${SCRIPTS:-/}start-deployFTBA "$@"
log "ERROR: TYPE=FTBA is not supported with this image variant."
log " Use itzg/minecraft-server:java8-multiarch instead."
exit 1
;;
FTB|CURSEFORGE)
log "**********************************************************************"
log "NOTE: Some mods and modpacks may require Java 8."
log " If so, use itzg/minecraft-server:java8"
log "**********************************************************************"
exec ${SCRIPTS:-/}start-deployCF "$@"
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployCF" "$@"
;;
VANILLA)
@@ -147,48 +151,50 @@ case "${TYPE^^}" in
;;
SPONGEVANILLA)
exec ${SCRIPTS:-/}start-deploySpongeVanilla "$@"
exec "${SCRIPTS:-/}start-deploySpongeVanilla" "$@"
;;
CUSTOM)
exec ${SCRIPTS:-/}start-deployCustom "$@"
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployCustom" "$@"
;;
MAGMA)
exec ${SCRIPTS:-/}start-deployMagma "$@"
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployMagma" "$@"
;;
MOHIST)
exec ${SCRIPTS:-/}start-deployMohist "$@"
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployMohist" "$@"
;;
CATSERVER)
exec ${SCRIPTS:-/}start-deployCatserver "$@"
evaluateJavaCompatibilityForForge
exec "${SCRIPTS:-/}start-deployCatserver" "$@"
;;
PURPUR)
exec ${SCRIPTS:-/}start-deployPurpur "$@"
exec "${SCRIPTS:-/}start-deployPurpur" "$@"
;;
AIRPLANE)
exec ${SCRIPTS:-/}start-deployAirplane "$@"
exec "${SCRIPTS:-/}start-deployAirplane" "$@"
;;
PUFFERFISH)
exec "${SCRIPTS:-/}start-deployPufferfish" "$@"
;;
CANYON)
exec ${SCRIPTS:-/}start-deployCanyon "$@"
exec "${SCRIPTS:-/}start-deployCanyon" "$@"
;;
LIMBO)
exec ${SCRIPTS:-/}start-deployLimbo "$@"
exec "${SCRIPTS:-/}start-deployLimbo" "$@"
;;
CRUCIBLE)
log "**********************************************************************"
log "WARNING: The image tag itzg/minecraft-server:java8 is recommended"
log " since some mods require Java 8"
log " Exception traces reporting ClassCastException: class jdk.internal.loader.ClassLoaders\$AppClassLoader"
log " can be fixed with java8"
log "**********************************************************************"
exec "${SCRIPTS:-/}start-deployCrucible" "$@"
;;
@@ -196,7 +202,7 @@ case "${TYPE^^}" in
log "Invalid type: '$TYPE'"
log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTBA (multiarch-only),"
log " CURSEFORGE, SPONGEVANILLA, PURPUR, CUSTOM,"
log " MAGMA, MOHIST, CATSERVER, AIRPLANE, CANYON, LIMBO, CRUCIBLE"
log " MAGMA, MOHIST, CATSERVER, AIRPLANE, PUFFERFISH, CANYON, LIMBO, CRUCIBLE"
exit 1
;;

View File

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

View File

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

View File

@@ -35,11 +35,37 @@ FTB_SERVER_MOD=${FTB_SERVER_MOD:-$CF_SERVER_MOD}
log "Looking for Feed-The-Beast / CurseForge server modpack."
requireVar FTB_SERVER_MOD
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
downloadModpack() {
srv_modpack=${FTB_SERVER_MOD}
if isURL "${srv_modpack}"; then
log "Downloading modpack from ${srv_modpack}..."
if ! srv_modpack=$(get -o /data --output-filename --skip-existing "${srv_modpack}"); then
log "ERROR: failed to download modpack"
exit 1
fi
fi
if [[ "${srv_modpack:0:5}" == "data/" ]]; then
# Prepend with "/"
srv_modpack="/${srv_modpack}"
fi
if [[ ! "${srv_modpack:0:1}" == "/" ]]; then
# If not an absolute path, assume file is in "/data"
srv_modpack=/data/${srv_modpack}
fi
if [[ ! -f "${srv_modpack}" ]]; then
log "FTB server modpack ${srv_modpack} not found."
exit 2
fi
if [[ ! "${srv_modpack: -4}" == ".zip" ]]; then
log "FTB server modpack ${srv_modpack} is not a zip archive."
log "Please set FTB_SERVER_MOD to a file with a .zip extension."
exit 2
fi
FTB_SERVER_MOD=${srv_modpack}
}
if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
downloadModpack
needsInstall=true
installMarker=/data/.curseforge-installed
@@ -47,7 +73,7 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
if [ "$(cat $installMarker)" != "${FTB_SERVER_MOD}" ]; then
log "Upgrading modpack"
serverJar=$(find "${FTB_BASE_DIR}" -not -name "forge*installer.jar" -name "forge*.jar")
serverJar=$(find "${FTB_BASE_DIR}" -type f \( -path "*/libraries/*" -o -path "*/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
if [[ "${serverJar}" ]]; then
rm -rf "$(dirname "${serverJar}")"/{mods,*.jar,libraries,resources,scripts,config}
fi
@@ -85,6 +111,8 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
exit 2
fi
forgeInstallerJar=$(ls -t "${forgeInstallerJar}" | head -1)
log "Installing forge server"
dirOfInstaller=$(dirname "${forgeInstallerJar}")
(cd "${dirOfInstaller}"; java -jar "$(basename "${forgeInstallerJar}")" --installServer)
@@ -132,32 +160,9 @@ 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
log "Downloading modpack from ${srv_modpack}..."
if ! srv_modpack=$(get -o /data --output-filename --skip-existing "${srv_modpack}"); then
log "ERROR: failed to download modpack"
exit 1
fi
fi
if [[ "${srv_modpack:0:5}" == "data/" ]]; then
# Prepend with "/"
srv_modpack="/${srv_modpack}"
fi
if [[ ! "${srv_modpack:0:1}" == "/" ]]; then
# If not an absolute path, assume file is in "/data"
srv_modpack=/data/${srv_modpack}
fi
if [[ ! -f "${srv_modpack}" ]]; then
log "FTB server modpack ${srv_modpack} not found."
exit 2
fi
if [[ ! "${srv_modpack: -4}" == ".zip" ]]; then
log "FTB server modpack ${srv_modpack} is not a zip archive."
log "Please set FTB_SERVER_MOD to a file with a .zip extension."
exit 2
fi
log "Unpacking FTB server modpack ${srv_modpack} ..."
mkdir -p "${FTB_BASE_DIR}"
unzip -o "${srv_modpack}" -d "${FTB_BASE_DIR}" | awk '{printf "."} END {print ""}'

View File

@@ -43,8 +43,6 @@ if [ ! -f "$SERVER" ]; then
fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -1,6 +1,7 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
set -o pipefail
set -e
@@ -26,8 +27,6 @@ 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 SKIP_LOG4J_CONFIG=true
export FAMILY=HYBRID
# Continue to Final Setup
exec ${SCRIPTS:-/}start-setupWorld "$@"
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -47,6 +47,7 @@ if [ ! -d "$librariesDir" ]; then
exit 1
fi
mkdir "$librariesDir"
if ! unzip /tmp/libraries.zip -d "$librariesDir"; then
log "ERROR: failed to unzip Crucible libraries"
exit 1
@@ -55,7 +56,6 @@ if [ ! -d "$librariesDir" ]; then
fi
export SERVER
export SKIP_LOG4J_CONFIG=true
export FAMILY=HYBRID
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"

View File

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

View File

@@ -2,7 +2,8 @@
ftbInstallMarker=".ftb-installed"
. ${SCRIPTS:-/}start-utils
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x
set -e
@@ -80,4 +81,5 @@ if ! [ -v SERVER ]; then
fi
export FAMILY=FORGE
exec ${SCRIPTS:-/}start-setupWorld $@

View File

@@ -2,27 +2,31 @@
set -eu
# shellcheck source=start-utils
. ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
requireVar VANILLA_VERSION
export TYPE=FABRIC
export SERVER=fabric-server-${VANILLA_VERSION}.jar
: "${FABRIC_INSTALLER_VERSION:=${FABRICVERSION:-LATEST}}"
: "${FABRIC_INSTALLER:=}"
: "${FABRIC_INSTALLER_URL:=}"
: "${FABRIC_LOADER_VERSION:=LATEST}"
isDebugging && set -x
if [[ ! -e ${SERVER} ]]; then
log "Checking Fabric version information."
if [[ $FABRIC_INSTALLER ]]; then
FABRIC_INSTALLER_VERSION=$(echo -n "$FABRIC_INSTALLER" | mc-image-helper hash)
elif [[ $FABRIC_INSTALLER_URL ]]; then
FABRIC_INSTALLER_VERSION=$(echo -n "$FABRIC_INSTALLER_URL" | mc-image-helper hash)
elif [[ ${FABRIC_INSTALLER_VERSION^^} = LATEST ]]; then
FABRIC_INSTALLER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-installer/maven-metadata.xml)
fi
: ${FABRIC_INSTALLER:=}
: ${FABRIC_INSTALLER_URL:=}
: ${FABRIC_LOADER_VERSION:=LATEST}
: ${FABRIC_INSTALLER_VERSION:=${FABRICVERSION:-LATEST}}
export SERVER=fabric-server-${VANILLA_VERSION}-${FABRIC_INSTALLER_VERSION}.jar
if [ ! \( -e ${SERVER} -a -e "server-${VANILLA_VERSION}.jar" \) ]; then
if [[ -z $FABRIC_INSTALLER && -z $FABRIC_INSTALLER_URL ]]; then
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
@@ -66,8 +70,12 @@ if [[ ! -e ${SERVER} ]]; then
exit 10
fi
mv server.jar "server-${VANILLA_VERSION}.jar"
mv fabric-server-launch.jar "${SERVER}"
fi
# Specify which server jar to run
echo "serverJar=server-${VANILLA_VERSION}.jar" > fabric-server-launcher.properties
export FAMILY=FABRIC
exec ${SCRIPTS:-/}start-setupWorld "$@"
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -38,18 +38,23 @@ install() {
get_installer "$normForgeVersion" "$shortForgeVersion"
fi
log "Installing Forge $shortForgeVersion using $FORGE_INSTALLER"
log "Installing Forge $shortForgeVersion. This might take a minute or two..."
mkdir -p mods
tries=3
while ((--tries >= 0)); do
if java -jar "$FORGE_INSTALLER" --installServer; then
break
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
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
@@ -148,4 +153,5 @@ else
fi
export FAMILY=FORGE
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

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

View File

@@ -1,13 +1,12 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
export SKIP_LOG4J_CONFIG=true
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x
: ${VANILLA_VERSION?}
: "${VANILLA_VERSION?}"
# stable, dev
: ${MAGMA_CHANNEL:=stable}
: "${MAGMA_CHANNEL:=stable}"
magmaDownloadServer() {
@@ -90,4 +89,5 @@ else
fi
export FAMILY=HYBRID
exec ${SCRIPTS:-/}start-setupWorld "$@"
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

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

View File

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

44
scripts/start-deployPufferfish Executable file
View File

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

View File

@@ -2,20 +2,19 @@
set -euo pipefail
IFS=$'\n\t'
. ${SCRIPTS:-/}start-utils
# shellcheck source=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
PURPUR_BUILD=$(curl -fsSL "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}" |
jq -r '.builds.latest' || echo "")
if [[ -z ${PURPUR_BUILD} ]]; then
if ! PURPUR_BUILD=$(get --json-path=".builds.latest" "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}"); then
log "ERROR: Failed to locate a Purpur build for ${VANILLA_VERSION}."
log " Please check if a download is available at https://purpur.pl3x.net/downloads/"
exit 3
exit 1
fi
fi
@@ -24,15 +23,13 @@ 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"
log "Downloading Purpur from $downloadUrl ..."
if ! curl -fsSL -o "$SERVER" "$downloadUrl"; then
if ! get -o "$SERVER" "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3
fi
fi
# Normalize on Spigot for later operations
export TYPE=SPIGOT
export FAMILY=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@"
exec "${SCRIPTS:-/}start-spiget" "$@"

View File

@@ -1,97 +1,9 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
# 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
if [ -n "$ICON" ]; then
if [ ! -e server-icon.png ] || [ "${OVERRIDE_ICON}" == "TRUE" ]; then
log "Using server icon from $ICON..."
@@ -107,7 +19,47 @@ 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
@@ -135,7 +87,7 @@ if versionLessThan 1.14 && [[ ${CONSOLE,,} = false ]]; then
fi
# Optional disable GUI for headless servers
if [[ ${GUI} = false || ${GUI} = FALSE ]]; then
if [[ ${GUI,,} = false ]]; then
EXTRA_ARGS+=" nogui"
fi
@@ -150,28 +102,6 @@ if [ -n "$JVM_DD_OPTS" ]; then
done
fi
patchLog4jConfig() {
file=${1?}
url=${2?}
if ! get -o "$file" "$url"; then
log "ERROR: failed to download corrected log4j config"
exit 1
fi
JVM_OPTS="-Dlog4j.configurationFile=${file} ${JVM_OPTS}"
}
# 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
elif versionLessThan 1.18.1; then
JVM_OPTS="-Dlog4j2.formatMsgNoLookups=true ${JVM_OPTS}"
fi
if isTrue ${ENABLE_JMX}; then
: ${JMX_PORT:=7091}
JVM_OPTS="${JVM_OPTS}
@@ -229,12 +159,6 @@ 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
@@ -322,10 +246,14 @@ EOF
else
exec mc-server-runner "${mcServerRunnerArgs[@]}" "${finalArgs[@]}"
fi
elif [[ -x run.sh ]]; then
elif [[ $SERVER =~ run.sh ]]; then
log "Using Forge supplied run.sh script..."
echo $JVM_XX_OPTS $JVM_OPTS $expandedDOpts > user_jvm_args.txt
exec mc-server-runner "${mcServerRunnerArgs[@]}" --shell bash run.sh
if isTrue ${SETUP_ONLY:=false}; then
echo "SETUP_ONLY: bash ${SERVER}"
exit
fi
exec mc-server-runner "${mcServerRunnerArgs[@]}" --shell bash "${SERVER}"
else
# If we have a bootstrap.txt file... feed that in to the server stdin
if [ -f /data/bootstrap.txt ]; then

77
scripts/start-setupDatapack Executable file
View File

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

View File

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

View File

@@ -0,0 +1,221 @@
#!/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}"
: "${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
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_FILE}" ]; then
removeOldMods /data/mods
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
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
current_project_file=$(jq -n "$project_files" | jq --arg FILE_NAME "$project_id_file_name" -jc '
.data | map(select(.fileName<=($FILE_NAME))) | .[0]')
else
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]')
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
}
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 -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
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 -n "$required_dependencies" | jq -c '.[]?' | 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 -jc '.projectId // empty' )
current_release_type=$(jq -n "$current_project" | jq -jc '.releaseType // empty' )
current_file_name=$(jq -n "$current_project" | jq -jc '.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
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" "$@"

View File

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

View File

@@ -6,6 +6,7 @@ set -e -o pipefail
: "${MODS_FILE:=}"
: "${REMOVE_OLD_MODS_DEPTH:=1} "
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar}"
sum_file=/data/.generic_pack.sum
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
@@ -18,16 +19,17 @@ CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects}
if isTrue "${REMOVE_OLD_MODS}" && [ -z "${MODS_FILE}" ]; then
removeOldMods /data/mods
removeOldMods /data/plugins
rm -f "$sum_file"
fi
# If packwiz url passed, bootstrap packwiz and update mods before other modpack processing
if [[ "${PACKWIZ_URL}" ]]; then
# Ensure we have the latest packwiz bootstrap installer
latestPackwiz=$(curl -fsSL https://api.github.com/repos/comp500/packwiz-installer-bootstrap/releases/latest)
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}"
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}"
@@ -65,7 +67,7 @@ if [[ "$MODPACK" ]]; then
exit 1
fi
if [ "$TYPE" = "SPIGOT" ]; then
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}"
@@ -79,7 +81,7 @@ if [[ "$MODPACK" ]]; then
rm -f /tmp/modpack.zip
elif [[ "$MODS" ]]; then
if [ "$TYPE" = "SPIGOT" ]; then
if [ "$FAMILY" = "SPIGOT" ]; then
out_dir=/data/plugins
else
out_dir=/data/mods
@@ -90,7 +92,7 @@ elif [[ "$MODS" ]]; then
do
if isURL "$i"; then
log "Downloading mod/plugin $i ..."
if ! get -o "${out_dir}" "$i"; then
if ! get --skip-up-to-date -o "${out_dir}" "$i"; then
log "ERROR: failed to download from $i into $out_dir"
exit 2
fi
@@ -116,7 +118,7 @@ elif [[ "$MODS_FILE" ]]; then
exit 2
fi
if [ "$TYPE" = "SPIGOT" ]; then
if [ "$FAMILY" = "SPIGOT" ]; then
out_dir=/data/plugins
else
out_dir=/data/mods
@@ -126,7 +128,7 @@ elif [[ "$MODS_FILE" ]]; then
args=(
-o "${out_dir}"
--log-progress-each
--skip-existing
--skip-up-to-date
--uris-file "${MODS_FILE}"
)
if isTrue "${REMOVE_OLD_MODS}"; then
@@ -186,15 +188,19 @@ esac
fi
: "${GENERIC_PACKS:=${GENERIC_PACK}}"
: "${GENERIC_PACKS_PREFIX:=}"
: "${GENERIC_PACKS_SUFFIX:=}"
if [[ "${GENERIC_PACKS}" ]]; then
IFS=',' read -ra packs <<< "${GENERIC_PACKS}"
packFiles=()
for pack in "${packs[@]}"; do
if isURL "$pack"; then
for packEntry in "${packs[@]}"; do
pack="${GENERIC_PACKS_PREFIX}${packEntry}${GENERIC_PACKS_SUFFIX}"
if isURL "${pack}"; then
mkdir -p /data/packs
if ! outfile=$(get -o /data/packs --output-filename --skip-existing "$pack"); then
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
@@ -204,14 +210,19 @@ if [[ "${GENERIC_PACKS}" ]]; then
fi
done
sum_file=/data/.generic_pack.sum
isDebugging && [ -f "$sum_file}" ] && cat "$sum_file"
if ! sha256sum -c "${sum_file}" --status 2> /dev/null; then
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}"
unzip -q -d ${base_dir} "${pack}"
extract "${pack}" "${base_dir}"
done
# recalculate the actual base directory of content
@@ -239,7 +250,8 @@ if [[ "${GENERIC_PACKS}" ]]; then
cp -R -f "${base_dir}"/* /data
rm -rf /tmp/generic_pack_base
sha256sum "${packFiles[@]}" > "${sum_file}"
log "Saving generic pack(s) checksum"
sha1sum "${packFiles[@]}" > "${sum_file}"
isDebugging && cat "$sum_file"
fi
fi

View File

@@ -1,14 +1,15 @@
#!/bin/bash
. ${SCRIPTS:-/}start-utils
# 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}
: "${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
@@ -24,8 +25,8 @@ else
fi
if [ -d /plugins ]; then
case ${TYPE} in
SPIGOT|BUKKIT|PAPER|MAGMA)
case ${FAMILY} in
SPIGOT|HYBRID)
mkdir -p /data/plugins
log "Copying plugins over..."
mc-image-helper \
@@ -40,7 +41,7 @@ if [ -d /plugins ]; then
fi
# If any modules have been provided, copy them over
: ${COPY_MODS_DEST:="/data/mods"}
: "${COPY_MODS_DEST:="/data/mods"}"
if [ -d /mods ]; then
log "Copying any mods over..."
@@ -53,7 +54,7 @@ if [ -d /mods ]; then
/mods "${COPY_MODS_DEST}"
fi
: ${COPY_CONFIG_DEST:="/data/config"}
: "${COPY_CONFIG_DEST:="/data/config"}"
if [ -d /config ]; then
log "Copying any configs from /config to ${COPY_CONFIG_DEST}"
@@ -66,4 +67,4 @@ if [ -d /config ]; then
/config "${COPY_CONFIG_DEST}"
fi
exec ${SCRIPTS:-/}start-setupServerProperties $@
exec "${SCRIPTS:-/}start-setupServerProperties" "$@"

98
scripts/start-setupRbac Normal file
View File

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

View File

@@ -48,7 +48,7 @@ function customizeServerProps {
# If not provided, generate a reasonable default message-of-the-day,
# which shows up in the server listing in the client
if [ -z "$MOTD" ]; then
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
@@ -62,6 +62,13 @@ function customizeServerProps {
MOTD="A ${label} Minecraft Server powered by Docker"
fi
# normalize MOTD
if [[ ${TYPE^^} = LIMBO ]]; then
if [[ $MOTD ]] && ! [[ $MOTD =~ ^{ ]]; then
MOTD="{\"text\":\"${MOTD}\"}"
fi
fi
setServerProp "server-name" SERVER_NAME
setServerProp "server-ip" SERVER_IP
setServerProp "server-port" SERVER_PORT

View File

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

View File

@@ -5,7 +5,7 @@
set -e
isDebugging && set -x
if [ $TYPE = "CURSEFORGE" ]; then
if [ "$TYPE" = "CURSEFORGE" ]; then
worldDest=$FTB_DIR/${LEVEL:-world}
else
worldDest=/data/${LEVEL:-world}
@@ -19,49 +19,102 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] );
"${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"
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 [[ "$zipSrc" ]]; then
log "Unzipping world"
if [ -f "$WORLD" ]; then
log "Extracting 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 ! extract "$WORLD" /tmp/world-data; then
exit 1
fi
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 "{}" \;)
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
baseDir="$(echo "$baseDirs" | sed -n ${WORLD_INDEX:-1}p)"
baseName=$(basename "$baseDir")
log "WARN multiple levels found, picking: $baseName"
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
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"
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
else
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 [ "$TYPE" = "SPIGOT" ]; then
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"
@@ -69,4 +122,4 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] );
fi
fi
exec "${SCRIPTS:-/}start-setupModpack" "$@"
exec "${SCRIPTS:-/}start-setupVanillaTweaks" "$@"

View File

@@ -22,6 +22,20 @@ 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?}
@@ -81,9 +95,12 @@ downloadResourceFromSpiget() {
log "Extracting contents of resource ${resource} into plugins"
unzip -o -q -d /data/plugins "${tmpfile}"
rm "${tmpfile}"
else
elif containsPlugin "${tmpfile}"; then
log "Moving resource ${resource} into plugins"
mv "${tmpfile}" "/data/plugins/${resource}.jar"
else
log "ERROR downloaded resource '${resource}' seems to be not a valid plugin"
exit 2
fi
}

View File

@@ -40,6 +40,10 @@ function getFilenameFromUrl() {
}
function isTrue() {
local oldState
oldState=$(shopt -po xtrace)
shopt -u -o xtrace
local value=${1,,}
result=
@@ -53,6 +57,7 @@ function isTrue() {
;;
esac
eval "$oldState"
return ${result}
}
@@ -82,7 +87,18 @@ function logn() {
}
function log() {
echo "[init] $*"
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-2822)"
else
ts=
fi
echo "[init]${ts} $*"
eval "$oldState"
}
function logAutopause() {
@@ -93,6 +109,14 @@ 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
@@ -170,5 +194,62 @@ function isFamily() {
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 checkSum() {
local sum_file=${1?}
# Get distro
distro=$(cat /etc/os-release | grep -E "^ID=" | cut -d= -f2 | sed -e 's/"//g')
if [ "${distro}" == "debian" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
return 0
elif [ "${distro}" == "ubuntu" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
return 0
elif [ "${distro}" == "alpine" ] && sha1sum -c "${sum_file}" -s 2> /dev/null; then
return 0
else
return 1
fi
}

1
tests/.gitignore vendored Normal file
View File

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

43
tests/fulltests/test.sh Normal file
View File

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

View File

@@ -1,4 +1,4 @@
version: "3.8"
version: "3"
services:
monitor:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,18 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
MODS_FORGEAPI_FILE: /config/forgeapi_mods.json
# Key is defined in .github/workflows/pr.yml and ci.yml
# This should be coming from github secrets.
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
REMOVE_OLD_FORGEAPI_MODS: "TRUE"
MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "FALSE"
volumes:
- ./forgeapi_mods.json:/config/forgeapi_mods.json:ro

View File

@@ -0,0 +1,17 @@
[{
"name": "fabric api",
"projectId": "306612",
"releaseType": "release"
},
{
"name": "Fabric Voice Mod",
"projectId": "416089",
"releaseType": "beta"
},
{
"name": "Biomes o plenty",
"projectId": "220318",
"fileName": "BiomesOPlenty-1.18.1-15.0.0.100-universal.jar",
"releaseType": "release"
}
]

View File

@@ -0,0 +1 @@
[[ $MODS_FORGEAPI_KEY ]] || exit 1

View File

@@ -0,0 +1,16 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "TRUE"
MODS_FORGEAPI_PROJECTIDS: 306612,416089,220318
# Allows for Beta releases of 416089 the Fabric Voice Mod
MODS_FORGEAPI_RELEASES: BETA
MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY}
REMOVE_OLD_FORGEAPI_MODS: "TRUE"

View File

@@ -0,0 +1 @@
[[ $MODS_FORGEAPI_KEY ]] || exit 1

View File

@@ -0,0 +1,14 @@
version: "3"
services:
mc:
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
SETUP_ONLY: "TRUE"
GENERIC_PACKS: testing
GENERIC_PACKS_PREFIX: /packs/
GENERIC_PACKS_SUFFIX: .zip
volumes:
- ./packs:/packs
- ./data:/data

View File

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

View File

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

Binary file not shown.

View File

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

Binary file not shown.

View File

@@ -0,0 +1,13 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
OPS: itzg
volumes:
- ./data:/data

View File

@@ -0,0 +1,3 @@
mc-image-helper assert jsonPathEquals --file=ops.json --path='$[0].name' --expect=itzg
mc-image-helper assert jsonPathEquals --file=ops.json --path='$[0].uuid' --expect=5cddfd26-fc86-4981-b52e-c42bb10bfdef
mc-image-helper assert jsonPathEquals --file=ops.json --path='$[0].level' --expect=4

View File

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

View File

@@ -0,0 +1,4 @@
mc-image-helper assert fileExists world/level.dat && \
mc-image-helper assert fileExists world/some_overworld_file && \
mc-image-helper assert fileExists world_nether/DIM-1/some_nether_file && \
mc-image-helper assert fileExists world_the_end/DIM1/some_end_file

View File

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

View File

@@ -0,0 +1,4 @@
mc-image-helper assert fileExists world/level.dat && \
mc-image-helper assert fileExists world/some_overworld_file && \
mc-image-helper assert fileExists world/DIM-1/some_nether_file && \
mc-image-helper assert fileExists world/DIM1/some_end_file

View File

@@ -0,0 +1,61 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
# go to script root directory
cd "$(dirname "$0")" || exit 1
# tests that only run the setup files for things like downloads and configuration.
setupOnlyMinecraftTest(){
folder=$1
cd "$folder"
result=0
if [ -f require.sh ]; then
# require.sh scripts can check for environment variables, etc that are required for the test.
# The script should exit with a non-zero status to indicate the test requirements are missing
# and the test should be skipped
if ! bash require.sh; then
echo "${folder} SKIP"
cd ..
return 0
fi
fi
if ! logs=$(docker-compose run mc 2>&1); then
echo "${folder} test scenario FAILED"
echo ":::::::::::: LOGS ::::::::::::::::
$logs
::::::::::::::::::::::::::::::::::
"
result=1
elif [ -f verify.sh ]; then
if ! docker run --rm --entrypoint bash -v "${PWD}/data":/data -v "${PWD}/verify.sh":/verify "${IMAGE_TO_TEST:-itzg/minecraft-server}" -e /verify; then
echo "${folder} verify FAILED"
result=1
else
echo "${folder} verify PASS"
fi
else
echo "${folder} PASS"
fi
docker-compose down -v --remove-orphans
cd ..
return $result
}
# go through each folder in setuponly and test setups
if (( $# > 0 )); then
for folder in "$@"; do
echo "Starting Tests in ${folder}"
setupOnlyMinecraftTest "$folder"
done
else
readarray -t folders < <(find . -maxdepth 2 -mindepth 2 -name docker-compose.yml -printf '%h\n')
for folder in "${folders[@]}"; do
echo "Starting Tests in ${folder}"
setupOnlyMinecraftTest "$folder"
done
fi

View File

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

View File

@@ -0,0 +1,3 @@
mc-image-helper assert fileExists world/level.dat && \
mc-image-helper assert fileExists world_nether/DIM-1/some_nether_file && \
mc-image-helper assert fileExists world_the_end/DIM1/some_end_file

View File

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

View File

@@ -0,0 +1,3 @@
mc-image-helper assert fileExists world/level.dat && \
mc-image-helper assert fileExists world/DIM-1/some_nether_file && \
mc-image-helper assert fileExists world/DIM1/some_end_file

View File

@@ -0,0 +1,17 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
VANILLATWEAKS_FILE: /config/vt-datapacks.json,/config/vt-craftingtweaks.json,/config/vt-resourcepacks.json
REMOVE_OLD_VANILLATWEAKS: "FALSE"
volumes:
- ./data:/data
- ./vt-datapacks.json:/config/vt-datapacks.json:ro
- ./vt-craftingtweaks.json:/config/vt-craftingtweaks.json:ro
- ./vt-resourcepacks.json:/config/vt-resourcepacks.json:ro

View File

@@ -0,0 +1,4 @@
mc-image-helper assert fileExists "/data/world/datapacks/afk*"
mc-image-helper assert fileExists "/data/world/datapacks/graves*"
mc-image-helper assert fileExists "/data/world/datapacks/craftingtweaks*"
mc-image-helper assert fileExists "/data/resourcepacks/resourcepacks*"

View File

@@ -0,0 +1,12 @@
{
"type": "craftingtweaks",
"version": "1.18",
"packs": {
"quality of life": [
"dropper to dispenser",
"double slabs",
"back to blocks"
]
},
"result": "ok"
}

View File

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

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