syntaxwebsite/app/routes/presenceapi.py

105 lines
4.0 KiB
Python

from flask import Blueprint, render_template, request, redirect, url_for, flash, session, abort, jsonify, make_response
from app.util import auth
from app.extensions import db, csrf, limiter
from flask_wtf.csrf import CSRFError, generate_csrf
from datetime import datetime, timedelta
from app.models.user_email import UserEmail
from app.models.user import User
from app.models.placeserver_players import PlaceServerPlayer
from app.models.placeservers import PlaceServer
from app.models.place import Place
from app.models.asset import Asset
PresenceAPIRoute = Blueprint('presenceapiroute', __name__, url_prefix='/')
csrf.exempt(PresenceAPIRoute)
@PresenceAPIRoute.errorhandler(CSRFError)
def handle_csrf_error(e):
ErrorResponse = make_response(jsonify({
"errors": [
{
"code": 0,
"message": "Token Validation Failed"
}
]
}))
ErrorResponse.status_code = 403
ErrorResponse.headers["x-csrf-token"] = generate_csrf()
return ErrorResponse
@PresenceAPIRoute.errorhandler(429)
def handle_ratelimit_reached(e):
return jsonify({
"errors": [
{
"code": 9,
"message": "The flood limit has been exceeded."
}
]
}), 429
@PresenceAPIRoute.before_request
def before_request():
if "Roblox/" not in request.user_agent.string:
csrf.protect()
@PresenceAPIRoute.route("/v1/presence/users", methods=["POST"])
@auth.authenticated_required_api
@limiter.limit("30/minute")
def multi_get_users_presence():
if not request.is_json:
return jsonify({"errors": [{"code": 0,"message": "Invalid Request"}]}), 400
if "userIds" not in request.json:
return jsonify({"errors": [{"code": 0,"message": "Invalid Request"}]}), 400
userIds = request.json["userIds"]
if type(userIds) is not list:
return jsonify({"errors": [{"code": 0,"message": "Invalid Request"}]}), 400
if len(userIds) > 100:
return jsonify({"errors": [{"code": 0,"message": "Invalid Request"}]}), 400
requestedData = []
for userId in userIds:
try:
userId = int(userId)
except:
return jsonify({"errors": [{"code": 1,"message": "Invalid UserId"}]}), 400
userObject : User = User.query.filter_by(id=userId).first()
if userObject is None:
return jsonify({"errors": [{"code": 1,"message": "Invalid UserId"}]}), 400
else:
isUserOnline = userObject.lastonline > datetime.utcnow() - timedelta(minutes=1)
UserPlaceServerPlayerObj : PlaceServerPlayer | None = PlaceServerPlayer.query.filter_by( userid = userId ).first()
isUserInGame = UserPlaceServerPlayerObj is not None
userPresenceType = 2 if isUserInGame else 1 if isUserOnline else 0
PlaceServerHost : PlaceServer | None = None
PlaceObject : Place | None = None
if isUserInGame:
PlaceServerHost : PlaceServer = PlaceServer.query.filter_by( serveruuid = UserPlaceServerPlayerObj.serveruuid ).first()
if PlaceServerHost is not None:
PlaceObject : Place = Place.query.filter_by( placeid = PlaceServerHost.serverPlaceId ).first()
PlaceAssetObj : Asset = PlaceObject.assetObj
else:
PlaceAssetObj = None
UserPlaceServerPlayerObj = None
requestedData.append({
"userPresenceType": userPresenceType,
"lastLocation": "Website" if not isUserInGame else PlaceAssetObj.name,
"placeId": PlaceAssetObj.id if isUserInGame else None,
"rootPlaceId": PlaceAssetObj.id if isUserInGame else None,
"gameId": PlaceServerHost.serveruuid if isUserInGame else None,
"userId": userId,
"lastOnline": userObject.lastonline.strftime("%Y-%m-%dT%H:%M:%S.000Z"),
})
return jsonify({
"userPresences": requestedData
}), 200