简易本地可执行版本

lzh
Kenneth 4 weeks ago
parent 241a6f95c6
commit 86ab82ec9e

@ -1,13 +1,30 @@
from flask import Flask, render_template, request, redirect, url_for, session
from flask import Flask, request, jsonify, send_from_directory
import os 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 = Flask(__name__)
app.secret_key = 'your_secret_key' # 用于会话管理,请替换为更安全的密钥 app.secret_key = os.urandom(24) # 生成更安全的会话密钥
app.config['UPLOAD_FOLDER'] = 'uploads' # 设置上传文件存储目录 app.config['UPLOAD_FOLDER'] = 'uploads/' # 设置上传文件存储目录
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) # 确保目录存在 os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) # 确保目录存在
# EXTERNAL_SCOUT_URL = 'http://192.168.78.178:5000/' # 外部侦查者页面URL # 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']) @app.route('/upload', methods=['POST'])
@ -17,14 +34,15 @@ def upload_file():
file = request.files['file'] file = request.files['file']
if file.filename == '': if file.filename == '':
return jsonify({'message': 'No selected file'}), 400 return jsonify({'message': 'No selected file'}), 400
if file: if file and allowed_file(file.filename):
filepath = os.path.join(app.config['UPLOAD_FOLDER'], file.filename) filename = secure_filename(f"{uuid.uuid4().hex}_{file.filename}")
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(filepath) file.save(filepath)
return jsonify({'message': 'File uploaded successfully', 'filepath': filepath}), 201 return jsonify({'message': 'File uploaded successfully', 'filepath': filepath}), 201
else:
return jsonify({'message': 'File type not allowed'}), 400
# 提供上传文件的访问 # 提供上传文件的访问
@app.route('/uploads/<filename>') @app.route('/uploads/<filename>')
def uploaded_file(filename): def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename) return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
@ -35,8 +53,6 @@ def login():
if request.method == 'POST': if request.method == 'POST':
username = request.form['username'] username = request.form['username']
password = request.form['password'] password = request.form['password']
# 在这里添加你的认证逻辑(例如,从数据库验证用户名和密码)
# 假设我们总是接受任何用户名和密码为'admin'的登录
if username == 'admin' and password == 'admin': if username == 'admin' and password == 'admin':
role = request.form['role'] role = request.form['role']
session['username'] = username session['username'] = username
@ -51,7 +67,6 @@ def login():
return "Invalid credentials. Please try again." return "Invalid credentials. Please try again."
return render_template('login.html') return render_template('login.html')
# 侦查者页面 # 侦查者页面
@app.route('/scout') @app.route('/scout')
def scout(): def scout():
@ -59,22 +74,75 @@ def scout():
return redirect(url_for('login')) return redirect(url_for('login'))
return render_template('scout.html') return render_template('scout.html')
# 指挥者页面 # 指挥者页面
@app.route('/commander') @app.route('/commander')
def commander(): def commander():
if 'username' not in session or session['role'] != '指挥者': if 'username' not in session or session['role'] != '指挥者':
return redirect(url_for('login')) return redirect(url_for('login'))
return render_template('commander.html')
# 获取特定目录下的所有文件和攻击坐标状态
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') @app.route('/attacker')
def attacker(): def attacker():
if 'username' not in session or session['role'] != '攻击者': if 'username' not in session or session['role'] != '攻击者':
return redirect(url_for('login')) return redirect(url_for('login'))
return render_template('attacker.html')
# 获取攻击坐标列表
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/<int:attack_id>', 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') @app.route('/logout')
@ -83,49 +151,54 @@ def logout():
session.pop('role', None) session.pop('role', None)
return redirect(url_for('login')) return redirect(url_for('login'))
# 发送消息
from werkzeug.utils import secure_filename
import uuid
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/send_message', methods=['GET', 'POST']) @app.route('/send_message', methods=['GET', 'POST'])
def send_message(): def send_message():
if request.method == 'POST': if request.method == 'POST':
# 处理照片上传
if 'photo' in request.files:
file = request.files['photo']
if file.filename == '':
return "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)
photo_url = url_for('uploaded_file', filename=filename, _external=True)
else:
return "Allowed file types are png, jpg, jpeg, gif", 400
else:
photo_url = None
# 处理消息文本上传
message = request.form.get('message') message = request.form.get('message')
if not message: if not message:
return "No message provided", 400 return "No message provided", 400
# 在这里处理消息和照片的存储或进一步处理 photo_url = None
# 例如将消息和照片URL存储到数据库 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 f"Message and photo (if uploaded) have been received. Message: {message}\nPhoto URL: {photo_url if photo_url else 'N/A'}"
# 如果是GET请求渲染发送消息的表单
return render_template('send_message.html') 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__': if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=8000) app.run(debug=True, host='0.0.0.0', port=8000)

