Ejemplo n.º 1
1
    def __init__(self, main, channels, default_channel=None):
        super(ChannelAddWidget, self).__init__()
        self.setObjectName("ChannelAddWidget")
        self.main_win = main
        self.channels = channels
        self.default_channel = default_channel
        self.channel = {}
        self.linedit_list = []
        self.game = self.main_win.games[self.main_win.game_index]
        combox_items = os.listdir(Utils.get_full_path('channelsdk'))

        v_layout = QVBoxLayout()
        v_layout.addSpacing(30)
        select_channel_combox = QComboBox()
        select_channel_combox.addItems(combox_items)
        select_channel_combox.activated[str].connect(self.select_channel)
        v_layout.addWidget(select_channel_combox, alignment=Qt.AlignHCenter)
        v_layout.addSpacing(30)

        h_layout1 = QHBoxLayout()
        form_layout1 = QFormLayout()
        form_layout1.setContentsMargins(10, 10, 10, 0)
        game_appid_value = QLabel(self.game['id'])
        form_layout1.addRow("游戏ID:", game_appid_value)
        game_appid_value.setTextInteractionFlags(Qt.TextSelectableByMouse)
        self.channel_id_value = QLineEdit()
        self.channel_id_value.setPlaceholderText("必填参数")
        form_layout1.addRow("渠道ID:", self.channel_id_value)
        self.game_name_value = QLineEdit()
        self.game_name_value.setText(self.game['name'])
        form_layout1.addRow("游戏名称:", self.game_name_value)
        self.game_package_value = QLineEdit()
        form_layout1.addRow("游戏包名:", self.game_package_value)
        self.game_vcode_value = QLineEdit()
        form_layout1.addRow("游戏版本号:", self.game_vcode_value)
        self.game_vname_value = QLineEdit()
        form_layout1.addRow("游戏版本名:", self.game_vname_value)
        self.debug_value = QLineEdit("false")
        form_layout1.addRow("打印日志:", self.debug_value)
        h_layout1.addLayout(form_layout1)
        self.form_layout2 = QFormLayout()
        self.form_layout2.setContentsMargins(10, 10, 10, 0)
        h_layout1.addLayout(self.form_layout2)
        v_layout.addLayout(h_layout1)

        h_layout2 = QHBoxLayout()
        back_btn = QPushButton("返 回")
        back_btn.setFixedWidth(100)
        back_btn.clicked.connect(self.back)
        h_layout2.addWidget(back_btn, alignment=Qt.AlignLeft)
        add_btn = QPushButton("添 加")
        add_btn.setFixedWidth(100)
        add_btn.clicked.connect(self.add)
        h_layout2.addWidget(add_btn, alignment=Qt.AlignRight)
        v_layout.addSpacing(50)
        v_layout.addLayout(h_layout2)

        self.setLayout(v_layout)
        # 默认松鼠SDK
        select_channel_combox.setCurrentText("songshu")
        self.select_channel("songshu")
Ejemplo n.º 2
0
 def add(self):
     if self.channel_id_value.text().strip() == "":
         QMessageBox.warning(self, "警告", "渠道ID不能为空!")
         return
     self.channel['channelId'] = self.channel_id_value.text().strip()
     for channel in self.channels:
         if self.channel['channelId'] == channel['channelId']:
             QMessageBox.warning(self, "警告", "渠道已存在!")
             return
     self.channel['gameName'] = self.game_name_value.text().strip()
     self.channel['package'] = self.game_package_value.text().strip()
     self.channel['gameVersionCode'] = self.game_vcode_value.text().strip()
     self.channel['gameVersionName'] = self.game_vname_value.text().strip()
     self.channel['debug'] = self.debug_value.text().strip()
     for i in range(len(self.linedit_list)):
         if self.linedit_list[i].text().strip() == "":
             QMessageBox.warning(self, "警告", "渠道参数不能为空!")
             return
         self.channel['sdkParams'][i]['value'] = self.linedit_list[i].text(
         ).strip()
     self.channels.append(self.channel)
     Utils.add_channel(
         Utils.get_full_path('games/' + self.game['id'] + '/config.xml'),
         self.channel)
     self.main_win.set_channel_list_widget(self.channels)
Ejemplo n.º 3
0
    def save_data(self):
        if self.game_name_value.text().strip() == "":
            QMessageBox.warning(self, "警告", "游戏名称不能为空!")
            return False
        if self.keystore_path.text().strip() == "":
            QMessageBox.warning(self, "警告", "必须上传keystore签名文件!")
            return False
        if self.keystore_pwd_value.text().strip() == "":
            QMessageBox.warning(self, "警告", "keystore密码不能为空!")
            return False
        if self.keystore_alias_value.text().strip() == "":
            QMessageBox.warning(self, "警告", "alias不能为空!")
            return False
        if self.keystore_aliaspwd_value.text().strip() == "":
            QMessageBox.warning(self, "警告", "alias密码不能为空!")
            return False
        self.game['name'] = self.game_name_value.text().strip()
        self.game['desc'] = self.game_desc_value.toPlainText().strip()
        if self.keystore_exchanged:
            keystore = os.path.basename(self.keystore_path.text().strip())
            self.game['keystore'] = keystore
            self.game['keypwd'] = self.keystore_pwd_value.text().strip()
            self.game['alias'] = self.keystore_alias_value.text().strip()
            self.game['aliaspwd'] = self.keystore_aliaspwd_value.text().strip()
            keystore_path = Utils.get_full_path('games/' + self.game['id'] +
                                                '/keystore/' + keystore)
            if not os.path.exists(keystore_path):
                Utils.copy_file(self.keystore_path.text().strip(),
                                keystore_path)

        self.main_win.games[self.main_win.game_index] = self.game
        self.game_list_model.update_item(self.main_win.game_index, self.game)
        return Utils.update_games(Utils.get_full_path('games/games.xml'),
                                  self.game, self.main_win.game_index)
