import os import uuid from flask import Flask, session, redirect, url_for, request, flash, render_template, jsonify, send_from_directory from flask_sqlalchemy import SQLAlchemy from flask_mysqldb import MySQL import MySQLdb.cursors from werkzeug.utils import secure_filename app = Flask(__name__) app.secret_key = os.urandom(24) # 生成更安全的会话密钥 app.config['UPLOAD_FOLDER'] = 'uploads/' # 设置上传文件存储目录 os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) # 确保目录存在 # MySQL 配置 app.config['MYSQL_HOST'] = 'localhost' app.config['MYSQL_USER'] = 'root' # 替换为你的 MySQL 用户名 app.config['MYSQL_PASSWORD'] = 'lin556688' # 替换为你的 MySQL 密码 app.config['MYSQL_DB'] = 'mydatabase' app.config['MYSQL_CURSORCLASS'] = 'DictCursor' mysql = MySQL(app) ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS # 处理文件上传 @app.route('/upload', methods=['POST']) def upload_file(): if 'file' not in request.files: return jsonify({'message': 'No file part'}), 400 file = request.files['file'] if file.filename == '': return jsonify({'message': 'No selected file'}), 400 if file and allowed_file(file.filename): filename = secure_filename(f"{uuid.uuid4().hex}_{file.filename}") filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save(filepath) return jsonify({'message': 'File uploaded successfully', 'filepath': filepath}), 201 else: return jsonify({'message': 'File type not allowed'}), 400 # 提供上传文件的访问 @app.route('/uploads/') def uploaded_file(filename): return send_from_directory(app.config['UPLOAD_FOLDER'], filename) # 登录页面 @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] if username == 'admin' and password == 'admin': role = request.form['role'] session['username'] = username session['role'] = role if role == '侦查者': return redirect(url_for('scout')) elif role == '指挥者': return redirect(url_for('commander')) elif role == '攻击者': return redirect(url_for('attacker')) else: return "Invalid credentials. Please try again." return render_template('login.html') # 侦查者页面 @app.route('/scout') def scout(): if 'username' not in session or session['role'] != '侦查者': return redirect(url_for('login')) return render_template('scout.html') # 指挥者页面 @app.route('/commander') def commander(): if 'username' not in session or session['role'] != '指挥者': return redirect(url_for('login')) # 获取特定目录下的所有文件和攻击坐标状态 directory = 'E:/_Ufo/0000jiegou/TheBattleCar/uploads' media_items = [] try: media_items = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f)) and allowed_file(f)] except Exception as e: flash(f"Error accessing directory: {str(e)}") # 获取攻击状态 cursor = mysql.connection.cursor() cursor.execute("SELECT id, coordinate, attacked, created_at FROM attacks ORDER BY created_at DESC") attacks = cursor.fetchall() cursor.close() return render_template('commander.html', media_items=media_items, attacks=attacks) # 指挥者发送攻击坐标 @app.route('/send_attack', methods=['POST']) def send_attack(): if 'username' not in session or session['role'] != '指挥者': return redirect(url_for('login')) coordinate = request.form.get('coordinate') if not coordinate: return "No coordinate provided", 400 # 插入攻击坐标到数据库 cursor = mysql.connection.cursor() cursor.execute("INSERT INTO attacks (coordinate) VALUES (%s)", (coordinate,)) mysql.connection.commit() cursor.close() flash('攻击坐标已发送') return redirect(url_for('commander')) # 攻击者页面 @app.route('/attacker') def attacker(): if 'username' not in session or session['role'] != '攻击者': return redirect(url_for('login')) # 获取攻击坐标列表 cursor = mysql.connection.cursor() cursor.execute("SELECT id, coordinate, created_at FROM attacks ORDER BY created_at DESC") attacks = cursor.fetchall() cursor.close() return render_template('attacker.html', attacks=attacks) # 攻击者执行攻击 @app.route('/execute_attack/', methods=['POST']) def execute_attack(attack_id): if 'username' not in session or session['role'] != '攻击者': return redirect(url_for('login')) cursor = mysql.connection.cursor() cursor.execute("UPDATE attacks SET attacked = TRUE WHERE id = %s", (attack_id,)) mysql.connection.commit() cursor.close() flash(f'已对坐标ID为 {attack_id} 的目标完成打击') return redirect(url_for('attacker')) # 退出登录(清除会话) @app.route('/logout') def logout(): session.pop('username', None) session.pop('role', None) return redirect(url_for('login')) # 发送消息 @app.route('/send_message', methods=['GET', 'POST']) def send_message(): if request.method == 'POST': message = request.form.get('message') if not message: return "No message provided", 400 photo_url = None if 'photo' in request.files: file = request.files['photo'] if file.filename != '': if file and allowed_file(file.filename): filename = secure_filename(f"{uuid.uuid4().hex}_{file.filename}") filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save(filepath) photo_url = url_for('uploaded_file', filename=filename, _external=True) else: return "Allowed file types are png, jpg, jpeg, gif", 400 # 插入数据到 MySQL cursor = mysql.connection.cursor() cursor.execute("INSERT INTO messages (message, photo_url) VALUES (%s, %s)", (message, photo_url)) mysql.connection.commit() cursor.close() return f"Message and photo (if uploaded) have been received. Message: {message}\nPhoto URL: {photo_url if photo_url else 'N/A'}" return render_template('send_message.html') # 获取所有消息 @app.route('/messages', methods=['GET']) def get_messages(): cursor = mysql.connection.cursor() cursor.execute("SELECT id, message, photo_url, created_at FROM messages") result = cursor.fetchall() cursor.close() messages = [] for row in result: messages.append({ 'id': row['id'], 'message': row['message'], 'photo_url': row['photo_url'], 'created_at': row['created_at'] }) return jsonify(messages) if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=8000)