Esempio n. 1
0
    def presetWebService(self):
        # web service to get the content of the preset file
        if self.vars.preset == None:
            raiseHttp(400, "Missing parameter preset")
        preset = self.vars.preset

        if IS_ALPHANUMERIC()(preset)[1] is not None:
            raiseHttp(400, "Preset name must be alphanumeric")

        if IS_LENGTH(maxsize=32, minsize=1)(preset)[1] is not None:
            raiseHttp(400, "Preset name must be between 1 and 32 characters")

        print("presetWebService: preset={}".format(preset))

        fullPath = '{}/{}.json'.format(getPresetDir(preset), preset)

        # check that the presets file exists
        if os.path.isfile(fullPath):
            # load it
            try:
                params = PresetLoader.factory(fullPath).params
            except Exception as e:
                raiseHttp(400, "Can't load the preset")
            params = json.dumps(params)
            return params
        else:
            raiseHttp(400, "Preset not found")
Esempio n. 2
0
    def loadPreset(self):
        # load conf from session if available
        loaded = False

        if self.vars.action is not None:
            # press solve, load or save button
            if self.vars.action in ['Update', 'Create']:
                # store the changes in case the form won't be accepted
                presetDict = self.genJsonFromParams(self.vars)
                self.session.presets['presetDict'] = presetDict
                params = PresetLoader.factory(presetDict).params
                loaded = True
            elif self.vars.action in ['Load']:
                # nothing to load, we'll load the new params file with the load form code
                pass
        else:
            # no forms button pressed
            if self.session.presets['presetDict'] is not None:
                params = PresetLoader.factory(
                    self.session.presets['presetDict']).params
                loaded = True

        if not loaded:
            presetPath = '{}/{}.json'.format(
                getPresetDir(self.session.presets['preset']),
                self.session.presets['preset'])
            params = PresetLoader.factory(presetPath).params

        return params
Esempio n. 3
0
    def getSkillLevelBarData(self, preset):
        result = {'name': preset}
        try:
            params = PresetLoader.factory('{}/{}.json'.format(
                getPresetDir(preset), preset)).params
            result['custom'] = (preset, params['score'])
            # add stats on the preset
            result['knowsKnown'] = len([
                know for know in params['Knows']
                if params['Knows'][know][0] == True
            ])
        except:
            result['custom'] = (preset, 'N/A')
            result['knowsKnown'] = 'N/A'

        # get score of standard presets
        standardScores = self.cache.ram('standardScores',
                                        lambda: dict(),
                                        time_expire=None)
        if not standardScores:
            for preset in [
                    'newbie', 'casual', 'regular', 'veteran', 'expert',
                    'master', 'samus'
            ]:
                score = PresetLoader.factory('{}/{}.json'.format(
                    getPresetDir(preset), preset)).params['score']
                standardScores[preset] = score

        result['standards'] = standardScores

        with DB() as db:
            result['lastAction'] = db.getPresetLastActionDate(
                result['custom'][0])

        # TODO: normalize result (or not ?)
        return result
Esempio n. 4
0
    def computeDifficulty(self, jsonRomFileName, preset):
        randomizedRom = os.path.basename(jsonRomFileName.replace(
            'json', 'sfc'))

        presetFileName = "{}/{}.json".format(getPresetDir(preset), preset)
        (fd, jsonFileName) = tempfile.mkstemp()

        db = DB()
        id = db.initSolver()

        params = [
            getPythonExec(),
            os.path.expanduser("~/RandomMetroidSolver/solver.py"), '-r',
            str(jsonRomFileName), '--preset', presetFileName,
            '--difficultyTarget',
            str(self.session.solver['difficultyTarget']), '--pickupStrategy',
            self.session.solver['pickupStrategy'], '--type', 'web', '--output',
            jsonFileName, '--runtime', '10'
        ]

        for item in self.session.solver['itemsForbidden']:
            params += ['--itemsForbidden', item]

        db.addSolverParams(id, randomizedRom, preset,
                           self.session.solver['difficultyTarget'],
                           self.session.solver['pickupStrategy'],
                           self.session.solver['itemsForbidden'])

        print("before calling solver: {}".format(params))
        start = datetime.now()
        ret = subprocess.call(params)
        end = datetime.now()
        duration = (end - start).total_seconds()
        print("ret: {}, duration: {}s".format(ret, duration))

        if ret == 0:
            with open(jsonFileName) as jsonFile:
                result = json.load(jsonFile)
        else:
            result = "Solver: something wrong happened while solving the ROM"

        db.addSolverResult(id, ret, duration, result)
        db.close()

        os.close(fd)
        os.remove(jsonFileName)

        return (ret == 0, result)
