Git Product home page Git Product logo

minecraft-server-hibernation's Introduction

Minecraft Server Hibernation

msh - loc msh - release msh - goreport msh - license msh - stars

Avoid wasting resources by starting your Minecraft server automatically when a player joins and stopping it when no one is online
(for vanilla/modded on linux/windows/macos)

version: v2.5.0
Copyright (C) 2019-2023 gekigek99

Join our discord server!


RELEASES:

Download the latest releases on github (for linux, windows and macos)

You can download msh from gekware or compile the dev branch to use a more recent version, but note that it may still need to be tested


PROGRAM COMPILATION:

This version was successfully compiled in go version 1.19
Compilation procedure:

git clone https://github.com/gekware/minecraft-server-hibernation.git  
cd minecraft-server-hibernation/  
git submodule update --init
git checkout dev # execute only if you want to compile the dev branch
go build .

INSTRUCTIONS:

  1. Install the Minecraft server you want
  2. Edit msh-config.json as needed (check definitions):
    • Folder
    • FileName
    • StartServerParam
    • StopServer
    • Whitelist
    • * TimeBeforeStoppingEmptyServer
    • * others...
  3. * put the frozen icon you want in path/to/server.jar/folder (must be called server-icon-frozen, supported formats: .png, .jpg)
  4. on the router (to which the server is connected): forward port 25555 to server (tutorial)
  5. on the server: open port 25555 (example: ufw firewall)
  6. run the msh executable
  7. You can connect to the server using the port from the configuration file (default 25555).

* = it's not compulsory to modify this parameter

notes

  • msh-config.json is not generated automatically. You will need to download it from the releases.
  • Automatically run msh at reboot.
  • In server.properties set server-ip=0.0.0.0 to avoid errors when msh tries to connect to the minecraft server.
  • You must remove all braces from msh-config.json.

DEFINITIONS:

  • Some of these parameters can be configured with command-line arguments (msh --help to know more) (user supplied arguments will override config)

Location of server folder and executable. You can find protocol/version here (but msh should set them automatically):

"Server": {
  "Folder": "{path/to/server/folder}"
  "FileName": "{server.jar}"
  "Version": "1.19.2"
  "Protocol": 760
}

Commands to start and stop minecraft server
StopServerAllowKill allows to kill the server after a certain amount of time (in seconds) when it's not responding

"Commands": {
  "StartServer": "java <Commands.StartServerParam> -jar <Server.FileName> nogui"
  "StartServerParam": "-Xmx1024M -Xms1024M"
  "StopServer": "stop"
  "StopServerAllowKill": 10	# set to -1 to disable
}

Set the logging level for debug purposes

"Debug": 1
# 0 - NONE: no log
# 1 - BASE: basic log
# 2 - SERV: minecraft server log
# 3 - DEVE: developement log
# 4 - BYTE: connection bytes log

Ports configuration

  • MshPort and MshPortQuery must be different from the respective ones in server.properties
  • query handling is enabled if EnableQuery: true in msh-config.json AND enable-query=true in server.properties
"MshPort": 25555		# port to which players can join
"MshPortQuery": 25555	# port to which stats query requests are performed from clients
"EnableQuery": true		# enable query handling

TimeBeforeStoppingEmptyServer sets the time (after the last player disconnected) that msh waits before hibernating the minecraft server

"TimeBeforeStoppingEmptyServer": 30

SuspendAllow enables msh to suspend minecraft server process when there are no players online
To mitigate ram usage you can set a high swappiness (on linux)

  • pro: player wait time to join frozen server is ~0
  • cons: ram usage as minecraft server without msh (cpu remains ~0)

SuspendRefresh enables refresh of minecraft server suspension every set seconds (to avoid watchdog crash at unsuspension)

  • setting these variables and SuspendRefresh might prevent minecraft server watchdog crash when SuspendAllow is enabled
file variable
server.properties max-tick-time= -1
spigot.yml timeout-time: -1, restart-on-crash: false
bukkit.yml warn-on-overload: false
paper-global.yml early-warning-delay: -1, early-warning-every: -1
"SuspendAllow": false
"SuspendRefresh": -1	# set -1 to disable, advised value: 120 (reduce if minecraft server keeps crashing)

Hibernation and Starting server description

"InfoHibernation": "                   §fserver status:\n                   §b§lHIBERNATING"
"InfoStarting": "                   §fserver status:\n                    §6§lWARMING UP"

Set to false if you don't want notifications (every 20 minutes)

"NotifyUpdate": true
"NotifyMessage": true

Whitelist contains IPs and player names that are allowed to start the server (leave empty to allow everyone)
WhitelistImport adds whitelist.json to player names that are allowed to start the server
unknown clients are not allowed to start the server, but can join

