├── .github └── workflows │ └── shellcheck-action.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── Makefile ├── README.md ├── iptables.rules ├── mscs ├── mscs-logo.png ├── mscs.completion ├── mscs.service ├── mscs@.service ├── msctl ├── runtests.sh ├── tests └── mscs-jvm-args.sh └── update.d └── 10-old-defaults /.github/workflows/shellcheck-action.yml: -------------------------------------------------------------------------------- 1 | # GitHub Actions (https://docs.github.com/en/actions/learn-github-actions) workflow 2 | # GitHub Actions enables automated builds, tests, and more through GitHub hosted infrastructure. 3 | 4 | # Name of the workflow 5 | name: shellcheck 6 | 7 | # Controls when the workflow will run 8 | on: 9 | # Triggers the workflow on push or pull request events but only for the main branch 10 | push: 11 | branches: [ main ] 12 | pull_request: 13 | branches: [ main ] 14 | 15 | # Allows you to run this workflow manually from the Actions tab 16 | workflow_dispatch: 17 | 18 | # A workflow is made up of one or more jobs that can run sequentially or in parallel 19 | jobs: 20 | # This workflow contains a single job called "run-shellcheck" 21 | run-shellcheck: 22 | # The type of operating system (called a "runner") that the that the job will run on 23 | # GitHub provides these for free! 24 | runs-on: ubuntu-latest 25 | # Steps represent a sequence of tasks that will be executed as part of the job 26 | steps: 27 | # Checks-out the MSCS repository under $GITHUB_WORKSPACE, so jobs can access the code 28 | # This is a GitHub-created action 29 | - uses: actions/checkout@v2 30 | # Runs the ShellCheck action (https://github.com/marketplace/actions/shellcheck) 31 | # This is a community-created action 32 | - name: Run ShellCheck 33 | uses: ludeeus/action-shellcheck@master 34 | with: 35 | severity: error 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .tags* 3 | .TAGS* 4 | tags 5 | TAGS 6 | .ctags 7 | ctags.cnf 8 | *.swo 9 | *.swp 10 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at sandain@hotmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2021 Jason M. Wood 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | MSCS_USER := minecraft 2 | MSCS_HOME := /opt/mscs 3 | 4 | MSCTL := /usr/local/bin/msctl 5 | MSCS := /usr/local/bin/mscs 6 | MSCS_INIT_D := /etc/init.d/mscs 7 | MSCS_SERVICE := /etc/systemd/system/mscs.service 8 | MSCS_SERVICE_TEMPLATE := /etc/systemd/system/mscs@.service 9 | MSCS_COMPLETION := /etc/bash_completion.d/mscs 10 | 11 | UPDATE_D := $(wildcard update.d/*) 12 | 13 | .PHONY: install adduser update clean 14 | 15 | install: adduser update 16 | if which systemctl; then \ 17 | systemctl -f enable mscs.service; \ 18 | else \ 19 | ln -s $(MSCS) $(MSCS_INIT_D); \ 20 | update-rc.d mscs defaults; \ 21 | fi 22 | 23 | adduser: 24 | # safety check to see if user exists before trying to create it 25 | if id $(MSCS_USER); then \ 26 | echo "Minecraft user $(MSCS_USER) exists so not creating it"; \ 27 | else \ 28 | useradd --system --user-group --create-home -K UMASK=0022 --home $(MSCS_HOME) $(MSCS_USER); \ 29 | fi 30 | 31 | update: 32 | install -m 0755 msctl $(MSCTL) 33 | install -m 0755 mscs $(MSCS) 34 | install -m 0644 mscs.completion $(MSCS_COMPLETION) 35 | if which systemctl; then \ 36 | install -m 0644 mscs.service $(MSCS_SERVICE); \ 37 | install -m 0644 mscs@.service $(MSCS_SERVICE_TEMPLATE); \ 38 | fi 39 | @for script in $(UPDATE_D); do \ 40 | sh $$script; \ 41 | done; true; 42 | 43 | clean: 44 | if which systemctl; then \ 45 | systemctl -f disable mscs.service; \ 46 | rm -f $(MSCS_SERVICE) $(MSCS_SERVICE_TEMPLATE); \ 47 | else \ 48 | update-rc.d mscs remove; \ 49 | rm -f $(MSCS_INIT_D); \ 50 | fi 51 | rm -f $(MSCTL) $(MSCS) $(MSCS_COMPLETION) 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | # Features 6 | **M**inecraft **S**erver **C**ontrol **S**cript (**MSCS**) 7 | is a server-management script for UNIX and Linux powered Minecraft servers. 8 | 9 | Features include: 10 | 11 | * Run multiple Minecraft worlds. 12 | * Start, stop, and restart single or multiple worlds. 13 | * Create, delete, disable, and enable worlds. 14 | * Includes support for additional server types: [Forge](http://www.minecraftforge.net/), 15 | [BungeeCord](http://www.spigotmc.org/wiki/bungeecord/), 16 | [SpigotMC](http://www.spigotmc.org/wiki/spigot/), etc. 17 | * Users automatically notified of important server events. 18 | * LSB and systemd compatible init script, 19 | allows for seamless integration with your server's startup and shutdown 20 | sequences. 21 | * Map worlds using the [Minecraft Overviewer](http://overviewer.org/) 22 | mapping software. 23 | * Automatically backup worlds, remove backups older than X days, 24 | and restart worlds. 25 | * Update the server and client software automatically. 26 | * Send commands to a world server from the command line. 27 | 28 | # Documentation 29 | 30 | Documentation has moved to [https://minecraftservercontrol.github.io/docs/mscs](https://minecraftservercontrol.github.io/docs/mscs). 31 | 32 | # Issues 33 | 34 | Please see [https://minecraftservercontrol.github.io/docs/mscs/troubleshooting-issues](https://minecraftservercontrol.github.io/docs/mscs/troubleshooting-issues). 35 | 36 | # Code of Conduct 37 | 38 | See [Code of Conduct](CODE_OF_CONDUCT.md) 39 | 40 | # License 41 | 42 | See [License](LICENSE) 43 | 44 | # Disclaimer 45 | 46 | Minecraft is a trademark of Mojang Synergies AB, a subsidiary of Microsoft 47 | Studios. MSCS and MSC-GUI are designed to ease the use of the Mojang produced 48 | Minecraft server software on Linux and UNIX servers. MSCS and MSC-GUI are 49 | independently developed by open software enthusiasts with no support or 50 | implied warranty provided by either Mojang or Microsoft. 51 | -------------------------------------------------------------------------------- /iptables.rules: -------------------------------------------------------------------------------- 1 | *filter 2 | :INPUT DROP [0:0] 3 | :FORWARD DROP [0:0] 4 | :OUTPUT DROP [0:0] 5 | 6 | # Handle loopback addresses 7 | -A INPUT -i lo -j ACCEPT 8 | -A OUTPUT -o lo -j ACCEPT 9 | 10 | # Allow outbound packets if state related, and inbound if established 11 | -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT 12 | -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 13 | 14 | # Drop stealth scans 15 | -A INPUT -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE 16 | -A INPUT -i eth0 -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN 17 | -A INPUT -i eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN,RST 18 | -A INPUT -i eth0 -p tcp -m tcp --tcp-flags FIN,RST FIN,RST 19 | -A INPUT -i eth0 -p tcp -m tcp --tcp-flags ACK,FIN FIN 20 | -A INPUT -i eth0 -p tcp -m tcp --tcp-flags ACK,URG URG 21 | 22 | # Allow ICMP pings 23 | -A OUTPUT -p icmp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT 24 | -A INPUT -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT 25 | 26 | # Allow port 22 for SSH 27 | -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT 28 | 29 | # Allow port 80 for HTTP 30 | -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT 31 | 32 | # Allow port 443 for HTTPS 33 | -A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT 34 | 35 | # Allow ports 25565 - 25575 for Minecraft world servers 36 | -A INPUT -m state --state NEW -m tcp -p tcp --dport 25565:25575 -j ACCEPT 37 | 38 | COMMIT 39 | -------------------------------------------------------------------------------- /mscs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: mscs 4 | # Required-Start: $remote_fs $syslog 5 | # Required-Stop: $remote_fs $syslog 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # chkconfig: 345 50 50 9 | # Description: Minecraft Server Control Script 10 | ### END INIT INFO 11 | 12 | # This is a wrapper to msctl that imitates traditional mscs behaviour: 13 | # uses the same default user, config file and location. 14 | 15 | # Get executable name 16 | PROG=$(basename $0) 17 | 18 | # Setup the default user name. 19 | USER_NAME="minecraft" 20 | 21 | # Setup the default installation location. 22 | LOCATION="/opt/mscs" 23 | 24 | # Setup the default location of the mscs.defaults file. 25 | MSCS_DEFAULTS="$LOCATION/mscs.defaults" 26 | 27 | # Setup the arguments to the msctl script. 28 | MSCS_ARGS="-p $PROG -l $LOCATION -c $MSCS_DEFAULTS $@" 29 | 30 | # Run the msctl script. 31 | if [ "$USER_NAME" = "$(whoami)" ]; then 32 | msctl $MSCS_ARGS 33 | else 34 | sudo "PATH=$PATH" -u $USER_NAME -H msctl $MSCS_ARGS 35 | fi 36 | -------------------------------------------------------------------------------- /mscs-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MinecraftServerControl/mscs/19e89eb49a83cbe54bdd19b8bcded73c80a1f9ab/mscs-logo.png -------------------------------------------------------------------------------- /mscs.completion: -------------------------------------------------------------------------------- 1 | list_worlds() { 2 | $MSCS ls $1 | sed -n '/:/{s/^ *//;s/:.*$//;p}' 3 | } 4 | 5 | _mscs() { 6 | local OPTS WORLDS 7 | MSCS="$1" 8 | COMPREPLY=() 9 | 10 | COMP_WORDBREAKS=${COMP_WORDBREAKS//:} 11 | 12 | OPTS=" 13 | backup console create delete disable enable force-restart force-stop list 14 | list-backups logrotate map new overviewer remove restart restore-backup 15 | broadcast send show start status stop sync update force-update watch usage 16 | " 17 | 18 | LIST_OPTS="enabled disabled running stopped" 19 | 20 | if [ $COMP_CWORD -eq 1 ]; then 21 | COMPREPLY=($(compgen -W "$OPTS" -- ${COMP_WORDS[COMP_CWORD]})) 22 | elif [ $COMP_CWORD -eq 2 ]; then 23 | case ${COMP_WORDS[COMP_CWORD-1]} in 24 | start) 25 | WORLDS=$(list_worlds stopped) 26 | COMPREPLY=($(compgen -W "$WORLDS" -- ${COMP_WORDS[COMP_CWORD]})) 27 | ;; 28 | stop|force-stop|restart|force-restart|send|console) 29 | WORLDS=$(list_worlds running) 30 | COMPREPLY=($(compgen -W "$WORLDS" -- ${COMP_WORDS[COMP_CWORD]})) 31 | ;; 32 | disable|sync|send|watch|logrotate|backup|map|overviewer|\ 33 | list-backups|restore-backup|update|force-update) 34 | WORLDS=$(list_worlds enabled) 35 | COMPREPLY=($(compgen -W "$WORLDS" -- ${COMP_WORDS[COMP_CWORD]})) 36 | ;; 37 | status|show|remove|delete) 38 | WORLDS=$(list_worlds) 39 | COMPREPLY=($(compgen -W "$WORLDS" -- ${COMP_WORDS[COMP_CWORD]})) 40 | ;; 41 | enable) 42 | WORLDS=$(list_worlds disabled) 43 | COMPREPLY=($(compgen -W "$WORLDS" -- ${COMP_WORDS[COMP_CWORD]})) 44 | ;; 45 | ls|list) 46 | COMPREPLY=($(compgen -W "$LIST_OPTS" -- ${COMP_WORDS[COMP_CWORD]})) 47 | ;; 48 | *) 49 | ;; 50 | esac 51 | elif [ $COMP_CWORD -eq 3 ]; then 52 | case ${COMP_WORDS[COMP_CWORD-2]} in 53 | restore-backup) 54 | BACKUPS=$($MSCS list-backups "${COMP_WORDS[COMP_CWORD-1]}") 55 | COMPREPLY=($(compgen -W "$BACKUPS" -- "${COMP_WORDS[COMP_CWORD]}")) 56 | ;; 57 | *) 58 | ;; 59 | esac 60 | fi 61 | return 0 62 | } 63 | complete -F _mscs msctl mscs 64 | -------------------------------------------------------------------------------- /mscs.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Minecraft Server Control Script 3 | Documentation=https://github.com/MinecraftServerControl/mscs 4 | Requires=network.target 5 | After=network.target 6 | 7 | [Service] 8 | User=minecraft 9 | Group=minecraft 10 | Environment="PATH=/usr/local/bin:/usr/bin:/bin" 11 | ExecStart=/usr/local/bin/mscs start 12 | ExecStop=/usr/local/bin/mscs stop 13 | ExecReload=/usr/local/bin/mscs restart 14 | Type=oneshot 15 | RemainAfterExit=yes 16 | 17 | [Install] 18 | WantedBy=multi-user.target 19 | -------------------------------------------------------------------------------- /mscs@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Minecraft Server Control Script for server %i 3 | Documentation=https://github.com/MinecraftServerControl/mscs 4 | Requires=network.target 5 | After=network.target 6 | 7 | [Service] 8 | User=minecraft 9 | Group=minecraft 10 | Environment="PATH=/usr/local/bin:/usr/bin:/bin" 11 | ExecStart=/usr/local/bin/mscs start %i 12 | ExecStop=/usr/local/bin/mscs stop %i 13 | ExecReload=/usr/local/bin/mscs restart %i 14 | Type=oneshot 15 | RemainAfterExit=yes 16 | 17 | [Install] 18 | WantedBy=multi-user.target 19 | -------------------------------------------------------------------------------- /msctl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # --------------------------------------------------------------------------- 4 | # Copyright (c) 2011-2021, Jason M. Wood 5 | # 6 | # All rights reserved. 7 | # 8 | # Redistribution and use in source and binary forms, with or without 9 | # modification, are permitted provided that the following conditions are met: 10 | # 11 | # 1. Redistributions of source code must retain the above copyright notice, 12 | # this list of conditions and the following disclaimer. 13 | # 2. Redistributions in binary form must reproduce the above copyright 14 | # notice, this list of conditions and the following disclaimer in the 15 | # documentation and/or other materials provided with the distribution. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | # --------------------------------------------------------------------------- 29 | 30 | # --------------------------------------------------------------------------- 31 | # Minecraft Server Control Script 32 | # 33 | # A powerful command-line control script for Linux-powered Minecraft servers. 34 | # --------------------------------------------------------------------------- 35 | 36 | # Get executable name 37 | # --------------------------------------------------------------------------- 38 | PROG=$(basename $0) 39 | 40 | # Required Software 41 | # --------------------------------------------------------------------------- 42 | # Detect its presence and location for later. 43 | JAVA=$(which java) 44 | PERL=$(which perl) 45 | PYTHON=$(which python3) 46 | WGET=$(which wget) 47 | RDIFF_BACKUP=$(which rdiff-backup) 48 | RSYNC=$(which rsync) 49 | SOCAT=$(which socat) 50 | FLOCK=$(which flock) 51 | 52 | # Script Usage 53 | # --------------------------------------------------------------------------- 54 | usage() { 55 | cat <] 57 | 58 | Actions: 59 | 60 | start <...> 61 | Start the Minecraft world server(s). Start all world servers by default. 62 | 63 | stop <...> 64 | Stop the Minecraft world server(s). Stop all world servers by default. 65 | 66 | force-stop <...> 67 | Forcibly stop the Minecraft world server(s). Forcibly stop all world 68 | servers by default. 69 | 70 | restart <...> 71 | Restart the Minecraft world server(s). Restart all world servers by default. 72 | 73 | force-restart <...> 74 | Forcibly restart the Minecraft world server(s). Forcibly restart all world 75 | servers by default. 76 | 77 | create [] 78 | Create a Minecraft world server. The world name and port must be 79 | provided, the IP address is usually blank. Without arguments, create a 80 | a default world at the default port. 81 | 82 | import [] 83 | Import an existing world server. The world name and port must be 84 | provided, the IP address is usually blank. 85 | 86 | rename 87 | Rename an existing world server. 88 | 89 | delete 90 | Delete a Minecraft world server. 91 | 92 | disable <...> 93 | Temporarily disables world server(s). Disables all world servers by default. 94 | 95 | enable <...> 96 | Enable disabled world server(s). Enables all world servers by default. 97 | 98 | ls