This commit is contained in:
UnitedAirforce
2025-11-29 11:27:22 +08:00
parent fceb34944a
commit 3dc00bab0d
6 changed files with 27 additions and 22 deletions

View File

@@ -3,7 +3,7 @@ from starlette.routing import Route
from starlette.responses import HTMLResponse, JSONResponse, RedirectResponse from starlette.responses import HTMLResponse, JSONResponse, RedirectResponse
import sqlalchemy import sqlalchemy
import json import json
import datetime from datetime import datetime
from api.database import player_database, accounts, results, devices, whitelists, blacklists, batch_tokens, binds, webs, logs, is_admin, read_user_save_file, write_user_save_file from api.database import player_database, accounts, results, devices, whitelists, blacklists, batch_tokens, binds, webs, logs, is_admin, read_user_save_file, write_user_save_file
from api.misc import crc32_decimal from api.misc import crc32_decimal
@@ -67,7 +67,7 @@ async def web_admin_get_table(request: Request):
# Validate size # Validate size
if size < 10: if size < 10:
size = 10 size = 10
if size > 100: elif size > 100:
size = 100 size = 100
table, allowed_fields = TABLE_MAP[table_name] table, allowed_fields = TABLE_MAP[table_name]
@@ -199,12 +199,12 @@ async def web_admin_table_set(request: Request):
# Try to convert to datetime object # Try to convert to datetime object
try: try:
if isinstance(value, str): if isinstance(value, str):
dt_obj = datetime.datetime.fromisoformat(value) dt_obj = datetime.fromisoformat(value)
row_data[key] = dt_obj row_data[key] = dt_obj
elif isinstance(value, (int, float)): elif isinstance(value, (int, float)):
dt_obj = datetime.datetime.fromtimestamp(value) dt_obj = datetime.fromtimestamp(value)
row_data[key] = dt_obj row_data[key] = dt_obj
elif isinstance(value, datetime.datetime): elif isinstance(value, datetime):
pass # already datetime pass # already datetime
else: else:
raise ValueError raise ValueError
@@ -297,12 +297,12 @@ async def web_admin_table_insert(request: Request):
elif expected_type.startswith("DATETIME"): elif expected_type.startswith("DATETIME"):
try: try:
if isinstance(value, str): if isinstance(value, str):
dt_obj = datetime.datetime.fromisoformat(value) dt_obj = datetime.fromisoformat(value)
row_data[key] = dt_obj row_data[key] = dt_obj
elif isinstance(value, (int, float)): elif isinstance(value, (int, float)):
dt_obj = datetime.datetime.fromtimestamp(value) dt_obj = datetime.fromtimestamp(value)
row_data[key] = dt_obj row_data[key] = dt_obj
elif isinstance(value, datetime.datetime): elif isinstance(value, datetime):
pass pass
else: else:
raise ValueError raise ValueError
@@ -338,7 +338,7 @@ async def web_admin_data_save(request: Request):
save_data = params['data'] save_data = params['data']
crc = crc32_decimal(save_data) crc = crc32_decimal(save_data)
formatted_time = datetime.datetime.now() formatted_time = datetime.now()
query = accounts.update().where(accounts.c.id == uid).values(save_crc=crc, save_timestamp=formatted_time) query = accounts.update().where(accounts.c.id == uid).values(save_crc=crc, save_timestamp=formatted_time)
await player_database.execute(query) await player_database.execute(query)

View File

@@ -226,14 +226,14 @@ async def log_download(user_id, filename, filesize):
user_id=user_id, user_id=user_id,
filename=filename, filename=filename,
filesize=filesize, filesize=filesize,
timestamp=datetime.datetime.utcnow() timestamp=datetime.utcnow()
) )
await player_database.execute(query) await player_database.execute(query)
async def get_downloaded_bytes(user_id, hours): async def get_downloaded_bytes(user_id, hours):
query = select(sqlalchemy.func.sum(logs.c.filesize)).where( query = select(sqlalchemy.func.sum(logs.c.filesize)).where(
(logs.c.user_id == user_id) & (logs.c.user_id == user_id) &
(logs.c.timestamp >= datetime.datetime.utcnow() - datetime.timedelta(hours=hours)) (logs.c.timestamp >= datetime.utcnow() - timedelta(hours=hours))
) )
result = await player_database.fetch_one(query) result = await player_database.fetch_one(query)
return result[0] if result[0] is not None else 0 return result[0] if result[0] is not None else 0
@@ -247,7 +247,7 @@ async def verify_user_code(code, user_id):
(binds.c.bind_code == code) & (binds.c.bind_code == code) &
(binds.c.user_id == user_id) & (binds.c.user_id == user_id) &
(binds.c.is_verified == 0) & (binds.c.is_verified == 0) &
(binds.c.bind_date >= datetime.datetime.utcnow() - datetime.timedelta(minutes=10)) (binds.c.bind_date >= datetime.utcnow() - timedelta(minutes=10))
) )
result = await player_database.fetch_one(query) result = await player_database.fetch_one(query)
if not result: if not result:
@@ -304,14 +304,14 @@ async def user_name_to_user_info(username):
async def check_whitelist(decrypted_fields): async def check_whitelist(decrypted_fields):
device_id = decrypted_fields[b'vid'][0].decode() device_id = decrypted_fields[b'vid'][0].decode()
user_info, device_info = await decrypt_fields_to_user_info(decrypted_fields) user_info, _ = await decrypt_fields_to_user_info(decrypted_fields)
query = select(whitelists.c.device_id).where((whitelists.c.device_id == device_id) | (whitelists.c.device_id == user_info['username'])) query = select(whitelists.c.device_id).where((whitelists.c.device_id == device_id) | (whitelists.c.device_id == user_info['username']))
result = await player_database.fetch_one(query) result = await player_database.fetch_one(query)
return result is not None return result is not None
async def check_blacklist(decrypted_fields): async def check_blacklist(decrypted_fields):
device_id = decrypted_fields[b'vid'][0].decode() device_id = decrypted_fields[b'vid'][0].decode()
user_info, device_info = await decrypt_fields_to_user_info(decrypted_fields) user_info, _ = await decrypt_fields_to_user_info(decrypted_fields)
query = select(blacklists.c.ban_terms).where((blacklists.c.ban_terms == device_id) | (blacklists.c.ban_terms == user_info['username'])) query = select(blacklists.c.ban_terms).where((blacklists.c.ban_terms == device_id) | (blacklists.c.ban_terms == user_info['username']))
result = await player_database.fetch_one(query) result = await player_database.fetch_one(query)
return result is None return result is None

