ye
This commit is contained in:
+12
-55
@@ -22,12 +22,9 @@ from app.models.place import Place
|
|||||||
from app.models.asset import Asset
|
from app.models.asset import Asset
|
||||||
from app.models.login_records import LoginRecord
|
from app.models.login_records import LoginRecord
|
||||||
from app.models.user_hwid_log import UserHWIDLog
|
from app.models.user_hwid_log import UserHWIDLog
|
||||||
from app.models.user_ban import UserBan
|
|
||||||
from app.models.admin_permissions import AdminPermissions
|
|
||||||
from app.models.universe import Universe
|
from app.models.universe import Universe
|
||||||
from app.models.asset_version import AssetVersion
|
from app.models.asset_version import AssetVersion
|
||||||
from app.enums.AssetType import AssetType
|
from app.enums.AssetType import AssetType
|
||||||
from app.enums.BanType import BanType
|
|
||||||
from app.enums.MembershipType import MembershipType
|
from app.enums.MembershipType import MembershipType
|
||||||
from app.enums.PlaceYear import PlaceYear
|
from app.enums.PlaceYear import PlaceYear
|
||||||
from app.services.gameserver_comm import perform_post
|
from app.services.gameserver_comm import perform_post
|
||||||
@@ -199,7 +196,6 @@ def CreateNewPlaceServer( placeId : int, reserved_server_access_code : str = Non
|
|||||||
serverIP = SelectedGameServerObj.serverIP,
|
serverIP = SelectedGameServerObj.serverIP,
|
||||||
serverPort = OpenJobReqJSON["port"],
|
serverPort = OpenJobReqJSON["port"],
|
||||||
serverPlaceId = placeId,
|
serverPlaceId = placeId,
|
||||||
serverRunningTime = 1,
|
|
||||||
maxPlayerCount = PlaceObj.maxplayers,
|
maxPlayerCount = PlaceObj.maxplayers,
|
||||||
reservedServerAccessCode = reserved_server_access_code
|
reservedServerAccessCode = reserved_server_access_code
|
||||||
)
|
)
|
||||||
@@ -245,7 +241,7 @@ def GetSuitablePlaceServer( placeId : int ) -> PlaceServer | bool:
|
|||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return NewPlaceServerObj
|
return False
|
||||||
|
|
||||||
GameJoinRoute = Blueprint('gamejoin', __name__, url_prefix='/')
|
GameJoinRoute = Blueprint('gamejoin', __name__, url_prefix='/')
|
||||||
|
|
||||||
@@ -320,48 +316,6 @@ def ReturnPlaceLauncher( message : str, status : int, authenticated_userid : int
|
|||||||
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
|
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def BanUsersForSharedHwid(hwid: str, triggering_user_id: int | None = None) -> bool:
|
|
||||||
MatchingHWIDLogs : list[UserHWIDLog] = UserHWIDLog.query.filter_by(hwid=hwid).distinct(UserHWIDLog.user_id).all()
|
|
||||||
if len(MatchingHWIDLogs) < 2:
|
|
||||||
return False
|
|
||||||
|
|
||||||
MatchingUserIds = {log.user_id for log in MatchingHWIDLogs if log.user_id is not None}
|
|
||||||
if len(MatchingUserIds) < 2:
|
|
||||||
return False
|
|
||||||
|
|
||||||
for user_id in MatchingUserIds:
|
|
||||||
UserObj : User | None = User.query.filter_by(id=user_id).first()
|
|
||||||
if UserObj is None:
|
|
||||||
continue
|
|
||||||
if AdminPermissions.query.filter_by(userid=UserObj.id).first() is not None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
for user_id in MatchingUserIds:
|
|
||||||
UserObj : User | None = User.query.filter_by(id=user_id).first()
|
|
||||||
if UserObj is None:
|
|
||||||
continue
|
|
||||||
if UserObj.accountstatus != 1:
|
|
||||||
continue
|
|
||||||
ExistingActiveBan : UserBan | None = UserBan.query.filter_by(userid=UserObj.id, acknowledged=False).order_by(UserBan.id.desc()).first()
|
|
||||||
if ExistingActiveBan is not None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
BanObj = UserBan(
|
|
||||||
userid=UserObj.id,
|
|
||||||
author_userid=1,
|
|
||||||
reason="Alting is not permitted on NEXIUM, contact us if you believe this is unfair",
|
|
||||||
ban_type=BanType.Deleted,
|
|
||||||
moderator_note=f"Automatic HWID alt ban for shared HWID {hwid}",
|
|
||||||
expires_at=None
|
|
||||||
)
|
|
||||||
db.session.add(BanObj)
|
|
||||||
UserObj.accountstatus = 3
|
|
||||||
|
|
||||||
if MatchingUserIds:
|
|
||||||
db.session.commit()
|
|
||||||
return True
|
|
||||||
|
|
||||||
@GameJoinRoute.route('/game/PlaceLauncher.ashx', methods=['GET', 'POST'])
|
@GameJoinRoute.route('/game/PlaceLauncher.ashx', methods=['GET', 'POST'])
|
||||||
@GameJoinRoute.route('/Game/PlaceLauncher.ashx', methods=['GET', 'POST'])
|
@GameJoinRoute.route('/Game/PlaceLauncher.ashx', methods=['GET', 'POST'])
|
||||||
@GameJoinRoute.route('/game/placelauncher.ashx', methods=['GET', 'POST'])
|
@GameJoinRoute.route('/game/placelauncher.ashx', methods=['GET', 'POST'])
|
||||||
@@ -369,7 +323,7 @@ def BanUsersForSharedHwid(hwid: str, triggering_user_id: int | None = None) -> b
|
|||||||
@csrf.exempt
|
@csrf.exempt
|
||||||
def placelauncher():
|
def placelauncher():
|
||||||
if not websiteFeatures.GetWebsiteFeature("GameJoinAPI"):
|
if not websiteFeatures.GetWebsiteFeature("GameJoinAPI"):
|
||||||
logging.warning("opsec")
|
return ReturnPlaceLauncher("GameJoinAPI is disabled", 12)
|
||||||
|
|
||||||
AuthenticatdUser = None
|
AuthenticatdUser = None
|
||||||
placeid = request.args.get( key = 'placeId', default = None, type = int) or request.args.get( key = 'placeid', default = None, type = int)
|
placeid = request.args.get( key = 'placeId', default = None, type = int) or request.args.get( key = 'placeid', default = None, type = int)
|
||||||
@@ -392,6 +346,12 @@ def placelauncher():
|
|||||||
if authticketInfo is None and AuthenticatdUser is None:
|
if authticketInfo is None and AuthenticatdUser is None:
|
||||||
return ReturnPlaceLauncher("Invalid authentication ticket", 12)
|
return ReturnPlaceLauncher("Invalid authentication ticket", 12)
|
||||||
|
|
||||||
|
#UserIPHash = hashlib.md5(get_remote_address().encode("utf-8")).hexdigest()
|
||||||
|
#LoginRecords : list[LoginRecord] = LoginRecord.query.filter(LoginRecord.ip == UserIPHash).distinct(LoginRecord.userid).all()
|
||||||
|
#for record in LoginRecords:
|
||||||
|
# if record.User.accountstatus != 1:
|
||||||
|
# return ReturnPlaceLauncher("Invalid authentication ticket", 12)
|
||||||
|
|
||||||
userId = int(authticketInfo) if authticketInfo is not None else AuthenticatdUser.id
|
userId = int(authticketInfo) if authticketInfo is not None else AuthenticatdUser.id
|
||||||
if PlaceServerPlayer.query.filter_by(userid=userId).first() is not None and not isTeleport:
|
if PlaceServerPlayer.query.filter_by(userid=userId).first() is not None and not isTeleport:
|
||||||
CurrentPlaceServerPlayerObj : PlaceServerPlayer = PlaceServerPlayer.query.filter_by(userid=userId).first()
|
CurrentPlaceServerPlayerObj : PlaceServerPlayer = PlaceServerPlayer.query.filter_by(userid=userId).first()
|
||||||
@@ -428,9 +388,6 @@ def placelauncher():
|
|||||||
|
|
||||||
redis_controller.delete(f"hwid:{str(Tracking_Cookie)}")
|
redis_controller.delete(f"hwid:{str(Tracking_Cookie)}")
|
||||||
|
|
||||||
if BanUsersForSharedHwid(UserHWIDHash, UserObj.id):
|
|
||||||
return ReturnPlaceLauncher("Invalid session", 12)
|
|
||||||
|
|
||||||
UserMembershipStatus : MembershipType = GetUserMembership(UserObj)
|
UserMembershipStatus : MembershipType = GetUserMembership(UserObj)
|
||||||
if UniverseObj.bc_required and UserMembershipStatus == MembershipType.NonBuildersClub:
|
if UniverseObj.bc_required and UserMembershipStatus == MembershipType.NonBuildersClub:
|
||||||
return ReturnPlaceLauncher("Builders Club required", 12)
|
return ReturnPlaceLauncher("Builders Club required", 12)
|
||||||
@@ -462,10 +419,11 @@ def placelauncher():
|
|||||||
if PlaceServerObj is False:
|
if PlaceServerObj is False:
|
||||||
logging.info(f"Placelauncher.ashx : {str(placeid)} : {UserObj.username} [{UserObj.id}] : No available place servers found yet")
|
logging.info(f"Placelauncher.ashx : {str(placeid)} : {UserObj.username} [{UserObj.id}] : No available place servers found yet")
|
||||||
return ReturnPlaceLauncher(None, 1, authenticated_userid=userId)
|
return ReturnPlaceLauncher(None, 1, authenticated_userid=userId)
|
||||||
|
redis_controller.delete(f"authticket:{ticket}")
|
||||||
authenticatedTicketUUID = str(uuid.uuid4())
|
authenticatedTicketUUID = str(uuid.uuid4())
|
||||||
redis_controller.setex(f"place:{placeid}:ticket:{authenticatedTicketUUID}", 60, json.dumps({"id": userId, "jobid": str(PlaceServerObj.serveruuid)}))
|
redis_controller.setex(f"place:{placeid}:ticket:{authenticatedTicketUUID}", 60, json.dumps({"id": userId, "jobid": str(PlaceServerObj.serveruuid)}))
|
||||||
|
|
||||||
authticket = ''.join(random.choices(string.ascii_uppercase + string.digits, k=256))
|
authticket = ''.join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(256))
|
||||||
redis_controller.set(f"authticket:{authticket}", userId, 60*10)
|
redis_controller.set(f"authticket:{authticket}", userId, 60*10)
|
||||||
resp = make_response(jsonify({
|
resp = make_response(jsonify({
|
||||||
"jobId": PlaceServerObj.serveruuid,
|
"jobId": PlaceServerObj.serveruuid,
|
||||||
@@ -613,7 +571,7 @@ def GenerateClientTicket( UserObj : User, JobId : str, CharacterURL : str = None
|
|||||||
if TicketVersion == 2:
|
if TicketVersion == 2:
|
||||||
CharacterURL = str(UserObj.id)
|
CharacterURL = str(UserObj.id)
|
||||||
elif TicketVersion == 1:
|
elif TicketVersion == 1:
|
||||||
CharacterURL = Config.BaseURL + "/Asset/CharacterFetch.ashx?userId=" + str(UserObj.id) # f"http://www.nexium.fit/v1.1/avatar-fetch?userId={str(UserObj.id)}&placeId={str(PlaceId)}"
|
CharacterURL = Config.BaseURL + "/Asset/CharacterFetch.ashx?userId=" + str(UserObj.id) # f"http://www.vortexi.cc/v1.1/avatar-fetch?userId={str(UserObj.id)}&placeId={str(PlaceId)}"
|
||||||
elif TicketVersion == 4:
|
elif TicketVersion == 4:
|
||||||
CharacterURL = f"http://www.nexium.fit/v1/avatar-fetch?userId={str(UserObj.id)}&placeId={str(PlaceId)}"
|
CharacterURL = f"http://www.nexium.fit/v1/avatar-fetch?userId={str(UserObj.id)}&placeId={str(PlaceId)}"
|
||||||
|
|
||||||
@@ -665,8 +623,7 @@ def join():
|
|||||||
PlaceObj : Place = Place.query.filter_by(placeid=placeid).first()
|
PlaceObj : Place = Place.query.filter_by(placeid=placeid).first()
|
||||||
AssetObj : Asset = Asset.query.filter_by(id=placeid).first()
|
AssetObj : Asset = Asset.query.filter_by(id=placeid).first()
|
||||||
UniverseObj : Universe = Universe.query.filter_by(id=PlaceObj.parent_universe_id).first()
|
UniverseObj : Universe = Universe.query.filter_by(id=PlaceObj.parent_universe_id).first()
|
||||||
if UniverseObj.place_year == PlaceYear.Sixteen:
|
|
||||||
return 'Who is bro', 400
|
|
||||||
ClientTicket = GenerateClientTicket(UserObj, jobid, TicketVersion = 1 if UniverseObj.place_year in [PlaceYear.Sixteen, PlaceYear.Fourteen] else ( 2 if UniverseObj.place_year == PlaceYear.Eighteen else 4), PlaceId = placeid)
|
ClientTicket = GenerateClientTicket(UserObj, jobid, TicketVersion = 1 if UniverseObj.place_year in [PlaceYear.Sixteen, PlaceYear.Fourteen] else ( 2 if UniverseObj.place_year == PlaceYear.Eighteen else 4), PlaceId = placeid)
|
||||||
|
|
||||||
AuthenticationTicket = auth.CreateToken(UserObj.id, get_remote_address() , (60*60*24) )
|
AuthenticationTicket = auth.CreateToken(UserObj.id, get_remote_address() , (60*60*24) )
|
||||||
|
|||||||
Reference in New Issue
Block a user