Ejemplo n.º 4
0
def copy_root_ext_files(apk_file, decompile_dir):
    aapt = Utils.get_full_path('tools/aapt2.exe')
    ignore_files = [
        'AndroidManifest.xml', 'apktool.yml', 'smali', 'res', 'original',
        'lib', 'libs', 'build', 'assets', 'unknown', 'kotlin',
        'smali_classes2', 'smali_classes3', 'smali_classes4', 'smali_classes5'
    ]
    ignore_file_paths = []
    for file in ignore_files:
        path = os.path.join(decompile_dir, file)
        ignore_file_paths.append(path)

    add_files = []
    add_files = Utils.list_files(decompile_dir, add_files, ignore_file_paths)
    if len(add_files) <= 0:
        return 0
    cmd = '%s add %s'
    for f in add_files:
        name = f[len(decompile_dir) + 1:]
        cmd = cmd + ' ' + name
    cmd = cmd % (aapt, apk_file)
    curr_path = os.getcwd()
    os.chdir(decompile_dir)
    ret = Utils.exec_cmd(cmd)
    os.chdir(curr_path)
    return ret
Ejemplo n.º 5
0
def copy_libs(decompile_dir, sdk_dir):

    cpus = [
        'arm64-v8a', 'armeabi', 'armeabi-v7a', 'mips', 'mips64', 'x86',
        'x86_64'
    ]
    dest_dir = os.path.join(decompile_dir, 'lib')
    src_dir = os.path.join(sdk_dir, 'libs')
    if not os.path.exists(src_dir):
        return
    if os.path.exists(dest_dir):
        for f in os.listdir(dest_dir):
            if f.endswith('.jar'):
                continue
            source_file = os.path.join(src_dir, f)
            target_file = os.path.join(dest_dir, f)
            if os.path.exists(source_file):
                Utils.copy_file(source_file, target_file)
    else:
        os.mkdir(dest_dir)
        for fi in os.listdir(src_dir):
            if fi.endswith('.jar'):
                continue
            source_file = os.path.join(src_dir, fi)
            target_file = os.path.join(dest_dir, fi)
            Utils.copy_file(source_file, target_file)
Ejemplo n.º 6
0
def decompile_apk(apk_file, target_dir, frame_work_dir):
    java = Utils.get_full_path('tools/jdk/bin/java')
    apk_tool = Utils.get_full_path('tools/apktool.jar')
    os.makedirs(target_dir)
    os.makedirs(frame_work_dir)
    cmd = "%s -jar %s d %s -o %s -p %s -f" % (java, apk_tool, apk_file,
                                              target_dir, frame_work_dir)
    return Utils.exec_cmd(cmd)
Ejemplo n.º 7
0
def signUp():
	if fl.request.method == 'POST':
		status = signUpUser(fl.request.form)
		if status:
			return fl.redirect(fl.url_for('renderLogin', err = status))
		else:
			ut.sendEmailConfirmation(fl.request.form['email'], fl.session['usrName'], host_url)
			return fl.render_template('signUpConfirmationPage.html')
	else:
		return fl.render_template('loginPage.html', parent = fl.url_for('signUp'))
Ejemplo n.º 8
0
def write_develop_info(game, channel, decompile_dir):
    assets_path = os.path.join(decompile_dir, 'assets')
    if not os.path.exists(assets_path):
        os.makedirs(assets_path)
    develop_config_file = os.path.join(assets_path,
                                       'developer_configs_ss.properties')
    ret = Utils.write_developer_properties(game, channel, develop_config_file)
    if ret:
        return ret
    plugin_file = os.path.join(assets_path, 'plugin_configs_ss.xml')
    return Utils.write_plugin_config(channel, plugin_file)
Ejemplo n.º 9
0
def dex2smali(dex_file, target_dir, path):
    """
        Transfer the dex to smali.
    """
    if not os.path.exists(dex_file):
        LogUtils.error('the dexfile is not exists. path:%s', dex_file)
        return 1
    if not os.path.exists(target_dir):
        os.makedirs(target_dir)
    smali_tool = Utils.get_full_path('tools/baksmali.jar')
    java = Utils.get_full_path('tools/jdk/bin/java')
    cmd = '%s -jar %s -o %s %s' % (java, smali_tool, target_dir, dex_file)
    return Utils.exec_cmd(cmd)
Ejemplo n.º 10
0
 def exchange_icon(self):
     fname = QFileDialog.getOpenFileName(
         self, '选择icon',
         Utils.get_full_path('games/' + self.game['id'] + '/icon/'),
         ("Images (*.png)"))
     if fname[0]:
         pix = QPixmap(fname[0])
         if pix.width() != 512 or pix.height() != 512:
             QMessageBox.warning(self, "警告", "必须上传512*512.png图片")
             return
         self.icon_img.setPixmap(pix)
         current_icon = Utils.get_full_path('games/' + self.game['id'] +
                                            '/icon/icon.png')
         if os.path.exists(current_icon):
             if os.path.samefile(os.path.dirname(fname[0]),
                                 os.path.dirname(current_icon)):
                 if not os.path.samefile(
                         fname[0], current_icon
                 ):  # 如果选中的,在game的icon目录下,但不是当前icon,则进行重命名
                     count = 0
                     temp = 'icon0.png'
                     while os.path.exists(
                             Utils.get_full_path('games/' +
                                                 self.game['id'] +
                                                 '/icon/' + temp)):
                         count += 1
                         temp = 'icon' + str(count) + '.png'
                     os.renames(
                         current_icon,
                         Utils.get_full_path('games/' + self.game['id'] +
                                             '/icon/' + temp))
                     os.renames(fname[0], current_icon)
                 else:  # 如果所选的是当前icon,不做处理
                     return
             else:  # 如果选中的不在game的icon目录下,则重命名当前icon,并将选中的icon复制到目录下作为当前icon
                 count = 0
                 temp = 'icon0.png'
                 while os.path.exists(
                         Utils.get_full_path('games/' + self.game['id'] +
                                             '/icon/' + temp)):
                     count += 1
                     temp = 'icon' + str(count) + '.png'
                 os.renames(
                     current_icon,
                     Utils.get_full_path('games/' + self.game['id'] +
                                         '/icon/' + temp))
                 Utils.copy_file(fname[0], current_icon)
         else:
             Utils.copy_file(fname[0], current_icon)
