Exemplo n.º 1
0
    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))
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    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))
Exemplo n.º 8
0
    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()})
Exemplo n.º 9
0
    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
Exemplo n.º 10
0
 def __init__(self, error_message="must be a 6 digit hex code!"):
     IS_MATCH.__init__(self, "^[0-9a-fA-F]{6}$", error_message)
Exemplo n.º 11
0
 def __init__(self, error_message="must be a 6 digit hex code!"):
     IS_MATCH.__init__(self, "^[0-9a-fA-F]{6}$", error_message)
Exemplo n.º 12
0
    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)
Exemplo n.º 13
0
    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)
Exemplo n.º 14
0
    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)
Exemplo n.º 15
0
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)