mcmotd-api/app.py
2025-07-30 09:23:01 +08:00

206 lines
6.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
# 从凌晨1点到6点就写了个 JavaServer 的状态获取,我这速度无敌了
from flask import Flask, render_template, request, jsonify
from mcstatus import JavaServer, BedrockServer
from flask_cors import CORS
# 我尝试了一下外部调用,出乎意料的可以跑
from srv_resolve import resolve_srv_record
import base64
app = Flask(__name__)
app.json.sort_keys = False
app.json.ensure_ascii = False
app.json.mimetype = 'application/json;charset=UTF-8'
app.json.compact = False
CORS(app)
http_code = None
@app.route('/')
def index():
return render_template('index.html')
# 这里是 Java 服务器的状态获取逻辑
# 不管你有没有选择 srv 记录,他都会跑一遍来验证
@app.route('/java')
def java_motd():
ip = request.args.get('ip') or ''
srv = request.args.get('srv', 'true').lower()
if not ip:
http_code = 400
return jsonify(
{'status': http_code,
'message': '缺少 ip 参数',
'usage': '/java?ip=<ip>&srv=<true|false>',
'tip': '第一次解析可能延迟很高,你可以考虑二次调用'
}
), http_code
try:
# 赋予默认变量
address = ip
port = 25565
is_srv = srv
resolved_type = 'normal'
http_code = 200
srv_warning_msg = None
# 霸道总裁强制爱(不是)
# 就是判断两个字符啦qwq
if srv not in ['true', 'false']:
http_code = 400
srv_error_msg = {
'status': f'Ciallo(∠・ω< )⌒★',
'error': 'srv 参数只能为 true 或 false'
}
return jsonify(srv_error_msg), http_code
if is_srv == 'true':
# 如果没有冒号尝试SRV解析
if ':' not in ip:
try:
address, port, resolved_type = resolve_srv_record(ip)
except Exception as e:
print(f"SRV记录解析失败: {str(e)}")
# 如果有冒号,直接解析地址和端口
else:
address, port_str = ip.split(':', 1)
port = int(port_str)
print(f"使用指定的地址和端口: {address}:{port}")
else:
# 禁用SRV解析直接处理IP地址
if ':' in ip:
address, port_str = ip.split(':', 1)
port = int(port_str)
# 如果没有端口使用默认端口25565
else:
port = 25565
# 测试连接
try:
test_server = JavaServer.lookup(f"{address}:{port}")
test_status = test_server.status()
except Exception as e:
srv_warning_msg = f'此解析可能为 srv 解析,已自动转换'
# 转换为 srv 解析
resolve_srv_record(ip)
address, port, resolved_type = resolve_srv_record(ip)
# 调用 mcstatus 获取服务器状态
server = JavaServer.lookup(f'{address}:{port}')
status = server.status()
# 处理在线玩家名字
player_name = []
if status.players.sample:
player_name = [player.name for player in status.players.sample]
# 处理服务器图标
icon_data = None
if status.icon:
icon_str = status.icon.strip()
# 添加Base64前缀
if not icon_str.startswith('data:image/png;base64,'):
icon_str = f"data:image/png;base64,{icon_str}"
# 验证Base64格式
try:
base64.b64decode(icon_str.split(',', 1)[-1])
icon_data = icon_str
except Exception as e:
print(f"无效的Base64图标数据: {str(e)}")
# 准备返回数据
java_data = {
'status': http_code,
'ip': f"{address}:{port}",
'description': status.description,
'type': resolved_type,
'version': status.version.name,
'latency': f"{status.latency}ms",
'players': {
'current': status.players.online,
'max': status.players.max,
'player_name': player_name
},
'icon': icon_data
}
# 如果有 srv 解析警告,添加到返回数据中
if srv_warning_msg:
java_data['warning'] = srv_warning_msg
return jsonify(java_data), http_code
# 蜜汁错误,我不管了啊啊啊啊啊啊啊啊啊啊!!!!!!!!
except Exception as e:
unknow_error = f"无法获取服务器信息: {str(e)}"
http_code = 500
unknow_error_msg = {
'status': http_code,
'ip': f"{address}:{port}",
'error': unknow_error
}
return jsonify(unknow_error_msg), http_code
# 这里是 Bedrock 服务器的状态获取逻辑
# 我已经做过功课了,他没有图标和在线玩家名字显示的!!!
@app.route('/be')
def bedrock_motd():
ip = request.args.get('ip') or ''
if not ip:
http_code = 400
return jsonify(
{'status': f'Ciallo(∠・ω< )⌒★',
'message': '缺少 ip 参数',
'usage': '/be?ip=<ip>',
'tip': '第一次解析可能延迟很高,你可以考虑二次调用'
}
), http_code
try:
# 赋予默认变量
address = ip
port = 19132
http_code = 200
if ':' in ip:
address, port_str = ip.split(':', 1)
port = int(port_str)
print(f"使用指定的地址和端口: {address}:{port}")
server = BedrockServer.lookup(f'{address}:{port}')
status = server.status()
# 准备返回数据
bedrock_data = {
'status': http_code,
'ip': f"{address}:{port}",
'description': status.description,
'version': status.version.name,
'latency': f"{status.latency}ms",
'players': {
'current': status.players.online,
'max': status.players.max
}
}
return jsonify(bedrock_data), http_code
except Exception as e:
unknow_error = f"无法获取服务器信息: {str(e)}"
http_code = 500
unknow_error_msg = {
'status': http_code,
'ip': f"{address}:{port}",
'error': unknow_error
}
return jsonify(unknow_error_msg), http_code
if __name__ == '__main__':
app.run(debug=True,port = 5000)