Esempio n. 5
0
    def skillPresetActionWebService(self):
        print("skillPresetActionWebService call")

        if self.session.presets is None:
            self.session.presets = {}

        # for create/update, not load
        (ok, msg) = self.validatePresetsParams(self.vars.action)
        if not ok:
            raiseHttp(400, json.dumps(msg))
        else:
            self.session.presets['currentTab'] = self.vars.currenttab

        if self.vars.action == 'Create':
            preset = self.vars.presetCreate
        else:
            preset = self.vars.preset

        # check if the presets file already exists
        password = self.vars['password']
        password = password.encode('utf-8')
        passwordSHA256 = hashlib.sha256(password).hexdigest()
        fullPath = '{}/{}.json'.format(getPresetDir(preset), preset)
        if os.path.isfile(fullPath):
            # load it
            end = False
            try:
                oldParams = PresetLoader.factory(fullPath).params
            except Exception as e:
                msg = "UC:Error loading the preset {}: {}".format(preset, e)
                end = True
            if end == True:
                raiseHttp(400, json.dumps(msg))

            # check if password match
            if 'password' in oldParams and passwordSHA256 == oldParams[
                    'password']:
                # update the presets file
                paramsDict = self.genJsonFromParams(self.vars)
                paramsDict['password'] = passwordSHA256
                try:
                    PresetLoader.factory(paramsDict).dump(fullPath)
                    with DB() as db:
                        db.addPresetAction(preset, 'update')
                    self.updatePresetsSession()
                    msg = "Preset {} updated".format(preset)
                    return json.dumps(msg)
                except Exception as e:
                    msg = "Error writing the preset {}: {}".format(preset, e)
                    raiseHttp(400, json.dumps(msg))
            else:
                msg = "Password mismatch with existing presets file {}".format(
                    preset)
                raiseHttp(400, json.dumps(msg))
        else:
            # prevent a malicious user from creating presets in a loop
            if not self.maxPresetsReach():
                # write the presets file
                paramsDict = self.genJsonFromParams(self.vars)
                paramsDict['password'] = passwordSHA256
                try:
                    PresetLoader.factory(paramsDict).dump(fullPath)
                    with DB() as db:
                        db.addPresetAction(preset, 'create')
                    self.updatePresetsSession()

                    # add new preset in cache
                    (stdPresets, tourPresets,
                     comPresets) = loadPresetsList(self.cache)
                    comPresets.append(preset)
                    comPresets.sort(key=lambda v: v.upper())

                    msg = "Preset {} created".format(preset)
                    return json.dumps(msg)
                except Exception as e:
                    msg = "Error writing the preset {}: {}".format(preset, e)
                    raiseHttp(400, json.dumps(msg))
                redirect(URL(r=request, f='presets'))
            else:
                msg = "Sorry, maximum number of presets reached, can't add more"
                raiseHttp(400, json.dumps(msg))
