This commit is contained in:
copyrighttxt
2026-08-04 18:24:32 -04:00
committed by GitHub
parent cb2bcb56d4
commit e79463ce20
+13 -56
View File
@@ -22,12 +22,9 @@ from app.models.place import Place
from app.models.asset import Asset
from app.models.login_records import LoginRecord
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.asset_version import AssetVersion
from app.enums.AssetType import AssetType
from app.enums.BanType import BanType
from app.enums.MembershipType import MembershipType
from app.enums.PlaceYear import PlaceYear
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,
serverPort = OpenJobReqJSON["port"],
serverPlaceId = placeId,
serverRunningTime = 1,
maxPlayerCount = PlaceObj.maxplayers,
reservedServerAccessCode = reserved_server_access_code
)
@@ -245,7 +241,7 @@ def GetSuitablePlaceServer( placeId : int ) -> PlaceServer | bool:
except:
return False
return NewPlaceServerObj
return False
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"
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'])
@@ -369,7 +323,7 @@ def BanUsersForSharedHwid(hwid: str, triggering_user_id: int | None = None) -> b
@csrf.exempt
def placelauncher():
if not websiteFeatures.GetWebsiteFeature("GameJoinAPI"):
logging.warning("opsec")
return ReturnPlaceLauncher("GameJoinAPI is disabled", 12)
AuthenticatdUser = None
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:
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
if PlaceServerPlayer.query.filter_by(userid=userId).first() is not None and not isTeleport:
CurrentPlaceServerPlayerObj : PlaceServerPlayer = PlaceServerPlayer.query.filter_by(userid=userId).first()
@@ -428,9 +388,6 @@ def placelauncher():
redis_controller.delete(f"hwid:{str(Tracking_Cookie)}")
if BanUsersForSharedHwid(UserHWIDHash, UserObj.id):
return ReturnPlaceLauncher("Invalid session", 12)
UserMembershipStatus : MembershipType = GetUserMembership(UserObj)
if UniverseObj.bc_required and UserMembershipStatus == MembershipType.NonBuildersClub:
return ReturnPlaceLauncher("Builders Club required", 12)
@@ -462,10 +419,11 @@ def placelauncher():
if PlaceServerObj is False:
logging.info(f"Placelauncher.ashx : {str(placeid)} : {UserObj.username} [{UserObj.id}] : No available place servers found yet")
return ReturnPlaceLauncher(None, 1, authenticated_userid=userId)
redis_controller.delete(f"authticket:{ticket}")
authenticatedTicketUUID = str(uuid.uuid4())
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)
resp = make_response(jsonify({
"jobId": PlaceServerObj.serveruuid,
@@ -613,7 +571,7 @@ def GenerateClientTicket( UserObj : User, JobId : str, CharacterURL : str = None
if TicketVersion == 2:
CharacterURL = str(UserObj.id)
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:
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()
AssetObj : Asset = Asset.query.filter_by(id=placeid).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)
AuthenticationTicket = auth.CreateToken(UserObj.id, get_remote_address() , (60*60*24) )
@@ -765,4 +722,4 @@ def join():
expires = datetime.utcnow() + timedelta(days=3),
domain = f".{config.BaseDomain}"
)
return joinResposne
return joinResposne