"Whitelist": ["127.0.0.1", "gekigek99"]
"WhitelistImport": false

ShowResourceUsage enables the logging of the msh tree process cpu/ram usage percent
for debug purposes (debug level 3 required)

"ShowResourceUsage": false

ShowInternetUsage enables the logging of the msh connection usage
for debug purposes (debug level 3 required)

"ShowInternetUsage": false

CREDITS:

Author: gekigek99

Contributors: najtin, f8ith, Br31zh, someotherotherguy, navidmafi, cromefire, andreblanke, KyleGospo, A-wels

Docker branch (outdated): lubocode

Pterodactyl egg: BolverBlitz

If you wish to contribute, please create a pull request using the dev branch as the base for your changes


Give a star to this repository on github!

minecraft-server-hibernation's People

Contributors

a-wels avatar andreblanke avatar bolverblitz avatar chris6ix avatar cromefire avatar dependabot[bot] avatar f8ith avatar gekigek99 avatar kylegospo avatar lubocode avatar najtin avatar navidmafi avatar someotherotherguy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

minecraft-server-hibernation's Issues

strings.ReplaceAll undefined

I just installed this, but it couldn't run. The exact message I got was
# command-line-arguments ./minecraft-server-hibernation.go:491:21: undefined: strings.ReplaceAll
I'm running this on an Ubuntu server install. Are there any dependencies I'm not aware of or something else of that order?

Possibly work with server panels.

I feel like this could be really useful for server panels that don't support this feature. The main one I can think of is Crafty Controller. Its a very barebones panel, but it is missing a hibernation feature.

No error messages / output on Ubuntu and File path specifications

I'm new to Ubuntu so I set up a VM on my computer before making my server run on it. I'm having some trouble getting the script work properly and I don't know what's wrong because there is no output to the terminal. It is likely because I incorrectly put in the server path. It is located in my home directory with all my other server files in a folder called minecraftdir. I am using the line "/home/gavvydizzle/minecraft" to reference the server folder. Just to add, I am using the terminal to run the python3 script. Is my directory wrong? or am I running the script incorrectly? Thanks for your help in advance. Edit: This was occuring on version 2.0 of the script

bug correction

Line 130 python (and corresponding golang) change from if to elif and adapt debug/client messages

freeze and unfreeze server to avoid warming up delay and cpu spikes

Hello,

That’s not really an issue, but I wanted to share this and don’t know where I can say it: I have my server on my (Linux) PC, and starting the server create CPU usage pikes, and freezes my other programs. So, instead of shutdown the server, I freeze it with a kill -STOP <pid> and resume with kill -CONT <pid>. It constantly use the 2GB of assigned RAM, but CPU, disk and network usage are null during this time. And the resume is instant, without CPU spike.

I had to set max-tick-time to -1 in server.properties and start the server before your script (and, since your script expect the server to be down, I freeze it before launching your script). I set the startup time to 1 in the configuration, and I resume the server before stopping it in my shutdown script (used when I want to completely stop the server).

It can give idea to others people, or to add new functionalities to the script, or as an example since it’s not an obvious way to use it.

Python version 5.3 - players max out on ping

Startup works fine. When I open multiplayer list as client, server instantly believes 126 players have joined:

A PLAYER JOINED THE SERVER! - 126 players online
Exception in main(): [Errno 24] Too many open files

Go Docker: MC server doesn't start up

For now all I have is the following:

2020/10/14 18:15:47 *** MINECRAFT SERVER IS STARTING!
2020/10/14 18:15:47 *** PLAYER tried to join from 172.24.144.1:25555 to 127.0.0.1:25565
2020/10/14 18:15:47 closing connection for: 172.24.144.1
2020/10/14 18:16:08 *** MINECRAFT SERVER IS UP!
2020/10/14 18:16:59 *** from 172.24.144.1:25555 to 127.0.0.1:25565
2020/10/14 18:16:59 handleClientSocket: error during serverSocket.Dial()
2020/10/14 18:17:08 error stopping minecraft server: exit status 1
2020/10/14 18:17:08 *** MINECRAFT SERVER IS SHUTTING DOWN!

This indicates that the console command executes without error, but does not do what is intended.
Probably some permission stuff, but I will not exclude some moved file as a possibility for now.

Error codes showing but the program is still executing

I've been running the 4.0 Version of the vanilla server hibernation script for about 2-3 weeks with no problems. Tonight I restarted my Ubuntu machine to come back to the error "OSError: [Errno 98] Address already in use." I'm not sure that this error entails so I'm asking here. The weird thing is that despite this error message, players can still join my server. Any suggestions or fixes? Thanks. I attached the error in the terminal window
image

py-version deprecation

this issue is to keep track of what to do before deprecating the python version.