Esempio n. 6
0
    def run(self):
        self.initPresetsSession()

        # use web2py builtin cache to avoid recomputing the hardrooms requirements
        hardRooms = self.cache.ram('hardRooms',
                                   lambda: dict(),
                                   time_expire=None)
        if len(hardRooms) == 0:
            self.computeHardRooms(hardRooms)

        hellRuns = self.cache.ram('hellRuns', lambda: dict(), time_expire=None)
        if len(hellRuns) == 0:
            self.computeHellruns(hellRuns)

        if self.vars.action is not None:
            (ok, msg) = self.validatePresetsParams(self.vars.action)
            if not ok:
                self.session.flash = msg
                redirect(URL(r=self.request, f='presets'))
            else:
                self.session.presets['currentTab'] = self.vars.currenttab

            preset = self.vars.preset

        # in web2py.js, in disableElement, remove 'working...' to have action with correct value
        if self.vars.action == 'Load':
            # check that the presets file exists
            fullPath = '{}/{}.json'.format(getPresetDir(preset), preset)
            if os.path.isfile(fullPath):
                # load it
                try:
                    params = PresetLoader.factory(fullPath).params
                    self.updatePresetsSession()
                    self.session.presets["presetDict"] = None
                except Exception as e:
                    self.session.flash = "L:Error loading the preset {}: {}".format(
                        preset, e)
            else:
                self.session.flash = "Presets file not found: {}".format(
                    fullPath)
            redirect(URL(r=self.request, f='presets'))

        # load conf from session if available
        error = False
        try:
            params = self.loadPreset()
        except Exception as e:
            self.session.presets['preset'] = 'regular'
            self.session.flash = "S:Error loading the preset: {}".format(e)
            error = True
        if error == True:
            redirect(URL(r=request, f='presets'))

        # load presets list
        (stdPresets, tourPresets, comPresets) = loadPresetsList(self.cache)

        # add missing knows/settings
        completePreset(params)

        # compute score for skill bar
        skillBarData = self.getSkillLevelBarData(
            self.session.presets['preset'])

        # send values to view
        return dict(desc=Knows.desc,
                    difficulties=diff2text,
                    categories=Knows.categories,
                    settings=params['Settings'],
                    knows=params['Knows'],
                    easy=easy,
                    medium=medium,
                    hard=hard,
                    harder=harder,
                    hardcore=hardcore,
                    mania=mania,
                    controller=params['Controller'],
                    stdPresets=stdPresets,
                    tourPresets=tourPresets,
                    comPresets=comPresets,
                    skillBarData=skillBarData,
                    hardRooms=hardRooms,
                    hellRuns=hellRuns)
        okValues = [value]
        if altValue is not None:
            okValues.append(altValue)

        if argDict[arg] not in okValues:
            argDict[arg] = value
            forcedArgs[webArg if webArg != None else arg] = webValue if webValue != None else value
            print(msg)
            optErrMsgs.append(msg)

    # if rando preset given, load it first
    if args.randoPreset != None:
        preset = loadRandoPreset(args.randoPreset, args)
        # use the skill preset from the rando preset
        if preset is not None and args.paramsFileName is None:
            args.paramsFileName = '{}/{}/{}.json'.format(appDir, getPresetDir(preset), preset)

    # if diff preset given, load it
    if args.paramsFileName is not None:
        PresetLoader.factory(args.paramsFileName).load()
        preset = os.path.splitext(os.path.basename(args.paramsFileName))[0]

        if args.preset is not None:
            preset = args.preset
    else:
        preset = 'default'

    logger.debug("preset: {}".format(preset))

    # if no seed given, choose one
    if args.seed == 0:
Esempio n. 8
0
            okValues.append(altValue)

        if argDict[arg] not in okValues:
            argDict[arg] = value
            forcedArgs[webArg if webArg != None else
                       arg] = webValue if webValue != None else value
            print(msg)
            optErrMsgs.append(msg)

    # if rando preset given, load it first
    if args.randoPreset != None:
        preset = loadRandoPreset(args.randoPreset, args)
        # use the skill preset from the rando preset
        if preset is not None and args.paramsFileName is None:
            args.paramsFileName = '{}/{}/{}.json'.format(
                appDir, getPresetDir(preset), preset)

    # if diff preset given, load it
    if args.paramsFileName is not None:
        PresetLoader.factory(args.paramsFileName).load()
        preset = os.path.splitext(os.path.basename(args.paramsFileName))[0]

        if args.preset is not None:
            preset = args.preset
    else:
        preset = 'default'

    logger.debug("preset: {}".format(preset))

    # if no seed given, choose one
    if args.seed == 0:
