def deletePlandoWebService(self): for param in ["plandoName", "plandoKey"]: if self.vars[param] == None: raiseHttp(400, "Missing parameter {}".format(param)) plandoName = self.vars.plandoName plandoKey = self.vars.plandoKey if IS_LENGTH(maxsize=32, minsize=1)(plandoName)[1] is not None: raiseHttp(400, "Plando name must be between 1 and 32 characters") if IS_MATCH('^[a-zA-Z0-9 -_]*$')(plandoName)[1] is not None: raiseHttp(400, "Plando name can only contain [a-zA-Z0-9 -_]") if IS_LENGTH(maxsize=8, minsize=1)(plandoKey)[1] is not None: raiseHttp(400, "Plando key must be between 1 and 8 characters") if IS_MATCH('^[a-zA-Z0-9]*$')(plandoKey)[1] is not None: raiseHttp(400, "Plando key can only contain [a-zA-Z0-9]") with DB() as db: valid = db.isValidPlandoKey(plandoName, plandoKey) if valid is None or len(valid) == 0: raiseHttp(400, "Plando key mismatch") db.deletePlandoRating(plandoName) db.deletePlando(plandoName) return json.dumps("Plando {} deleted".format(plandoName))
def __init__( self, error_message=None): """Constructor Args: error_message: see IS_MATCH """ # twitter handles: @username # * Starts with '@' # * from 1 to 15 alphanumeric characters. if error_message is None: error_message = 'Enter a valid twitter handle, eg @username' IS_MATCH.__init__(self, r'^@[\w]{1,15}$', error_message)
def downloadPlandoWebService(self): if self.vars.plando is None: raiseHttp(400, "Missing parameter plando") plandoName = self.vars.plando if IS_LENGTH(maxsize=32, minsize=1)(plandoName)[1] is not None: raiseHttp(400, "Plando name must be between 1 and 32 characters") if IS_MATCH('^[a-zA-Z0-9 -_]*$')(plandoName)[1] is not None: raiseHttp(400, "Plando name can only contain [a-zA-Z0-9 -_]") ipsFileName = os.path.join(ipsBasePath, "{}.ips".format(plandoName)) if not os.path.isfile(ipsFileName): raiseHttp(400, "Plando ips not found on server") with open(ipsFileName, 'rb') as ipsFile: ipsData = ipsFile.read() with DB() as db: maxSize = db.getPlandoIpsMaxSize(plandoName) db.increaseDownloadCount(plandoName) data = { "ips": base64.b64encode(ipsData).decode(), "fileName": "{}.sfc".format(plandoName), "maxSize": maxSize } return json.dumps(data)
def plandoRateWebService(self): if self.vars.plando == None: raiseHttp(400, "Missing parameter plando") plando = self.vars.plando if self.vars.rate == None: raiseHttp(400, "Missing parameter rate") rate = self.vars.rate if IS_LENGTH(maxsize=32, minsize=1)(plando)[1] is not None: raiseHttp(400, "Plando name must be between 1 and 32 characters") if IS_MATCH('^[a-zA-Z0-9 -_]*$')(plando)[1] is not None: raiseHttp(400, "Plando name can only contain [a-zA-Z0-9 -_]") if IS_INT_IN_RANGE(1, 6)(rate)[1] is not None: raiseHttp(400, "Rate name must be between 1 and 5") rate = int(rate) ip = self.request.client with DB() as db: db.addRating(plando, rate, ip) newRate = db.getPlandoRate(plando) if newRate == None: raiseHttp(400, "Can't get new rate") newCount = newRate[0][0] newRate = float(newRate[0][1]) data = { "msg": "", "purePlandoName": re.sub('[\W_]+', '', plando), "rate": newRate, "count": newCount } return json.dumps(data)
def run(self): with DB() as db: url = self.request.env.request_uri.split('/') msg = "" plandos = [] expand = True if len(url) > 0 and url[-1] != 'plandorepo': # a plando name was passed as parameter plandoName = url[-1] # decode url plandoName = urllib.parse.unquote(plandoName) # sanity check if IS_MATCH('^[a-zA-Z0-9 -_]*$')(plandoName)[1] is not None: msg = "Plando name can only contain [a-zA-Z0-9 -_]" else: plandos = db.getPlando(plandoName) if plandos is None or len(plandos) == 0: msg = "Plando not found" if plandos is None or len(plandos) == 0: # get plando list plandos = db.getPlandos() expand = False return dict(plandos=plandos, msg=msg, expand=expand, math=math, re=re)
def uploadPlandoWebService(self): with DB() as db: count = db.getPlandoCount() plandoLimit = 2048 if count is None or count[0][0] >= plandoLimit: raiseHttp(400, "Maximum number of plandos reach: {}".format(plandoLimit)) for param in ["author", "plandoName", "longDesc", "preset", "romData"]: if self.vars[param] == None: raiseHttp(400, "Missing parameter {}".format(param)) for param in ["author", "plandoName", "preset"]: if IS_LENGTH(maxsize=32, minsize=1)(self.vars[param])[1] is not None: raiseHttp(400, "{} must be between 1 and 32 characters".format(param)) for param in ["longDesc"]: if IS_LENGTH(maxsize=2048, minsize=1)(self.vars[param])[1] is not None: raiseHttp(400, "{} must be between 1 and 2048 characters".format(param)) plandoName = self.vars.plandoName if IS_MATCH('^[a-zA-Z0-9 -_]*$')(plandoName)[1] is not None: raiseHttp(400, "Plando name can only contain [a-zA-Z0-9 -_]") # check if plando doesn't already exist with DB() as db: check = db.checkPlando(plandoName) if check is not None and len(check) > 0 and check[0][0] == plandoName: raiseHttp(400, "Can't create plando, a plando with the same name already exists") author = self.vars.author longDesc = self.removeHtmlTags(self.vars.longDesc) preset = self.vars.preset maxSize = self.handleIps(plandoName, self.vars.romData) updateKey = self.generateUpdateKey() with DB() as db: db.insertPlando((plandoName, author, longDesc, preset, updateKey, maxSize)) if webhookAvailable: self.plandoWebhook(plandoName, author, preset, longDesc) return json.dumps(updateKey)
def updatePlandoWebService(self): for param in ["author", "plandoName", "longDesc", "preset", "plandoKey"]: if self.vars[param] == None: raiseHttp(400, "Missing parameter {}".format(param)) for param in ["author", "plandoName", "preset"]: if IS_LENGTH(maxsize=32, minsize=1)(self.vars[param])[1] is not None: raiseHttp(400, "{} must be between 1 and 32 characters".format(param)) for param in ["plandoKey"]: if IS_LENGTH(maxsize=8, minsize=1)(self.vars[param])[1] is not None: raiseHttp(400, "{} must be between 1 and 8 characters".format(param)) for param in ["longDesc"]: if IS_LENGTH(maxsize=2048, minsize=1)(self.vars[param])[1] is not None: raiseHttp(400, "{} must be between 1 and 2048 characters".format(param)) plandoName = self.vars.plandoName if IS_MATCH('^[a-zA-Z0-9 -_]*$')(plandoName)[1] is not None: raiseHttp(400, "Plando name can only contain [a-zA-Z0-9 -_]") author = self.vars.author longDesc = self.removeHtmlTags(self.vars.longDesc) preset = self.vars.preset plandoKey = self.vars.plandoKey # check update key with DB() as db: valid = db.isValidPlandoKey(plandoName, plandoKey) if valid is None or len(valid) == 0: raiseHttp(400, "Plando key mismatch") if self.vars.romData is not None: print("updatePlandoWebService: update ips") maxSize = self.handleIps(plandoName, self.vars.romData) db.updatePlandoAll((author, longDesc, preset, maxSize, plandoName)) else: db.updatePlandoMeta((author, longDesc, preset, plandoName)) return json.dumps("Plando {} updated succesfully.".format(plandoName))
def getSpcFile(self): songName = self.vars.songName if IS_NOT_EMPTY()(songName)[1] is not None: raiseHttp(400, "Song is empty") if IS_MATCH('[a-zA-Z0-9_\.() ,\-/]*', strict=True)(songName)[1] is not None: raiseHttp(400, "Invalid char in song name") if IS_LENGTH(64)(songName)[1] is not None: raiseHttp(400, "Song must be max 64 chars") print("getSpcFile songName: {}".format(songName)) musics = self.loadMusics() if songName not in musics: raiseHttp(400, "No preview for this song") if 'spc_path' not in musics[songName] or musics[songName][ 'spc_path'] == "": raiseHttp(400, "No preview for this song") songFile = musics[songName]['spc_path'] with open(os.path.join('music', songFile), 'rb') as spcFile: spcFileData = spcFile.read() return json.dumps({'spc': base64.b64encode(spcFileData).decode()})
def define_tables(self, username=None, signature=None, migrate=None, fake_migrate=None): """ To be called unless tables are defined manually Examples: Use as:: # defines all needed tables and table files # 'myprefix_auth_user.table', ... auth.define_tables(migrate='myprefix_') # defines all needed tables without migration/table files auth.define_tables(migrate=False) """ db = self.db if migrate is None: migrate = db._migrate if fake_migrate is None: fake_migrate = db._fake_migrate settings = self.settings if username is None: username = settings.use_username else: settings.use_username = username if not self.signature: self.define_signature() if signature is True: signature_list = [self.signature] elif not signature: signature_list = [] elif isinstance(signature, Table): signature_list = [signature] else: signature_list = signature self._table_signature_list = signature_list # Should it defined in __init__ first?? is_not_empty = IS_NOT_EMPTY(error_message=self.messages.is_empty) is_crypted = CRYPT(key=settings.hmac_key, min_length=settings.password_min_length) is_unique_email = [ IS_EMAIL(error_message=self.messages.invalid_email), IS_NOT_IN_DB(db, '%s.email' % settings.table_user_name, error_message=self.messages.email_taken) ] if not settings.email_case_sensitive: is_unique_email.insert(1, IS_LOWER()) if settings.table_user_name not in db.tables: passfield = settings.password_field extra_fields = settings.extra_fields.get(settings.table_user_name, []) + signature_list # cas_provider Will always be None here but we compare it anyway so subclasses can use our define_tables if username or settings.cas_provider: is_unique_username = \ [IS_MATCH('[\w\.\-]+', strict=True, error_message=self.messages.invalid_username), IS_NOT_IN_DB(db, '%s.username' % settings.table_user_name, error_message=self.messages.username_taken)] if not settings.username_case_sensitive: is_unique_username.insert(1, IS_LOWER()) db.define_table( settings.table_user_name, Field('first_name', length=128, default='', label=self.messages.label_first_name, requires=is_not_empty), Field('last_name', length=128, default='', label=self.messages.label_last_name, requires=is_not_empty), Field('email', length=512, default='', label=self.messages.label_email, requires=is_unique_email), Field('username', length=128, default='', label=self.messages.label_username, requires=is_unique_username), Field(passfield, 'password', length=512, readable=False, label=self.messages.label_password, requires=[is_crypted]), Field('registration_key', length=512, writable=False, readable=False, default='', label=self.messages.label_registration_key), Field('reset_password_key', length=512, writable=False, readable=False, default='', label=self.messages.label_reset_password_key), Field('registration_id', length=512, writable=False, readable=False, default='', label=self.messages.label_registration_id), *extra_fields, **dict(migrate=self._get_migrate(settings.table_user_name, migrate), fake_migrate=fake_migrate, format='%(username)s')) else: db.define_table( settings.table_user_name, Field('first_name', length=128, default='', label=self.messages.label_first_name, requires=is_not_empty), Field('last_name', length=128, default='', label=self.messages.label_last_name, requires=is_not_empty), Field('email', length=512, default='', label=self.messages.label_email, requires=is_unique_email), Field(passfield, 'password', length=512, readable=False, label=self.messages.label_password, requires=[is_crypted]), Field('registration_key', length=512, writable=False, readable=False, default='', label=self.messages.label_registration_key), Field('reset_password_key', length=512, writable=False, readable=False, default='', label=self.messages.label_reset_password_key), Field('registration_id', length=512, writable=False, readable=False, default='', label=self.messages.label_registration_id), *extra_fields, **dict(migrate=self._get_migrate(settings.table_user_name, migrate), fake_migrate=fake_migrate, format='%(first_name)s %(last_name)s (%(id)s)')) reference_table_user = '******' % settings.table_user_name if settings.table_group_name not in db.tables: extra_fields = settings.extra_fields.get(settings.table_group_name, []) + signature_list db.define_table( settings.table_group_name, Field('role', length=512, default='', label=self.messages.label_role, requires=IS_NOT_IN_DB( db, '%s.role' % settings.table_group_name)), Field('description', 'text', label=self.messages.label_description), *extra_fields, **dict(migrate=self._get_migrate(settings.table_group_name, migrate), fake_migrate=fake_migrate, format='%(role)s (%(id)s)')) reference_table_group = 'reference %s' % settings.table_group_name if settings.table_membership_name not in db.tables: extra_fields = settings.extra_fields.get( settings.table_membership_name, []) + signature_list db.define_table( settings.table_membership_name, Field('user_id', reference_table_user, label=self.messages.label_user_id), Field('group_id', reference_table_group, label=self.messages.label_group_id), *extra_fields, **dict(migrate=self._get_migrate( settings.table_membership_name, migrate), fake_migrate=fake_migrate)) if settings.table_permission_name not in db.tables: extra_fields = settings.extra_fields.get( settings.table_permission_name, []) + signature_list db.define_table( settings.table_permission_name, Field('group_id', reference_table_group, label=self.messages.label_group_id), Field('name', default='default', length=512, label=self.messages.label_name, requires=is_not_empty), Field('table_name', length=512, label=self.messages.label_table_name), Field('record_id', 'integer', default=0, label=self.messages.label_record_id, requires=IS_INT_IN_RANGE(0, 10**9)), *extra_fields, **dict(migrate=self._get_migrate( settings.table_permission_name, migrate), fake_migrate=fake_migrate)) if settings.table_event_name not in db.tables: db.define_table( settings.table_event_name, Field('time_stamp', 'datetime', default=current.request.now, label=self.messages.label_time_stamp), Field('client_ip', default=current.request.client, label=self.messages.label_client_ip), Field('user_id', reference_table_user, default=None, label=self.messages.label_user_id), Field('origin', default='auth', length=512, label=self.messages.label_origin, requires=is_not_empty), Field('description', 'text', default='', label=self.messages.label_description, requires=is_not_empty), *settings.extra_fields.get(settings.table_event_name, []), **dict(migrate=self._get_migrate(settings.table_event_name, migrate), fake_migrate=fake_migrate)) return self
def __init__(self, error_message="must be a 6 digit hex code!"): IS_MATCH.__init__(self, "^[0-9a-fA-F]{6}$", error_message)
def __init__(self, error_message="must be a 6 digit hex code!"): IS_MATCH.__init__(self, "^[0-9a-fA-F]{6}$", error_message)
def validateSolverParams(self): for param in ['difficultyTarget', 'pickupStrategy', 'complexity']: if self.vars[param] is None: return (False, "Missing parameter {}".format(param)) if self.vars.preset == None: return (False, "Missing parameter preset") preset = self.vars.preset if IS_ALPHANUMERIC()(preset)[1] is not None: return (False, "Wrong value for preset, must be alphanumeric") if IS_LENGTH(maxsize=32, minsize=1)(preset)[1] is not None: return ( False, "Wrong length for preset, name must be between 1 and 32 characters" ) # check that preset exists fullPath = '{}/{}.json'.format(getPresetDir(preset), preset) if not os.path.isfile(fullPath): return (False, "Unknown preset: {}".format(preset)) difficultyTargetChoices = [ "easy", "medium", "hard", "very hard", "hardcore", "mania" ] if self.vars.difficultyTarget not in difficultyTargetChoices: return ( False, "Wrong value for difficultyTarget: {}, authorized values: {}". format(self.vars.difficultyTarget, difficultyTargetChoices)) pickupStrategyChoices = ["all", "any"] if self.vars.pickupStrategy not in pickupStrategyChoices: return (False, "Wrong value for pickupStrategy: {}, authorized values: {}" .format(self.vars.pickupStrategy, pickupStrategyChoice)) complexityChoices = ["simple", "advanced"] if self.vars.complexity not in complexityChoices: return ( False, "Wrong value for complexity: {}, authorized values: {}".format( self.vars.complexity, complexityChoices)) itemsForbidden = [] for item in [ 'ETank', 'Missile', 'Super', 'PowerBomb', 'Bomb', 'Charge', 'Ice', 'HiJump', 'SpeedBooster', 'Wave', 'Spazer', 'SpringBall', 'Varia', 'Plasma', 'Grapple', 'Morph', 'Reserve', 'Gravity', 'XRayScope', 'SpaceJump', 'ScrewAttack' ]: boolvar = self.vars[item + "_bool"] if boolvar is not None: if boolvar != 'on': return (False, "Wrong value for {}: {}, authorized values: on/off" .format(item, boolvar)) if self.vars.romJson is None and self.vars.uploadFile is None and self.vars.romFile is None: return (False, "Missing ROM to solve") if self.vars.romFile is not None: if IS_LENGTH(maxsize=255, minsize=1)(self.vars.romFile)[1] is not None: return ( False, "Wrong length for romFile, name must be between 1 and 256 characters: {}" .format(request.vars.romFile)) if self.vars.romJson is not None and len(self.vars.romJson) > 0: try: json.loads(self.vars.romJson) except: return (False, "Wrong value for romJson, must be a JSON string: [{}]". format(self.vars.romJson)) if self.vars.uploadFile is not None: if type(self.vars.uploadFile) == str: if IS_MATCH('[a-zA-Z0-9_\.() ,\-]*', strict=True)( request.vars.uploadFile)[1] is not None: return ( False, "Wrong value for uploadFile, must be a valid file name: {}" .format(self.vars.uploadFile)) if IS_LENGTH(maxsize=256, minsize=1)(self.vars.uploadFile)[1] is not None: return ( False, "Wrong length for uploadFile, name must be between 1 and 255 characters" ) return (True, None)
def run(self): self.initCustomSprites() self.initCustomizerSession() musics = self.loadMusics() (stdPresets, tourPresets, comPresets) = loadPresetsList(self.cache) url = self.request.env.request_uri.split('/') msg = "" seedInfo = None seedParams = None defaultParams = None if len(url) > 0 and url[-1] != 'customizer': # a seed unique key was passed as parameter key = url[-1] # decode url key = urllib.parse.unquote(key) # sanity check if IS_MATCH('^[0-9a-z-]*$')(key)[1] is not None: msg = "Seed key can only contain [0-9a-z-]" elif IS_LENGTH(maxsize=36, minsize=36)(key)[1] is not None: msg = "Seed key must be 36 chars long" else: with DB() as db: seedInfo = db.getSeedInfo(key) if seedInfo is None or len(seedInfo) == 0: msg = "Seed {} not found".format(key) seedInfo = None else: # get a dict with seed info and another one with seed parameters info = {} seedParams = {} infoKeys = [ 'time', 'filename', 'preset', 'runtime', 'complexity', 'upload_status', 'seed', 'raceMode' ] for (k, value) in seedInfo: if k in infoKeys: info[k] = value else: seedParams[k] = updateParameterDisplay(value) seedInfo = info seedInfo['key'] = key # if new parameters have been added since the seed creation, add them with value "n/a" defaultParams = getRandomizerDefaultParameters() for k in defaultParams: if k not in infoKeys and k not in seedParams: seedParams[k] = "n/a" # check that the seed ips is available if seedInfo["upload_status"] not in [ 'pending', 'uploaded', 'local' ]: msg = "Seed {} not available".format(key) seedInfo = None seedParams = None # accessing the url tell us to store the ips for more than 7 days elif seedInfo["upload_status"] == 'local': with DB() as db: db.updateSeedUploadStatus(key, 'pending') return dict(customSprites=customSprites, customShips=customShips, musics=musics, comPresets=comPresets, seedInfo=seedInfo, seedParams=seedParams, msg=msg, defaultParams=defaultParams)
def run(self): self.initRandomizerSession() (stdPresets, tourPresets, comPresets) = loadPresetsList(self.cache) randoPresetsDesc = { "all_random": "all the parameters set to random", "Chozo_Speedrun": "speedrun progression speed with Chozo split", "default": "VARIA randomizer default settings", "doors_long": "be prepared to hunt for beams and ammo to open doors", "doors_short": "uses Chozo/speedrun settings for a quicker door color rando", "free": "easiest possible settings", "hardway2hell": "harder highway2hell", "haste": "inspired by DASH randomizer with Nerfed Charge / Progressive Suits", "highway2hell": "favors suitless seeds", "hud": "Full rando with remaining major upgrades in the area shown in the HUD", "hud_hard": "Low resources and VARIA HUD enabled to help you track of actual items count", "hud_start": "Non-vanilla start with Major or Chozo split", "minimizer":"Typical 'boss rush' settings with random start and nerfed charge", "minimizer_hardcore":"Have fun 'rushing' bosses with no equipment on a tiny map", "minimizer_maximizer":"No longer a boss rush", "quite_random": "randomizes a few significant settings to have various seeds", "scavenger_hard":"Pretty hostile Scavenger mode", "scavenger_random":"Randomize everything within Scavenger mode", "scavenger_speedrun":"Quickest Scavenger settings", "scavenger_vanilla_but_not":"Items are vanilla, but area and bosses are not", "stupid_hard": "hardest possible settings", "surprise": "quite_random with Area/Boss/Doors/Start settings randomized", "vanilla": "closest possible to vanilla Super Metroid", "way_of_chozo": "chozo split with boss randomization", "where_am_i": "Area mode with random start location and early morph", "where_is_morph": "Area mode with late Morph", "Multi_Category_Randomizer_Week_1": "Multi-Category Randomizer Tournament week 1", "Multi_Category_Randomizer_Week_2": "Multi-Category Randomizer Tournament week 2", "Multi_Category_Randomizer_Week_3": "Multi-Category Randomizer Tournament week 3", "Multi_Category_Randomizer_Week_4": "Multi-Category Randomizer Tournament week 4", "Multi_Category_Randomizer_Week_5": "Multi-Category Randomizer Tournament week 5", "Multi_Category_Randomizer_Week_6": "Multi-Category Randomizer Tournament week 6", "Multi_Category_Randomizer_Week_7": "Multi-Category Randomizer Tournament week 7", "Season_Races": "rando league races (Majors/Minors split)", "SGLive2022_Race_1": "SGLive 2022 Super Metroid randomizer tournament race 1", "SGLive2022_Race_2": "SGLive 2022 Super Metroid randomizer tournament race 2", "SGLive2022_Race_3": "SGLive 2022 Super Metroid randomizer tournament race 3", "SMRAT2021": "Super Metroid Randomizer Accessible Tournament 2021", "VARIA_Weekly": "Casual logic community races" } randoPresetsCategories = { "Standard": ["", "default", "Chozo_Speedrun", "free", "haste", "vanilla"], "Hud": ["hud", "hud_hard", "hud_start"], "Scavenger": ["scavenger_hard", "scavenger_random", "scavenger_speedrun", "scavenger_vanilla_but_not"], "Area": ["way_of_chozo", "where_am_i", "where_is_morph"], "Doors": ["doors_long", "doors_short"], "Minimizer": ["minimizer", "minimizer_hardcore", "minimizer_maximizer"], "Hard": ["hardway2hell", "highway2hell", "stupid_hard"], "Random": ["all_random", "quite_random", "surprise"], "Tournament": ["Season_Races", "SMRAT2021", "VARIA_Weekly", "SGLive2022_Race_1", "SGLive2022_Race_2", "SGLive2022_Race_3", "Multi_Category_Randomizer_Week_1", "Multi_Category_Randomizer_Week_2", "Multi_Category_Randomizer_Week_3", "Multi_Category_Randomizer_Week_4", "Multi_Category_Randomizer_Week_5", "Multi_Category_Randomizer_Week_6", "Multi_Category_Randomizer_Week_7"] } startAPs = GraphUtils.getStartAccessPointNamesCategory() startAPs = [OPTGROUP(_label="Standard", *startAPs["regular"]), OPTGROUP(_label="Custom", *startAPs["custom"]), OPTGROUP(_label="Custom (Area rando only)", *startAPs["area"])] # get multi currentMultiValues = self.getCurrentMultiValues() defaultMultiValues = getDefaultMultiValues() # objectives self exclusions objectivesExclusions = Objectives.getExclusions() objectivesTypes = Objectives.getObjectivesTypes() objectivesSort = Objectives.getObjectivesSort() objectivesCategories = Objectives.getObjectivesCategories() # check if we have a guid in the url url = self.request.env.request_uri.split('/') if len(url) > 0 and url[-1] != 'randomizer': # a seed unique key was passed as parameter key = url[-1] # decode url key = urllib.parse.unquote(key) # sanity check if IS_MATCH('^[0-9a-z-]*$')(key)[1] is None and IS_LENGTH(maxsize=36, minsize=36)(key)[1] is None: with DB() as db: seedInfo = db.getSeedInfo(key) if seedInfo is not None and len(seedInfo) > 0: defaultParams = getRandomizerDefaultParameters() defaultParams.update(seedInfo) seedInfo = defaultParams # check that the seed ips is available if seedInfo["upload_status"] in ['pending', 'uploaded', 'local']: # load parameters in session for key, value in seedInfo.items(): if key in ["complexity", "randoPreset", "raceMode"]: continue elif key in defaultMultiValues: keyMulti = key + 'MultiSelect' if keyMulti in seedInfo: if key == 'objective' and value == 'nothing': self.session.randomizer[key] = "" else: self.session.randomizer[key] = seedInfo[key] valueMulti = seedInfo[keyMulti] if type(valueMulti) == str: valueMulti = valueMulti.split(',') self.session.randomizer[keyMulti] = valueMulti currentMultiValues[key] = valueMulti elif key in self.session.randomizer and 'MultiSelect' not in key: self.session.randomizer[key] = value return dict(stdPresets=stdPresets, tourPresets=tourPresets, comPresets=comPresets, randoPresetsDesc=randoPresetsDesc, randoPresetsCategories=randoPresetsCategories, startAPs=startAPs, currentMultiValues=currentMultiValues, defaultMultiValues=defaultMultiValues, maxsize=sys.maxsize, displayNames=displayNames, objectivesExclusions=objectivesExclusions, objectivesTypes=objectivesTypes, objectivesSort=objectivesSort, objectivesCategories=objectivesCategories)
def validateWebServiceParams(request, switchs, quantities, multis, others, isJson=False): parameters = switchs + quantities + multis + others for param in parameters: if request.vars[param] is None: raiseHttp(400, "Missing parameter: {}".format(param), isJson) # switchs for switch in switchs: if request.vars[switch] not in ['on', 'off', 'random']: raiseHttp( 400, "Wrong value for {}, authorized values: on/off".format(switch), isJson) # quantities for qty in quantities: if request.vars[qty] == 'random': continue if qty == 'minimizerQty': if request.vars.minimizer == 'on': qtyInt = getInt(request, qty, isJson) if qtyInt < 30 or qtyInt > 100: raiseHttp( 400, "Wrong value for {}, must be between 30 and 100". format(qty), isJson) elif qty == 'scavNumLocs': if request.vars.majorsSplit == 'Scavenger': qtyInt = getInt(request, qty, isJson) if qtyInt < 4 or qtyInt > 17: raiseHttp( 400, "Wrong value for {}, must be between 4 and 16".format( qty), isJson) else: qtyFloat = getFloat(request, qty, isJson) if qtyFloat < 1.0 or qtyFloat > 9.0: raiseHttp( 400, "Wrong value for {}, must be between 1 and 9".format(qty), isJson) # multis defaultMultiValues = getDefaultMultiValues() for param in multis: paramMulti = param + "MultiSelect" value = request.vars[param] if value == 'random': if request.vars[paramMulti] is not None: # get multi values for value in request.vars[paramMulti].split(','): # check multi values if value not in defaultMultiValues[param]: raiseHttp( 400, "Wrong value for {}, authorized values: {}".format( param, defaultMultiValues[param]), isJson) else: # check value if value not in defaultMultiValues[param]: raiseHttp( 400, "Wrong value for {}, authorized values: {}".format( param, defaultMultiValues[param]), isJson) # others if request.vars.minorQty not in ['random', None]: minorQtyInt = getInt(request, 'minorQty', isJson) if minorQtyInt < 7 or minorQtyInt > 100: raiseHttp(400, "Wrong value for minorQty, must be between 7 and 100", isJson) if 'gravityBehaviour' in others: if request.vars.gravityBehaviour not in [ 'Balanced', 'Progressive', 'Vanilla' ]: raiseHttp(400, "Wrong value for gravityBehaviour", isJson) if 'complexity' in others: if request.vars['complexity'] not in ['simple', 'medium', 'advanced']: raiseHttp( 400, "Wrong value for complexity, authorized values simple/medium/advanced", isJson) if 'paramsFileTarget' in others: try: json.loads(request.vars.paramsFileTarget) except: raiseHttp( 400, "Wrong value for paramsFileTarget, must be a JSON string", isJson) if 'seed' in others: seedInt = getInt(request, 'seed', isJson) if seedInt < 0 or seedInt > sys.maxsize: raiseHttp(400, "Wrong value for seed", isJson) if 'objective' in others: objective = request.vars.objective.split(',') authorizedObjectives = defaultMultiValues['objective'] + [ 'random', 'nothing' ] for value in objective: if value not in authorizedObjectives: raiseHttp(400, "Wrong value for objective", isJson) if objective == ['random']: for value in request.vars.objectiveMultiSelect.split(','): if value not in authorizedObjectives: raiseHttp(400, "Wrong value for objectiveMultiSelect", isJson) if 'tourian' in others: if request.vars['tourian'] not in ['Vanilla', 'Fast', 'Disabled']: raiseHttp( 400, "Wrong value fro tourian, authorized values: Vanilla/Fast/Disabled", isJson) if 'hellrun_rate' in others and request.vars.hellrun_rate != 'off': hellrun_rate = getInt(request, 'hellrun_rate', isJson) if hellrun_rate < 0 or hellrun_rate > 400: raiseHttp(400, "Wrong value for hellrun_rate", isJson) if 'etanks' in others and request.vars.etanks != 'off': etanks = getInt(request, 'etanks', isJson) if etanks < 0 or etanks > 14: raiseHttp(400, "Wrong value for etanks", isJson) preset = request.vars.preset if preset != None: if IS_ALPHANUMERIC()(preset)[1] is not None: raiseHttp(400, "Wrong value for preset, must be alphanumeric", isJson) if IS_LENGTH(maxsize=32, minsize=1)(preset)[1] is not None: raiseHttp( 400, "Wrong length for preset, name must be between 1 and 32 characters", isJson) # check that preset exists fullPath = '{}/{}.json'.format(getPresetDir(preset), preset) if not os.path.isfile(fullPath): raiseHttp(400, "Unknown preset", isJson) randoPreset = request.vars.randoPreset if randoPreset != None and len(randoPreset) > 0: if IS_ALPHANUMERIC()(randoPreset)[1] is not None: raiseHttp(400, "Wrong value for randoPreset, must be alphanumeric", isJson) if IS_LENGTH(maxsize=32, minsize=1)(randoPreset)[1] is not None: raiseHttp( 400, "Wrong length for randoPreset, name must be between 1 and 32 characters", isJson) # check that randoPreset exists fullPath = 'rando_presets/{}.json'.format(randoPreset) if not os.path.isfile(fullPath): raiseHttp(400, "Unknown randoPreset", isJson) # check race mode if 'raceMode' in request.vars: if request.vars.raceMode not in ['on', 'off']: raiseHttp(400, "Wrong value for race mode, must on/off", isJson) # check seed key if 'seedKey' in request.vars: if IS_MATCH('^[0-9a-z-]*$')(request.vars.seedKey)[1] is not None: raiseHttp(400, "Seed key can only contain [0-9a-z-]", isJson) if IS_LENGTH(maxsize=36, minsize=36)(request.vars.seedKey)[1] is not None: raiseHttp(400, "Seed key must be 36 chars long", isJson)