sdk_script.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import file_utils
  2. import xml_utils
  3. import package_utils
  4. import os.path
  5. import xml.etree.ElementTree as ET
  6. namespaces = {'android' : 'http://schemas.android.com/apk/res/android'}
  7. encoding = 'UTF-8'
  8. def execute(game, sdk, config):
  9. if not checkConfig(config):
  10. return 1
  11. #config['splitDex'] = False
  12. subChannel = config['subChannel']
  13. createJmhyProperties(game, sdk, subChannel, config)
  14. createProperties(game, sdk, subChannel, config)
  15. createSdkProperties(game, sdk, subChannel, config)
  16. orientation = getScreenOrientation(game, sdk, subChannel, config)
  17. if orientation is None:
  18. orientation = 'landscape'
  19. config['screenOrientation'] = orientation
  20. changePlaceholders(game, sdk, subChannel, config)
  21. ret = deleteSplash(game, sdk, subChannel, config)
  22. if ret:
  23. return ret
  24. return copyWechatCode(game, sdk, subChannel, config)
  25. def checkConfig(config):
  26. '''
  27. 检查配置
  28. '''
  29. if 'properties' not in config:
  30. print('properties not exists in config')
  31. return False
  32. if 'ysdk' not in config:
  33. print('ysdk not exists in config')
  34. return False
  35. properties = config['properties']
  36. if 'agent' not in properties or 'version' not in properties:
  37. print('agent or version not exists in properties')
  38. return False
  39. '''if 'appid' not in config or 'appkey' not in config:
  40. print('appid or appkey not exists in config')
  41. return False'''
  42. return True
  43. def createJmhyProperties(game, sdk, subChannel, config):
  44. '''
  45. 创建jmhy.properties
  46. '''
  47. print('create jmhy.properties')
  48. propValue = config['properties']
  49. decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache'])
  50. properties = os.path.join(decompliePath, 'assets', 'jmhy.properties')
  51. content = ''
  52. for key in propValue:
  53. content = '%s%s=%s\n' % (content, key, propValue[key])
  54. file_utils.createFile(properties, content)
  55. return 0
  56. def createProperties(game, sdk, subChannel, config):
  57. '''
  58. 创建ysdkconf.ini
  59. '''
  60. print('create ysdkconf.ini')
  61. ysdkConfig = config['ysdk']
  62. decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache'])
  63. properties = os.path.join(decompliePath, 'assets', 'ysdkconf.ini')
  64. content = ''
  65. for key in ysdkConfig:
  66. content = '%s%s=%s\n' % (content, key, ysdkConfig[key])
  67. file_utils.createFile(properties, content)
  68. return 0
  69. def createSdkProperties(game, sdk, subChannel, config):
  70. '''
  71. 创建sdk.properties
  72. '''
  73. print('create sdk.properties')
  74. zysdkConfig = config['zysdk_properties']
  75. decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache'])
  76. properties = os.path.join(decompliePath, 'assets', 'sdk.properties')
  77. content = ''
  78. for key in zysdkConfig:
  79. content = '%s%s=%s\n' % (content, key, zysdkConfig[key])
  80. file_utils.createFile(properties, content)
  81. return 0
  82. def copyWechatCode(game, sdk, subChannel, config):
  83. '''
  84. 拷贝微信sdk的代码
  85. '''
  86. print('copy WXEntryActivity.smali')
  87. sdkPath = file_utils.getFullSDKPath(sdk)
  88. WXEntryActivity = 'WXEntryActivity.smali'
  89. wxFile = os.path.join(sdkPath, 'smali', WXEntryActivity)
  90. decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache'])
  91. smaliPath = os.path.join(decompliePath, 'smali')
  92. targetPath = file_utils.getPackagePath(smaliPath, config['packageName'])
  93. targetFile = os.path.join(targetPath, 'wxapi', WXEntryActivity)
  94. ret = file_utils.copyFile(wxFile, targetFile)
  95. if ret:
  96. return ret
  97. file_utils.replaceContent(targetFile, '${packageName}', config['packageName'].replace('.', '/'))
  98. manifest = os.path.join(decompliePath, 'AndroidManifest.xml')
  99. changeLauncherLaunchMode(manifest)
  100. xml_utils.changeLauncherAttr(manifest, 'configChanges', 'orientation|screenSize|keyboardHidden')
  101. return 0
  102. def deleteSplash(game, sdk, subChannel, config):
  103. '''
  104. 删除闪屏
  105. '''
  106. if game != 'wzjh':
  107. return 0
  108. channelPath = file_utils.getSubChannelPath(game, sdk, subChannel)
  109. print('delete Splash...')
  110. decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache'])
  111. manifest = os.path.join(decompliePath, 'AndroidManifest.xml')
  112. activity = xml_utils.getLauncherActivityName(manifest)
  113. activity = xml_utils.removeLauncherActivity(manifest)
  114. xml_utils.deleteActivityByName(manifest,'com.hugenstar.nanobox.NaNoUnityContext')
  115. addLauncherActivity(manifest, config['screenOrientation'], 'com.hugenstar.nanobox.NaNoUnityContext')
  116. return 0
  117. def changeLauncherLaunchMode(manifest):
  118. '''
  119. 修改启动的activity的launchMode
  120. '''
  121. for key in namespaces:
  122. ET.register_namespace(key, namespaces[key])
  123. tree = ET.parse(manifest)
  124. root = tree.getroot()
  125. launcherActivity = xml_utils.getLauncherActivity(root)
  126. if launcherActivity is None:
  127. return 1
  128. attrName = xml_utils.getNamespacesFormat('android:launchMode', namespaces)
  129. if attrName not in launcherActivity.attrib or 'standard' == launcherActivity.attrib[attrName]:
  130. launcherActivity.attrib[attrName] = 'singleTop'
  131. tree.write(manifest, encoding)
  132. return 0
  133. def getScreenOrientation(game, sdk, subChannel, config):
  134. decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache'])
  135. manifest = os.path.join(decompliePath, 'AndroidManifest.xml')
  136. return getLauncherAttr(manifest, 'screenOrientation')
  137. def getLauncherAttr(manifest, attrType):
  138. '''
  139. 获取启动的activity的属性
  140. '''
  141. for key in namespaces:
  142. ET.register_namespace(key, namespaces[key])
  143. tree = ET.parse(manifest)
  144. root = tree.getroot()
  145. launcherActivity = xml_utils.getLauncherActivity(root)
  146. if launcherActivity is None:
  147. return None
  148. attrName = xml_utils.getNamespacesFormat('android:%s' % attrType, namespaces)
  149. if attrName in launcherActivity.attrib:
  150. return launcherActivity.attrib[attrName]
  151. return None
  152. def changePlaceholders(game, sdk, subChannel, config):
  153. decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache'])
  154. manifest = os.path.join(decompliePath, 'AndroidManifest.xml')
  155. file_utils.replaceContent(manifest, '${screenOrientation}', config['screenOrientation'])
  156. def addLauncherActivity(manifest, screenOrientation, activity):
  157. '''
  158. 添加启动的activity
  159. '''
  160. for key in namespaces:
  161. ET.register_namespace(key, namespaces[key])
  162. tree = ET.parse(manifest)
  163. root = tree.getroot()
  164. # activity
  165. '''<activity android:name=".LauncherActivity"
  166. android:theme="@style/LauncherStyle">
  167. <intent-filter>
  168. <action android:name="android.intent.action.MAIN" />
  169. <category android:name="android.intent.category.LAUNCHER" />
  170. </intent-filter>
  171. </activity>'''
  172. activity = ET.Element('activity', {'android:name' : activity,
  173. 'android:theme' : '@android:style/Theme.Holo.Light.NoActionBar.Fullscreen',
  174. 'android:launchMode' : 'singleTop',
  175. 'android:configChanges' : 'orientation|screenSize|keyboardHidden',
  176. 'android:screenOrientation' : screenOrientation})
  177. intent = ET.Element('intent-filter')
  178. action = ET.Element('action', {'android:name' : 'android.intent.action.MAIN'})
  179. category = ET.Element('category', {'android:name' : 'android.intent.category.LAUNCHER'})
  180. intent.append(action)
  181. intent.append(category)
  182. activity.append(intent)
  183. intent2 = ET.Element('intent-filter')
  184. category = ET.Element('category', {'android:name' : 'android.intent.category.LEANBACK_LAUNCHER'})
  185. intent2.append(category)
  186. activity.append(intent2)
  187. application = root.find('application')
  188. application.insert(0, activity)
  189. tree.write(manifest, encoding)