Ejemplo n.º 11
0
 def __init__(self):
     super(MainWindow, self).__init__()
     LogUtils.add_logger()
     self.games = Utils.get_games(Utils.get_full_path('games/games.xml'))
     self.game_index = 0
     self.setObjectName("MainWindow")
     self.resize(960, 540)
     size_policy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed,
                                         QtWidgets.QSizePolicy.Fixed)
     size_policy.setHorizontalStretch(0)
     size_policy.setVerticalStretch(0)
     size_policy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
     self.setSizePolicy(size_policy)
     self.setWindowIcon(QIcon('pack.ico'))
     self.set_main_widget()
Ejemplo n.º 12
0
def jar2dex(src_dir, dex_path):
    """
        compile jar files to dex.
    """
    dex_tool_path = Utils.get_full_path('tools/dx.jar')
    java = Utils.get_full_path('tools/jdk/bin/java')
    cmd = '%s -jar %s --dex --output %s' % (java, dex_tool_path, dex_path)

    for f in os.listdir(src_dir):
        if f.endswith('.jar'):
            cmd = cmd + ' ' + os.path.join(src_dir, f)

    for f in os.listdir(os.path.join(src_dir, 'libs')):
        if f.endswith('.jar'):
            cmd = cmd + ' ' + os.path.join(src_dir, 'libs', f)
    return Utils.exec_cmd(cmd)
Ejemplo n.º 13
0
def edit_yml(channel, decompile_dir):
    LogUtils.info('-----> EditYML <------')
    path = decompile_dir + '/apktool.yml'
    yml_file = open(path, encoding='utf-8')
    content = ''
    while True:
        line = yml_file.readline()
        if line.find('- assets/') == 0:
            yml_file.tell()
        elif line.find('targetSdkVersion') != -1:
            config = Utils.get_local_config()
            if config is not None and config['TARGET_SDK_VERSION'] != '0':
                content += '  targetSdkVersion: \'' + config[
                    'TARGET_SDK_VERSION'] + '\'\n'
            else:
                content += line
        elif line.find('versionCode') != -1 and len(
                channel['gameVersionCode']) > 0:
            content += '  versionCode: \'' + channel['gameVersionCode'] + '\'\n'
        elif line.find('versionName') != -1 and len(
                channel['gameVersionName']) > 0:
            content += '  versionName: ' + channel['gameVersionName'] + '\n'
        else:
            if not line:
                break
            line.replace('\r', '')
            if line.strip() != '':
                if line.find('doNotCompress:') == 0:
                    yml_file.tell()
                    content += 'doNotCompress:\n- assets/*\n'
                else:
                    content += line
    LogUtils.info("apktool.yml:\n%s", content)
    with open(path, 'w', encoding='utf-8') as f:
        f.write(content)
Ejemplo n.º 14
0
 def select_list(self):
     index = self.qpb_list_widget.currentIndex().row()
     channel_id = self.channels[self.indexs[index]]['channelId']
     success = self.lbps[channel_id]['success']
     dest_apk_dir = Utils.get_full_path('output/' + self.game['id'] + '/' +
                                        channel_id)
     if success:
         os.startfile(dest_apk_dir)
     else:
         QMessageBox.warning(self, "警告", "打包成功了吗?")
Ejemplo n.º 15
0
 def save_data(self):
     self.channel['gameName'] = self.game_name_value.text().strip()
     self.channel['package'] = self.game_package_value.text().strip()
     self.channel['gameVersionCode'] = self.game_vcode_value.text().strip()
     self.channel['gameVersionName'] = self.game_vname_value.text().strip()
     self.channel['debug'] = self.debug_value.text().strip()
     i = 0
     while i < len(self.linedit_list):
         if self.linedit_list[i].text().strip() == "":
             QMessageBox.warning(self, "警告", "渠道参数不能为空!")
             return False
         self.channel['sdkParams'][i]['value'] = self.linedit_list[i].text(
         ).strip()
         i += 1
     self.channels[self.channel_index] = self.channel
     game_id = self.main_win.games[self.main_win.game_index]['id']
     return Utils.update_channels(
         Utils.get_full_path('games/' + game_id + '/config.xml'),
         self.channel, self.channel_index)
Ejemplo n.º 16
0
 def next(self):
     if not self.save_data():
         return
     channels = Utils.get_channels(
         Utils.get_full_path('games/' + self.game['id'] + '/config.xml'))
     if channels is None:
         if not os.path.exists(Utils.get_full_path('channelsdk')):
             QMessageBox.warning(
                 self, "警告",
                 os.path.dirname(os.getcwd()) + " 没有channelsdk文件夹")
             return
         elif len(os.listdir(Utils.get_full_path('channelsdk'))) <= 0:
             QMessageBox.warning(
                 self, "警告", "本地没有渠道sdk,请手动添加sdk文件夹到" +
                 Utils.get_full_path('channelsdk'))
             return
         channels = []
         self.main_win.set_add_channel_widget(channels)
     else:
         self.main_win.set_channel_list_widget(channels)
