import file_utils import xml_utils import package_utils import os.path import xml.etree.ElementTree as ET namespaces = {'android' : 'http://schemas.android.com/apk/res/android'} encoding = 'UTF-8' def execute(game, sdk, config): if not checkConfig(config): return 1 subChannel = config['subChannel'] createJmhyProperties(game, sdk, subChannel, config) createProperties(game, sdk, subChannel, config) createSdkProperties(game, sdk, subChannel, config) orientation = getScreenOrientation(game, sdk, subChannel, config) if orientation is None: orientation = 'landscape' config['screenOrientation'] = orientation changePlaceholders(game, sdk, subChannel, config) ret = deleteSplash(game, sdk, subChannel, config) if ret: return ret return copyWechatCode(game, sdk, subChannel, config) def checkConfig(config): ''' 检查配置 ''' if 'properties' not in config: print('properties not exists in config') return False if 'ysdk' not in config: print('ysdk not exists in config') return False properties = config['properties'] if 'agent' not in properties or 'version' not in properties: print('agent or version not exists in properties') return False '''if 'appid' not in config or 'appkey' not in config: print('appid or appkey not exists in config') return False''' return True def createJmhyProperties(game, sdk, subChannel, config): ''' 创建jmhy.properties ''' print('create jmhy.properties') propValue = config['properties'] decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache']) properties = os.path.join(decompliePath, 'assets', 'jmhy.properties') content = '' for key in propValue: content = '%s%s=%s\n' % (content, key, propValue[key]) file_utils.createFile(properties, content) return 0 def createProperties(game, sdk, subChannel, config): ''' 创建ysdkconf.ini ''' print('create ysdkconf.ini') ysdkConfig = config['ysdk'] decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache']) properties = os.path.join(decompliePath, 'assets', 'ysdkconf.ini') content = '' for key in ysdkConfig: content = '%s%s=%s\n' % (content, key, ysdkConfig[key]) file_utils.createFile(properties, content) return 0 def createSdkProperties(game, sdk, subChannel, config): ''' 创建sdk.properties ''' print('create sdk.properties') zysdkConfig = config['zysdk_properties'] decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache']) properties = os.path.join(decompliePath, 'assets', 'sdk.properties') content = '' for key in zysdkConfig: content = '%s%s=%s\n' % (content, key, zysdkConfig[key]) file_utils.createFile(properties, content) return 0 def copyWechatCode(game, sdk, subChannel, config): ''' 拷贝微信sdk的代码 ''' print('copy WXEntryActivity.smali') sdkPath = file_utils.getFullSDKPath(sdk) WXEntryActivity = 'WXEntryActivity.smali' wxFile = os.path.join(sdkPath, 'smali', WXEntryActivity) decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache']) smaliPath = os.path.join(decompliePath, 'smali') targetPath = file_utils.getPackagePath(smaliPath, config['packageName']) targetFile = os.path.join(targetPath, 'wxapi', WXEntryActivity) ret = file_utils.copyFile(wxFile, targetFile) if ret: return ret file_utils.replaceContent(targetFile, '${packageName}', config['packageName'].replace('.', '/')) manifest = os.path.join(decompliePath, 'AndroidManifest.xml') changeLauncherLaunchMode(manifest) xml_utils.changeLauncherAttr(manifest, 'configChanges', 'orientation|screenSize|keyboardHidden') return 0 def deleteSplash(game, sdk, subChannel, config): ''' 删除闪屏 ''' if game != 'wzjh': return 0 channelPath = file_utils.getSubChannelPath(game, sdk, subChannel) print('delete Splash...') decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache']) manifest = os.path.join(decompliePath, 'AndroidManifest.xml') activity = xml_utils.getLauncherActivityName(manifest) activity = xml_utils.removeLauncherActivity(manifest) xml_utils.deleteActivityByName(manifest,'com.hugenstar.nanobox.NaNoUnityContext') addLauncherActivity(manifest, config['screenOrientation'], 'com.hugenstar.nanobox.NaNoUnityContext') return 0 def changeLauncherLaunchMode(manifest): ''' 修改启动的activity的launchMode ''' for key in namespaces: ET.register_namespace(key, namespaces[key]) tree = ET.parse(manifest) root = tree.getroot() launcherActivity = xml_utils.getLauncherActivity(root) if launcherActivity is None: return 1 attrName = xml_utils.getNamespacesFormat('android:launchMode', namespaces) if attrName not in launcherActivity.attrib or 'standard' == launcherActivity.attrib[attrName]: launcherActivity.attrib[attrName] = 'singleTop' tree.write(manifest, encoding) return 0 def getScreenOrientation(game, sdk, subChannel, config): decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache']) manifest = os.path.join(decompliePath, 'AndroidManifest.xml') return getLauncherAttr(manifest, 'screenOrientation') def getLauncherAttr(manifest, attrType): ''' 获取启动的activity的属性 ''' for key in namespaces: ET.register_namespace(key, namespaces[key]) tree = ET.parse(manifest) root = tree.getroot() launcherActivity = xml_utils.getLauncherActivity(root) if launcherActivity is None: return None attrName = xml_utils.getNamespacesFormat('android:%s' % attrType, namespaces) if attrName in launcherActivity.attrib: return launcherActivity.attrib[attrName] return None def changePlaceholders(game, sdk, subChannel, config): decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache']) manifest = os.path.join(decompliePath, 'AndroidManifest.xml') file_utils.replaceContent(manifest, '${screenOrientation}', config['screenOrientation']) def addLauncherActivity(manifest, screenOrientation, activity): ''' 添加启动的activity ''' for key in namespaces: ET.register_namespace(key, namespaces[key]) tree = ET.parse(manifest) root = tree.getroot() # activity ''' ''' activity = ET.Element('activity', {'android:name' : activity, 'android:theme' : '@android:style/Theme.Holo.Light.NoActionBar.Fullscreen', 'android:launchMode' : 'singleTop', 'android:configChanges' : 'orientation|screenSize|keyboardHidden', 'android:screenOrientation' : screenOrientation}) intent = ET.Element('intent-filter') action = ET.Element('action', {'android:name' : 'android.intent.action.MAIN'}) category = ET.Element('category', {'android:name' : 'android.intent.category.LAUNCHER'}) intent.append(action) intent.append(category) activity.append(intent) intent2 = ET.Element('intent-filter') category = ET.Element('category', {'android:name' : 'android.intent.category.LEANBACK_LAUNCHER'}) intent2.append(category) activity.append(intent2) application = root.find('application') application.insert(0, activity) tree.write(manifest, encoding)