syntaxwebsite/app/routes/legacydatapersistence.py

125 lines
5.1 KiB
Python

from flask import Blueprint, render_template, request, redirect, url_for, flash, make_response, jsonify, abort, after_this_request
from config import Config
from app.models.user import User
from app.models.gameservers import GameServer
from app.models.place import Place
from app.models.universe import Universe
from app.models.legacy_data_persistence import LegacyDataPersistence
from app.extensions import redis_controller, get_remote_address, csrf, limiter, db
from datetime import datetime
import logging
import gzip
LegacyDataPersistenceRoute = Blueprint('legacyDataPersistence', __name__, url_prefix='/persistence/legacy')
@LegacyDataPersistenceRoute.before_request
def before_request():
if "Roblox/" not in request.user_agent.string:
logging.info(f"LegacyDataPersistence - UserAgent {request.user_agent} - Not allowed")
abort(404)
RemoteAddress = get_remote_address()
GameServerObj : GameServer = GameServer.query.filter_by( serverIP = RemoteAddress ).first()
if GameServerObj is None:
logging.info(f"LegacyDataPersistence - {RemoteAddress} - Not found")
abort(404)
if "Roblox-Place-Id" not in request.headers and "placeId" not in request.args:
logging.info(f"LegacyDataPersistence - GameServer {RemoteAddress} - Roblox-Place-Id header and cookie not found")
abort(404)
PlaceId = request.headers.get( key = "Roblox-Place-Id", default = None, type = int ) or request.args.get( key = "placeId", default = None, type = int )
if PlaceId is None:
logging.info(f"LegacyDataPersistence - GameServer {RemoteAddress} - Roblox-Place-Id header or arg not expected type")
abort(404)
PlaceObj : Place = Place.query.filter_by( placeid = PlaceId ).first()
if PlaceObj is None:
logging.info(f"LegacyDataPersistence - Place {PlaceId} - Place not found")
abort(404)
@LegacyDataPersistenceRoute.route('/load', methods=['POST', 'GET'])
@csrf.exempt
def LoadData():
PlaceId = request.headers.get( key = "Roblox-Place-Id", default = None, type = int ) or request.args.get( key = "placeId", default = None, type = int )
RequestedUserId = request.args.get(
key = "userId",
default = None,
type = int
)
if RequestedUserId is None:
return "Invalid request", 400
UserObj : User = User.query.filter_by( id = RequestedUserId ).first()
if UserObj is None:
return "Invalid request", 400
PlaceObj : Place = Place.query.filter_by( placeid = PlaceId ).first()
if PlaceObj is None:
return "Invalid request", 400
UniverseObj : Universe = Universe.query.filter_by( id = PlaceObj.parent_universe_id ).first()
if UniverseObj is None:
return "Invalid request", 400
LegacyDataPersistenceObj : LegacyDataPersistence = LegacyDataPersistence.query.filter_by(
userid = RequestedUserId,
universe_id = UniverseObj.id
).first()
logging.info(f"LegacyDataPersistence - User {UserObj.id} - Place {PlaceId} - Universe {UniverseObj.id} - Data requested")
if LegacyDataPersistenceObj is None:
return "", 200
return gzip.decompress(LegacyDataPersistenceObj.data), 200
@LegacyDataPersistenceRoute.route('/save', methods=['POST'])
@csrf.exempt
def SaveData():
PlaceId = request.headers.get( key = "Roblox-Place-Id", default = None, type = int ) or request.args.get( key = "placeId", default = None, type = int )
PayloadData = request.data
if request.content_encoding != "gzip":
PayloadData = gzip.compress( PayloadData )
RequestedUserId = request.args.get(
key = "userId",
default = None,
type = int
)
if RequestedUserId is None:
return "Invalid request", 400
UserObj : User = User.query.filter_by( id = RequestedUserId ).first()
if UserObj is None:
return "Invalid request", 400
if len(PayloadData) > 1024 * 1024 * 2:
logging.info(f"LegacyDataPersistence - User {UserObj.id} - Place {PlaceId} - Universe {UniverseObj.id} - Payload too large, {len(PayloadData)} bytes")
return "Payload too large", 400
PlaceObj : Place = Place.query.filter_by( placeid = PlaceId ).first()
if PlaceObj is None:
return "Invalid request", 400
UniverseObj : Universe = Universe.query.filter_by( id = PlaceObj.parent_universe_id ).first()
if UniverseObj is None:
return "Invalid request", 400
LegacyDataPersistenceObj : LegacyDataPersistence = LegacyDataPersistence.query.filter_by(
userid = RequestedUserId,
universe_id = UniverseObj.id
).first()
if LegacyDataPersistenceObj is None:
LegacyDataPersistenceObj = LegacyDataPersistence(
placeid = PlaceId,
userid = RequestedUserId,
universe_id = UniverseObj.id
)
db.session.add( LegacyDataPersistenceObj )
LegacyDataPersistenceObj.data = PayloadData
LegacyDataPersistenceObj.last_updated = datetime.utcnow()
db.session.commit()
logging.info(f"LegacyDataPersistence - User {UserObj.id} - Place {PlaceId} - Universe {UniverseObj.id} - Saved {len(LegacyDataPersistenceObj.data)} bytes")
return "OK", 200