before deprecating I want:

  1. make a release of 9.12 with the changes from version 7.9
  2. decide the new versioning system
  3. announce in the 9.12 release that python version will be deprecated and why
  4. announce in the 9.12 release the new versioning system
  5. add in the description that the go-version compiled binary will be available for each release (for windows and linux)

Docker MC server commands

Change from screen to systemctl for Docker version to follow master.
Further testing required before changes can be implemented.

check for updates

I think it might be helpful for users if the scripts advise them when a update is available. This would be set as an option in the config file.

(I would like to implement it before the v2.0.0 is released)

Windows compatibility feature

make the python version windows compatible.

(it's better to maintain just one file and use different if to execute different instructions)

Python graceful exit upon interrupt signal

Currently the Python script throws exceptions when interrupted through a SIGINT (ctrl + c) or SIGTERM.
To gracefully exit the script a signal handler needs to be introduced. This could look something like this:

from threading import Thread, Timer, Lock, enumerate, main_thread
import signal

def interruptHandler(signal, frame):
	print('Termination signal detected. Exiting gracefully.')
	threads = enumerate()
	print("Trying to join the following threads:")
	print(threads)
	for t in threads:
		if t != main_thread():
			if t is threading.Timer:
				t.cancel()
			else:
				t.join()
	sys.exit(0)

def main():
	# Listen for interrupt signal (e.g.: ctrl + c)
	signal.signal(signal.SIGINT, interruptHandler)
	signal.signal(signal.SIGTERM, interruptHandler)

Though after trying around a bit, the script continues to run even after successfully going through the join loop on my PC.
It also spawns a new Timer thread, which at least shows that the original Timer thread was successfully cancelled.
I think that either there is a thread that is not listed with enumerate() or sys.exit(0) is not working correctly, but I don't have enough experience with python threading to figure out what's really going on.

Resources:
Signal library
Threading library

Auto-detect when server is up

Hello,

Do you think it’s possible to auto-detect when the server is up instead or using an static defined timer? By trying to connect to it, or using rcon, for example.

Improve logging system [logging update]

the script has come to the point where a reliable and complete log system is required.
I don't have particular plans but a good starting point could be to add in the logger() function the ability to write the logs to a file.

log server public IP instead of localhost when players connect [logging update]

Currently all connection messages just say that someone wanted to connect to 127.0.0.1:25565 or in other words localhost.
This is the way the script communicates with the MC server, but for the user it would be more useful to know the IP address the script uses to communicate with the clients.
Maybe this should be added in the logging messages or perhaps even replace the 127.0.0.1:25565.

handleClientSocket should check client join packets based on config's ListenPort

Function handleClientSocket at line 267 onwards for managing client joins should be changed so it looks manages packets based on the config's ListenPort rather than looking for [221, 2].

I changed my listening port to 25565 and target port to 25555. handleClientSocket is hard-coded to look for packets [...63 DD 2...] which is specifically for port 25565. When changing target to port 25555 it should be looking for [...63 D3 2...]. What should happen is it looks for bytes based on the config's Listen port.

edit - clarification

Check for server.jar on startup of script

Checking whether or not the server.jar can be found on script startup should be essential to avoid users setting up something incorrectly and thinking their setup is working, while the script cannot find the server when a users actually tries to connect.

This should be handled with OS independent functions/libraries.

Connection Refused in Minecraft Version 1.16.2

I've been using the script for months now without any problems. It even worked in versions 1.16.0 and 1.16.1. Once I updated my server to 1.16.x the message telling clients how long it is until the server comes up isn't showing anymore. And with my current problem, I am getting the message "Exception in main(): [Errno 111] Connection refused" once I try to connect after the server has started. Any help is appreciated. Also, do you have any plans on updating the script to 1.16.2 for Linux?

Make server icon modifiable by users

Since one can usually set their own MC server icon by naming a 64x64 pixel png to "server-icon.png" and putting it in the main server folder, how about having the current static image as a kind of default image and trying to detect, once on script startup, whether there is a user image and then using that?

warning "time remaining to server-up" not showing in 1.16.2 version

mojang probaby changed some rules and I would like to know how @najtin come up with the string to communicate the warning during server startup.

did you just captured the the bytes exchanged with the clients to reproduce them? if so how did you make the minecraft server send those?

Just to avoid tons of hours to solve this "stupid" issue.
thanks

Access server command line? (linux)

Is it any way possible to access the server command line? Starting the script @reboot with crontab and launching the server.jar in a screen session as readme explains. Can't find any running screen sessions, but can connect to the server with minecraft client?

Question about script/improvements suggested

Is it planned to be able to pause the process?
And can you not let the port listen to that of the server when the server is stopped?
You can simply query the number of players.
Can the motd be transferred or replaced with a text?

Go Docker: config.json location

The location of the config.json inside the docker does not make much sense without further info, as it is not easy to change.

I have three ideas for this:

  • Copy the config upon docker build into the volume (only possible if docker image is build by oneself and not pulled from Dockerhub, so probably not the best option)
  • Have a warning in the Docker readme that the config.json has to be downloaded from the github repo and put beside the minecraft.jar
  • Have the config.json inside the container with the script and include instructions in the Docker readme on how to change it with vim or something like that over the linux shell of the container

That being said, it will still work without the user touching the config, but having options is always nice.

Disable windows system hibernation while there are players online

I may have totally misunderstood but this "just" sleeps and wakes the server on an active machine?

I'd like to Sleep/Hibernate/Shutdown the Windows PC when nobody on server (and machine inactive also) and to use Wake on LAN to wake the machine and resume server.

Use case: 2nd PC I sometimes use... so don't want it suddenly sleeping when I am actually using it (which Windows itself takes care of, or MacOS or Linux if I were to use them). So I need it to pass the decision as to when to sleep to the OS when the MC server is inactive and on resume (someone remotely WOL's the PC) the MC server needs to resume....

