Пример #1
0
 def test_encrypt(self):
     message_string = "Important information with quite some length. " + \
                      "This message is as long as this because otherwise only one cipher block would " + \
                      "be encrypted. This long message insures that more than one block is needed."
     password = "******"
     message = message_string.encode('utf-8')
     crypter = Crypter(Crypter.createIvKey(password.encode('utf-8'), "pepper".encode('utf-8'), iterations=3))
     ciphertext = crypter.encrypt(message)
     self.assertEqual(
         b'EFEgY5bexGnwjGSUQKK35TPD7fAjG66REq5m9N1eyFHrZQwzv+aLc7bVmJ9FzCyxbCnbyUnzDKiY505br' +
         b'oEb+KO41XKW668xJzh/JvOK0Cu/+bc4/zSFHZM6JsTYEVDIXgR39ZlypeB34jDVI2544w1ey+DmTWbe8n' +
         b'UbagjnmRkok6kOAq8Avsf9BVJMw3BnSn/4cCC+gOxOJY5fp4DecNDQnp0HyyUz2VMMh/JUYILS5+67fXq' +
         b'29CbIQ1DOTqDfqRPA62nkRVPY83cKIe/UXw==',
         b64encode(ciphertext))
Пример #2
0
 def test_encrypt(self):
     message_string = "Important information with quite some length. " + \
                      "This message is as long as this because otherwise only one cipher block would " + \
                      "be encrypted. This long message insures that more than one block is needed."
     password = "******"
     message = message_string.encode('utf-8')
     crypter = Crypter(
         Crypter.createIvKey(password.encode('utf-8'),
                             "pepper".encode('utf-8'),
                             iterations=3))
     ciphertext = crypter.encrypt(message)
     self.assertEqual(
         b'EFEgY5bexGnwjGSUQKK35TPD7fAjG66REq5m9N1eyFHrZQwzv+aLc7bVmJ9FzCyxbCnbyUnzDKiY505br'
         +
         b'oEb+KO41XKW668xJzh/JvOK0Cu/+bc4/zSFHZM6JsTYEVDIXgR39ZlypeB34jDVI2544w1ey+DmTWbe8n'
         +
         b'UbagjnmRkok6kOAq8Avsf9BVJMw3BnSn/4cCC+gOxOJY5fp4DecNDQnp0HyyUz2VMMh/JUYILS5+67fXq'
         + b'29CbIQ1DOTqDfqRPA62nkRVPY83cKIe/UXw==', b64encode(ciphertext))
Пример #3
0
class Scrambler(object):
    def __init__(self, parser, password):
        self.crypter = Crypter(password)
        self.parser = parser

    def scramble_func_names(self):
        scrambled = dict()

        for func_name in self.parser.func_names:
            scrambled[func_name] = self._scramble(func_name)

        return scrambled

    def _scramble(self, str):
        data = str.encode()
        encrypted = self.crypter.encrypt(data)
        hasher = MD5.new()
        hasher.update(encrypted)
        return hasher.hexdigest()
