125 lines
5.1 KiB
Python
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
|
|
|
|
|