171 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Python
		
	
	
	
		
		
			
		
	
	
			171 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Python
		
	
	
	
| 
								 | 
							
								import os
							 | 
						|||
| 
								 | 
							
								import re
							 | 
						|||
| 
								 | 
							
								import xml.etree.ElementTree as ET
							 | 
						|||
| 
								 | 
							
								from xml.dom import minidom
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								from scripts.task import Task
							 | 
						|||
| 
								 | 
							
								from utils import FileUtils
							 | 
						|||
| 
								 | 
							
								from utils.logger_utils import app_logger
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								GAME_ACTIVITY_PATH = f"launcher-game/src/com/game/launcher/activity/GLGameActivity.kt".replace("/", os.sep)
							 | 
						|||
| 
								 | 
							
								ANDROID_MANIFEST_PATH = f"launcher-game/AndroidManifest.xml".replace("/", os.sep)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								def process_manifest(input_path, output_path):
							 | 
						|||
| 
								 | 
							
								    # 解析XML文件
							 | 
						|||
| 
								 | 
							
								    tree = ET.parse(input_path)
							 | 
						|||
| 
								 | 
							
								    root = tree.getroot()
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    # 定义命名空间映射
							 | 
						|||
| 
								 | 
							
								    android_namespace = 'http://schemas.android.com/apk/res/android'
							 | 
						|||
| 
								 | 
							
								    ET.register_namespace('android', android_namespace)
							 | 
						|||
| 
								 | 
							
								    namespaces = {'android': android_namespace}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    # 处理application标签,移除所有属性
							 | 
						|||
| 
								 | 
							
								    application = root.find('application')
							 | 
						|||
| 
								 | 
							
								    if application is not None:
							 | 
						|||
| 
								 | 
							
								        # 保存所有子节点
							 | 
						|||
| 
								 | 
							
								        children = list(application)
							 | 
						|||
| 
								 | 
							
								        # 清除application标签
							 | 
						|||
| 
								 | 
							
								        root.remove(application)
							 | 
						|||
| 
								 | 
							
								        # 创建新的application标签(无属性)
							 | 
						|||
| 
								 | 
							
								        new_application = ET.Element('application')
							 | 
						|||
| 
								 | 
							
								        # 添加回所有子节点
							 | 
						|||
| 
								 | 
							
								        for child in children:
							 | 
						|||
| 
								 | 
							
								            new_application.append(child)
							 | 
						|||
| 
								 | 
							
								        # 将新的application标签添加回root
							 | 
						|||
| 
								 | 
							
								        root.append(new_application)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        # 查找并删除指定的activity节点
							 | 
						|||
| 
								 | 
							
								        activity_to_remove = new_application.find(
							 | 
						|||
| 
								 | 
							
								            ".//activity[@android:name='com.unity3d.player.UnityPlayerActivity']",
							 | 
						|||
| 
								 | 
							
								            namespaces=namespaces
							 | 
						|||
| 
								 | 
							
								        )
							 | 
						|||
| 
								 | 
							
								        if activity_to_remove is not None:
							 | 
						|||
| 
								 | 
							
								            new_application.remove(activity_to_remove)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    # 保存处理后的XML,保留android命名空间前缀
							 | 
						|||
| 
								 | 
							
								    rough_string = ET.tostring(root, 'utf-8')
							 | 
						|||
| 
								 | 
							
								    reparsed = minidom.parseString(rough_string)
							 | 
						|||
| 
								 | 
							
								    pretty_xml = reparsed.toprettyxml(indent="  ", encoding='utf-8')
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    # 去除空行
							 | 
						|||
| 
								 | 
							
								    lines = pretty_xml.decode('utf-8').split('\n')
							 | 
						|||
| 
								 | 
							
								    non_empty_lines = [line for line in lines if line.strip() != '']
							 | 
						|||
| 
								 | 
							
								    pretty_xml = '\n'.join(non_empty_lines).encode('utf-8')
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    with open(output_path, 'wb') as f:
							 | 
						|||
