-
Notifications
You must be signed in to change notification settings - Fork 0
/
run.py
133 lines (103 loc) · 3.73 KB
/
run.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
"""
This script automatically starts and stops a Minecraft server.
If someone tries to join the server is started.
If no players are online anymore the server is stopped.
"""
import os
import socket
import time
import subprocess
import logging
import sys
import fileinput
import config
import mcstatus
logger = logging.getLogger()
logging.basicConfig(level=config.LOGGING)
server = mcstatus.JavaServer.lookup(f"{config.HOST}:{config.PORT}")
whitelist = []
blacklist = []
if os.path.exists("whitelist.txt"):
with open("whitelist.txt") as f:
whitelist = [l.strip() for l in f.readlines() if not l.startswith("#")]
if whitelist:
logger.info(f"Whitelisted addresses: {whitelist}")
if os.path.exists("blacklist.txt") and not whitelist:
with open("blacklist.txt") as f:
blacklist = [l.strip() for l in f.readlines() if not l.startswith("#")]
if blacklist:
logger.info(f"Blacklisted addresses: {blacklist}")
def start_server():
logger.info("Starting server")
subprocess.call("./start.sh")
logger.debug(f"Waiting {config.STARTUP_DELAY} seconds for port to become available")
time.sleep(config.STARTUP_DELAY)
def stop_server():
logger.info("Stopping server")
subprocess.call("./stop.sh")
logger.debug(
f"Waiting {config.SHUTDOWN_DELAY} seconds for port to become available"
)
time.sleep(config.SHUTDOWN_DELAY)
def server_status() -> int:
try:
status = server.status()
logger.info(f"{status.players.online} players online")
return status.players.online
except Exception as e:
logger.debug(e)
logger.info(f"Failed to check mcstatus, assuming Minecraft is not running")
return -1
def wait_for_connection():
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(("0.0.0.0", config.PORT))
serversocket.listen(5)
logger.info("Waiting for connection...")
address = None
while not address:
(clientsocket, address) = serversocket.accept()
if (not whitelist and address[0] not in blacklist) or (address[0] in whitelist):
logger.info(f"Got a connection from {address}")
clientsocket.send("Server is starting".encode("utf-8"))
logger.debug("Closing sockets")
clientsocket.close()
serversocket.close()
else:
logger.warning(f"Ignoring IP {address[0]}")
address = None
def wait_for_empty_server():
while server_status() > 0:
logger.debug(
f"Minecraft Server is active, sleeping for {config.SHUTDOWN_TIMER} seconds"
)
time.sleep(config.SHUTDOWN_TIMER)
logger.debug("Minecraft Server is not active")
def edit_motd():
for line in fileinput.input(config.SERVER_PROPERTIES, inplace=True):
if "motd=" in line:
sys.stdout.write(f"motd=Server started at {time.strftime('%H:%M')}")
if __name__ == "__main__":
# Start the main flow
while True:
status = server_status()
sys.stdout.flush() # show log in systemd service
if status == 0:
stop_server()
sys.stdout.flush()
elif status > 0:
logger.debug(
f"Minecraft Server is active, sleeping for {config.SHUTDOWN_TIMER} seconds"
)
sys.stdout.flush()
time.sleep(config.SHUTDOWN_TIMER)
wait_for_empty_server()
sys.stdout.flush()
wait_for_connection()
sys.stdout.flush()
if config.EDIT_MOTD:
logger.debug("Editing motd")
edit_motd()
start_server()
sys.stdout.flush()
logger.debug(f"Wait {config.STARTUP_TIMER} seconds for the player to join")
time.sleep(config.STARTUP_TIMER)