@ -0,0 +1,9 @@
# models.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
role = db.Column(db.String(20), nullable=False) # 角色字段,例如 '指挥者' 或 '成员'

@ -4,7 +4,24 @@
<title>攻击者界面</title> <title>攻击者界面</title>
</head> </head>
<body> <body>
<h1>攻击者界面</h1> <h1>攻击坐标列表</h1>
<h2>功能待实现</h2> <ul>
{% if attacks %}
{% for attack in attacks %}
<li>
<strong>坐标:</strong> {{ attack.coordinate }} - <em>{{ attack.created_at }}</em>
{% if not attack.attacked %}
<form action="{{ url_for('execute_attack', attack_id=attack.id) }}" method="post" style="display:inline;">
<button type="submit">打击</button>
</form>
{% else %}
<span>已完成打击</span>
{% endif %}
</li>
{% endfor %}
{% else %}
<li>No attack coordinates available.</li>
{% endif %}
</ul>
</body> </body>
</html> </html>

@ -4,11 +4,43 @@
<title>指挥者界面</title> <title>指挥者界面</title>
</head> </head>
<body> <body>
<h1>指挥者查看照片</h1> <h1>指挥者界面</h1>
<h2>发送攻击坐标</h2>
<form action="{{ url_for('send_attack') }}" method="post">
<label for="coordinate">攻击坐标:</label>
<input type="text" id="coordinate" name="coordinate" required>
<button type="submit">发送消息</button>
</form>
<h2>攻击坐标状态</h2>
<ul> <ul>
{% for media in media_items %} {% if attacks %}
<li><img src="{{ url_for('static', filename=media.filename) }}" width="100"></li> {% for attack in attacks %}
{% endfor %} <li>
<strong>坐标:</strong> {{ attack.coordinate }}
- <em>{{ attack.created_at }}</em>
- <span>{% if attack.attacked %}已完成打击{% else %}等待打击{% endif %}</span>
</li>
{% endfor %}
{% else %}
<li>No attack coordinates available.</li>
{% endif %}
</ul>
<h2>查看照片</h2>
<ul>
{% if media_items %}
{% for filename in media_items %}
<li>
<a href="{{ url_for('uploaded_file', filename=filename) }}" target="_blank">
<img src="{{ url_for('uploaded_file', filename=filename) }}" width="100">
</a>
</li>
{% endfor %}
{% else %}
<li>No images found in the directory.</li>
{% endif %}
</ul> </ul>
</body> </body>
</html> </html>

@ -0,0 +1,14 @@
<!-- templates/upload.html -->
<!DOCTYPE html>
<html>
<head>
<title>上传照片</title>
</head>
<body>
<h1>上传照片</h1>
<form method="POST" action="{{ url_for('upload') }}" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="上传">
</form>
</body>
</html>

@ -0,0 +1,6 @@
# test.py
from models import db, User
user = User(username='commander', role='指挥者')
db.session.add(user)
db.session.commit()

@ -0,0 +1,52 @@
from flask import Flask, request, jsonify
from flask_mysqldb import MySQL
import MySQLdb.cursors
app = Flask(__name__)
# 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)
# 添加消息和照片
@app.route('/message', methods=['POST'])
def add_message():
message = request.form['message']
photo = request.files['photo']
# 读取照片内容
photo_data = photo.read()
# 插入数据到 MySQL
cursor = mysql.connection.cursor()
cursor.execute("INSERT INTO messages (message, photo) VALUES (%s, %s)", (message, photo_data))
mysql.connection.commit()
cursor.close()
return jsonify({'status': 'success'}), 201
# 获取所有消息
@app.route('/messages', methods=['GET'])
def get_messages():
cursor = mysql.connection.cursor()
cursor.execute("SELECT id, message, created_at FROM messages") # 不直接查询照片以提高性能
result = cursor.fetchall()
cursor.close()
messages = []
for row in result:
messages.append({
'id': row['id'],
'message': row['message'],
'created_at': row['created_at']
})
return jsonify(messages)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Loading…
Cancel
Save