Merge branch 'main' of https://github.com/MeBeBruno/SCOicideSquad
This commit is contained in:
commit
339e0c72ad
3 files changed
+55
-33
No files matched your search
+46
-29
@@ -1,3 +1,6 @@
|
||||
from gevent import monkey
|
||||
monkey.patch_all()
|
||||
|
||||
import sqlite3
|
||||
import string
|
||||
import secrets
|
||||
@@ -10,16 +13,17 @@ from passlib.hash import argon2
|
||||
import pyotp
|
||||
import qrcode
|
||||
import qrcode.image.svg
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from apscheduler.schedulers.gevent import GeventScheduler
|
||||
from apscheduler.triggers.cron import CronTrigger
|
||||
from apscheduler.triggers.date import DateTrigger
|
||||
from flask import Flask, request, session, redirect, render_template, url_for, abort, send_from_directory
|
||||
from flask_socketio import SocketIO, emit, join_room
|
||||
|
||||
application = Flask(__name__)
|
||||
app = application # Fallback-Alias für Gunicorn und Pella
|
||||
application.secret_key = secrets.token_hex(64)
|
||||
websocket_manager = SocketIO(application, manage_session=False)
|
||||
scheduler_instance = BackgroundScheduler(timezone="Europe/Berlin")
|
||||
websocket_manager = SocketIO(application, manage_session=False, async_mode='gevent')
|
||||
scheduler_instance = GeventScheduler(timezone="Europe/Berlin")
|
||||
european_timezone = zoneinfo.ZoneInfo("Europe/Berlin")
|
||||
|
||||
IDENTIFIER_LENGTH = 5
|
||||
@@ -62,7 +66,7 @@ def initialize_database():
|
||||
""")
|
||||
connection.execute("""
|
||||
CREATE TABLE IF NOT EXISTS kill_log (
|
||||
kill_identifier INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
kill_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
killer_identifier TEXT,
|
||||
victim_identifier TEXT,
|
||||
victim_previous_target TEXT,
|
||||
@@ -240,13 +244,13 @@ def process_administrator_action(action_type, form_data):
|
||||
new_target = victim["target_identifier"]
|
||||
connection.execute("UPDATE player SET is_alive = 0, target_identifier = NULL, pending_attacker_identifier = NULL WHERE player_identifier = ?", (target_identifier,))
|
||||
|
||||
attacker_identifier = None
|
||||
attacker_id = None
|
||||
if attacker:
|
||||
attacker_identifier = attacker["player_identifier"]
|
||||
connection.execute("UPDATE player SET target_identifier = ? WHERE player_identifier = ?", (new_target, attacker_identifier))
|
||||
attacker_id = attacker["player_identifier"]
|
||||
connection.execute("UPDATE player SET target_identifier = ? WHERE player_identifier = ?", (new_target, attacker_id))
|
||||
|
||||
timestamp = datetime.now(european_timezone).isoformat()
|
||||
connection.execute("INSERT INTO kill_log (killer_identifier, victim_identifier, victim_previous_target, kill_timestamp) VALUES (?, ?, ?, ?)", (attacker_identifier, target_identifier, new_target, timestamp))
|
||||
connection.execute("INSERT INTO kill_log (killer_identifier, victim_identifier, victim_previous_target, kill_timestamp) VALUES (?, ?, ?, ?)", (attacker_id, target_identifier, new_target, timestamp))
|
||||
|
||||
alive_count_record = connection.execute("SELECT COUNT(*) as alive_count FROM player WHERE is_alive = 1 AND is_approved = 1").fetchone()
|
||||
if alive_count_record["alive_count"] <= 1:
|
||||
@@ -261,50 +265,50 @@ def process_administrator_action(action_type, form_data):
|
||||
has_game_state_changed = True
|
||||
|
||||
elif action_type == "edit_kill":
|
||||
kill_identifier = form_data.get("kill_identifier")
|
||||
new_killer_identifier = form_data.get("new_killer_identifier")
|
||||
if new_killer_identifier == "":
|
||||
new_killer_identifier = None
|
||||
kill_id = form_data.get("kill_id")
|
||||
new_killer_id = form_data.get("new_killer_identifier")
|
||||
if new_killer_id == "":
|
||||
new_killer_id = None
|
||||
new_timestamp = form_data.get("kill_timestamp")
|
||||
|
||||
old_kill = connection.execute("SELECT * FROM kill_log WHERE kill_identifier = ?", (kill_identifier,)).fetchone()
|
||||
old_kill = connection.execute("SELECT * FROM kill_log WHERE kill_id = ?", (kill_id,)).fetchone()
|
||||
if old_kill:
|
||||
old_killer_identifier = old_kill["killer_identifier"]
|
||||
if old_killer_identifier != new_killer_identifier:
|
||||
if old_killer_identifier:
|
||||
connection.execute("UPDATE player SET score = MAX(0, score - 1) WHERE player_identifier = ?", (old_killer_identifier,))
|
||||
if new_killer_identifier:
|
||||
connection.execute("UPDATE player SET score = score + 1 WHERE player_identifier = ?", (new_killer_identifier,))
|
||||
old_killer_id = old_kill["killer_identifier"]
|
||||
if old_killer_id != new_killer_id:
|
||||
if old_killer_id:
|
||||
connection.execute("UPDATE player SET score = MAX(0, score - 1) WHERE player_identifier = ?", (old_killer_id,))
|
||||
if new_killer_id:
|
||||
connection.execute("UPDATE player SET score = score + 1 WHERE player_identifier = ?", (new_killer_id,))
|
||||
|
||||
connection.execute("UPDATE kill_log SET killer_identifier = ?, kill_timestamp = ? WHERE kill_identifier = ?", (new_killer_identifier, new_timestamp, kill_identifier))
|
||||
connection.execute("UPDATE kill_log SET killer_identifier = ?, kill_timestamp = ? WHERE kill_id = ?", (new_killer_id, new_timestamp, kill_id))
|
||||
connection.commit()
|
||||
has_game_state_changed = True
|
||||
|
||||
elif action_type == "revoke_kill":
|
||||
kill_identifier = form_data.get("kill_identifier")
|
||||
kill_record = connection.execute("SELECT * FROM kill_log WHERE kill_identifier = ?", (kill_identifier,)).fetchone()
|
||||
kill_id = form_data.get("kill_id")
|
||||
kill_record = connection.execute("SELECT * FROM kill_log WHERE kill_id = ?", (kill_id,)).fetchone()
|
||||
|
||||
if kill_record:
|
||||
if kill_record["killer_identifier"]:
|
||||
connection.execute("UPDATE player SET score = MAX(0, score - 1) WHERE player_identifier = ?", (kill_record["killer_identifier"],))
|
||||
|
||||
victim_identifier = kill_record["victim_identifier"]
|
||||
victim_id = kill_record["victim_identifier"]
|
||||
target_to_restore = kill_record["victim_previous_target"]
|
||||
|
||||
player_pointing_to_target = connection.execute("SELECT player_identifier FROM player WHERE target_identifier = ?", (target_to_restore,)).fetchone()
|
||||
|
||||
connection.execute("UPDATE player SET is_alive = 1, target_identifier = ? WHERE player_identifier = ?", (target_to_restore, victim_identifier))
|
||||
connection.execute("UPDATE player SET is_alive = 1, target_identifier = ? WHERE player_identifier = ?", (target_to_restore, victim_id))
|
||||
if player_pointing_to_target:
|
||||
connection.execute("UPDATE player SET target_identifier = ? WHERE player_identifier = ?", (victim_identifier, player_pointing_to_target["player_identifier"]))
|
||||
connection.execute("UPDATE player SET target_identifier = ? WHERE player_identifier = ?", (victim_id, player_pointing_to_target["player_identifier"]))
|
||||
|
||||
connection.execute("DELETE FROM kill_log WHERE kill_identifier = ?", (kill_identifier,))
|
||||
connection.execute("DELETE FROM kill_log WHERE kill_id = ?", (kill_id,))
|
||||
|
||||
alive_count = connection.execute("SELECT COUNT(*) as alive_count FROM player WHERE is_alive = 1 AND is_approved = 1").fetchone()["alive_count"]
|
||||
if alive_count > 1:
|
||||
status = connection.execute("SELECT configuration_value FROM game_configuration WHERE configuration_key = 'game_status'").fetchone()["configuration_value"]
|
||||
if status == 'finished':
|
||||
connection.execute("UPDATE game_configuration SET configuration_value = 'running' WHERE configuration_key = 'game_status'")
|
||||
connection.execute("UPDATE player SET score = MAX(0, score - 3) WHERE is_alive = 1 AND is_approved = 1 AND player_identifier != ?", (victim_identifier,))
|
||||
connection.execute("UPDATE player SET score = MAX(0, score - 3) WHERE is_alive = 1 AND is_approved = 1 AND player_identifier != ?", (victim_id,))
|
||||
|
||||
connection.commit()
|
||||
has_game_state_changed = True
|
||||
@@ -362,6 +366,11 @@ def scheduled_action_wrapper(action_type, form_data):
|
||||
def serve_service_worker():
|
||||
return send_from_directory(application.static_folder, "service_worker.js")
|
||||
|
||||
@application.route("/health")
|
||||
@application.route("/ping")
|
||||
def handle_health_check():
|
||||
return "OK", 200
|
||||
|
||||
@application.route("/")
|
||||
@require_player_authentication
|
||||
def handle_index():
|
||||
@@ -630,7 +639,15 @@ def handle_elimination_rejection():
|
||||
emit("elimination_rejected", to=attacker_identifier)
|
||||
connection.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
# --- PRODUKTIONS-SETUP (GUNICORN) ---
|
||||
with application.app_context():
|
||||
initialize_database()
|
||||
scheduler_instance.start()
|
||||
|
||||
try:
|
||||
if getattr(scheduler_instance, 'state', 0) == 0:
|
||||
scheduler_instance.start()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if __name__ == "__main__":
|
||||
websocket_manager.run(application, host="0.0.0.0", port=5000)
|
||||
@@ -0,0 +1,2 @@
|
||||
worker_class = "geventwebsocket.gunicorn.workers.GeventWebSocketWorker"
|
||||
workers = 1
|
||||
+7
-4
@@ -1,8 +1,11 @@
|
||||
flask
|
||||
flask-socketio
|
||||
Flask
|
||||
Flask-SocketIO
|
||||
APScheduler
|
||||
passlib
|
||||
argon2-cffi
|
||||
pyotp
|
||||
apscheduler
|
||||
qrcode
|
||||
markdown
|
||||
Markdown
|
||||
gunicorn
|
||||
gevent
|
||||
gevent-websocket
|
||||
Reference in new issue
Block a user