View File

@@ -1,5 +1,5 @@
from starlette.responses import HTMLResponse, JSONResponse from starlette.responses import JSONResponse
from starlette.requests import Request from starlette.requests import Request
from starlette.routing import Route from starlette.routing import Route
from datetime import datetime from datetime import datetime

View File

@@ -2,9 +2,6 @@ import smtplib
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from datetime import datetime from datetime import datetime
import uuid
from starlette.responses import JSONResponse
from config import SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD from config import SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD
@@ -28,7 +25,7 @@ def init_email():
async def send_email(to_addr, code, lang): async def send_email(to_addr, code, lang):
global server global server
title = {"en": "Project Taiyo - Email Verification", "zh": "项目 Taiyo - 邮件验证", "tc": "專案 Taiyo - 郵件驗證", "jp": "プロジェクト Taiyo - メール認証"} title = {"en": "Project Taiyo - Email Verification", "zh": "项目 Taiyo - 邮件验证", "tc": "專案 Taiyo - 郵件驗證", "jp": "プロジェクト Taiyo - メール認証"}
with open(f"api/web/email_{lang}.html", "r", encoding="utf-8") as file: with open(f"web/email_{lang}.html", "r", encoding="utf-8") as file:
body = file.read() body = file.read()
body = body.format(code=code) body = body.format(code=code)

View File

@@ -252,7 +252,7 @@ async def should_serve(decrypted_fields):
should_serve = await check_whitelist(decrypted_fields) and not await check_blacklist(decrypted_fields) should_serve = await check_whitelist(decrypted_fields) and not await check_blacklist(decrypted_fields)
if AUTHORIZATION_MODE and should_serve: if AUTHORIZATION_MODE and should_serve:
user_info, device_info = await decrypt_fields_to_user_info(decrypted_fields, "id") user_info, _ = await decrypt_fields_to_user_info(decrypted_fields)
bind_info = await get_bind(user_info["id"]) bind_info = await get_bind(user_info["id"])
if not bind_info or bind_info['is_verified'] != 1: if not bind_info or bind_info['is_verified'] != 1:
should_serve = False should_serve = False

View File

@@ -366,12 +366,20 @@ async def convert_db():
all_devices = await old_database.fetch_all(select(old_metadata.tables["daily_reward"])) all_devices = await old_database.fetch_all(select(old_metadata.tables["daily_reward"]))
all_devices = [dict(d) for d in all_devices] all_devices = [dict(d) for d in all_devices]
for device in all_devices: for device in all_devices:
connected_user = await old_database.fetch_one( connected_old_user = await old_database.fetch_one(
select(old_metadata.tables["user"]).where(old_metadata.tables["user"].c.device_id == device['device_id']) select(old_metadata.tables["user"]).where(old_metadata.tables["user"].c.device_id == device['device_id'])
) )
new_user_id = None
old_user_username = connected_old_user['username'] if connected_old_user else None
if old_user_username:
connected_user = await player_database.fetch_one(
select(accounts).where(accounts.c.username == old_user_username)
)
new_user_id = connected_user['id'] if connected_user else None
insert_query = insert(devices).values( insert_query = insert(devices).values(
device_id=device['device_id'], device_id=device['device_id'],
user_id=connected_user['id'] if connected_user else None, user_id=new_user_id,
my_stage=device['my_stage'], my_stage=device['my_stage'],
my_avatar=device['my_avatar'], my_avatar=device['my_avatar'],
item=device['item'], item=device['item'],