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