| 
								 | 
							
								        f.write(pretty_xml)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    print(f"处理完成,结果已保存到 {output_path}")
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								def uncomment_line(content, line_pattern):
							 | 
						|||
| 
								 | 
							
								    """
							 | 
						|||
| 
								 | 
							
								    取消指定行的注释
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    :param content: 文件内容
							 | 
						|||
| 
								 | 
							
								    :param line_pattern: 要取消注释的行内容(不含前导//和空格)
							 | 
						|||
| 
								 | 
							
								    :return: 更新后的内容
							 | 
						|||
| 
								 | 
							
								    """
							 | 
						|||
| 
								 | 
							
								    # 匹配以//开头,后跟任意空格,然后是目标行内容
							 | 
						|||
| 
								 | 
							
								    pattern = rf'^(\s*)//\s*({re.escape(line_pattern)}\s*)$'
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    # 替换为去注释版本(保留原有缩进)
							 | 
						|||
| 
								 | 
							
								    replacement = rf'\1\2'
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    updated_content = re.sub(pattern, replacement, content, flags=re.MULTILINE)
							 | 
						|||
| 
								 | 
							
								    return updated_content
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								class ProjectUpdateGameRes(Task):
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    def update_game_result(self):
							 | 
						|||
| 
								 | 
							
								        if not self.context.update_res_unity:
							 | 
						|||
| 
								 | 
							
								            app_logger().info("No update game res found")
							 | 
						|||
| 
								 | 
							
								            return
							 | 
						|||
| 
								 | 
							
								        """
							 | 
						|||
| 
								 | 
							
								        更新游戏资源
							 | 
						|||
| 
								 | 
							
								        :return:
							 | 
						|||
| 
								 | 
							
								        """
							 | 
						|||
| 
								 | 
							
								        if self.context.game_type == "unity_native":
							 | 
						|||
| 
								 | 
							
								            res_path = self.context.res_unity_path
							 | 
						|||
| 
								 | 
							
								            dst = os.path.join(self.context.temp_project_path, "unityLibrary")
							 | 
						|||
| 
								 | 
							
								            temp_dst = dst + "_res"
							 | 
						|||
| 
								 | 
							
								            if os.path.exists(dst):
							 | 
						|||
| 
								 | 
							
								                result = FileUtils.delete(dst, True)
							 | 
						|||
| 
								 | 
							
								                app_logger().info(f"删除unityLibrary结果 : {result}")
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            if os.path.exists(temp_dst):
							 | 
						|||
| 
								 | 
							
								                result = FileUtils.delete(temp_dst, True)
							 | 
						|||
| 
								 | 
							
								                app_logger().info(f"删除temp unityLibrary结果 : {result}")
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            FileUtils.decompress(res_path, temp_dst)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            build_path = os.path.join(temp_dst, "build")
							 | 
						|||
| 
								 | 
							
								            if os.path.exists(build_path):
							 | 
						|||
| 
								 | 
							
								                FileUtils.delete(build_path, True)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            if os.listdir(temp_dst).index("unityLibrary") >= 0:
							 | 
						|||
| 
								 | 
							
								                FileUtils.copy(os.path.join(temp_dst, "unityLibrary"), dst)
							 | 
						|||
| 
								 | 
							
								            else:
							 | 
						|||
| 
								 | 
							
								                FileUtils.copy(temp_dst, dst)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            android_manifest_xml_path = os.path.join(dst, "src", "main", "AndroidManifest.xml")
							 | 
						|||
| 
								 | 
							
								            process_manifest(android_manifest_xml_path, android_manifest_xml_path)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            text = open(os.path.join(dst, "build.gradle"), "r", encoding="utf-8").read()
							 | 
						|||
| 
								 | 
							
								            text = text.replace("implementation", "api")
							 | 
						|||
| 
								 | 
							
								            if not 'namespace "com.unity3d.player"' in text:
							 | 
						|||
