-
Notifications
You must be signed in to change notification settings - Fork 0
/
mcstatus-httpd.py
154 lines (128 loc) · 6.2 KB
/
mcstatus-httpd.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env python
#-*- coding: utf-8 -*-
"""
mcstatus-httpd
https://github.com/Tob1as/mcstatus-httpd
mcstatus-httpd shows any information of a Minecraft Server via HTTP-Server as JSON.
It used https://github.com/py-mine/mcstatus
"""
import os
import sys
import logging
import time
import json
from mcstatus import JavaServer # mcstatus docs: https://github.com/py-mine/mcstatus
from mcstatus import BedrockServer # mcstatus docs: https://github.com/py-mine/mcstatus
from http.server import BaseHTTPRequestHandler, HTTPServer
from http import HTTPStatus
import ssl
# Variables
LOGLEVEL = str(os.environ.get('LOGLEVEL', 'INFO').upper())
MINECRAFT_JAVA_SERVER = str(os.environ.get('MINECRAFT_JAVA_SERVER', ''))
MINECRAFT_JAVA_SERVER_PORT = int(os.environ.get('MINECRAFT_JAVA_SERVER_PORT', 25565)) # TCP Port
MINECRAFT_JAVA_SERVER_PORT_QUERY = int(os.environ.get('MINECRAFT_JAVA_SERVER_PORT_QUERY', MINECRAFT_JAVA_SERVER_PORT)) # UDP Port
MINECRAFT_JAVA_SERVER_OVERWRITE = str(os.environ.get('MINECRAFT_JAVA_SERVER_OVERWRITE', MINECRAFT_JAVA_SERVER)) # overwrite with DNS or something
MINECRAFT_BEDROCK_SERVER = str(os.environ.get('MINECRAFT_BEDROCK_SERVER', ''))
MINECRAFT_BEDROCK_SERVER_PORT = int(os.environ.get('MINECRAFT_BEDROCK_SERVER_PORT', 19132)) # UDP Port
MINECRAFT_BEDROCK_SERVER_OVERWRITE = str(os.environ.get('MINECRAFT_BEDROCK_SERVER_OVERWRITE', MINECRAFT_BEDROCK_SERVER)) # overwrite with DNS or something
HTTPD_HOST = str(os.environ.get('HTTP_HOST', '0.0.0.0'))
HTTPD_PORT = int(os.environ.get('HTTP_PORT', 8080))
HTTPD_SSL_ENABLE = int(os.environ.get('HTTPD_SSL_ENABLE', 0))
# Logging
logging.root.handlers = []
logging.basicConfig(format='%(asctime)s %(name)-12s %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', encoding='utf-8', stream=sys.stdout, level=LOGLEVEL)
logger = logging.getLogger(__name__)
logger.info(f"LOAD ENV: HTTPD_HOST={HTTPD_HOST} ; HTTPD_PORT={HTTPD_PORT} ; HTTPD_SSL_ENABLE={HTTPD_SSL_ENABLE}")
logger.info(f"LOAD ENV: MINECRAFT_JAVA_SERVER={MINECRAFT_JAVA_SERVER}:{MINECRAFT_JAVA_SERVER_PORT_QUERY} ; MINECRAFT_BEDROCK_SERVER={MINECRAFT_BEDROCK_SERVER}:{MINECRAFT_BEDROCK_SERVER_PORT}")
# current time
def currenttime():
t = time.localtime()
current_time = time.strftime("%Y-%m-%d %H:%M:%S", t)
return current_time
# healthcheck
def do_healthcheck(self):
self.send_response(HTTPStatus.OK.value) # 200
self.send_header('Content-type','text/plain')
self.end_headers()
#self.wfile.write(bytes("It Works!", "utf-8"))
# mc status as json
def do_mcstatus(self):
self.send_response(HTTPStatus.OK.value) # 200
self.send_header("Content-type", "application/json")
self.send_header('Access-Control-Allow-Origin', '*')
self.end_headers()
# inital json
jsondata={
'date': currenttime()
}
if(MINECRAFT_JAVA_SERVER and not MINECRAFT_JAVA_SERVER.isspace()):
# Minecraft Java Server
java_server = JavaServer.lookup(MINECRAFT_JAVA_SERVER + ':' + str(MINECRAFT_JAVA_SERVER_PORT_QUERY))
java_server_query = java_server.query() # 'query' has to be enabled in a servers' server.properties file.
logger.info(f"The Minecraft Java Server has {java_server_query.players.online} players online, list: {', '.join(java_server_query.players.names)}")
PLAYER_ONLINE_NAMES=(f"{', '.join(java_server_query.players.names)}")
SOFTWARE_PLUGINS=(f"{', '.join(java_server_query.software.plugins)}")
jsondata["java"]= {
'hostname': MINECRAFT_JAVA_SERVER_OVERWRITE,
'port': int(MINECRAFT_JAVA_SERVER_PORT),
'software': {
'version': java_server_query.software.version,
'brand': java_server_query.software.brand,
'plugins': SOFTWARE_PLUGINS
},
'players': {
'online': int(java_server_query.players.online),
'max': int(java_server_query.players.max),
'list': PLAYER_ONLINE_NAMES
},
'map': java_server_query.map,
'motd': java_server_query.motd.raw
}
if(MINECRAFT_BEDROCK_SERVER and not MINECRAFT_BEDROCK_SERVER.isspace()):
# Minecraft Bedrock Server
bedrock_server = BedrockServer.lookup(MINECRAFT_BEDROCK_SERVER + ':' + str(MINECRAFT_BEDROCK_SERVER_PORT))
bedrock_server_status = bedrock_server.status()
logger.info(f"The Minecraft Bedrock Server has {bedrock_server_status.players.online} players online.")
jsondata["bedrock"]= {
'hostname': MINECRAFT_BEDROCK_SERVER_OVERWRITE,
'port': int(MINECRAFT_BEDROCK_SERVER_PORT),
'software': {
'version': bedrock_server_status.version.name,
'brand': bedrock_server_status.version.brand,
'protocol': bedrock_server_status.version.protocol
},
'players': {
'online': int(bedrock_server_status.players.online),
'max': int(bedrock_server_status.players.max)
},
'map': bedrock_server_status.map_name,
'motd': bedrock_server_status.motd.raw,
'gamemode': bedrock_server_status.gamemode
}
# httpd output
self.wfile.write(json.dumps(jsondata).encode('utf-8'))
class MinecraftStatusServer(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/healthcheck':
do_healthcheck(self)
else:
do_mcstatus(self)
if __name__ == "__main__":
httpd = HTTPServer((HTTPD_HOST, HTTPD_PORT), MinecraftStatusServer)
# https/ssl
if HTTPD_SSL_ENABLE and HTTPD_SSL_ENABLE == 1 and os.path.exists('ssl.crt') and os.path.exists('ssl.key'):
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.set_ciphers('EECDH+AESGCM:EDH+AESGCM')
ctx.check_hostname = False
ctx.load_cert_chain(certfile='ssl.crt', keyfile='ssl.key')
httpd.socket = ctx.wrap_socket(httpd.socket, server_side=True)
HTTPD_SCHEME="https"
else:
HTTPD_SCHEME="http"
logger.info("Server started %s://%s:%s" % (HTTPD_SCHEME, HTTPD_HOST, HTTPD_PORT))
try:
httpd.serve_forever()
except KeyboardInterrupt:
pass
httpd.server_close()
logger.info("Server stopped.")