added training
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
from flask import Blueprint
|
||||
|
||||
bp = Blueprint('game', __name__)
|
||||
|
||||
from . import routes, socket # Import routes and socket modules
|
||||
9
training/srdnlenctf-2025/sparklingsky/src/game/models.py
Normal file
9
training/srdnlenctf-2025/sparklingsky/src/game/models.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from flask_login import UserMixin
|
||||
from app import db
|
||||
|
||||
class User(UserMixin, db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
||||
username = db.Column(db.String(80), unique=True, nullable=False)
|
||||
password = db.Column(db.String(300), nullable=False, unique=True)
|
||||
color = db.Column(db.String(10), nullable=True)
|
||||
is_playing = db.Column(db.Boolean, nullable=True)
|
||||
59
training/srdnlenctf-2025/sparklingsky/src/game/routes.py
Normal file
59
training/srdnlenctf-2025/sparklingsky/src/game/routes.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from flask import render_template, redirect, url_for, request, flash
|
||||
from flask_login import login_user, logout_user, login_required, current_user
|
||||
from . import bp
|
||||
from .models import *
|
||||
from app import login_manager
|
||||
from .utils import *
|
||||
from random import randint
|
||||
|
||||
@login_manager.user_loader
|
||||
def load_user(user_id):
|
||||
user = User.query.get(int(user_id))
|
||||
return user
|
||||
|
||||
@login_manager.unauthorized_handler
|
||||
def unauthorized_callback():
|
||||
return redirect('/login')
|
||||
|
||||
|
||||
@bp.route('/')
|
||||
@login_required
|
||||
def home():
|
||||
return render_template('home.html')
|
||||
|
||||
|
||||
@bp.route('/play')
|
||||
@login_required
|
||||
def play():
|
||||
current_players = User.query.filter_by(is_playing=True).with_entities(User.id).all()
|
||||
current_players = [user_id[0] for user_id in current_players]
|
||||
userID = int(current_user.get_id())
|
||||
if userID in current_players:
|
||||
return render_template('play.html')
|
||||
else:
|
||||
return render_template("spectate.html", position=randint(1, 300))
|
||||
|
||||
|
||||
@bp.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
if request.method == 'POST':
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
|
||||
user = User.query.filter(User.username == username).first()
|
||||
if user is None:
|
||||
return redirect(url_for('game.login'))
|
||||
if user.password == password:
|
||||
login_user(user)
|
||||
return redirect(url_for('game.home'))
|
||||
|
||||
return redirect(url_for('game.login'))
|
||||
|
||||
return render_template('login.html')
|
||||
|
||||
@bp.route('/logout')
|
||||
@login_required
|
||||
def logout():
|
||||
logout_user()
|
||||
flash('Logged out successfully!')
|
||||
return redirect(url_for('game.login'))
|
||||
48
training/srdnlenctf-2025/sparklingsky/src/game/socket.py
Normal file
48
training/srdnlenctf-2025/sparklingsky/src/game/socket.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from flask_socketio import emit
|
||||
from flask_login import current_user, login_required
|
||||
from threading import Lock
|
||||
from .models import *
|
||||
from anticheat import log_action, analyze_movement
|
||||
lock = Lock()
|
||||
|
||||
def init_socket_events(socketio, players):
|
||||
@socketio.on('connect')
|
||||
@login_required
|
||||
def handle_connect():
|
||||
user_id = int(current_user.get_id())
|
||||
log_action(user_id, "is connecting")
|
||||
|
||||
if user_id in players.keys():
|
||||
# Player already exists, send their current position
|
||||
emit('connected', {'user_id': user_id, 'x': players[user_id]['x'], 'y': players[user_id]['y'], 'angle': players[user_id]['angle']})
|
||||
else:
|
||||
# TODO: Check if the lobby is full and add the player to the queue
|
||||
log_action(user_id, f"is spectating")
|
||||
emit('update_bird_positions', players, broadcast=True)
|
||||
|
||||
@socketio.on('move_bird')
|
||||
@login_required
|
||||
def handle_bird_movement(data):
|
||||
user_id = data.get('user_id')
|
||||
if user_id in players:
|
||||
del data['user_id']
|
||||
if players[user_id] != data:
|
||||
with lock:
|
||||
players[user_id] = {
|
||||
'x': data['x'],
|
||||
'y': data['y'],
|
||||
'color': 'black',
|
||||
'angle': data.get('angle', 0)
|
||||
}
|
||||
if analyze_movement(user_id, data['x'], data['y'], data.get('angle', 0)):
|
||||
log_action(user_id, f"was cheating with final position ({data['x']}, {data['y']}) and final angle: {data['angle']}")
|
||||
# del players[user_id] # Remove the player from the game - we are in beta so idc
|
||||
emit('update_bird_positions', players, broadcast=True)
|
||||
|
||||
@socketio.on('disconnect')
|
||||
@login_required
|
||||
def handle_disconnect(data):
|
||||
user_id = current_user.get_id()
|
||||
if user_id in players:
|
||||
del players[user_id]
|
||||
emit('update_bird_positions', players, broadcast=True)
|
||||
35
training/srdnlenctf-2025/sparklingsky/src/game/utils.py
Normal file
35
training/srdnlenctf-2025/sparklingsky/src/game/utils.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from .models import db, User
|
||||
import secrets
|
||||
import string
|
||||
from uuid import uuid4 as userID
|
||||
|
||||
def init_db():
|
||||
if User.query.first() is None:
|
||||
for i in range(10):
|
||||
username = 'user' + str(userID())
|
||||
password = ''.join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(16))
|
||||
user = User(username=username, password=password, color=secrets.choice(['black', 'blue', 'white', 'green', 'red', 'grey', 'yellow', 'cyan', 'orange', 'pink']), is_playing=True)
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
user = User(username='user1337', password='user1337', color=secrets.choice(['black', 'blue', 'white', 'green', 'red', 'grey', 'yellow', 'cyan', 'orange', 'pink']))
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
|
||||
def get_players():
|
||||
current_players = User.query.filter_by(is_playing=True).with_entities(User.id).all()
|
||||
current_players = [user_id[0] for user_id in current_players]
|
||||
return current_players
|
||||
|
||||
from random import randint, uniform
|
||||
|
||||
def update_birds_from_db():
|
||||
players = {}
|
||||
current_players = get_players()
|
||||
for user_id in current_players:
|
||||
players[user_id] = {
|
||||
'x': randint(0,500),
|
||||
'y': randint(0,500),
|
||||
'color': 'black', # TODO: implement color from db
|
||||
'angle': uniform(0,6)
|
||||
}
|
||||
return players
|
||||
Reference in New Issue
Block a user