Ejemplo n.º 17
0
 def select_game(self, p_int):
     self.game_index = p_int
     if 'apk' in self.main_win.games[self.game_index]:
         self.apk_path.setText(self.main_win.games[self.game_index]['apk'])
     else:
         self.apk_path.setText("<h3><font color=%s>%s</font></h3>" %
                               ('red', "请浏览选择本地母包路径"))
         # self.apk_path.setText("请浏览选择本地母包路径")
     # 当前选中的game,其下的所有渠道列表
     self.channels = Utils.get_channels(
         Utils.get_full_path('games/' + self.main_win.games[p_int]['id'] +
                             '/config.xml'))
     channel_ids = []
     for channel in self.channels:
         channel_ids.append(channel['channelId'])
     list_model = QStringListModel()
     list_model.setStringList(channel_ids)
     self.clv = self.tool_box.currentWidget()
     self.clv.doubleClicked.connect(self.select_channel)
     self.clv.setModel(list_model)
Ejemplo n.º 18
0
 def select_ketstore(self):
     fname = QFileDialog.getOpenFileName(
         self, '选择签名文件',
         Utils.get_full_path('games/' + self.game['id'] + '/keystore/'))
     if fname[0]:
         if os.path.samefile(
                 fname[0],
                 Utils.get_full_path('games/' + self.game['id'] +
                                     '/keystore/' + self.game['keystore'])):
             self.keystore_path.setText(self.game['keystore'])
             self.keystore_pwd_value.setText(self.game['keypwd'])
             self.keystore_alias_value.setText(self.game['alias'])
             self.keystore_aliaspwd_value.setText(self.game['aliaspwd'])
             self.keystore_exchanged = False
         else:
             self.keystore_path.setText(fname[0])
             self.keystore_pwd_value.clear()
             self.keystore_alias_value.clear()
             self.keystore_aliaspwd_value.clear()
             self.keystore_exchanged = True
Ejemplo n.º 19
0
 def del_channel(self):
     reply = QMessageBox.warning(self, "警告", "确定删除当前渠道?",
                                 QMessageBox.Yes | QMessageBox.No,
                                 QMessageBox.No)
     if reply == QMessageBox.Yes:
         # 更新listview
         self.channel_ids.pop(self.channel_index)
         self.list_model.setStringList(self.channel_ids)
         # 更新表单view(index前移一位)
         self.channel = self.channels[self.channel_index - 1]
         self.set_info()
         # 更新本地数据
         self.channels.pop(self.channel_index)
         game_id = self.main_win.games[self.main_win.game_index]['id']
         Utils.del_channel(
             Utils.get_full_path('games/' + game_id + '/config.xml'),
             self.channel_index)
         # 重置index,防止 index out of range
         self.channel_index = self.channel_index - 1
         if self.channel_index < 0:
             reply = QMessageBox.warning(self, "警告", "当前游戏未添加渠道,将返回游戏列表界面!",
                                         QMessageBox.Yes)
             if reply == QMessageBox.Yes:
                 self.back()
Ejemplo n.º 20
0
    def set_game_info(self):
        self.game_name_value.setText(self.game['name'])
        self.game_desc_value.setText(self.game['desc'])
        self.game_appid_value.setText(self.game['id'])
        self.game_appkey_value.setText(self.game['key'])
        self.keystore_path.setText(self.game['keystore'])
        self.keystore_pwd_value.setText(self.game['keypwd'])
        self.keystore_alias_value.setText(self.game['alias'])
        self.keystore_aliaspwd_value.setText(self.game['aliaspwd'])

        icon = Utils.get_full_path('games/' + self.game['id'] +
                                   '/icon/icon.png')
        if not os.path.exists(icon):
            icon = 'icon.png'
        self.icon_img.setPixmap(QPixmap(icon))
Ejemplo n.º 21
0
    def select_channel(self, text):
        # 先初始化数据
        self.linedit_list.clear()
        self.channel.clear()
        # 排序包体参数,防止参数写入乱排序
        self.channel['name'] = ''
        self.channel['sdk'] = text
        self.channel['channelId'] = ''
        self.channel['gameName'] = ''
        self.channel['package'] = ''
        self.channel['gameVersionCode'] = ''
        self.channel['gameVersionName'] = ''
        self.channel['debug'] = "false"
        # 获取渠道参数定义
        if not Utils.get_channel_config(self.channel):
            return

        # 再添加当前选择的渠道参数模板,刷新界面(先清空之前渠道参数表单,再添加)
        for i in range(self.form_layout2.rowCount()):
            # 因为formlayout清除一行,会自动上移,所以只需remove第一行
            self.form_layout2.removeRow(0)
        channel_name = QLabel(self.channel['name'] + '\t\t\tVersion:' +
                              self.channel['sdkVersionName'] + '\t\tUpdate:' +
                              self.channel['sdkUpdateTime'])
        channel_name.setAlignment(Qt.AlignRight)
        self.form_layout2.addRow(channel_name)
        if self.default_channel is not None and text == self.default_channel[
                'sdk']:
            self.channel_id_value.setText(self.default_channel['channelId'])
            self.game_name_value.setText(self.default_channel['gameName'])
            self.game_package_value.setText(self.default_channel['package'])
            self.game_vcode_value.setText(
                self.default_channel['gameVersionCode'])
            self.game_vname_value.setText(
                self.default_channel['gameVersionName'])
            for param in self.default_channel['sdkParams']:
                line_edit = QLineEdit()
                line_edit.setText(param['value'])
                self.form_layout2.addRow(param['showName'] + ':', line_edit)
                self.linedit_list.append(line_edit)
        else:
            for param in self.channel['sdkParams']:
                line_edit = QLineEdit()
                line_edit.setPlaceholderText("渠道参数必填")
                self.form_layout2.addRow(param['showName'] + ':', line_edit)
                self.linedit_list.append(line_edit)