Пример #4
0
class API(object):
    def __init__(self):
        self.crypter = Crypter()
        self.base = 'https://g-api.grandsummoners.com/app/'
        self.s = requests.Session()
        self.s.headers.update({
            'Content-Type': 'application/x-www-form-urlencoded',
            'Connection': 'keep-alive',
            'User-Agent':
            'Grand%20Summoners/145 CFNetwork/808.2.16 Darwin/16.3.0',
            'Accept-Language': 'en-gb',
            'Accept-Encoding': 'gzip, deflate'
        })
        self.s.verify = False
        self.app_hash = 'c8fb64652fcdfb325012c09f7efea208'
        self.app_version = 33
        self.master_version = 438
        self.resource_version = 191
        self.scenario_master_version = 150
        self.key = 'ZFlyUU0ycFJaTVlFRkVoaA=='
        self.useNewKey = False
        self.device_id = None
        self.session_id = None

    def setDevice(self, id):
        self.platform_type = id

    def setProxy(self, ip, port):
        part = '%s:%s' % (ip, port)
        self.log('using proxy %s' % (part))
        self.s.proxies.update({
            'http': 'http://%s' % part,
            'https': 'https://%s' % part,
        })

    def getUnitName(self, id):
        id = str(id)
        if id in unit_master.data:
            return unit_master.data[id]['name']
        self.log('%s missing' % (id))
        return None

    def getUnitRarity(self, id):
        id = str(id)
        if id in unit_master.data:
            return unit_master.data[id]['rarity']
        self.log('%s missing' % (id))
        return None

    def getEquipName(self, id):
        id = str(id)
        if id in item_master.data:
            return item_master.data[id]['name']
        self.log('%s missing' % (id))
        return None

    def getEquipRarity(self, id):
        id = str(id)
        if id in item_master.data:
            return item_master.data[id]['rarity']
        self.log('%s missing' % (id))
        return None

    def setNextKey(self, key):
        self.key = base64.b64encode(key)

    def challenge_end(self, challenge_id):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "challenge_id": challenge_id,
            "master_version": self.master_version,
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "user_unique_id": ""
        })

    def challenge_top(self):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "master_version": self.master_version,
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "user_unique_id": ""
        })

    def eventshop_page(self, event_id):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "event_id": event_id,
            "master_version": self.master_version,
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "user_unique_id": ""
        })

    def gacha_do(self, button_no, gacha_id):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "button_no": button_no,
            "gacha_id": gacha_id,
            "master_version": self.master_version,
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "user_unique_id": ""
        })

    def gacha_top(self):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "master_version": self.master_version,
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "user_unique_id": ""
        })

    def game_init(self):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "encryption_key": "dYrQM2pRZMYEFEhh\\ZgAEi{I[?ZToT@G",
            "master_version": 0,
            "platform_type": self.platform_type,
            "resource_version": 0,
            "scenario_master_version": 0
        })

    def home(self):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "master_version": self.master_version,
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "user_unique_id": ""
        })

    def login(self):
        res = self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "country_code": "",
            "device_id": "",
            "device_token": "",
            "is_agree": 1,
            "master_version": self.master_version,
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "user_unique_id": ""
        })
        self.useNewKey = True
        return res

    def setSessionId(self, id):
        self.session_id = id

    def setDeviceId(self, id):
        self.device_id = id

    def doLogin(self, id1, id2, force=False):
        if force:
            self.useNewKey = False
            self.setSessionId(id2)
            self.setDeviceId(id1)
            return self.login()
        else:
            self.game_init()
            self.version_get()
            self.setSessionId(id2)
            self.setDeviceId(id1)
            return self.login()

    def message_list_get(self, page):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "get_type": 0,
            "master_version": self.master_version,
            "page": page,
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "user_unique_id": ""
        })

    def message_open(self, message_id_list):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "master_version": self.master_version,
            "message_id_list": message_id_list,
            "page": 1,
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "user_unique_id": ""
        })

    def party_update(self, user_party_list):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "master_version": self.master_version,
            "party": {
                "main_no": 0,
                "user_party_list": user_party_list
            },
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "user_unique_id": ""
        })

    def quest_end(self,
                  quest_end,
                  tutorial_is_end=None,
                  tutorial_step=None,
                  tutorial_type=None):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "is_ranking_view": False,
            "master_version": self.master_version,
            "platform_type": self.platform_type,
            "quest_end": quest_end,
            "resource_version": self.resource_version,
            "tutorial_is_end": tutorial_is_end,
            "tutorial_step": tutorial_step,
            "tutorial_type": tutorial_type,
            "user_unique_id": ""
        })

    def quest_start(self, quest_id, dungeon_id=10100, map_id=10000):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "dungeon_id": dungeon_id,
            "food_id": 0,
            "map_id": map_id,
            "master_version": self.master_version,
            "party": {},
            "platform_type": self.platform_type,
            "quest_id": quest_id,
            "resource_version": self.resource_version,
            "supporter_id": "0",
            "user_tool_id": 0,
            "user_unique_id": ""
        })

    def register_email(self, mail, password):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "email": mail,
            "master_version": self.master_version,
            "password": password,
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "user_unique_id": ""
        })

    def scenario_end(self,
                     played_scenario_id,
                     tutorial_is_end=0,
                     tutorial_step=0,
                     tutorial_type=0):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "master_version": self.master_version,
            "platform_type": self.platform_type,
            "played_scenario_id": played_scenario_id,
            "resource_version": self.resource_version,
            "tutorial_is_end": tutorial_is_end,
            "tutorial_step": tutorial_step,
            "tutorial_type": tutorial_type,
            "user_unique_id": ""
        })

    def tutorial_update(self, tutorial_is_end, tutorial_step, tutorial_type):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "master_version": self.master_version,
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "tutorial_is_end": tutorial_is_end,
            "tutorial_step": tutorial_step,
            "tutorial_type": tutorial_type,
            "user_unique_id": ""
        })

    def user_create(self, nickname):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "country_code": "",
            "master_version": self.master_version,
            "nickname": nickname,
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "user_unique_id": ""
        })

    def tutorial_skip(self):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "country_code": "",
            "master_version": self.master_version,
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "user_unique_id": ""
        })

    def tutorial_unit_add(self, tutorial_step, tutorial_type, unit_no=1):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "country_code": "",
            "master_version": self.master_version,
            "platform_type": self.platform_type,
            "resource_version": self.resource_version,
            "tutorial_step": tutorial_step,
            "tutorial_type": tutorial_type,
            "unit_no": unit_no,
            "user_unique_id": ""
        })

    def version_get(self):
        return self.callAPI({
            "app_hash": self.app_hash,
            "app_version": self.app_version,
            "master_version": 0,
            "platform_type": self.platform_type,
            "resource_version": 0
        })

    def decrypt(self, input):
        return self.crypter.decrypt(
            input,
            'ZFlyUU0ycFJaTVlFRkVoaA==' if not self.useNewKey else self.key)

    def encrypt(self, input):
        return self.crypter.encrypt(
            input,
            'ZFlyUU0ycFJaTVlFRkVoaA==' if not self.useNewKey else self.key)

    def genRandomIP(self):
        return socket.inet_ntoa(
            struct.pack('>I', random.randint(1, 0xffffffff)))

    def callAPI(self, idata):
        _caller = sys._getframe(1).f_code.co_name
        if 'scenario_master_version' not in idata:
            idata['scenario_master_version'] = self.scenario_master_version
        self.log('..%s()' % (_caller))
        r = self.s.post(self.base + _caller,
                        data=json.dumps({
                            'body':
                            self.encrypt(idata),
                            'device_id':
                            '' if not self.device_id else self.device_id,
                            'session_id':
                            '' if not self.session_id else self.session_id
                        }))
        if 'error_message' in r.content:
            self.log('error_message:%s()' % (_caller))
            return None
        body = json.loads(r.content)['body']
        if len(body) <= 100: return body
        data = json.loads(self.decrypt(body))
        if 'STATUS' in data and data['STATUS'] != 100:
            self.log('%s() status:%s' % (_caller, data['STATUS']))
            return None
        if 'encryption_key' in data: self.setNextKey(data['encryption_key'])
        if 'session_id' in data:
            self.session_id = data['session_id']
            if 'player_update' in data['result']:
                if 'public_id' in data['result']['player_update']:
                    self.log('hello %s:%s' %
                             (data['result']['player_update']['public_id'],
                              data['result']['player_update']['nickname']))
                if 'device_id' in data['result']['player_update']:
                    self.device_id = data['result']['player_update'][
                        'device_id']
            if 'master_version' in data['result']:
                self.master_version = data['result']['master_version']
                self.resource_version = data['result']['resource_version']
                self.scenario_master_version = data['result'][
                    'scenario_master_version']
        return data

    def log(self, msg):
        print '[%s]%s' % (time.strftime('%H:%M:%S'), msg.encode('utf-8'))

    def sappend(self, d, f):
        with io.open(f, 'a', encoding='utf8') as the_file:
            the_file.write('%s\n' % (unicode(d)))

    def genRandomHex(self, n):
        return ''.join([random.choice('0123456789ABCDEF')
                        for x in range(n)]).lower()

    def doMission(self,
                  quest_id,
                  tutorial_is_end=None,
                  tutorial_step=None,
                  tutorial_type=None):
        start = self.quest_start(quest_id)
        defeated_enemies = []
        for i in start['result']['quest']['battle_list']:
            for j in i['enemy_list']:
                if j == 0: continue
                defeated_enemies.append(j['enemy_no'])
        quest_end = {}
        quest_end['boss_id'] = -1
        quest_end['break_count'] = 0
        quest_end['break_max_damage'] = 0
        quest_end['clear_time'] = 13.312557220458984
        quest_end['combo_max'] = 0
        quest_end['continue_count'] = 0
        quest_end['crystal_count'] = 11
        quest_end['dead_count'] = 0
        quest_end['defeated_enemies'] = defeated_enemies
        quest_end['dungeon_id'] = 1
        quest_end['equipped_item_id_list'] = [300018000, 300001050]
        quest_end['fullcharge_kill'] = True
        quest_end['is_state_abnormal'] = False
        quest_end['live_unit_count'] = 2
        quest_end['map_id'] = 10000
        quest_end['max_damage'] = 3528
        quest_end['multi_user_id_list'] = []
        quest_end['quest_id'] = quest_id
        quest_end['reached_battle_no'] = len(
            start['result']['quest']['battle_list'])
        quest_end['rest_boss_hp'] = 0
        quest_end['result'] = 1
        quest_end['used_item_count'] = {}
        return self.quest_end(quest_end, tutorial_is_end, tutorial_step,
                              tutorial_type)

    def getAllGifts(self):
        message_list = self.message_list_get(1)['result']['message_list']
        message_id_list = []
        for i in message_list:
            message_id_list.append(i['id'])
        while (True):
            res = self.message_open(
                message_id_list)['result']['message']['player_message_list']
            if len(res) == 0: break
            message_id_list = []
            for i in res:
                message_id_list.append(i['id'])

    def getAllChallenges(self):
        challenge = self.challenge_top(
        )['result']['player_update']['challenge']
        for i in challenge:
            if i['clear_value'] == i['current_value']:
                self.challenge_end(i['user_challenge_id'])

    def exportUnits(self):
        units = {}
        equip = {}
        device_id = self.device_id
        session_id = self.session_id
        self.device_id = None
        self.session_id = None
        res = self.doLogin(device_id, session_id, True)
        player_unit_list = res['result']['player']['unit']['player_unit_list']
        player_item_list = res['result']['player']['item']['player_item_list']
        fourstar = 0
        for u in player_unit_list:
            name = self.getUnitName(u['unit_id'])
            if not name: continue
            rare = self.getUnitRarity(u['unit_id'])
            if not rare: continue
            if rare < 4:
                self.log('unit:%s rare:%s' % (name, rare))
                continue
            if rare >= 4 and 'Chicken' not in name: fourstar += 1
            if u['unit_id'] not in units:
                units[u['unit_id']] = {}
                units[u['unit_id']]['name'] = name
                units[u['unit_id']]['count'] = 1
            else:
                units[u['unit_id']]['count'] += 1
        units = ';'.join(
            ['%s x%s' % (units[x]['name'], units[x]['count']) for x in units])
        fourstare = 0
        for u in player_item_list:
            name = self.getEquipName(u['item_id'])
            if not name: continue
            rare = self.getEquipRarity(u['item_id'])
            if not rare: continue
            if rare < 4:
                self.log('equip:%s rare:%s' % (name, rare))
                continue
            if rare >= 4: fourstare += 1
            if u['item_id'] not in equip:
                equip[u['item_id']] = {}
                equip[u['item_id']]['name'] = name
                equip[u['item_id']]['count'] = 1
            else:
                equip[u['item_id']]['count'] += 1
        if True:
            _password = self.genRandomHex(10)
            _mail = '*****@*****.**' % (self.genRandomHex(8))
            #self.getAllGifts()
            print _mail, _password
            self.register_email(_mail, _password)
            equip = ';'.join([
                '%s x%s' % (equip[x]['name'], equip[x]['count']) for x in equip
            ])
            self.sappend(
                '%s,%s,%s,%s,%s,%s:%s,%s,%s' %
                ('ios' if self.platform_type == 2 else 'android', fourstar,
                 units, fourstare, equip, _mail, _password, device_id,
                 session_id), 'reroll.csv')
        else:
            print fourstar

    def reroll(self, skipTut=False):
        if skipTut:
            self.game_init()
            self.version_get()
            self.user_create(self.genRandomHex(6))
            if not self.login(): return
            self.tutorial_skip()
            self.tutorial_unit_add(12, 1, 2)
            self.scenario_end(1010399, 1, 13, 1)
            self.home()
            self.getAllGifts()
            self.exportUnits()
        else:
            self.game_init()
            self.version_get()
            self.user_create(self.genRandomHex(6))
            if not self.login(): return
            self.scenario_end(1000000, 0, 2, 1)
            res = self.doMission(10101, 0, 4, 1)
            self.scenario_end(1010190)
            self.tutorial_update(0, 5, 1)
            self.scenario_end(10020, 0, 6, 1)
            self.tutorial_update(0, 7, 1)
            self.home()
            player_unit_list = res['result']['player_update']['unit'][
                'player_unit_list']
            user_party_list = [{
                "leader_unit_id":
                player_unit_list[1]['id'],
                "no":
                0,
                "unit": [{
                    "id": player_unit_list[1]['id'],
                    "no": 0
                }, {
                    "id": player_unit_list[0]['id'],
                    "no": 1
                }, {
                    "id": -1,
                    "no": 2
                }, {
                    "id": -1,
                    "no": 3
                }]
            }]
            self.party_update(user_party_list)
            self.scenario_end(1010201, 0, 7, 1)
            self.scenario_end(10041)
            self.doMission(10102)
            self.scenario_end(1010290)  #17
            self.scenario_end(10050, 0, 9, 1)
            self.scenario_end(10060, 0, 10, 1)
            self.scenario_end(10070)  #20
            self.doMission(10103)
            self.scenario_end(1010301)
            self.scenario_end(1010390)  #25
            self.tutorial_unit_add(12, 1, 2)
            self.scenario_end(1010399, 1, 13, 1)
            self.gacha_top()
            self.home()
            self.gacha_do(3, 10001)
            self.gacha_do(3, 20001)
            self.getAllGifts()
            self.eventshop_page(2008000)
            self.scenario_end(201805301)
            self.getAllChallenges()
            #self.gacha_do(2,10017)
            #self.gacha_do(2,10018)
            #self.gacha_do(2,20006)
            #self.gacha_do(2,20007)
            self.home()
            self.exportUnits()