Esempio n. 9
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)
Esempio n. 10
0
    def customWebService(self):
        print("customWebService")

        # check validity of all parameters
        switchs = [
            'itemsounds', 'spinjumprestart', 'rando_speed', 'elevators_speed',
            'fast_doors', 'AimAnyButton', 'max_ammo_display',
            'supermetroid_msu1', 'Infinite_Space_Jump', 'refill_before_save',
            'customSpriteEnable', 'customItemsEnable', 'noSpinAttack',
            'customShipEnable', 'remove_itemsounds', 'remove_elevators_speed',
            'remove_fast_doors', 'remove_Infinite_Space_Jump',
            'remove_rando_speed', 'remove_spinjumprestart', 'gamepadMapping',
            'widescreen', 'hell', 'lava_acid_physics'
        ]
        others = [
            'colorsRandomization', 'suitsPalettes', 'beamsPalettes',
            'tilesPalettes', 'enemiesPalettes', 'bossesPalettes', 'minDegree',
            'maxDegree', 'invert', 'hellrun_rate', 'etanks'
        ]
        validateWebServiceParams(self.request,
                                 switchs, [], [],
                                 others,
                                 isJson=True)
        if self.vars.customSpriteEnable == 'on':
            if self.vars.customSprite == 'random':
                for sprite in self.vars.customSpriteMultiSelect.split(','):
                    if sprite not in customSprites:
                        raiseHttp(400,
                                  "Wrong value for customSpriteMultiSelect",
                                  True)
            elif self.vars.customSprite not in customSprites:
                raiseHttp(400, "Wrong value for customSprite", True)
        if self.vars.customShipEnable == 'on':
            if self.vars.customShip == 'random':
                for ship in self.vars.customShipMultiSelect.split(','):
                    if ship not in customShips:
                        raiseHttp(400, "Wrong value for customShipMultiSelect",
                                  True)
            elif self.vars.customShip not in customShips:
                raiseHttp(400, "Wrong value for customShip", True)

        if self.vars.music not in [
                "Don't touch", "Disable", "Randomize", "Customize", "Restore"
        ]:
            raiseHttp(400, "Wrong value for music", True)

        if self.session.customizer == None:
            self.session.customizer = {}

        # update session
        self.session.customizer[
            'colorsRandomization'] = self.vars.colorsRandomization
        self.session.customizer['suitsPalettes'] = self.vars.suitsPalettes
        self.session.customizer['beamsPalettes'] = self.vars.beamsPalettes
        self.session.customizer['tilesPalettes'] = self.vars.tilesPalettes
        self.session.customizer['enemiesPalettes'] = self.vars.enemiesPalettes
        self.session.customizer['bossesPalettes'] = self.vars.bossesPalettes
        self.session.customizer['minDegree'] = self.vars.minDegree
        self.session.customizer['maxDegree'] = self.vars.maxDegree
        self.session.customizer['invert'] = self.vars.invert
        self.session.customizer['globalShift'] = self.vars.globalShift
        self.session.customizer[
            'customSpriteEnable'] = self.vars.customSpriteEnable
        self.session.customizer['customSprite'] = self.vars.customSprite
        if self.vars.customSprite == 'random':
            self.session.customizer[
                'customSpriteMultiSelect'] = self.vars.customSpriteMultiSelect.split(
                    ',')
        self.session.customizer[
            'customItemsEnable'] = self.vars.customItemsEnable
        self.session.customizer['noSpinAttack'] = self.vars.noSpinAttack
        self.session.customizer[
            'customShipEnable'] = self.vars.customShipEnable
        self.session.customizer['customShip'] = self.vars.customShip
        if self.vars.customShip == 'random':
            self.session.customizer[
                'customShipMultiSelect'] = self.vars.customShipMultiSelect.split(
                    ',')
        self.session.customizer['gamepadMapping'] = self.vars.gamepadMapping
        if self.session.customizer['gamepadMapping'] == "on":
            self.session.customizer['preset'] = self.vars.preset
        self.session.customizer['itemsounds'] = self.vars.itemsounds
        self.session.customizer['spinjumprestart'] = self.vars.spinjumprestart
        self.session.customizer['rando_speed'] = self.vars.rando_speed
        self.session.customizer['elevators_speed'] = self.vars.elevators_speed
        self.session.customizer['fast_doors'] = self.vars.fast_doors
        self.session.customizer[
            'Infinite_Space_Jump'] = self.vars.Infinite_Space_Jump
        self.session.customizer[
            'refill_before_save'] = self.vars.refill_before_save
        self.session.customizer['widescreen'] = self.vars.widescreen
        self.session.customizer['AimAnyButton'] = self.vars.AimAnyButton
        self.session.customizer[
            'max_ammo_display'] = self.vars.max_ammo_display
        self.session.customizer[
            'supermetroid_msu1'] = self.vars.supermetroid_msu1
        self.session.customizer[
            'remove_itemsounds'] = self.vars.remove_itemsounds
        self.session.customizer[
            'remove_elevators_speed'] = self.vars.remove_elevators_speed
        self.session.customizer[
            'remove_fast_doors'] = self.vars.remove_fast_doors
        self.session.customizer[
            'remove_spinjumprestart'] = self.vars.remove_spinjumprestart
        self.session.customizer[
            'remove_Infinite_Space_Jump'] = self.vars.remove_Infinite_Space_Jump
        self.session.customizer[
            'remove_rando_speed'] = self.vars.remove_rando_speed
        self.session.customizer[
            'lava_acid_physics'] = self.vars.lava_acid_physics
        self.session.customizer['hell'] = self.vars.hell
        self.session.customizer['hellrun_rate'] = self.vars.hellrun_rate
        self.session.customizer['etanks'] = self.vars.etanks
        self.session.customizer['music'] = self.vars.music

        if self.vars.music == 'Customize':
            musics = self.loadMusics()
            for song, songId in musics["_list"]:
                self.session.customizer[songId] = self.vars[songId]

        # when beam doors patch is detected, don't randomize blue door palette
        no_blue_door_palette = self.vars.no_blue_door_palette

        # call the randomizer
        (fd, jsonFileName) = tempfile.mkstemp()
        params = [
            getPythonExec(),
            os.path.expanduser("~/RandomMetroidSolver/randomizer.py"),
            '--output', jsonFileName, '--patchOnly'
        ]

        if self.vars.itemsounds == 'on':
            params += ['-c', 'itemsounds.ips']
        if self.vars.elevators_speed == 'on':
            params += ['-c', 'elevators_speed.ips']
        if self.vars.fast_doors == 'on':
            params += ['-c', 'fast_doors.ips']
        if self.vars.spinjumprestart == 'on':
            params += ['-c', 'spinjumprestart.ips']
        if self.vars.rando_speed == 'on':
            params += ['-c', 'rando_speed.ips']
        if self.vars.AimAnyButton == 'on':
            params += ['-c', 'AimAnyButton.ips']
        if self.vars.max_ammo_display == 'on':
            params += ['-c', 'max_ammo_display.ips']
        if self.vars.supermetroid_msu1 == 'on':
            params += ['-c', 'supermetroid_msu1.ips']
        if self.vars.Infinite_Space_Jump == 'on':
            params += ['-c', 'Infinite_Space_Jump']
        if self.vars.refill_before_save == 'on':
            params += ['-c', 'refill_before_save.ips']
        if self.vars.widescreen == 'on':
            params += ['-c', 'widescreen.ips']
        if self.vars.remove_itemsounds == 'on':
            params += ['-c', 'remove_itemsounds.ips']
        if self.vars.remove_elevators_speed == 'on':
            params += ['-c', 'remove_elevators_speed.ips']
        if self.vars.remove_fast_doors == 'on':
            params += ['-c', 'remove_fast_doors.ips']
        if self.vars.remove_rando_speed == 'on':
            params += ['-c', 'remove_rando_speed.ips']
        if self.vars.remove_spinjumprestart == 'on':
            params += ['-c', 'remove_spinjumprestart.ips']
        if self.vars.remove_Infinite_Space_Jump == 'on':
            params += ['-c', 'remove_Infinite_Space_Jump.ips']
        if self.vars.music == 'Disable':
            params += ['-c', 'No_Music']
        if self.vars.music == 'Randomize':
            params += ['-c', 'random_music.ips']
        if self.vars.music == 'Restore':
            params += ['-c', 'vanilla_music.ips']
        if self.vars.lava_acid_physics == 'on':
            params += ['-c', 'lava_acid_physics.ips']
        if self.vars.hell == 'on':
            params += ['-c', 'hell.ips']
        if self.vars.hellrun_rate != 'off':
            params += ['--hellrun', self.vars.hellrun_rate]
        if self.vars.etanks != 'off':
            params += ['--etanks', self.vars.etanks]

        if self.vars.colorsRandomization == 'on':
            params.append('--palette')
            if self.vars.suitsPalettes == 'off':
                params.append('--no_shift_suit_palettes')
            if self.vars.beamsPalettes == 'off':
                params.append('--no_shift_beam_palettes')
            if self.vars.tilesPalettes == 'off':
                params.append('--no_shift_tileset_palette')
            if self.vars.enemiesPalettes == 'off':
                params.append('--no_shift_enemy_palettes')
            if self.vars.bossesPalettes == 'off':
                params.append('--no_shift_boss_palettes')
            if self.vars.globalShift == 'off':
                params.append('--no_global_shift')
                params.append('--individual_suit_shift')
                params.append('--individual_tileset_shift')
                params.append('--no_match_ship_and_power')
            params += [
                '--min_degree', self.vars.minDegree, '--max_degree',
                self.vars.maxDegree
            ]
            if self.vars.invert == 'on':
                params.append('--invert')
            if no_blue_door_palette == 'on':
                params.append('--no_blue_door_palette')

        if self.vars.customSpriteEnable == 'on':
            if self.vars.customSprite == 'random':
                sprite = random.choice(
                    self.session.customizer['customSpriteMultiSelect'])
            else:
                sprite = self.vars.customSprite

            params += ['--sprite', "{}.ips".format(sprite)]
            with DB() as db:
                db.addSprite(sprite)
            if self.vars.customItemsEnable == 'on':
                params.append('--customItemNames')
            if self.vars.noSpinAttack == 'on':
                params.append('--no_spin_attack')
        if self.vars.customShipEnable == 'on':
            if self.vars.customShip == 'random':
                ship = random.choice(
                    self.session.customizer['customShipMultiSelect'])
            else:
                ship = self.vars.customShip

            params += ['--ship', "{}.ips".format(ship)]
            with DB() as db:
                db.addShip(ship)
            if customShips[ship].get("hideSamus", False):
                params += ['-c', 'custom_ship.ips']
            if customShips[ship].get("showSamusAtTakeoff", False):
                params += ['-c', 'Ship_Takeoff_Disable_Hide_Samus']
        if self.vars.seedKey != None:
            with DB() as db:
                seedIpsInfo = db.getSeedIpsInfo(self.vars.seedKey)
            print("seedIpsInfo: {}".format(seedIpsInfo))
            if seedIpsInfo == None or len(seedIpsInfo) == 0:
                raiseHttp(400, json.dumps("Can't get seed info"))
            (uploadStatus, fileName) = seedIpsInfo[0]
            if uploadStatus not in ['local', 'pending', 'uploaded']:
                raiseHttp(400, json.dumps("Seed is not available"))

            ipsFileName = os.path.join(localIpsDir, self.vars.seedKey,
                                       fileName.replace('sfc', 'ips'))
            params += ['--seedIps', ipsFileName]

        if self.vars.music == "Customize":
            musics = self.loadMusics()
            customMusic = {
                'params': {
                    "varia": self.vars.varia == "true",
                    "area": self.vars.area == "true",
                    "boss": self.vars.boss == "true"
                },
                'mapping': {}
            }
            for song, songId in musics["_list"]:
                newSong = self.vars[songId]
                if newSong not in musics:
                    raiseHttp(400, "unknown song for {}".format(song))
                if newSong != song:
                    customMusic['mapping'][song] = newSong
            (fd2, jsonMusicFileName) = tempfile.mkstemp()
            with open(jsonMusicFileName, 'w') as musicFile:
                json.dump(customMusic, musicFile)
            params += ['--music', jsonMusicFileName]

        if self.vars.gamepadMapping == "on":
            preset = self.vars.preset
            fullPath = '{}/{}.json'.format(getPresetDir(preset), preset)
            controlMapping = PresetLoader.factory(
                fullPath).params['Controller']
            (custom, controlParam) = getCustomMapping(controlMapping)
            if custom == True:
                print("apply custom gamepad mapping from preset: {}".format(
                    self.vars.preset))
                params += ['--controls', controlParam]
                if "Moonwalk" in controlMapping and controlMapping[
                        "Moonwalk"] == True:
                    params.append('--moonwalk')

        print("before calling: {}".format(params))
        start = datetime.now()
        ret = subprocess.call(params)
        end = datetime.now()
        duration = (end - start).total_seconds()
        print("ret: {}, duration: {}s".format(ret, duration))

        if self.vars.music == "Customize":
            os.close(fd2)
            os.remove(jsonMusicFileName)

        if ret == 0:
            with open(jsonFileName) as jsonFile:
                data = json.load(jsonFile)

            os.close(fd)
            os.remove(jsonFileName)

            return json.dumps(data)
        else:
            # extract error from json
            try:
                with open(jsonFileName) as jsonFile:
                    msg = json.load(jsonFile)['errorMsg']
            except:
                msg = "customizerWebService: something wrong happened"

            os.close(fd)
            os.remove(jsonFileName)
            raiseHttp(400, json.dumps(msg))
Esempio n. 11
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)
Esempio n. 12
0
    def run(self):
        self.initExtStatsSession()

        if self.vars.action == 'Load':
            (ok, msg) = self.validateExtStatsParams()
            if not ok:
                self.session.flash = msg
                redirect(URL(r=self.request, f='extStats'))

            self.updateExtStatsSession()

            skillPreset = self.vars.preset
            randoPreset = self.vars.randoPreset

            # load rando preset to get majors split
            fullPath = 'rando_presets/{}.json'.format(randoPreset)
            if not os.path.isfile(fullPath):
                raiseHttp(400, "Unknown rando preset: {}".format(e))
            try:
                with open(fullPath) as jsonFile:
                    randoPresetContent = json.load(jsonFile)
            except Exception as e:
                raiseHttp(400, "Can't load the rando preset: {}".format(e))
            majorsSplit = randoPresetContent["majorsSplit"]

            # load skill preset
            fullPath = '{}/{}.json'.format(getPresetDir(skillPreset),
                                           skillPreset)
            try:
                skillPresetContent = PresetLoader.factory(fullPath).params
                completePreset(skillPresetContent)
            except Exception as e:
                raiseHttp(400, "Error loading the skill preset: {}".format(e))

            with DB() as db:
                (itemsStats, techniquesStats, difficulties,
                 solverStatsRaw) = db.getExtStat(skillPreset, randoPreset)

            solverStats = {}
            if "avgLocs" in solverStatsRaw:
                solverStats["avgLocs"] = transformStats(
                    solverStatsRaw["avgLocs"])
                solverStats["avgLocs"].insert(
                    0, ['Available locations', 'Percentage'])
            if "open14" in solverStatsRaw:
                open14 = transformStats(solverStatsRaw["open14"])
                open24 = transformStats(solverStatsRaw["open24"])
                open34 = transformStats(solverStatsRaw["open34"])
                open44 = transformStats(solverStatsRaw["open44"])
                solverStats["open"] = zipStats(
                    [open14, open24, open34, open44])
                solverStats["open"].insert(0, [
                    'Collected items', '1/4 locations available',
                    '2/4 locations available', '3/4 locations available',
                    '4/4 locations available'
                ])

            # check that all items are present in the stats:
            nbItems = 19
            nbLocs = 109
            if itemsStats and len(itemsStats) != nbItems:
                for i, item in enumerate([
                        'Bomb', 'Charge', 'Grapple', 'Gravity', 'HiJump',
                        'Ice', 'Missile', 'Morph', 'Plasma', 'PowerBomb',
                        'ScrewAttack', 'SpaceJump', 'Spazer', 'SpeedBooster',
                        'SpringBall', 'Super', 'Varia', 'Wave', 'XRayScope'
                ]):
                    if itemsStats[i][1] != item:
                        itemsStats.insert(i, [itemsStats[0][0], item] +
                                          [0] * nbLocs)
        else:
            itemsStats = None
            techniquesStats = None
            difficulties = None
            solverStats = None
            skillPresetContent = None
            majorsSplit = None

        (randoPresets, tourRandoPresets) = loadRandoPresetsList(self.cache,
                                                                filter=True)
        (stdPresets, tourPresets, comPresets) = loadPresetsList(self.cache)

        return dict(stdPresets=stdPresets,
                    tourPresets=tourPresets,
                    randoPresets=randoPresets,
                    tourRandoPresets=tourRandoPresets,
                    itemsStats=itemsStats,
                    techniquesStats=techniquesStats,
                    categories=Knows.categories,
                    knowsDesc=Knows.desc,
                    skillPresetContent=skillPresetContent,
                    locations=locations,
                    majorsSplit=majorsSplit,
                    difficulties=difficulties,
                    solverStats=solverStats)