Does that make any sense?!?

Python Docker: not functional

The python Dockerfile and script on Branch "docker" currently do not work.

  1. Implement argument parsing into the script
  2. Add listening for termination signal from Docker container in script
    -> Add server shutdown upon script exit
  3. Relocate python script to inside Docker image during build process of Dockerfile
  4. Add ENV variables for argument parsing in Dockerfile
  5. Create README for python docker

Problems with the newest version

When trying to run the latest version of the python script I encountered a few errors. Some I was able to fix, others I am not.

  • On line 19 "true" should start with a capital T.
  • It may have been a problem created on my end but lines 194-200 were giving improper indentation/spacing errors. I fixed by just readjusting the spacing.

After fixing these issues, the script would start but after starting up the server it would send me the error message:

  • "Exception in main(): a bytes-like object is required, not 'NoneType'"
  • Also, it wouldn't show the startup message.
  • Lastly, when joining the server after it says the server is up it keeps throwing the error "Exception in main(): [Errno 24] Too many open files" and doesn't let me join my server.

Implement Analytics [logging update]

Analytic logging level mention in #43 would be local analytics (saved to file).
Brainstorming for fledging out this feature needed.
Useful for optimizing server hardware and utilization.

Current ideas include (but are not guaranteed or limited to):

  • number of players (max and avg(ignoring times, when server is down and no one online))
  • name of all players (useful for whitelisting/blacklisting)
  • time of connection (heat map; time as in daytime not duration of connection establishment)
  • avg lag / avg lag of single players (-> troubleshoot network problems)
  • MC world size
  • MC world ticks
  • avg server start time (#37 needed)

@gekigek99 just treat this as an idea collection to write anything that comes to mind to.
Before starting work on this feature, it needs to be properly planned out and it should also be done after most of the other issues.

Strange "**** FAILED TO BIND TO PORT!" Error

Hi gekigek99, I came across this script yesterday and was excited to see it was exactly what I was looking for with the server I'm currently hosting.

However, I'm having an issue when trying to join the server after launching the script. As soon as I attempt to connect, the error message:

"**** FAILED TO BIND TO PORT!
[00:23:44] [Server thread/WARN]: The exception was: io.netty.channel.unix.Errors$NativeIoException: bind(..) failed: Address already in use
[00:23:44] [Server thread/WARN]: Perhaps a server is already running on that port?"

comes up and stops the server immediately.

What I tryed:

I have made sure that no other instances of the server are running
I have made sure that nothing else is assigned to that port.
I have also tried using several different ports
I have edited the ports within the server.properties file as well as the python script.

What I noticed:

The server also runs flawlessly when I do not run it with the python script and there is no error message.

Any suggestions would be greatly appreciated. Thank you!

Check for Java installation

Since you need to have java installed to run a Minecraft server it might be nice to inform the user if the Java installation is not found or the version is insufficient.
A simple java -version command in cmd/bash works on Windows and Linux and prints the current Java version along some other info.
Since this is probably language specific, it might be hard to parse the string that comes back.
A first step would then be to log the output so that the user can at least interpret it themselves.

Go Docker: Connection establishment fails

  • Make Server version into a Docker ENV variable and parse it in main.

  • Currently script advertises vanilla server. Previously, when neither advertising version number nor vanilla status, modded MC servers worked without a problem. Make this either dynamic or remove it from info string.

    • This refers to e.g. forge or bukkit servers (with additional mods installed)

Edit: The two things above are partly implemented with the config.json from the latest commits on master.
The actual problem seems to be earlier during the connection establishment of the join process.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.