Last active
June 20, 2025 00:34
-
-
Save crischutu07/9c4e9ae237e62472e215edd6dd9afe0b to your computer and use it in GitHub Desktop.
Minecraft server installer for Linux (requires fzf and jq and probably curl and tac)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
servers=(PurpurMC PaperMC Velocity Waterfall "PocketMine-MP") | |
DEFAULT_SERVER="${servers[0]}" | |
# Dependency programs | |
DEPS=(curl fzf tac jq) | |
for i in "${DEPS[@]}"; do | |
if ! command -v "$i" > /dev/null 2>&1; then | |
echo "Command '$i' is not found." | |
exit 1 | |
fi | |
done | |
echo -e "Select the server you wanted to install" | |
for ((i=0; i<${#servers[@]}; i++)); do | |
if [ "${DEFAULT_SERVER}" = "${servers[i]}" ]; then | |
echo "$((i+1)). ${servers[i]} (Default)" | |
else | |
echo "$((i+1)). ${servers[i]}" | |
fi | |
done | |
read -rp '> ' selectserver | |
# make case-insensitive. | |
case "${selectserver,,}" in | |
1|purpur|purpurmc) selectedServer="${servers[0]}";; | |
2|paper|papermc) selectedServer="${servers[1]}";; | |
3|velocity) selectedServer="${servers[2]}";; | |
4|waterfall) selectedServer="${servers[3]}";; | |
5|pmmp|pocketmine-mp|pocketmine|pocketminemp) selectedServer="${servers[4]}";; | |
'') selectedServer="${DEFAULT_SERVER}";; | |
*) echo "Invalid selection."; exit 1;; | |
esac | |
function getPaper() { | |
case "$1" in | |
velocity) | |
endpoint="https://api.papermc.io/v2/projects/velocity" | |
brand="Velocity" | |
id="velocity";; | |
waterfall) | |
endpoint="https://api.papermc.io/v2/projects/waterfall" | |
brand="Waterfall" | |
id="waterfall" | |
echo "WARNING: Waterfall is depecreated, consider using Velocity over Waterfall, proceed with caution!";; | |
*) endpoint="https://api.papermc.io/v2/projects/paper"; brand="PaperMC"; id="paper";; | |
esac | |
stty -echo | |
echo "[$brand] Fetching available versions..." | |
tmpversion=$(curl -s "$endpoint" | jq -r '.versions[]') | |
stty -echo | |
version=$(fzf --tac --prompt="[$brand] Version: " --exact <<< "$tmpversion") | |
unset tmpvesion | |
stty -echo | |
if [ -z "$version" ]; then | |
echo " ╰─ Please select the version" | |
stty echo | |
exit 1 | |
fi | |
echo " ╰─ Version: $version" | |
echo "[$brand] Fetching available builds..." | |
tmpbuild=$(curl -s "$endpoint/versions/${version}" | jq -r '.builds[]') | |
stty echo | |
build=$(fzf --tac --prompt="[$brand $version] Build: " --exact <<< "$tmpbuild") | |
unset tmpbuild | |
stty -echo | |
if [ -z "$build" ]; then | |
echo " ╰─ Please select the build for $version" | |
stty echo | |
exit 1 | |
fi | |
echo " ╰─ Build: $build" | |
stty -echo | |
result=$(curl -s "$endpoint/versions/${version}/builds/${build}") | |
channel="$(jq -r '.channel' <<< "${result}")" | |
date="$(jq -r '.time' <<< "${result}")" | |
if [ "$channel" = 'experimental' ]; then | |
echo "WARNING: This build may contains bug and not compatible with some plugins, proceed with caution!" | |
fi | |
echo "${brand} ${version} (build #${build})" | |
echo " ├─ Released in: $(date -d "${date}" '+%A %B %d, %Y (%r)')" | |
echo " ╰─ Channel: $channel" | |
stty echo | |
read -rp "> Proceed install this build? [Y/N] (default: Y): " yn | |
echo | |
case "${yn:0:1}" in | |
[Yy]) | |
echo "[$brand] Running: curl -o \"${id}-${version}-${build}.jar\" \"${endpoint}/versions/${version}/builds/${build}/downloads/${id}-${version}-${build}.jar\"" | |
curl -o "${id}-${version}-${build}.jar" "${endpoint}/versions/${version}/builds/${build}/downloads/${id}-${version}-${build}.jar" | |
;; | |
[Nn]) exit 2;; | |
'') | |
echo "[$brand] Running: curl -o \"${id}-${version}-${build}.jar\" \"${endpoint}/versions/${version}/builds/${build}/downloads/${id}-${version}-${build}.jar\"" | |
curl -o "${id}-${version}-${build}.jar" "${endpoint}/versions/${version}/builds/${build}/downloads/${id}-${version}-${build}.jar" | |
;; | |
*) exit 2;; | |
esac | |
} | |
getPurpur () { | |
brand="PurpurMC" | |
id="purpur" | |
endpoint="https://api.purpurmc.org/v2/${id}" | |
stty -echo | |
echo "[$brand] Fetching minecraft versions.." | |
tmpversion=$(curl -s "$endpoint" | jq -r '.versions[]') | |
stty echo | |
version=$(fzf --tac --prompt="[$brand] Version: " --exact <<< "$tmpversion") | |
unset tmpvesion | |
stty -echo | |
if [ -z "$version" ]; then | |
echo "Please select the version" | |
stty echo | |
exit 1 | |
fi | |
echo " ╰─ Version: $version" | |
echo "[$brand] Fetching available builds..." | |
tmpbuild=$(curl -s "$endpoint/${version}" | jq -r '.builds.all[]' | sort -n) | |
stty echo | |
build=$(fzf --tac --prompt="[$brand $version] Build: " --exact <<< "$tmpbuild") | |
unset tmpbuild | |
stty -echo | |
if [ -z "$build" ]; then | |
echo " ╰─ Please select the build for $version" | |
stty echo | |
exit 1 | |
fi | |
echo " ╰─ Build: $build" | |
stty -echo | |
result=$(curl -s "$endpoint/${version}/${build}") | |
channel=$(jq -r '.result' <<< "${result}") | |
# Unix timestamp (in milliseconds) | |
date=$(jq -r '.timestamp' <<< "${result}") | |
echo "$brand $version (Build #${build})" | |
echo " ╰─ Build date: $(date -d "@$(("${date}"/1000))" '+%A %B %d, %Y (%r)')" | |
echo " ╰─ Channel: ${channel}" | |
stty echo | |
read -rp "> Proceed install this build? [Y/N] (default: Y): " yn | |
echo | |
case "${yn:0:1}" in | |
[Nn]) exit 2;; | |
[Yy]) | |
echo "[$brand] Running: curl -o \"${id}-${version}-${build}.jar\" \"${endpoint}/${version}/${build}/download\"" | |
curl -o "${id}-${version}-${build}.jar" "${endpoint}/${version}/${build}/download" | |
;; | |
'') | |
echo "[$brand] Running: curl -o \"${id}-${version}-${build}.jar\" \"${endpoint}/${version}/${build}/download\"" | |
curl -o "${id}-${version}-${build}.jar" "${endpoint}/${version}/${build}/download" | |
;; | |
*) exit 2;; | |
esac | |
} | |
getPMMP (){ | |
url="https://get.pmmp.io" | |
brand="PocketMine-MP" | |
# id="pmmp" | |
echo "NOTICE: $brand is a server software for Bedrock Edition" | |
read -rp "Press [Enter] to proceed the action." yn | |
case "${yn:0:1}" in | |
'') echo;; | |
*) exit 2;; | |
esac | |
echo "[${brand}] Running ${url}" | |
curl -sL "${url}" | bash -s - | |
} | |
case "$selectedServer" in | |
"${servers[0]}") getPurpur;; | |
"${servers[1]}") getPaper;; | |
"${servers[2]}") getPaper velocity;; | |
"${servers[3]}") getPaper waterfall;; | |
"${servers[4]}") getPMMP;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment