You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

308 lines
15 KiB
Python

import os
import logging
import time
from datetime import datetime
6 months ago
from flask import Flask, request, jsonify
#from win10toast import ToastNotifier
#import asyncio
6 months ago
import subprocess
import signal
import psutil
import telegram
6 months ago
from telegram import Update
from telegram.ext import Updater, CommandHandler, CallbackContext, MessageHandler, filters
import telegram.error
logging.basicConfig(filename='osiris_listener.log', level=logging.DEBUG, format='%(asctime)s %(message)s')
app = Flask(__name__)
#toaster = ToastNotifier()
6 months ago
####
# Constants
####
# Define the scripts and their parameters
java_minecraft_servers = [
{
'server_name': 'Vanilla 1.21',
'directory': 'C:/Users/4lexK/Desktop/GameServers/Minecraft/Vanilla_1-21/',
'command': ['C:/Program Files/Java/jdk-22/bin/java.exe', '-Xmx1024M', '-Xms1024M', '-jar', 'minecraft_server.1.21.jar', '--nogui', '--bonusChest'],
'wait_time': 30
},
{
'server_name': 'The 1.12.2 Pack (SanderPack)',
'directory': 'C:/Users/4lexK/Desktop/GameServers/Minecraft/1-12-2-Pack/',
'command': ['C:/Program Files/OpenLogic/jdk-8.0.412.08-hotspot/bin/java.exe', '-Xmx16G', '-XX:+UseG1GC','-Xms4G', '-Dsun.rmi.dgc.server.gcInterval=2147483646', '-XX:+UnlockExperimentalVMOptions', '-XX:G1NewSizePercent=20', '-XX:G1ReservePercent=20', '-XX:MaxGCPauseMillis=50', '-XX:G1HeapRegionSize=32M', '-Dfml.queryResult=confirm', '-Duser.language=en', '-jar', 'forge-1.12.2-14.23.5.2860.jar', '--nogui', '--bonusChest'],
'wait_time': 30
},
{
'server_name': 'GT New Horizons 2.6.0 (SanderHorizons)',
'directory': 'C:/Users/4lexK/Desktop/GameServers/Minecraft/gt_new_horizons_2.6.0/',
'command': ['C:/Program Files/OpenLogic/jdk-8.0.412.08-hotspot/bin/java.exe', '-Xmx12G', '-Xms4G', '-XX:+UseStringDeduplication', '-XX:+UseCompressedOops', '-XX:+UseCodeCacheFlushing', '-Dfml.readTimeout=180', '-jar', 'forge-1.7.10-10.13.4.1614-1.7.10-universal.jar', '--nogui', '--bonusChest'],
'wait_time': 30
},
{
'server_name': 'RLCraft 2.9.3 (SanderHardcore)',
'directory': 'C:/Users/4lexK/Desktop/GameServers/Minecraft/rlcraft/',
'command': ['C:/Program Files/OpenLogic/jdk-8.0.412.08-hotspot/bin/java.exe', '-Xmx16G', '-Xms4G', '-jar', 'forge-1.12.2-14.23.5.2860.jar', '--nogui', '--bonusChest'],
'wait_time': 30
}
]
6 months ago
####
# Telegramm Functions
####
# Telegram bot token
TELEGRAM_BOT_TOKEN = '6984289827:AAHNUM4F_U6233oa75nX5jXyQY6vC0NlZvw'
# Create an Bot with a larger connection pool and longer pool timeout
bot = telegram.Bot(token=TELEGRAM_BOT_TOKEN)
# File to store subscriber chat IDs
SUBSCRIBERS_FILE = 'telegramm_subscribers.txt'
def load_subscribers():
"""Load subscriber chat IDs from the file."""
if os.path.exists(SUBSCRIBERS_FILE):
with open(SUBSCRIBERS_FILE, 'r') as file:
return [line.strip() for line in file.readlines()]
return []
async def send_telegram_message(message):
"""Send a message to all subscribers."""
subscribers = load_subscribers()
for chat_id in subscribers:
try:
prepped_message = f"{message}"
await bot.send_message(chat_id=chat_id, text=prepped_message)
except telegram.error.TelegramError as e:
logging.error(f"Error sending message to {chat_id}: {e}")
####
# Tool Functions
####
def read_pid_file(pid_file):
"""Read the PID from the specified PID file."""
try:
with open(pid_file, 'r') as file:
pid = int(file.read().strip())
return pid
except (FileNotFoundError, ValueError):
return None
def is_java_process(pid):
try:
p = psutil.Process(pid)
return 'java' in p.name().lower()
except psutil.NoSuchProcess:
return False
6 months ago
####
# Flask Functions
####
@app.route('/osiris_execute', methods=['POST'])
def execute_script():
logging.info("Commando zur Ausführung erhalten.")
data = request.get_json()
command = data.get('command')
if not command:
logging.error("No command provided in request.")
return jsonify({'error': 'No command provided'}), 400
logging.debug(f"Commando: {command}")
# Hier neue Commands zur Prüfung einpflegen
clean_command = command.strip()
match clean_command:
case 'testcommand':
try:
#toaster.show_toast("TestCommand", "Verbindung wurde getestet", d)uration=10)
#asyncio.run(send_telegram_message("Test command executed."))
return jsonify({'message': 'Test Command abgesetzt und Notification auf bei Host erstellt.'})
except Exception as exc:
logging.error(f"Error executing test command: {exc}")
#asyncio.run(send_telegram_message(f"Error executing test command: {e}"))
return jsonify({'message': f'Error: {str(exc)}'}), 500
case 'shutdown':
logging.info("Received request to shutdown.")
try:
#toaster.show_toast("Shutdown", "Shutdown Command erhalten. Host wird heruntergefahren.", duration=10)
os.system("shutdown /s /t 1")
#asyncio.run(send_telegram_message("Ich schlafe dann weiter. Bis demnächst :-)"))
return jsonify({'message': 'Shutdown command wurde ausgeführt. System fährt herunter.'})
except Exception as e:
logging.error(f"Error executing shutdown command: {exc}")
#asyncio.run(send_telegram_message(f"Error executing shutdown command: {e}"))
return jsonify({"message": "Fehler beim veranlassen des Shutdowns", 'error': str(e)}), 500
case 'start_gameservers_minecraft':
logging.info("Received request to start minecraft servers.")
#toaster.show_toast("start_gameservers_minecraft", "Starte Minecraft-Server", duration=10)
response_msg = "Folgende Minecraft-Server wurden bearbeitet:"
for server in java_minecraft_servers:
os.chdir(server['directory'])
pid_file = os.path.join(server['directory'], 'server.pid')
log_file = os.path.join(server['directory'], 'logs', f'server_{datetime.now().strftime("%Y%m%d_%H%M%S")}.log')
#wait_time = server['wait_time']
# Create logs directory if it doesn't exist
os.makedirs(os.path.dirname(log_file), exist_ok=True)
if os.path.exists(pid_file):
with open(pid_file, 'r') as file:
pid = int(file.read().strip())
if psutil.pid_exists(pid) and is_java_process(pid):
response_msg += f"\nServer {server['server_name']} läuft bereits."
continue
else:
os.remove(pid_file)
#response_msg += f"Server {server['server_name']} wird gestartet."
with open(log_file, 'w') as log:
process = subprocess.Popen(
server['command'],
cwd=server['directory'],
stdout=log,
stderr=log,
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if os.name == 'nt' else 0
)
#time.sleep(wait_time)
with open(pid_file, 'w') as file:
file.write(str(process.pid))
response_msg += f"\nServer {server['server_name']} wurde mit PID '{process.pid}' gestartet."
return jsonify({"message": f"{response_msg}"})
#return jsonify({'message': 'Minecraft-Server werden gestartet.'})
case 'stop_gameservers_minecraft':
logging.info("Received request to stop minecraft servers.")
response_msg = "Folgende Minecraft-Server wurden bearbeitet:"
for server in java_minecraft_servers:
pid_file = os.path.join(server['directory'], 'server.pid')
wait_time = server['wait_time']
flag_delete_pid = False
if os.path.exists(pid_file):
with open(pid_file, 'r') as file:
pid = int(file.read().strip())
if psutil.pid_exists(pid) and is_java_process(pid):
p = psutil.Process(pid)
if os.name == 'nt':
p.terminate() # Use terminate for Windows
else:
p.send_signal(signal.SIGTERM)
try:
p.wait(timeout=wait_time)
if not psutil.pid_exists(pid):
flag_delete_pid = True
response_msg += f"\nServer {server['server_name']} mit PID {pid} gestoppt."
else:
response_msg += f"\nFehler beim Stoppen des Servers {server['server_name']} mit PID {pid}."
except psutil.TimeoutExpired:
response_msg += f"Timeout während stoppen des Server {server['server_name']} mit PID {pid}."
else:
flag_delete_pid = True
response_msg += f"Stale PID file von Server {server['server_name']} entfernt."
if flag_delete_pid:
os.remove(pid_file)
response_msg += f"PID File gelöscht"
flag_delete_pid = False
else:
response_msg += f"Es existiert kein PID File für Server {server['server_name']}"
#asyncio.run(send_telegram_message("Minecraft-Server wurden heruntergefahren."))
return jsonify({'message': response_msg})
case 'start_gameservers_dontstarve':
try:
#toaster.show_toast("start_gameservers_dontstarve", "Starte Dont Starve Together-Server", duration=10)
# hier pgm aufrufen
return jsonify({'message': 'Dont Starve Together-Server werden gestartet.'})
except Exception as exc:
logging.error(f"Error executing start_gameservers_dontstarve command: {exc}")
return jsonify({'error': str(exc)}), 500
case 'stop_gameservers_dontstarve':
try:
#toaster.show_toast("stop_gameservers_dontstarve", "Stoppe Dont Starve Together-Server", duration=10)
# hier pgm aufrufen
return jsonify({'message': 'Dont Starve Together-Server wurden angehalten.'})
except Exception as exc:
logging.error(f"Error executing stop_gameservers_dontstarve command: {exc}")
return jsonify({'error': str(exc)}), 500
case 'start_gameservers_ragnarokonline':
try:
#toaster.show_toast("start_gameservers_ragnarokonline", "Starte RO-Server", duration=10)
# hier pgm aufrufen
return jsonify({'message': 'RO-Server werden gestartet.'})
except Exception as exc:
logging.error(f"Error executing start_gameservers_ragnarokonline command: {exc}")
return jsonify({'error': str(exc)}), 500
case 'stop_gameservers_ragnarokonline':
try:
#toaster.show_toast("stop_gameservers_ragnarokonline", "Stoppe RO-Server", duration=10)
# hier pgm aufrufen
return jsonify({'message': 'RO-Server wurden angehalten.'})
except Exception as exc:
logging.error(f"Error executing stop_gameservers_ragnarokonline command: {exc}")
return jsonify({'error': str(exc)}), 500
case 'start_gameservers_wow':
try:
#toaster.show_toast("start_gameservers_wow", "Starte WoW-Server", duration=10)
# hier pgm aufrufen
return jsonify({'message': 'WoW-Server werden gestartet.'})
except Exception as exc:
logging.error(f"Error executing start_gameservers_wow command: {exc}")
return jsonify({'error': str(exc)}), 500
case 'stop_gameservers_wow':
try:
#toaster.show_toast("stop_gameservers_wow", "Stoppe WoW-Server", duration=10)
# hier pgm aufrufen
return jsonify({'message': 'WoW-Server wurden angehalten.'})
except Exception as exc:
logging.error(f"Error executing stop_gameservers_wow command: {exc}")
return jsonify({'error': str(exc)}), 500
case _:
try:
result = subprocess.run(['python','-c', command], capture_output=True, text=True, shell=True)
#send_telegram_message(f"Script executed with output: {result.stdout}")
return jsonify({'output': result.stdout, 'error': result.stderr, 'returncode': result.returncode})
except Exception as exc:
logging.error(f"Error executing command: {exc}")
#send_telegram_message(f"Error executing script: {e}")
return jsonify({'error': str(exc)}), 500
@app.route('/status', methods=['GET'])
def status():
logging.info("Status Check received.")
#asyncio.run(send_telegram_message(f"Bin da. Wer nohoch?"))
return jsonify({'message': 'status = online'})
@app.route('/status_servers', methods=['GET'])
def status_gameservers():
logging.info("Check Status der Server")
response_msg = "Status Game Server:"
for server in java_minecraft_servers:
pid_file = os.path.join(server['directory'], 'server.pid')
if os.path.exists(pid_file):
with open(pid_file, 'r') as file:
pid = int(file.read().strip())
if psutil.pid_exists(pid) and is_java_process(pid):
response_msg += f"\nServer {server['server_name']} läuft mit PID {pid}."
else:
response_msg += f"\nServer {server['server_name']} läuft nicht."
else:
response_msg += f"\nKein PID file für Server {server['server_name']} gefunden."
#asyncio.run(send_telegram_message(f"Aktuell laufende Server: {server_list}"))
return jsonify({"message": response_msg })
if __name__ == '__main__':
#toaster.show_toast("Starte Osiris", "Osiris Listener wurde gestartet. Warte auf Befehle...", duration=30)
logging.info("Starte Server.")
#asyncio.run(send_telegram_message(f"Nuc_Morroc hier. Bin jetzt wach ;-)"))
6 months ago
app.run(host='0.0.0.0', port=9713)