Ejemplo n.º 22
0
 def data(self, index, role):
     if index.isValid() or (0 <= index.row() < len(self.ListItemData)):
         if role == Qt.DisplayRole:
             return QVariant(self.games[index.row()]['id'])
         elif role == Qt.DecorationRole:
             icon = self.games[index.row()]['id']
             icon = Utils.get_full_path('games/' + icon + '/icon/icon.png')
             if not os.path.exists(icon):
                 icon = 'icon.png'
             return QVariant(QIcon(icon))
         elif role == Qt.SizeHintRole:
             return QVariant(QSize(80, 80))
         elif role == Qt.TextAlignmentRole:
             return QVariant(int(Qt.AlignHCenter | Qt.AlignVCenter))
         elif role == Qt.FontRole:
             font = QFont()
             font.setPixelSize(16)
             font.setFamily("Microsoft YaHei")
             return QVariant(font)
         else:
             return QVariant()
Ejemplo n.º 23
0
def validLogin(postForm):
	'''
	Given email and password, authorize user 
	to access Virtual Admin Dashboard
	'''
	usr_name = postForm['email'].split('@')[0]
	psswrd = ut.hashPassword(postForm['password'])

	try:
		chapter = c_chapters.find({ 'email':postForm['email'], 'password':psswrd })[0]
	except IndexError:
		chapter = None

	if chapter:	#If entry found do...
		if chapter['email_confirmed'] == True:
			fl.session['usrName'] = usr_name
			fl.session['password'] = psswrd
			return True
		else:
			return False
	else:
		return False
Ejemplo n.º 24
0
def sign_apk(game, apk_file):
    key_path = Utils.get_full_path('games/' + game['id'] + '/keystore/' +
                                   game['keystore'])
    if not os.path.exists(key_path):
        LogUtils.info('the keystore file not exists: %s', key_path)
        return 1
    LogUtils.info('the keystore file is %s', key_path)
    aapt = Utils.get_full_path('tools/aapt.exe')
    lcmd = "%s list %s" % (aapt, apk_file)
    out = Utils.exec_cmd2(lcmd)
    if out is not None and len(out) > 0:
        for filename in out.split('\n'):
            if filename.find('META-INF') == 0:
                rmcmd = "%s remove %s %s" % (aapt, apk_file, filename)
                Utils.exec_cmd(rmcmd)
    jar_signer = Utils.get_full_path('tools/jdk/bin/jarsigner')
    sign_cmd = "%s -keystore %s -storepass %s -keypass %s %s %s -sigalg  SHA1withRSA -digestalg SHA1" % (
        jar_signer, key_path, game['keypwd'], game['aliaspwd'], apk_file,
        game['alias'])
    return Utils.exec_cmd(sign_cmd)
Ejemplo n.º 25
0
def align_apk(apk_file, target_file):
    align = Utils.get_full_path('tools/zipalign.exe')
    cmd = '%s -f 4 %s %s' % (align, apk_file, target_file)
    return Utils.exec_cmd(cmd)
Ejemplo n.º 26
0
def copy_ext_res(game, decompile_dir):
    ext_res_path = 'games/' + game['id'] + '/ext'
    ext_res_path = Utils.get_full_path(ext_res_path)
    if os.path.exists(ext_res_path):
        LogUtils.warning('the game ext res path: %s', ext_res_path)
        Utils.copy_file(ext_res_path, decompile_dir)
Ejemplo n.º 27
0
def modify_manifest(channel, decompile_dir, package_name):
    manifest_file = decompile_dir + '/AndroidManifest.xml'
    ET.register_namespace('android', androidNS)
    tree = ET.parse(manifest_file)
    root = tree.getroot()
    app_node = root.find('application')
    # 修改游戏名称
    if len(channel['gameName']) > 0:
        label = app_node.get('{' + androidNS + '}label')
        if label.find('@string/') == 0:
            app_name = label[8:len(label)]
        else:
            app_name = 'app_name'
            app_node.set('{' + androidNS + '}label', '@string/' + app_name)
        activity_node_lst = app_node.findall('activity')
        for activity_node in activity_node_lst:
            if activity_node.get('{' + androidNS + '}label') is not None:
                activity_node.set('{' + androidNS + '}label',
                                  '@string/' + app_name)
        string_file = decompile_dir + '/res/values/strings.xml'
        string_tree = ET.parse(string_file)
        strings = string_tree.getroot().findall('string')
        for string in strings:
            if string.get('name') == app_name:
                string_tree.getroot().remove(string)
                break
        string_node = SubElement(string_tree.getroot(), 'string',
                                 {'name': app_name})
        string_node.text = channel['gameName']
        string_tree.write(string_file,
                          xml_declaration=True,
                          encoding='utf-8',
                          method='xml')
        LogUtils.info('modify game name: %s', channel['gameName'])
    # 写入meta-data
    key = '{' + androidNS + '}name'
    val = '{' + androidNS + '}value'
    meta_data_list = app_node.findall('meta-data')
    if meta_data_list is not None:
        for metaDataNode in meta_data_list:
            key_name = metaDataNode.attrib[key]
            for child in channel['sdkParams']:
                if key_name == child['name'] and child['writeIn'] == '1':
                    LogUtils.warning(
                        'the meta-data node %s repeated. remove it .',
                        key_name)
                    app_node.remove(metaDataNode)
    for child in channel['sdkParams']:
        if child['writeIn'] is not None and child['writeIn'] == '1':
            meta_node = SubElement(app_node, 'meta-data')
            meta_node.set(key, child['name'])
            meta_node.set(val, child['value'])
            LogUtils.info('writeIn meta-data: %s=%s', child['name'],
                          child['value'])
    # 修改替换包名占位符
    xml_str = ET.tostring(root, 'utf-8').decode('utf-8')
    if xml_str.find('NEW_PACKAGE_NAME') != -1:
        LogUtils.info('modify package name: %s', package_name)
        xml_str = xml_str.replace('NEW_PACKAGE_NAME', package_name)
        root = ET.fromstring(xml_str)

    Utils.indent(root)
    tree = ET.ElementTree(root)
    tree.write(manifest_file,
               xml_declaration=True,
               encoding='utf-8',
               method='xml')
    LogUtils.info('The manifestFile modify successfully')
