-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This should be a working copy of the program. The whole reason I was making this repo was because I wanted to add the planned feature I mention in the README, but now it's taken me two hours to prepare the code for public use and I don't feel like it any more ¯\_(ツ)_/¯ Signed-off-by: Rhotias <[email protected]>
- Loading branch information
Showing
5 changed files
with
315 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*.sublime-workspace |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,41 @@ | ||
# mcserver | ||
A collection of Bash and Python scripts to simplify the management of multiple Minecraft servers | ||
A collection of Bash and Python scripts to simplify the management of multiple Minecraft servers from a single unified location | ||
|
||
Current features: | ||
* All servers (logs, world, and associated configuration files) are stored in separate directories, by default located in *~/.minecraft-server* | ||
* All backups are stored in separate dated directories, by default located in *~/.minecraft-server/backups* | ||
* * "backups" are just full copies of an entire server. The dated directory may contain backups of multiple servers for that day | ||
* The server message of the day (MotD) may be viewed and changed prior to launch | ||
* Prompts for backing up the server are presented when the server is stopped | ||
|
||
Planned features: | ||
* Ability to create a new server from a blank template, and populate the world with data from a chosen directory | ||
|
||
## Requirements | ||
The script requires the following packages and libraries: | ||
* python | ||
* * sys, getopt, pyjavaproperties | ||
|
||
You may need to install pyjavaproperties: | ||
|
||
$ pip install pyjavaproperties | ||
|
||
## Installation | ||
Clone the repository with | ||
|
||
$ git clone https://github.com/Rhotias/mcserver.git | ||
|
||
Copy the *mcserver* and *mcserver-motd* files to your directory of choice. *~/.local/bin/* is a good one, if that's on your $PATH. Make the primary script executable with | ||
|
||
$ chmod +x mcserver | ||
|
||
Edit the *mcserver* file if necessary to ensure it points at an existing servers directory containing more directories where each consists of the components for one server | ||
|
||
Each directory must contain a *run.sh* script that will cause that server to start. An example of a valid *run.sh* script is the following: | ||
|
||
java -Xms2G -Xmx4G -jar ../minecraft_server.1.8.8.jar nogui | ||
|
||
Note that the implication here is that the main servers directory contains server JAR files, which is recommended to keep them out of the backups. If you wish to keep the server JAR in the same directory as the server itself, do so and remove the *../* from the example above | ||
|
||
## Execution | ||
The primary program accepts no flags or arguments |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
#!/bin/sh | ||
|
||
# Author: Rhotias B | ||
# Create: 2015-07-10 | ||
|
||
# v0.1: 2015-07-10 | ||
# v1.0: 2015-07-14 | ||
|
||
serversDir=~/.minecraft-server | ||
backupsDir=$serversDir/backups | ||
itsNotTomorrowUntilIWakeUp=true # True - Up until 06:00, the date will be considered the previous day | ||
reminder="Pause your torrents!" # An optional short reminder printed immediately after execution; set to "" to ignore | ||
|
||
_requestServer() # _resultVar | ||
{ | ||
local _requestServer_resultVar=$1 | ||
local serversArr=() | ||
|
||
# Get array of directories in the serverDir, that aren't $backupsDir | ||
for file in $serversDir/*; do | ||
if [[ -d "$file" && "$(basename $file)" != "$(basename $backupsDir)" ]]; then | ||
serversArr+=("$(basename $file)") | ||
fi | ||
done | ||
|
||
# Request user input and set _resultVar to the chosen server | ||
printf "%s\n" "Select a server by ID" | ||
for index in ${!serversArr[*]}; do # Gets an array of the array indices | ||
printf "%s\n" " ($index) ${serversArr[$index]}" | ||
done | ||
while true; do | ||
read -p "[0]: " usrOpt | ||
if [[ $usrOpt -ge 0 && $usrOpt -lt ${#serversArr[*]} ]]; then # Checks against total number of entries in array | ||
# Set the variable which was passed to this function to the chosen server | ||
eval $_requestServer_resultVar="${serversArr[$usrOpt]}" | ||
break | ||
else | ||
printf "%s\n" " Error: Invalid selection" | ||
fi | ||
done | ||
} | ||
|
||
_launch() | ||
{ | ||
# Put the server choice into a variable | ||
local serverBasename | ||
_requestServer serverBasename | ||
|
||
# Offer the user to change the server MotD | ||
_changeMotd serverBasename | ||
|
||
printf "\n" | ||
|
||
printf "Debug: pretending to start server in $serverBasename \n" | ||
# cd "$serversDir/$serverBasename"; sh run.sh | ||
|
||
printf "\n%s\n" "(Returning to mcserver)" | ||
|
||
printf "%s\n" "Back up this server now?" | ||
while true; do | ||
read -p "[y]: " usrOpt | ||
case $usrOpt in | ||
y|Y|"") | ||
_backUp "$serverBasename"; break | ||
;; | ||
n|N) | ||
break | ||
;; | ||
*) | ||
printf "%s\n" " Error: Invalid selection" | ||
;; | ||
esac | ||
done | ||
} | ||
|
||
_backUp() # serverBasename | ||
{ | ||
local serverBasename=$1 | ||
|
||
if [[ $serverBasename == "" ]]; then | ||
_requestServer serverBasename | ||
fi | ||
serverDir="$serversDir/$serverBasename" | ||
|
||
# Get current date in the local timezone | ||
local date="$(date "+%Y-%m-%d")" | ||
|
||
# Personal preference: I consider it to be the previous day if it's still not sunrise (06:00) | ||
if [[ $itsNotTomorrowUntilIWakeUp == true && $(date "+%H") -lt 6 ]]; then | ||
# Get current date in the UTC timezone, which is ~10 hours behind me here in Australia | ||
local date="$(date -u "+%Y-%m-%d")" | ||
fi | ||
|
||
local bkDir="$backupsDir/$date" | ||
|
||
# Create or use backup directory, or abort on error | ||
printf "%s" "Making backup directory for $date... " | ||
mkdir "$bkDir" >/dev/null 2>&1 | ||
if [[ $? == 0 ]]; then | ||
printf "%s\n" "Done!" | ||
elif [[ $? == 1 ]]; then | ||
printf "%s\n" "Found existing directory; using it" | ||
else | ||
printf "%s\n" "Failed with error code $?. Aborting backup" | ||
exit 1 | ||
fi | ||
|
||
# Check for existing backups and either delete them or prepare to skip the copying step | ||
local doCopy=true | ||
if [[ -e "$bkDir/$serverBasename" ]]; then | ||
printf "%s\n" "A backup of $serverBasename for $date already exists. Delete and replace it?" | ||
while true; do | ||
read -p "[y]: " usrOpt | ||
case $usrOpt in | ||
y|Y|"") | ||
rm -rf "$bkDir/$serverBasename" >/dev/null 2>&1 | ||
break | ||
;; | ||
n|N) | ||
doCopy=false | ||
break | ||
;; | ||
*) | ||
printf "%s\n" " Error: Invalid selection" | ||
;; | ||
esac | ||
done | ||
fi | ||
|
||
# Copy the server data, or abort on error | ||
if [[ $doCopy == true ]]; then | ||
printf "%s" "Copying server files for $serverBasename... " | ||
cp -r "$serverDir" "$bkDir" >/dev/null 2>&1 | ||
if [[ $? == 0 ]]; then | ||
printf "%s\n" "Done!" | ||
else | ||
printf "%s\n" "Failed with error code $?. Aborting backup" | ||
exit 1 | ||
fi | ||
fi | ||
|
||
# If necessary, recursively call the function to back up another server | ||
printf "%s\n" "Back up another server for this same date?" | ||
while true; do | ||
read -p "[n]: " usrOpt | ||
case $usrOpt in | ||
n|N|"") | ||
break | ||
;; | ||
y|Y) | ||
local newServerBasename=$serverBasename | ||
while [[ $newServerBasename == $serverBasename ]]; do | ||
printf "%s\n" "Choose a server that isn't this one" | ||
_requestServer newServerBasename | ||
done | ||
_backUp "$newServerBasename" | ||
break | ||
;; | ||
*) | ||
printf "%s\n" " Error: Invalid selection" | ||
;; | ||
esac | ||
done | ||
} | ||
|
||
_changeMotd() # serverBasename | ||
{ | ||
local infile="$serversDir/$serverBasename/server.properties" | ||
|
||
if [[ -e $infile ]]; then | ||
local motd="$(python mcserver-motd $infile -g)" | ||
|
||
printf "%s\n" "Set message of the day" | ||
while true; do | ||
read -p "[$motd]: " usrOpt | ||
case "$usrOpt" in | ||
"") | ||
break | ||
;; | ||
*) | ||
python mcserver-motd $infile -s "$usrOpt" | ||
break | ||
;; | ||
esac | ||
done | ||
else # infile does not exist | ||
printf "%s\n" "mcserver error: $infile does not exist. It may not have been created yet" | ||
fi | ||
} | ||
|
||
# program | ||
if [[ $reminder != "" ]]; then | ||
printf "%s\n" "(Reminder: $reminder)" | ||
fi | ||
printf "%s\n" "Select mode" | ||
printf "%s\n" " (0) Launch" | ||
printf "%s\n" " (1) Create backup" | ||
while true; do | ||
read -p "[0]: " usrOpt | ||
case $usrOpt in | ||
0|launch|l|"") | ||
_launch; break | ||
;; | ||
1|create|backup|c|b) | ||
_backUp; break | ||
;; | ||
*) | ||
printf "%s\n" " Error: Invalid selection" | ||
;; | ||
esac | ||
done | ||
# end program |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#!/usr/bin/env python | ||
|
||
# Author : Rhotias B | ||
# Create : 2015-10-01 | ||
|
||
# This is a support script for the mcserver Bash script. If you want to though, you can make it executable with "chmod +x mcserver-motd" and use it as described in the usage | ||
|
||
import sys, getopt | ||
from pyjavaproperties import Properties | ||
|
||
def showUsage(): | ||
print "Usage: mcserver-motd <infile.properties> -g" | ||
print " or: mcserver-motd <infile.properties> -s <\"new message\">" | ||
print "For the given file, get the current MotD or set a new one" | ||
|
||
def main(infile, argv): | ||
if len(argv) == 0: | ||
showUsage() | ||
sys.exit(2) | ||
|
||
try: | ||
opts, args = getopt.getopt(argv, "hgs:") | ||
except getopt.GetoptError: | ||
showUsage() | ||
sys.exit(2) | ||
|
||
try: | ||
p = Properties() | ||
p.load(open(infile)) | ||
except IOError as detail: | ||
sys.exit( "{} {}".format("mcserver-motd error:", detail) ) | ||
|
||
for opt, arg in opts: | ||
if opt == "-g": | ||
print p["motd"] | ||
elif opt == "-s": | ||
p["motd"] = arg | ||
elif opt == "-h": | ||
showUsage() | ||
|
||
p.store(open(infile,"w")) | ||
# end def | ||
|
||
# program | ||
try: | ||
infile = sys.argv[1] | ||
except IndexError: | ||
showUsage() | ||
sys.exit(2) | ||
|
||
if __name__ == "__main__": | ||
main(infile, sys.argv[2:]) | ||
# end program |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"folders": | ||
[ | ||
{ | ||
"path": ".", | ||
"file_exclude_patterns": ["*.sublime-*"] | ||
} | ||
] | ||
} |