| 
								 | 
							
								                text = text.replace("compileSdkVersion", """
							 | 
						|||
| 
								 | 
							
								            namespace "com.unity3d.player"
							 | 
						|||
| 
								 | 
							
								            compileSdkVersion""")
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            text = text.replace("unityStreamingAssets.tokenize(', ')",
							 | 
						|||
| 
								 | 
							
								                                '[".unity3d", ".bundle", ".version", ".bytes", ".hash"]')
							 | 
						|||
| 
								 | 
							
								            text = text.replace("apply plugin: 'com.android.library'", """
							 | 
						|||
| 
								 | 
							
								    plugins {
							 | 
						|||
| 
								 | 
							
								        id 'com.android.library'
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								                """)
							 | 
						|||
| 
								 | 
							
								            open(os.path.join(dst, "build.gradle"), "w", encoding="utf-8").write(text)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            lines = open(os.path.join(dst, "build.gradle"), "r", encoding="utf-8").readlines()
							 | 
						|||
| 
								 | 
							
								            new_lines = []
							 | 
						|||
| 
								 | 
							
								            for line in lines:
							 | 
						|||
| 
								 | 
							
								                if line.find("com.game:hachisdk") > 0:
							 | 
						|||
| 
								 | 
							
								                    continue
							 | 
						|||
| 
								 | 
							
								                new_lines.append(line)
							 | 
						|||
| 
								 | 
							
								            open(os.path.join(dst, "build.gradle"), "w", encoding="utf-8").writelines(new_lines)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            # 引用Unity项目
							 | 
						|||
| 
								 | 
							
								            text = open(os.path.join(self.context.temp_project_path, "ad.gradle"), "r", encoding="utf-8").read()
							 | 
						|||
| 
								 | 
							
								            text = uncomment_line(text, "implementation projects.unityLibrary")
							 | 
						|||
| 
								 | 
							
								            open(os.path.join(self.context.temp_project_path, "ad.gradle"), "w", encoding="utf-8").write(text)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            text = open(os.path.join(self.context.temp_project_path, "settings.gradle"), "r", encoding="utf-8").read()
							 | 
						|||
| 
								 | 
							
								            text = uncomment_line(text, "include ':unityLibrary'")
							 | 
						|||
| 
								 | 
							
								            open(os.path.join(self.context.temp_project_path, "settings.gradle"), "w", encoding="utf-8").write(text)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            # launcher 引用 unityActivity
							 | 
						|||
| 
								 | 
							
								            text = open(os.path.join(self.context.temp_project_path, GAME_ACTIVITY_PATH), "r", encoding="utf-8").read()
							 | 
						|||
| 
								 | 
							
								            text = text.replace("GLGameWebActivity", "com.unity3d.player.UnityPlayerActivity")
							 | 
						|||
| 
								 | 
							
								            open(os.path.join(self.context.temp_project_path, GAME_ACTIVITY_PATH), "w", encoding="utf-8").write(text)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            text = open(os.path.join(self.context.temp_project_path, ANDROID_MANIFEST_PATH), "r",
							 | 
						|||
| 
								 | 
							
								                        encoding="utf-8").read()
							 | 
						|||
| 
								 | 
							
								            text = text.replace("@style/LauncherGameIntroTheme", "@style/UnityThemeSelector")
							 | 
						|||
| 
								 | 
							
								            open(os.path.join(self.context.temp_project_path, ANDROID_MANIFEST_PATH), "w", encoding="utf-8").write(text)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        else:
							 | 
						|||
| 
								 | 
							
								            raise Exception(f"不支持的游戏类型 : {self.context.game_type}")
							 | 
						|||
| 
								 | 
							
								        pass
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    def execute(self):
							 | 
						|||
| 
								 | 
							
								        self.update_game_result()
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        self.context.save_cache_config("res_unity", self.context.config_res_unity_md5)
							 | 
						|||
| 
								 | 
							
								        pass
							 |