Ejemplo n.º 28
0
def signUpUser(postForm):
	newUser = True
	fl.session['usrName'] = postForm['email'].split('@')[0]
	fl.session['password'] = ut.hashPassword(postForm['password'])
	post = {
		'email': postForm['email'],
		'name': fl.session['usrName'],
		'password': fl.session['password'],
		'joined_on': ut.dateNow(),
		'email_confirmed': False,
		'gfolder_link':None,
		'w_agenda_date':None,
		'integrations': {
			'asana': {
				'auth_token':None		
			},
			'gdrive': {
				'client_id':None,
				'client_secret':None,
				'scope':None,
				'redirect_uri':None	
			},
			'slack':{
				'auth_token':None,
				'webhook_url':None
			},
			'twilio':{
				'accnt_sid':None,
				'auth_token':None,
				'twilio_num':None,
			}
		},
		'members': {
			'Add-member': {
				'email': None,
				'phone_num': None,
				'reminder_pref': None
			}
		},
		'organization': None
	}

	try:
		chapter = c_chapters.find({ 'email':postForm['email'] })[0]
	except IndexError:
		chapter = None

	if chapter:
		newUser = False

	if newUser:
		c_chapters.insert_one(post)
		status = None
	elif newUser and postForm['password'] == None:
		status = 'Password is a required field!'
	elif not newUser and postForm['password'] == None:
		status = 'Password is a required field!'
	else:
		status = 'There already exists an account with the email {0}. Please Log in here: {1}/login'.format(usr_email, host_url)

	return status
Ejemplo n.º 29
0
def generate_r_file(package_name, decompile_dir):
    # check_value_resources(decompile_dir)
    temp_path = os.path.dirname(decompile_dir) + '/temp'
    LogUtils.debug('generate R:the temp path is %s', temp_path)
    if os.path.exists(temp_path):
        Utils.del_file(temp_path)
    os.makedirs(temp_path)
    res_path = decompile_dir + '/res'
    temp_res_path = temp_path + '/res'
    Utils.copy_file(res_path, temp_res_path)
    gen_path = temp_path + '/gen'
    os.makedirs(gen_path)

    aapt_path = Utils.get_full_path('tools/aapt2.exe')
    android_path = Utils.get_full_path('tools/android.jar')
    java = Utils.get_full_path('tools/jdk/bin/java')
    javac = Utils.get_full_path('tools/jdk/bin/javac')

    manifest_path = decompile_dir + '/AndroidManifest.xml'
    res_flat_path = temp_path + "/res_flat.zip"
    cmd = '%s compile -o %s --dir %s' % (aapt_path, res_flat_path,
                                         temp_res_path)
    ret = Utils.exec_cmd(cmd)
    if ret:
        return 1
    cmd = '%s link -o %s --manifest %s -I %s --java %s %s' % (
        aapt_path, temp_path + '/res.apk', manifest_path, android_path,
        gen_path, res_flat_path)
    ret = Utils.exec_cmd(cmd)
    if ret:
        return 1

    LogUtils.info('package_name:%s', package_name)
    r_path = package_name.replace('.', '/')
    r_path = gen_path + '/' + r_path + '/R.java'
    cmd = '%s -source 1.8 -target 1.8 -encoding UTF-8 %s' % (javac, r_path)
    ret = Utils.exec_cmd(cmd)
    if ret:
        return 1
    dex_path = temp_path + '/classes.dex'
    dex_tool_path = Utils.get_full_path('tools/dx.jar')
    cmd = '%s -jar %s --dex --output %s %s' % (java, dex_tool_path, dex_path,
                                               gen_path)
    ret = Utils.exec_cmd(cmd)
    if ret:
        return 1
    smali_path = decompile_dir + '/smali'
    ret = dex2smali(dex_path, smali_path, '')
    if ret:
        return 1
    return 0
Ejemplo n.º 30
0
from multiprocessing import Process

'''Web Imports'''
import flask as fl
from pymongo import MongoClient
import oauth2client.client as client

'''App Imports'''
import scripts.Utils as ut
import scripts.ApiUtils as au

'''Web & Worker Clients'''
host_url = 'http://127.0.0.1:5000'
# host_url = 'http://virtualadmin.herokuapp.com'
app = fl.Flask(__name__)
app.secret_key = ut.generateAppKey()
app.logger.addHandler(logging.StreamHandler(sys.stdout))
app.logger.setLevel(logging.ERROR)

'''MongoDB Client & Collections'''
#For Localhost use only
mongo_client = MongoClient()
va_db = mongo_client['virtual-admin-db']
c_chapters = va_db['chapters']

def signUpUser(postForm):
	newUser = True
	fl.session['usrName'] = postForm['email'].split('@')[0]
	fl.session['password'] = ut.hashPassword(postForm['password'])
	post = {
		'email': postForm['email'],
Ejemplo n.º 31
0
def recompile_apk(source_folder, apk_file, frame_work_dir):
    java = Utils.get_full_path('tools/jdk/bin/java')
    apk_tool = Utils.get_full_path('tools/apktool.jar')
    cmd = "%s -jar %s b %s -o %s -p %s" % (java, apk_tool, source_folder,
                                           apk_file, frame_work_dir)
    return Utils.exec_cmd(cmd)
Ejemplo n.º 32
0
    def run(self):
        # 开启任务,发送打包信号
        self.signal.signal.emit(self.channel['channelId'], 0, "正在打包......", 0)
        # 清空已有的workspace
        work_dir = Utils.get_full_path('workspace/' + self.game['id'] + '/' +
                                       self.channel['channelId'])
        Utils.del_file(work_dir)
        os.makedirs(work_dir)
        # 生成当前打包任务的logger,添加到字典
        LogUtils.add_logger(work_dir)

        LogUtils.info('Current Selected Game ID is : %s, with SDK is : %s',
                      self.game['id'], self.channel['sdk'])
        LogUtils.info('game:\n%s', self.game)
        LogUtils.info('channel:\n%s', self.channel)

        src_apk_path = work_dir + '/songshu.apk'
        # 复制上传母包到workspace
        result = Utils.copy_file(self.apk, src_apk_path)
        if self.flag(result, "打包失败:复制母包文件失败,详情查看log.log", 5):
            return

        # 反编译母包
        decompile_dir = work_dir + '/decompile'
        frame_work_dir = work_dir + '/framework'
        result = ApkUtils.decompile_apk(src_apk_path, decompile_dir,
                                        frame_work_dir)
        if self.flag(result, "打包失败:反编译母包异常,详情查看log.log", 15):
            return

        # 复制sdk资源到工作目录
        sdk_source_dir = Utils.get_full_path('channelsdk/' +
                                             self.channel['sdk'])
        sdk_dest_dir = work_dir + '/sdk'
        result = Utils.copy_file(sdk_source_dir, sdk_dest_dir)
        if self.flag(result, "打包失败:复制SDK文件夹失败,详情查看log.log", 18):
            return

        # 将插件里的jar资源转dex
        result = ApkUtils.jar2dex(sdk_source_dir,
                                  sdk_dest_dir + '/classes.dex')
        if self.flag(result, "打包失败:渠道jar转dex异常,详情查看log.log", 25):
            return

        # 将插件里的dex资源转smali,合并到母包反编译目录中
        result = ApkUtils.dex2smali(sdk_dest_dir + '/classes.dex',
                                    decompile_dir + '/smali', '')
        if self.flag(result, "打包失败:渠道dex转smali异常,详情查看log.log", 28):
            return

        # 合并manifest文件
        result = ApkUtils.merge_manifest(decompile_dir, sdk_dest_dir)
        if self.flag(result, "打包失败:合并manifest文件失败,详情查看log.log", 30):
            return

        # 复制插件libs里的so库
        ApkUtils.copy_libs(decompile_dir, sdk_dest_dir)
        if self.flag(0, "", 33):
            return

        # 复制插件assets文件夹
        result = Utils.copy_file(sdk_dest_dir + '/assets',
                                 decompile_dir + '/assets')
        if self.flag(result, "打包失败:复制assets文件夹失败,详情查看log.log", 35):
            return

        # 复制插件res文件夹
        result = Utils.copy_file(sdk_dest_dir + '/res', decompile_dir + '/res')
        if self.flag(result, "打包失败:复制res文件夹失败,详情查看log.log", 38):
            return

        # 复制渠道特殊配置资源,比如,针对个别渠道设置的loading页或logo
        ApkUtils.copy_ext_res(self.game, decompile_dir)
        if self.flag(0, "", 40):
            return

        # 将游戏原来的包名替换成渠道里面的包名,四大组件也会按照相关规则替换包名
        package_name = ApkUtils.rename_package_name(decompile_dir,
                                                    self.channel['package'])
        if self.flag(0, "", 45):
            return

        # 给对应的icon添加角标
        ApkUtils.append_channel_mark(self.game, sdk_dest_dir, decompile_dir)
        if self.flag(0, "", 50):
            return

        # 配置参数写入
        result = ApkUtils.write_develop_info(self.game, self.channel,
                                             decompile_dir)
        if self.flag(result, "打包失败:写入配置参数失败,详情查看log.log", 52):
            return

        # 如果主sdk有特殊的逻辑。执行特殊的逻辑脚本。
        result = ApkUtils.do_sdk_script(self.channel, decompile_dir,
                                        package_name, sdk_dest_dir)
        if self.flag(result, "打包失败:执行渠道脚本异常,详情查看log.log", 55):
            return

        # 修改游戏名称,并将meta-data写入manifest文件
        ApkUtils.modify_manifest(self.channel, decompile_dir, package_name)
        if self.flag(0, "", 60):
            return

        # 重新生成R文件,并导入到包名下
        result = ApkUtils.generate_r_file(package_name, decompile_dir)
        if self.flag(result, "打包失败:重新生成R文件异常,详情查看log.log", 75):
            return

        # 防止方法数超65535,判断是否分dex
        result = ApkUtils.classes_split(decompile_dir, sdk_dest_dir)
        if self.flag(result, "打包失败:分dex出现异常,详情查看log.log", 78):
            return

        # 修改apktool.yml里的压缩配置,防止包体变大
        ApkUtils.edit_yml(self.channel, decompile_dir)
        if self.flag(0, "", 80):
            return

        # 回编译生成apk
        target_apk = work_dir + '/output.apk'
        result = ApkUtils.recompile_apk(decompile_dir, target_apk,
                                        frame_work_dir)
        if self.flag(result, "打包失败:回编译APK异常,详情查看log.log", 90):
            return

        # 复制添加资源到apk
        result = ApkUtils.copy_root_ext_files(target_apk, decompile_dir)
        if self.flag(result, "打包失败:母包其余资源导入异常,详情查看log.log", 92):
            return

        # apk签名(v1签名)
        result = ApkUtils.sign_apk(self.game, target_apk)
        if self.flag(result, "打包失败:渠道包签名异常,详情查看log.log", 98):
            return

        # apk对齐
        time_str = QDateTime.currentDateTime().toString("yyyyMMddhhmm")
        dest_apk_name = self.game['name'] + '-' + self.channel[
            'name'] + '-' + time_str + '.apk'
        dest_apk_dir = Utils.get_full_path('output/' + self.game['id'] + '/' +
                                           self.channel['channelId'])
        if not os.path.exists(dest_apk_dir):
            os.makedirs(dest_apk_dir)
        dest_apk = dest_apk_dir + '/' + dest_apk_name
        result = ApkUtils.align_apk(target_apk, dest_apk)
        if self.is_close:
            pass
        else:
            if result == 0:
                self.signal.signal.emit(self.channel['channelId'], 1,
                                        "打包成功:双击打开出包目录", 100)
            else:
                self.signal.signal.emit(self.channel['channelId'], result,
                                        "打包失败:apk包体4k对齐异常,详情查看log.log", 100)
        LogUtils.close()
Ejemplo n.º 33
0
def append_channel_mark(game, sdk_dest_dir, decompile_dir):
    game_icon_path = 'games/' + game['id'] + '/icon/icon.png'
    game_icon_path = Utils.get_full_path(game_icon_path)
    if not os.path.exists(game_icon_path):
        LogUtils.info('The game %s icon is not exists : %s', game['id'],
                      game_icon_path)
        return
    LogUtils.info('The game %s icon path : %s', game['id'], game_icon_path)

    game_icon_name = get_app_icon_name(decompile_dir)
    if game_icon_name is None:
        return
    game_icon_name = game_icon_name + '.png'
    LogUtils.info('The game icon name: %s', game_icon_name)

    icon_img = Image.open(game_icon_path)
    mark_path = sdk_dest_dir + '/mark.png'
    if not os.path.exists(mark_path):
        LogUtils.info('The mark path is not exists : %s', mark_path)
    else:
        LogUtils.info('The mark path : %s', mark_path)
        mark_img = Image.open(mark_path)
        icon_img = merge_icon_mark(icon_img, mark_img, (0, 0))

    ldpi_icon = icon_img.resize((36, 36), Image.ANTIALIAS)
    mdpi_icon = icon_img.resize((48, 48), Image.ANTIALIAS)
    hdpi_icon = icon_img.resize((72, 72), Image.ANTIALIAS)
    xhdpi_icon = icon_img.resize((96, 96), Image.ANTIALIAS)
    xxhdpi_icon = icon_img.resize((144, 144), Image.ANTIALIAS)
    xxxhdpi_icon = icon_img.resize((192, 192), Image.ANTIALIAS)
    icons = (ldpi_icon, mdpi_icon, hdpi_icon, xhdpi_icon, xxhdpi_icon,
             xxxhdpi_icon)

    drawables = ('drawable-ldpi', 'drawable-mdpi', 'drawable-hdpi',
                 'drawable-xhdpi', 'drawable-xxhdpi', 'drawable-xxxhdpi')
    mipmaps = ('mipmap-ldpi', 'mipmap-mdpi', 'mipmap-hdpi', 'mipmap-xhdpi',
               'mipmap-xxhdpi', 'mipmap-xxxhdpi')
    for drawable in drawables:
        icon_dir = decompile_dir + '/res/' + drawable
        Utils.del_file(icon_dir + '/' + game_icon_name)
        if os.path.exists(icon_dir) and len(os.listdir(icon_dir)) <= 0:
            os.rmdir(icon_dir)

        icon_dir = decompile_dir + '/res/' + drawable + '-v4'
        Utils.del_file(icon_dir + '/' + game_icon_name)
        if os.path.exists(icon_dir) and len(os.listdir(icon_dir)) <= 0:
            os.rmdir(icon_dir)
    if not os.path.exists(decompile_dir + '/res/drawable'):
        os.mkdir(decompile_dir + '/res/drawable')
    xxhdpi_icon.save(decompile_dir + '/res/drawable/' + game_icon_name, 'PNG')

    for i in range(len(mipmaps)):
        icon_dir = decompile_dir + '/res/' + mipmaps[i] + '-v4'
        Utils.del_file(icon_dir + '/' + game_icon_name)
        if os.path.exists(icon_dir) and len(os.listdir(icon_dir)) <= 0:
            os.rmdir(icon_dir)

        icon_dir = decompile_dir + '/res/' + mipmaps[i]
        if not os.path.exists(icon_dir):
            os.makedirs(icon_dir)
        icons[i].save(os.path.join(icon_dir, game_icon_name), 'PNG')
Ejemplo n.º 34
0
# -*- coding: utf-8 -*-
import sys, os
if hasattr(sys, 'frozen'):
    os.environ['PATH'] = sys._MEIPASS + ";" + os.environ['PATH']
from PyQt5.Qt import QApplication, QFile, QTextStream
from scripts.MainWindow import MainWindow
from scripts import Utils


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWin = MainWindow()
    theme = Utils.get_local_config()['THEME']
    file = QFile(theme + '.qss')
    file.open(QFile.ReadOnly | QFile.Text)
    stream = QTextStream(file)
    mainWin.setStyleSheet(stream.readAll())
    mainWin.show()
    sys.exit(app.exec_())