diff --git a/1/a78482dagy1h1boqumoo7j20jh0xctb6.jpg b/1/a78482dagy1h1boqumoo7j20jh0xctb6.jpg new file mode 100755 index 0000000..0d71d7e Binary files /dev/null and b/1/a78482dagy1h1boqumoo7j20jh0xctb6.jpg differ diff --git a/1/我好命苦.png b/1/我好命苦.png new file mode 100755 index 0000000..8a29ddc Binary files /dev/null and b/1/我好命苦.png differ diff --git a/1/气死我了.png b/1/气死我了.png new file mode 100755 index 0000000..657684c Binary files /dev/null and b/1/气死我了.png differ diff --git a/README.md b/README.md index 46e93fe..716c235 100755 --- a/README.md +++ b/README.md @@ -1,18 +1,35 @@ -# UEngine 运行器 1.6.0 +# UEngine 运行器 1.6.1 ### 介绍         新版本Deepin/UOS发布后,可以在应用商店安装部分官方已适配的安卓应用,对爱好者来说,不能自己安装APK软件包始终差点意思,本程序可以为Deepin/UOS上的UEngine安卓运行环境安装自定义APK软件包,并能发送安装的APK包启动菜单到桌面或系统菜单。 -![1.6.0](https://storage.deepin.org/thread/202202122214208076_截图_选择区域_20220212221349.png) -(测试平台:UOS 家庭版 21.1,deepin 20.4,UOS 专业版 1040) +![截图_tk_20220521175128.png](https://storage.deepin.org/thread/202205211806252353_截图_tk_20220521175128.png) +(测试平台:UOS 家庭版 21.1,deepin 20.6,UOS 专业版 1040) (自己美术功底太差,图标直接用 anbox 的了) ## 安装前必读 + releases 里有两个 deb 包,**是一样的除了包名和打包标准不同**,**只能选择其中一个安装**,**两个都安装会产生冲突**,两个deb包的作用如下: - 包名为`spark-uengine-runner`的,是旧包,按照**正常标准打包**,适用于从**星火应用商店安装**以及**从低版本(即1.3.2即以下版本升级上来的用户)升级**或者**之前就安装该版本的用户**甚至**想跨平台的用户**等等 - 包名为`com.gitee.uengine.runner.spark`的,是按照**deepin/UOS的标准打包的**,适用于**之前就安装该版本并升级上来的用户**以及**希望按照该方法打包的用户**等等 -+ **近期升级的 UEngine 安装时会自动把要安装的 apk 删除**,如果这个 apk 文件非常重要请**拷贝一个备份版并安装这个备份版** ++ **近期升级的 UEngine 安装时会自动把要安装的 apk 删除**,如果这个 apk 文件非常重要请**拷贝一个备份版并安装这个备份版或者在程序设置里面选择“备份APK包然后在安装后自动拷贝原先目录”选项** +![image.png](https://storage.deepin.org/thread/202205211808393526_image.png) + ### 更新内容 +#### V1.6.1(2022年05月21日,521) +**※1、修复了打包 deb 包在 APK 的包名有大写时无法启动的问题** +**※2、提供新版本的 UEngine Root 镜像** +**※3、更新了 UEngine Root 的下载地址** +**※4、修复了本程序的“UEngine 键盘映射”无法启动的问题** +5、把构建 UEngine Root 镜像修改为多线程下载(wget=>aria2) +6、提供了 UEngine 运行器的 API(可以从项目地址中获取) +7、补上遗漏的项目参与者“星空露光”,新加项目参与者“为什么您不喜欢熊出没和阿布呢” +![截图_选择区域_20220521175308.png](https://storage.deepin.org/thread/202205211806261045_截图_选择区域_20220521175308.png) +![截图_选择区域_20220521175238.png](https://storage.deepin.org/thread/202205211806269003_截图_选择区域_20220521175238.png) +![截图_选择区域_20220521175156.png](https://storage.deepin.org/thread/202205211806255140_截图_选择区域_20220521175156.png) +![截图_tk_20220521175128.png](https://storage.deepin.org/thread/202205211806252353_截图_tk_20220521175128.png) +![截图_选择区域_20220521175342.png](https://storage.deepin.org/thread/202205211806254882_截图_选择区域_20220521175342.png) + + #### V1.6.0(开学版,开学前一天完成) **※1、更换了新的图标已完成(感谢[@星空露光](https://gitee.com/Cynorkyle))** **※2、支持程序的评分和查看分数详情的功能** diff --git a/api/__init__.py b/api/__init__.py index 2404a76..16bbad0 100644 --- a/api/__init__.py +++ b/api/__init__.py @@ -298,7 +298,7 @@ class UEngine: if not os.path.exists: os.mkdir("/tmp/uengine-runner") File("/tmp/uengine-runner/install.sh").write("sudo dpkg -i /tmp/uengine-runner/u*.deb\nsudo apt install -f") - os.system("wget -P '/tmp/uengine-runner' 'https://hub.fastgit.org/gfdgd-xi/uengine-runner/releases/download/U1.1.14/uengine-android-image_1.1.14_amd64.deb' && pkexec bash '/tmp/uengine-runner/install.sh'") + os.system("wget -P '/tmp/uengine-runner' 'https://hub.fastgit.org/gfdgd-xi/uengine-runner/releases/download/U1.2.15/uengine-android-image_1.2.15_amd64.deb' && pkexec bash '/tmp/uengine-runner/install.sh'") class Services: def Open(): os.system("pkexec systemctl enable uengine-container uengine-session && systemctl start uengine-container uengine-session") @@ -350,13 +350,6 @@ class UengineRunner: if __name__ == "__main__": print("本 API 不支持直接运行,请通过引入的方式使用此 API") - apki = APK("/home/gfdgd_xi/下载/60D3B51B76CCAC313B3F0809FD1A64FD.apk") - print(apki.packageName()) - print(apki.chineseLabel()) - #print(apki.install()) - #apki.run() - #apki.buildDeb("/home/gfdgd_xi/下载/好奇时间.deb") - apki.uninstall() quit() if not ROOT.GetRoot(): diff --git a/api/root-uengine.sh b/api/root-uengine.sh index 896b42d..335f765 100755 --- a/api/root-uengine.sh +++ b/api/root-uengine.sh @@ -5,7 +5,7 @@ mkdir -p ~/temp cd ~/temp echo "正在下载supersu" -wget -P ~/temp http://supersuroot.org/downloads/SuperSU-v2.82-201705271822.zip +aria2c -x 16 -s 16 -d ~/temp http://supersuroot.org/downloads/SuperSU-v2.82-201705271822.zip cd .. mkdir -p ~/temp/work/dabao/extract/DEBIAN echo "正在解压supersu" diff --git a/build/DEBIAN/control b/build/DEBIAN/control index 535bd7e..8de24f3 100644 --- a/build/DEBIAN/control +++ b/build/DEBIAN/control @@ -1,10 +1,10 @@ Package: spark-uengine-runner -Version: 1.6.0 -Maintainer: gfdgd xi <3025613752@qq.com>, actionchen<917981399@qq.com> +Version: 1.6.1 +Maintainer: gfdgd xi <3025613752@qq.com>, actionchen<917981399@qq.com>, 柚子, 为什么您不喜欢熊出没和阿布呢, 星空露光 Homepage: [https://gitee.com/gfdgd-xi/uengine-runner, https://github.com/gfdgd-xi/uengine-runner] Architecture: all Priority: optional Conflicts: com.gitee.uengine.runner.spark, spark-uengine-apk-builder -Depends: python3, python3-tk, python3-pip, aapt, uengine, python3-setuptools, deepin-terminal, curl, python3-pil, python3-pil.imagetk, python3-requests, adb, translate-shell, python3-xlib, fonts-noto-cjk, python3-numpy, python3-matplotlib, wget, inotify-tools +Depends: python3, python3-tk, python3-pip, aapt, uengine, python3-setuptools, deepin-terminal, curl, python3-pil, python3-pil.imagetk, python3-requests, adb, translate-shell, python3-xlib, fonts-noto-cjk, python3-numpy, python3-matplotlib, wget, inotify-tools, aria2 Description: UEngine Runner for deepin and UOS diff --git a/build/DEBIAN/postinst b/build/DEBIAN/postinst index 4138656..f97044c 100755 --- a/build/DEBIAN/postinst +++ b/build/DEBIAN/postinst @@ -8,4 +8,4 @@ python3 -m pip install --upgrade easygui -i http://mirrors.aliyun.com/pypi/si # 刷新图标缓存 gtk-update-icon-cache /usr/share/icons/bloom # 向服务器返回安装数加1(不显示内容且忽略错误) -curl http://120.25.153.144/uengine-runner/Install.php?Version=1.6.0 -s > /dev/null | true \ No newline at end of file +curl http://120.25.153.144/uengine-runner/Install.php?Version=1.6.1 -s > /dev/null | true \ No newline at end of file diff --git a/build/opt/apps/uengine-runner/api/README.md b/build/opt/apps/uengine-runner/api/README.md new file mode 100644 index 0000000..8630a4e --- /dev/null +++ b/build/opt/apps/uengine-runner/api/README.md @@ -0,0 +1,109 @@ +# API 介绍 +# 必知 +1. 此 API 只支持可以运行 UEngine 的 Linux 上,Windows 上无法使用 +2. 部分函数需要 root 权限 +3. 这是 UEngine 运行器的函数重构,所以一些 UEngine 运行器上没有的 bug 可能在这个 API 里有 +## ProgramInformation +用于获取一些程序信息,详细如下(未特殊表明的是变量,否则是函数): +| 变量/函数名 | 变量/函数介绍 | +|:-:|:-:| +| programPath | 获取程序所在路径 | +| version | API 版本 | +| updateTime | 更新时间 | +| websize | 程序官网 | +| home | 用户 home(用户文件)目录 | +| developer | 参与的开发者列表 | +| language | 当前语言 | +| DesktopPath() | (函数)用户桌面目录 | + +## Check +用于检查 API 所需的东西是否完整,详细如下: +| 函数名 | 函数介绍 | +|:-:|:-:| +| CheckDepend() | 检查 API 所需的依赖是否完整 | + +## ROOT +用于检查 ROOT 方面问题,详细如下: +| 函数名 | 函数介绍 | +|:-:|:-:| +| GetRoot() | 检查程序/API是否以 ROOT 权限运行 | + +## APK +这是面向对象的写法,所以应用方式也不一样: +```python +import api +xxx = api.APK("APK 所在路径") +``` +具体函数介绍: +| 函数名 | 函数介绍 | +|:-:|:-:| +| xxx.install() | 安装这个 APK 包(需要 Root) | +| xxx.uninstall()| 卸载这个 APK 包(需要 Root) | +| xxx.information()| 获取从 aapt 获取到的 APK 信息 | +| xxx.activityName() | 获取 APK 的 Activity 信息 | +| xxx.packageName() | 获取 APK 包名 | +| xxx.chineseLabel() | 获取 APK 中文名称 | +| xxx.saveApkIcon("图标保存路径") | 保存 APK 的图标到指定路径 | +| xxx.version() | 获取 APK 版本号 | +| xxx.saveDesktopFile("图标保存路径", "快捷方式保存路径") | 保存支持 UEngine 启动的 APK 快捷方式 | +| xxx.run() | 运行该应用(需要保证已经安装) | +| xxx.buildDeb("deb 包保存路径", qianZhui) | 打包为 deb 包(“qianZhui”是布尔值,可略,True代表有前缀为“uengine-dc”,False代表没有前缀) | + +## UEngine +用于对 UEngine 进行一点点操控,详细如下: +| 函数名 | 函数介绍 | +|:-:|:-:| +| UengineAppManager() | 显示 UEngine 安装应用程序管理器 | +| OpenApp("应用包名", "应用Activity") | 运行指定的应用(需要保证程序已经安装) | +| UengineDataClean() | 清空 UEngine 数据(需要 Root) | +| RemoveUengineCheck() | 删除 UEngine 的检查脚本(需要 Root) | +| CPUCheck() | 检查 CPU 是否支持运行 UEngine | +| BuildUengineRootImage() | 构建 UEngine 的 Root 镜像 | +| OpenUengineRootData() | 打开 UEngine 数据目录 | +| InstallRootUengineImage() | 安装已经被 Root 过的 UEngine 镜像(需要 Root) | +| Services | 用于操控 UEngine 服务的类,见下(需要 Root) | +| InternetBridge | 用于操控 UEngine 网络桥接的类,见下(需要 Root) | +### Services +关于 UEngine 的服务控制: +| 函数名 | 函数介绍 | +|:-:|:-:| +| Services.Open() | 打开 UEngine 服务(需要 Root) | +| Services.Close() | 关闭 UEngine 服务(需要 Root) | +| Services.Restart() | 重启 UEngine 服务(需要 Root) | +### InternetBridge +关于 UEngine 的网络桥接控制: +| 函数名 | 函数介绍 | +|:-:|:-:| +| InternetBridge.Open() | 打开 UEngine 网络桥接(需要 Root) | +| InternetBridge.Close() | 关闭 UEngine 网络桥接(需要 Root) | +| InternetBridge.Restart() | 重启 UEngine 网络桥接(需要 Root) | +| InternetBridge.Reload() | 重新加载 UEngine 网络桥接(需要 Root) | +| InternetBridge.ForceReload() | 强制加载 UEngine 网络桥接(需要 Root) | +## Adb +用于对 Adb 的部分操控 +| 函数名 | 函数介绍 | +|:-:|:-:| +| Services | 用于操控 Adb 服务的类,见下 | +### Service +关于 Adb 的服务控制: +| 函数名 | 函数介绍 | +|:-:|:-:| +| Services.Open() | 打开 Adb 服务 | +| Services.Close() | 关闭 Adb 服务 | +| Services.Kill() | 杀死 Adb 进程 | +## File +关于文件的读取和写入,这是面向对象的写法,所以应用方式也不一样: +```python +import api +xxx = api.File("文件所在路径") +``` +| 函数名 | 函数介绍 | +|:-:|:-:| +| xxx.read() | 读取这个文件 | +| xxx.write("写入内容") | 写入这个文件 | + +## UengineRunner +用于 UEngine 运行器的部分操控(请保证安装了 UEngine 运行器) +| 函数名 | 函数介绍 | +|:-:|:-:| +| CleanHistory() | 清理 UEngine 运行器的历史记录 | \ No newline at end of file diff --git a/build/opt/apps/uengine-runner/api/__init__.py b/build/opt/apps/uengine-runner/api/__init__.py new file mode 100644 index 0000000..16bbad0 --- /dev/null +++ b/build/opt/apps/uengine-runner/api/__init__.py @@ -0,0 +1,356 @@ +import os +import random +import shutil +import zipfile +import traceback +import subprocess +from getxmlimg import getsavexml + +class ProgramInformation: + programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string + version = "1.6.0Alpha2" + updateTime = "2022年05月21日" + websize = ["https://gitee.com/gfdgd-xi/uengine-runner", "https://github.com/gfdgd-xi/uengine-runner"] + home = os.path.expanduser('~') + developer = ["gfdgd xi<3025613752@qq.com>", "为什么您不喜欢熊出没和阿布呢", "星空露光", "actionchen<917981399@qq.com>", "柚子"] + lang = os.getenv('LANG') + # 获取用户桌面目录 + def DesktopPath() -> "获取用户桌面目录": + for line in open(get_home() + "/.config/user-dirs.dirs"): # 以行来读取配置文件 + desktop_index = line.find("XDG_DESKTOP_DIR=\"") # 寻找是否有对应项,有返回 0,没有返回 -1 + if desktop_index != -1: # 如果有对应项 + break # 结束循环 + if desktop_index == -1: # 如果是提前结束,值一定≠-1,如果是没有提前结束,值一定=-1 + return -1 + else: + get = line[17:-2] # 截取桌面目录路径 + get_index = get.find("$HOME") # 寻找是否有对应的项,需要替换内容 + if get != -1: # 如果有 + get = get.replace("$HOME", get_home()) # 则把其替换为用户目录(~) + return get # 返回目录 + +# 判断程序以正确方式运行 +class Check: + def CheckDepend(): + depend = ["/usr/bin/uengine", "UEngine", "/usr/bin/adb", "adb", "/usr/bin/uengine-session-launch-helper", "UEngine", "/usr/bin/aapt", "aapt"] + for i in range(0, len(depend), 2): + if not os.path.exists(depend[i]): + print("依赖{}不存在".format(depend[i + 1])) + +class ROOT: + def GetRoot(): + return os.geteuid() == 0 + +class APK: + def __init__(self, apkPath): + self.apkPath = apkPath + def install(self): + os.system("pkexec /usr/bin/uengine-session-launch-helper -- uengine install --apk='{}'".format(self.apkPath)) + def uninstall(self): + os.system("pkexec /usr/bin/uengine-session-launch-helper -- uengine uninstall --pkg='{}'".format(self.packageName())) + def information(self): + return subprocess.getoutput("aapt dump badging '{}'".format(self.apkPath)) + def activityName(self): + info = self.information() + for line in info.split('\n'): + if "launchable-activity" in line: + line = line[0: line.index("label='")] + line = line.replace("launchable-activity: ", "") + line = line.replace("'", "") + line = line.replace(" ", "") + line = line.replace("name=", "") + line = line.replace("label=", "") + line = line.replace("icon=", "") + return line + # 获取 apk 包名 + def packageName(self): + info = self.information() + for line in info.split('\n'): + if "package:" in line: + line = line[0: line.index("versionCode='")] + line = line.replace("package:", "") + line = line.replace("name=", "") + line = line.replace("'", "") + line = line.replace(" ", "") + return line + # 获取软件的中文名称 + def chineseLabel(self) -> "获取软件的中文名称": + info = self.information() + for line in info.split('\n'): + if "application-label:" in line: + line = line.replace("application-label:", "") + line = line.replace("'", "") + return line + # 保存apk图标 + def saveApkIcon(self, iconSavePath) -> "保存 apk 文件的图标": + try: + if os.path.exists(iconSavePath): + os.remove(iconSavePath) + info = self.information() + for line in info.split('\n'): + if "application:" in line: + xmlpath = line.split(":")[-1].split()[-1].split("=")[-1].replace("'", "") + if xmlpath.endswith('.xml'): + xmlsave = getsavexml() + print(xmlpath) + xmlsave.savexml(self.apkPath, xmlpath, iconSavePath) + return + else: + zip = zipfile.ZipFile(self.apkPath) + iconData = zip.read(xmlpath) + with open(iconSavePath, 'w+b') as saveIconFile: + saveIconFile.write(iconData) + return + print("None Icon! Show defult icon") + shutil.copy(ProgramInformation.programPath + "/defult.png", iconSavePath) + except: + traceback.print_exc() + print("Error, show defult icon") + shutil.copy(ProgramInformation.programPath + "/defult.png", iconSavePath) + def version(self): + info = self.information() + for line in info.split('\n'): + if "package:" in line: + if "compileSdkVersion='" in line: + line = line.replace(line[line.index("compileSdkVersion='"): -1], "") + if "platform" in line: + line = line.replace(line[line.index("platform"): -1], "") + line = line.replace(line[0: line.index("versionName='")], "") + line = line.replace("versionName='", "") + line = line.replace("'", "") + line = line.replace(" ", "") + return line + def saveDesktopFile(self, desktopPath, iconPath): + showName = self.chineseLabel() + if showName == "" or showName == None: + showName = "未知应用" + self.saveApkIcon(iconPath) + things = '''[Desktop Entry] + Categories=app; + Encoding=UTF-8 + Exec=uengine launch --action=android.intent.action.MAIN --package={} --component={} + GenericName={} + Icon={} + MimeType= + Name={} + StartupWMClass={} + Terminal=false + Type=Application + '''.format(self.packageName(), self.activityName(), showName, iconPath, showName, showName) + File(desktopPath).write(things) + def run(self): + UEngine.OpenApp(self.packageName(), self.activityName()) + + def buildDeb(self, savePath, qianZhui = True): + tempPath = "/tmp/uengine-apk-builder-{}".format(int(random.randint(0, 1024))) + #RunCommandShow("echo '======================================New===================================='") + #RunCommandShow("echo '创建目录'") + os.makedirs("{}/DEBIAN".format(tempPath)) + os.makedirs("{}/usr/share/applications".format(tempPath)) + os.makedirs("{}/usr/share/uengine/apk".format(tempPath)) + os.makedirs("{}/usr/share/uengine/icons".format(tempPath)) + apkPackageName = self.packageName() + if qianZhui: + apkPackageNameNew = "uengine-dc-" + self.packageName().lower() + else: + apkPackageNameNew = self.packageName().lower() + apkPackageVersion = self.version() + if apkPackageVersion[0].upper() == "V": + package = list(apkPackageVersion) + package.pop(0) + apkPackageVersion = "".join(package) + apkChineseLabel = self.chineseLabel() + apkActivityName = self.activityName() + iconSavePath = "{}/usr/share/uengine/icons/{}.png".format(tempPath, apkPackageNameNew) + debControl = '''Package: {} +Version: {} +Architecture: all +Maintainer: {} +Depends: deepin-elf-verify (>= 0.0.16.7-1), uengine (>= 1.0.1) +Section: utils +Priority: optional +Description: {}\n'''.format(apkPackageNameNew, apkPackageVersion, apkChineseLabel, apkChineseLabel) + debPostinst = '''#!/bin/sh + +APK_DIR="/usr/share/uengine/apk" +APK_NAME="{}" +APK_PATH="$APK_DIR/$APK_NAME" +DESKTOP_FILE="{}" + + +if [ -f $APK_PATH ]; then + echo "Installing $APK_NAME" +else + echo "ERROR: $APK_NAME does not exist." + exit 0 +fi + +session_manager=`ps -ef | grep "uengine session-manager" | grep -v grep` +if test -z "$session_manager"; then + echo "ERROR: app install failed(session-manager is not running)." + sess_dir="/usr/share/uengine/session_install" + if [ ! -d $sess_dir ]; then + mkdir $sess_dir + chmod 777 $sess_dir + fi + apk_name=${{APK_PATH##*/}} + fileName="$sess_dir/$apk_name" + echo $DESKTOP_FILE > $fileName + abistr="" + if test -n "$abistr"; then + abi=`echo $abistr |awk -F \= '{{print $2}}'` + echo $abi >> $fileName + fi + chmod 766 $fileName +fi + +/usr/bin/uengine-session-launch-helper -- uengine install --apk="$APK_PATH" + +exit 0'''.format(apkPackageNameNew + ".apk", "/usr/share/applications/{}.desktop".format(apkPackageNameNew)) + debPrerm = '''#!/bin/sh + +APP_NAME="{}" +DESKTOP_FILE="{}" + +session_manager=`ps -ef | grep "uengine session-manager" | grep -v grep` +if test -z "$session_manager"; then + echo "ERROR: app uninstall failed(session-manager is not running)." + sess_dir="/usr/share/uengine/session_uninstall" + if [ ! -d $sess_dir ]; then + mkdir $sess_dir + chmod 777 $sess_dir + fi + fileName="$sess_dir/$APP_NAME" + echo $DESKTOP_FILE > $fileName + chmod 766 $fileName +fi + +echo "Uninstalling $APP_NAME" +/usr/bin/uengine-session-launch-helper -- uengine uninstall --pkg="$APP_NAME" + +exit 0'''.format(apkPackageName, "/usr/share/applications/{}.desktop".format(apkPackageNameNew)) + desktopFile = '''[Desktop Entry] +Categories=Other; +Exec=uengine launch --action=android.intent.action.MAIN --package={} --component={} +Icon=/usr/share/uengine/icons/{}.png +Terminal=false +Type=Application +GenericName={} +Name={} +''' + # RunCommandShow("echo '{}' > '{}/DEBIAN/control'".format(debControl, tempPath)) + #RunCommandShow("echo 正在写入文件:'{}/DEBIAN/control'".format(tempPath)) + File("{}/DEBIAN/control".format(tempPath)).write(debControl) + #RunCommandShow("echo 正在写入文件:'{}/DEBIAN/postinst'".format(tempPath)) + File("{}/DEBIAN/postinst".format(tempPath)).write(debPostinst) + #RunCommandShow("echo 正在写入文件:'{}/DEBIAN/prerm'".format(tempPath)) + File("{}/DEBIAN/prerm".format(tempPath)).write(debPrerm) + #RunCommandShow("echo 正在写入文件:'/usr/share/applications/{}.desktop'".format(apkPackageNameNew)) + # write_txt("{}/usr/share/applications/{}.desktop".format(tempPath, apkPackageNameNew), desktopFile) + self.saveDesktopFile("{}/usr/share/applications/{}.desktop".format(tempPath, apkPackageNameNew), + "{}/usr/share/uengine/icons/{}.png".format(tempPath, apkPackageNameNew)) + #BuildUengineDesktop(apkPackageName, apkActivityName, apkChineseLabel, + # "/usr/share/uengine/icons/{}.png".format(apkPackageNameNew), + # "{}/usr/share/applications/{}.desktop".format(tempPath, apkPackageNameNew)) + #RunCommandShow("echo '复制文件'") + #RunCommandShow("echo '写入 APK 软件图标'") + #SaveApkIcon(apkPath, iconSavePath) + self.saveApkIcon(iconSavePath) + #RunCommandShow("echo '复制 APK 文件'") + shutil.copy(self.apkPath, "{}/usr/share/uengine/apk/{}.apk".format(tempPath, apkPackageNameNew)) + #RunCommandShow("cp -rv '{}' '{}/usr/share/uengine/apk/{}.apk'".format(apkPath, tempPath, apkPackageNameNew)) + #RunCommandShow("echo '正在设置文件权限……'") + os.system("chmod 0775 -vR '{}/DEBIAN/postinst'".format(tempPath)) + os.system("chmod 0775 -vR '{}/DEBIAN/prerm'".format(tempPath)) + #RunCommandShow("echo '打包 deb 到桌面……'") + os.system( + "dpkg -b '{}' '{}'".format(tempPath, savePath)) + #RunCommandShow("echo '正在删除临时目录……'") + #shutil.rmtree(tempPath) + #RunCommandShow("rm -rfv '{}'".format(tempPath)) + #RunCommandShow("echo '完成!'") + #findApkHistory.append(apkPath) + #combobox1['value'] = findApkHistory + #write_txt(get_home() + "/.config/uengine-runner/FindApkBuildHistory.json", + # str(json.dumps(ListToDictionary(findApkHistory)))) # 将历史记录的数组转换为字典并写入 + #messagebox.showinfo(title="提示", message="打包完成") + #DisabledAndEnbled(False) + + +class UEngine: + def UengineAppManager(): + os.system("uengine launch --package=org.anbox.appmgr --component=org.anbox.appmgr.AppViewActivity") + def OpenApp(appPackage, appActivity): + os.system("uengine launch --package={} --component={}".format(appPackage, appActivity)) + # 清空 uengine 数据 + def UengineDataClean() -> "清空 uengine 数据": + shutil.rmtree("{}/.local/share/applications/uengine/".format(ProgramInformation.home)) + shutil.rmtree("/data/uengine") + def RemoveUengineCheck(): + os.remove("/usr/share/uengine/uengine-check-runnable.sh") + def CPUCheck(): + return subprocess.getoutput("uengine check-features") + def BuildUengineRootImage(): + os.system(ProgramInformation.programPath + "/root-uengine.sh") + def OpenUengineRootData(): + os.system("xdg-open /data/uengine/data/data") + def InstallRootUengineImage(): + if not os.path.exists: + os.mkdir("/tmp/uengine-runner") + File("/tmp/uengine-runner/install.sh").write("sudo dpkg -i /tmp/uengine-runner/u*.deb\nsudo apt install -f") + os.system("wget -P '/tmp/uengine-runner' 'https://hub.fastgit.org/gfdgd-xi/uengine-runner/releases/download/U1.2.15/uengine-android-image_1.2.15_amd64.deb' && pkexec bash '/tmp/uengine-runner/install.sh'") + class Services: + def Open(): + os.system("pkexec systemctl enable uengine-container uengine-session && systemctl start uengine-container uengine-session") + def Close(): + os.system("pkexec systemctl disable uengine-container uengine-session") + def Restart(): + os.system("pkexec systemctl restart uengine*") + class InternetBridge: + def Open(): + os.system("pkexec uengine-bridge.sh start") + def Close(): + os.system("pkexec uengine-bridge.sh stop") + def Restart(): + os.system("pkexec uengine-bridge.sh restart") + def Reload(): + os.system("pkexec uengine-bridge.sh reload") + def ForceReload(): + os.system("pkexec uengine-bridge.sh force-reload") + +class Adb: + class Service: + def Open(): + os.system("adb start-server") + def Close(): + os.system("adb kill-server") + def Kill(): + os.system("killall adb") + +class File: + def __init__(self, filePath): + self.filePath = filePath + def read(self): + f = open(self.filePath, "r") # 设置文件对象 + str = f.read() # 获取内容 + f.close() # 关闭文本对象 + return str # 返回结果 + def write(self, things) -> "写入文本文档": + TxtDir = os.path.dirname(self.filePath) + print(TxtDir) + if not os.path.exists(TxtDir): + os.makedirs(TxtDir, exist_ok=True) + file = open(self.filePath, 'w', encoding='UTF-8') # 设置文件对象 + file.write(things) # 写入文本 + file.close() # 关闭文本对象 + +class UengineRunner: + def CleanHistory(): + shutil.rmtree(ProgramInformation.home + "/.config/uengine-runner") + +if __name__ == "__main__": + print("本 API 不支持直接运行,请通过引入的方式使用此 API") + quit() + +if not ROOT.GetRoot(): + print("请获取 ROOT 权限以便更好的使用该 API") \ No newline at end of file diff --git a/build/opt/apps/uengine-runner/api/__pycache__/getxmlimg.cpython-37.pyc b/build/opt/apps/uengine-runner/api/__pycache__/getxmlimg.cpython-37.pyc new file mode 100644 index 0000000..79021ab Binary files /dev/null and b/build/opt/apps/uengine-runner/api/__pycache__/getxmlimg.cpython-37.pyc differ diff --git a/build/opt/apps/uengine-runner/api/defult.png b/build/opt/apps/uengine-runner/api/defult.png new file mode 100644 index 0000000..c836b68 Binary files /dev/null and b/build/opt/apps/uengine-runner/api/defult.png differ diff --git a/build/opt/apps/uengine-runner/api/getxmlimg.py b/build/opt/apps/uengine-runner/api/getxmlimg.py new file mode 100755 index 0000000..af59a70 --- /dev/null +++ b/build/opt/apps/uengine-runner/api/getxmlimg.py @@ -0,0 +1,118 @@ +import PIL.Image as Image +import PIL.ImageDraw as ImageDraw +import zipfile +import subprocess +import re + +class getsavexml(): + + def savexml(self,apkFilePath,xmlpath,iconSavePath): + cmddumpid = "aapt dump xmltree "+ apkFilePath + " " + xmlpath + print(cmddumpid) + xmltree = subprocess.getoutput(cmddumpid) + xmls = xmltree.splitlines() + # find strs ,print next line + def FindStrs(lines,strs): + i=0 + while i < len(lines): + if re.search(strs,lines[i]): + tmpstr = lines[i+1] + i += 1 + Resultstr = tmpstr.split(":")[-1].split("=")[-1].split("0x")[-1] + return Resultstr + else: + i += 1 + #从apk的信息中获取前后景图片的ID号 + backimgid = FindStrs(xmls,"background") + foreimgid = FindStrs(xmls,"foreground") + print(backimgid) + print(foreimgid) + + # 直接从apk resource文件获取前后两层图片路径及ID字符串 + resource = subprocess.getoutput("aapt dump --values resources " + apkFilePath + "| grep -iE -A1 " + "\"" + backimgid + "|" + foreimgid + "\"") + resourcelines = resource.splitlines() + print(resourcelines) + + # 从过滤出的字符串中获取所有相同ID的图片路径 + def Findpicpath(lines,imgid): + i=0 + Resultstr = [] + while i < len(lines): + if re.search(imgid,lines[i]) and re.search("string8",lines[i+1]) : + print(lines[i+1]) + tmpstr = lines[i+1].replace("\"","") + i += 1 + Resultstr.append(tmpstr.split()[-1]) + else: + i += 1 + return Resultstr + + #获取所有带前后图片ID的图片路径(相同背景或者前景的图片ID但分辨率不一样) + backimgs = Findpicpath(resourcelines,backimgid) + foreimgs = Findpicpath(resourcelines,foreimgid) + print(backimgs) + print(foreimgs) + #获取分辨率最高的图片路径 + def getmaxsize(imgs): + j = 0 + size=(0,0) + zipapk = zipfile.ZipFile(apkFilePath) + imgpath = "" + while j < len(imgs): + print(imgs[j]) + img = Image.open(zipapk.open(imgs[j])) + print(imgs[j]) + print(img.size) + if size < img.size: + size = img.size + imgpath = imgs[j] + j += 1 + return imgpath + + # 获取到文件列表后,进行比较分辨率,选取分辨率最高的张图片 + iconbackpath = getmaxsize(backimgs) + iconforepath = getmaxsize(foreimgs) + print(iconbackpath + " " + iconforepath) + + #从APK文件获取最终图片 + zipapk = zipfile.ZipFile(apkFilePath) + iconback = zipapk.open(iconbackpath) + iconfore = zipapk.open(iconforepath) + + + # 叠加图片,mask 设置前景为蒙版 + iconbackimg = Image.open(iconback).convert("RGBA") + iconforeimg = Image.open(iconfore).convert("RGBA") + iconbackimg.paste(iconforeimg,mask=iconforeimg) + + + # 圆角图片函数,网上拷贝的 + def circle_corner(img, radii): #把原图片变成圆角,这个函数是从网上找的,原址 https://www.pyget.cn/p/185266 + """ + 圆角处理 + :param img: 源图象。 + :param radii: 半径,如:30。 + :return: 返回一个圆角处理后的图象。 + """ + # 画圆(用于分离4个角) + circle = Image.new('L', (radii * 2, radii * 2), 0) # 创建一个黑色背景的画布 + draw = ImageDraw.Draw(circle) + draw.ellipse((0, 0, radii * 2, radii * 2), fill=255) # 画白色圆形 + # 原图 + img = img.convert("RGBA") + w, h = img.size + # 画4个角(将整圆分离为4个部分) + alpha = Image.new('L', img.size, 255) + alpha.paste(circle.crop((0, 0, radii, radii)), (0, 0)) # 左上角 + alpha.paste(circle.crop((radii, 0, radii * 2, radii)), (w - radii, 0)) # 右上角 + alpha.paste(circle.crop((radii, radii, radii * 2, radii * 2)), (w - radii, h - radii)) # 右下角 + alpha.paste(circle.crop((0, radii, radii, radii * 2)), (0, h - radii)) # 左下角 + # alpha.show() + img.putalpha(alpha) # 白色区域透明可见,黑色区域不可见 + return img + + # 圆角半径1/8边长,保存icon图片 + w,h = iconbackimg.size + iconimg = circle_corner(iconbackimg,int(w/8)) + iconimg.save(iconSavePath) + diff --git a/build/opt/apps/uengine-runner/api/root-uengine.sh b/build/opt/apps/uengine-runner/api/root-uengine.sh new file mode 100755 index 0000000..335f765 --- /dev/null +++ b/build/opt/apps/uengine-runner/api/root-uengine.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +#sudo apt install squashfs-tools + +mkdir -p ~/temp +cd ~/temp +echo "正在下载supersu" +aria2c -x 16 -s 16 -d ~/temp http://supersuroot.org/downloads/SuperSU-v2.82-201705271822.zip +cd .. +mkdir -p ~/temp/work/dabao/extract/DEBIAN +echo "正在解压supersu" +unzip ~/temp/SuperSU-v2.82-201705271822.zip -d ~/temp/work/su +WORKDIR=~/temp/work +cd "$WORKDIR" +echo "正在下载uengine-android-image" +apt download uengine-android-image +echo "正在解压uengine-android-image" +cd dabao +dpkg-deb -x $WORKDIR/uengine-android-image*.deb extract/ +dpkg-deb -e $WORKDIR/uengine-android-image*.deb extract/DEBIAN +cd .. +cp dabao/extract/usr/share/uengine/android.img android.img + +echo "正在解压android镜像" +sudo unsquashfs android.img + +sudo mkdir -p ./squashfs-root/system/app/SuperSU +sudo mkdir -p ./squashfs-root/system/bin/.ext/ + +echo "正在将supersu安装到android镜像" +sudo cp ./su/common/Superuser.apk ./squashfs-root/system/app/SuperSU/SuperSU.apk +sudo cp ./su/common/install-recovery.sh ./squashfs-root/system/etc/install-recovery.sh +sudo cp ./su/common/install-recovery.sh ./squashfs-root/system/bin/install-recovery.sh +sudo cp ./su/x64/su ./squashfs-root/system/xbin/su +sudo cp ./su/x64/su ./squashfs-root/system/bin/.ext/.su +sudo cp ./su/x64/su ./squashfs-root/system/xbin/daemonsu +sudo cp ./su/x64/supolicy ./squashfs-root/system/xbin/supolicy +sudo cp ./su/x64/libsupol.so ./squashfs-root/system/lib64/libsupol.so +sudo cp ./squashfs-root/system/bin/app_process64 ./squashfs-root/system/bin/app_process_init +sudo cp ./squashfs-root/system/bin/app_process64 ./squashfs-root/system/bin/app_process64_original +sudo cp ./squashfs-root/system/xbin/daemonsu ./squashfs-root/system/bin/app_process +sudo cp ./squashfs-root/system/xbin/daemonsu ./squashfs-root/system/bin/app_process64 + +sudo chmod +x ./squashfs-root/system/app/SuperSU/SuperSU.apk +sudo chmod +x ./squashfs-root/system/etc/install-recovery.sh +sudo chmod +x ./squashfs-root/system/bin/install-recovery.sh +sudo chmod +x ./squashfs-root/system/xbin/su +sudo chmod +x ./squashfs-root/system/bin/.ext/.su +sudo chmod +x ./squashfs-root/system/xbin/daemonsu +sudo chmod +x ./squashfs-root/system/xbin/supolicy +sudo chmod +x ./squashfs-root/system/lib64/libsupol.so +sudo chmod +x ./squashfs-root/system/bin/app_process_init +sudo chmod +x ./squashfs-root/system/bin/app_process64_original +sudo chmod +x ./squashfs-root/system/bin/app_process +sudo chmod +x ./squashfs-root/system/bin/app_process64 + +echo "正在打包android镜像" +sudo rm android.img +sudo mksquashfs squashfs-root android.img -b 131072 -comp xz -Xbcj ia64 + + +cp android.img dabao/extract/usr/share/uengine/android.img + +echo "正在打包uengine-android-image" +cd dabao/extract +find usr -type f -print0 |xargs -0 md5sum >md5sums +cd .. +mkdir build +dpkg-deb -b extract/ build/ + +cp build/*.deb ~/ + +echo "正在清理垃圾" +sudo rm -rf ~/temp + +echo "已在用户主目录生成新的安装包,安装后重启即可生效" \ No newline at end of file diff --git a/build/opt/apps/uengine-runner/information.json b/build/opt/apps/uengine-runner/information.json index 383fa29..8e02ff9 100755 --- a/build/opt/apps/uengine-runner/information.json +++ b/build/opt/apps/uengine-runner/information.json @@ -4,7 +4,7 @@ "https://gitee.com/gfdgd-xi/uengine-runner", "https://github.com/gfdgd-xi/uengine-runner" ], - "Version": "1.6.0", + "Version": "1.6.1", "System": "Linux(deepin/UOS)", "Tips": [ "更多可见:https://gitee.com/gfdgd-xi/uengine-runner/wikis", @@ -22,6 +22,14 @@ "5、如果想要使用adb连接UEngine或其他手机,请使用 1.2.0 以前的版本。(如需连接UEngine请安装adb补丁)" ], "Update": [ + "V1.6.1:", + "※1、修复了打包 deb 包在 APK 的包名有大写时无法启动的问题", + "※2、提供新版本的 UEngine Root 镜像", + "※3、更新了 UEngine Root 的下载地址", + "※4、修复了本程序的“UEngine 键盘映射”无法启动的问题", + "5、把构建 UEngine Root 镜像修改为多线程下载(wget=>aria2)", + "6、提供了 UEngine 运行器的 API(可以从项目地址中获取)", + "7、补上遗漏的项目参与者“星空露光”,新加项目参与者“为什么您不喜欢熊出没和阿布呢”", "V1.6.0:", "※1、更换了新的图标", "※2、支持程序的评分和查看分数详情的功能(如果炸了我的服务器,这个就作废了)", @@ -147,6 +155,8 @@ "Contribute": [ "gfdgd xi<3025613752@qq.com>", "actionchen<917981399@qq.com>", - "柚子" + "柚子", + "为什么您不喜欢熊出没和阿布呢", + "星空露光" ] } \ No newline at end of file diff --git a/build/opt/apps/uengine-runner/root-uengine.sh b/build/opt/apps/uengine-runner/root-uengine.sh index 896b42d..a7edcda 100755 --- a/build/opt/apps/uengine-runner/root-uengine.sh +++ b/build/opt/apps/uengine-runner/root-uengine.sh @@ -1,11 +1,11 @@ #!/bin/bash -#sudo apt install squashfs-tools +sudo apt install squashfs-tools mkdir -p ~/temp cd ~/temp echo "正在下载supersu" -wget -P ~/temp http://supersuroot.org/downloads/SuperSU-v2.82-201705271822.zip +aria2c -x 16 -s 16 -d ~/temp http://supersuroot.org/downloads/SuperSU-v2.82-201705271822.zip cd .. mkdir -p ~/temp/work/dabao/extract/DEBIAN echo "正在解压supersu" diff --git a/build/opt/apps/uengine-runner/uengine-apk-builder b/build/opt/apps/uengine-runner/uengine-apk-builder index 2f5756f..6a963bd 100755 --- a/build/opt/apps/uengine-runner/uengine-apk-builder +++ b/build/opt/apps/uengine-runner/uengine-apk-builder @@ -2,8 +2,8 @@ # 使用系统默认的 python3 运行 ########################################################################################### # 作者:gfdgd xi -# 版本:1.5.3 -# 更新时间:2022年02月07日(要开学了) +# 版本:1.6.1 +# 更新时间:2022年04月30日(五一了) # 感谢:anbox、deepin 和 统信 # 基于 Python3 的 tkinter 构建 ########################################################################################### @@ -68,9 +68,9 @@ def BuildApkDeb(apkPath): RunCommandShow("echo '写入文件,因为写入过程过于复杂,不显示写入命令……'") apkPackageName = GetApkPackageName(apkPath, False) if qianZhui.get(): - apkPackageNameNew = GetApkPackageName(apkPath, True) + apkPackageNameNew = GetApkPackageName(apkPath, True).lower() else: - apkPackageNameNew = GetApkPackageName(apkPath, False) + apkPackageNameNew = GetApkPackageName(apkPath, False).lower() apkPackageVersion = GetApkVersion(apkPath) if apkPackageVersion[0].upper() == "V": package = list(apkPackageVersion) @@ -274,8 +274,8 @@ def GetApkPackageName(apkFilePath, setting): line = line.replace(" ", "") # 此较为特殊,因为需要判断用户是否要添加前缀 if setting: - return "uengine-dc-{}".format(line).lower() - return line.lower() + return "uengine-dc-{}".format(line) + return line def GetApkVersion(apkFilePath): info = GetApkInformation(apkFilePath) diff --git a/build/opt/apps/uengine-runner/uengine-keyboard b/build/opt/apps/uengine-runner/uengine-keyboard index da87fd1..5ec0b70 100755 --- a/build/opt/apps/uengine-runner/uengine-keyboard +++ b/build/opt/apps/uengine-runner/uengine-keyboard @@ -1,7 +1,7 @@ #!/usr/bin/env python3 ######################################### -# 版本:1.5.1 -# 更新时间:2021年10月06日 +# 版本:1.6.1 +# 更新时间:2022年10月06日 # Need: unix, python3-tk, python3-pip, pymouse, keyboard ######################################### import os @@ -57,7 +57,10 @@ def Mouse(key): print(keybo[key.name]["MousePlace"]) pyautogui.FAILSAFE = False #os.system(programPath + "/mouse.py {} {}".format(keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1])) - pyautogui.click(keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1]) + try: + pyautogui.click(keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1]) + except: + pass #pyautogui.click(1500, 800) #m.click(keybo[key.name]["MousePlace"][0],keybo[key.name]["MousePlace"][1]) @@ -72,6 +75,7 @@ def Setting(key): return False def ShowTips(): + global close try: if setting: settingLabelText.set('''设置方法:把鼠标移动带所需位置然后按下需要设置的按键即可({}x{}) @@ -90,15 +94,23 @@ def ShowTips(): 4、映射时会占用鼠标,所以在使用时最好不要使用鼠标;'''.format(pyautogui.position()[0], pyautogui.position()[1])) settingButton.configure(state=tk.NORMAL) time.sleep(0.1) - ShowTips() + if not close: + ShowTips() except: traceback.print_exc() + print(close) if not close: ShowTips() def Closing(): + global close close = True window.destroy() + #key.close() + #stop_thread(keys) + keyboard.unhook(Inputt) + sys.exit(0) + def Key(): keyboard.hook(Inputt) @@ -150,6 +162,7 @@ programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string iconPath = "{}/icon.png".format(os.path.split(os.path.realpath(__file__))[0]) keybo = json.loads(readtxt("{}/.config/uengine-keyboard/key.json".format(get_home()))) version = json.loads(readtxt("{}/information.json".format(programPath)))["Version"] +pyautogui.PAUSE = 0 ################### # 判断是不是 root @@ -214,7 +227,8 @@ settingButton.grid(row=0, column=1) win.pack(fill="both", expand="yes") #threaded.lock.allocate_lock() -threading.Thread(target=Key).start() +keys = threading.Thread(target=Key) +keys.start() threading.Thread(target=ShowTips).start() pyautogui.FAILSAFE = False '''def B(key): diff --git a/build/opt/apps/uengine-runner/uengine-runner b/build/opt/apps/uengine-runner/uengine-runner index da2ea10..a258f70 100755 --- a/build/opt/apps/uengine-runner/uengine-runner +++ b/build/opt/apps/uengine-runner/uengine-runner @@ -3,10 +3,10 @@ ########################################################################################### # 作者:gfdgd xi<3025613752@qq.com> # 版本:1.6.1 -# 更新时间:2022年2月6日(要开学了) +# 更新时间:2022年5月21日(要开学了) # 感谢:anbox、deepin 和 UOS # 基于 Python3 的 tkinter 构建 -# 更新:gfdgd xi<3025613752@qq.com>、actionchen<917981399@qq.com> +# 更新:gfdgd xi<3025613752@qq.com>、actionchen<917981399@qq.com>、为什么您不喜欢熊出没和阿布呢 ########################################################################################### ################# # 引入所需的库 @@ -331,7 +331,7 @@ def InstallRootUengineImage(): if not os.path.exists: os.mkdir("/tmp/uengine-runner") write_txt("/tmp/uengine-runner/install.sh", "sudo dpkg -i /tmp/uengine-runner/u*.deb\nsudo apt install -f") - threading.Thread(target=os.system, args=["deepin-terminal -C \"wget -P '/tmp/uengine-runner' 'https://hub.fastgit.org/gfdgd-xi/uengine-runner/releases/download/U1.1.14/uengine-android-image_1.1.14_amd64.deb' && pkexec bash '/tmp/uengine-runner/install.sh'\""]).start() + threading.Thread(target=os.system, args=["deepin-terminal -C \"wget -P '/tmp/uengine-runner' 'https://hub.fastgit.xyz/gfdgd-xi/uengine-runner/releases/download/U1.2.15/uengine-android-image_1.2.15_amd64.deb' && pkexec bash '/tmp/uengine-runner/install.sh'\""]).start() def BuildRootUengineImage(): threading.Thread(target=os.system, args=["deepin-terminal -C \"bash '{}'\"".format(programPath + "/root-uengine.sh")]).start() diff --git a/com.gitee.uengine.runner.spark.deb b/com.gitee.uengine.runner.spark.deb index f5e8451..3d47a0b 100755 Binary files a/com.gitee.uengine.runner.spark.deb and b/com.gitee.uengine.runner.spark.deb differ diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..0b0f47a Binary files /dev/null and b/icon.png differ diff --git a/information-new.json b/information-new.json index 98805d6..1c3033c 100755 --- a/information-new.json +++ b/information-new.json @@ -24,6 +24,12 @@ "Update": [ "V1.6.1:", "※1、修复了打包 deb 包在 APK 的包名有大写时无法启动的问题", + "※2、提供新版本的 UEngine Root 镜像", + "※3、更新了 UEngine Root 的下载地址", + "※4、修复了本程序的“UEngine 键盘映射”无法启动的问题", + "5、把构建 UEngine Root 镜像修改为多线程下载(wget=>aria2)", + "6、提供了 UEngine 运行器的 API(可以从项目地址中获取)", + "7、补上遗漏的项目参与者“星空露光”,新加项目参与者“为什么您不喜欢熊出没和阿布呢”", "V1.6.0:", "※1、更换了新的图标", "※2、支持程序的评分和查看分数详情的功能(如果炸了我的服务器,这个就作废了)", diff --git a/information.json b/information.json index 2cdfeab..8e02ff9 100755 --- a/information.json +++ b/information.json @@ -24,6 +24,12 @@ "Update": [ "V1.6.1:", "※1、修复了打包 deb 包在 APK 的包名有大写时无法启动的问题", + "※2、提供新版本的 UEngine Root 镜像", + "※3、更新了 UEngine Root 的下载地址", + "※4、修复了本程序的“UEngine 键盘映射”无法启动的问题", + "5、把构建 UEngine Root 镜像修改为多线程下载(wget=>aria2)", + "6、提供了 UEngine 运行器的 API(可以从项目地址中获取)", + "7、补上遗漏的项目参与者“星空露光”,新加项目参与者“为什么您不喜欢熊出没和阿布呢”", "V1.6.0:", "※1、更换了新的图标", "※2、支持程序的评分和查看分数详情的功能(如果炸了我的服务器,这个就作废了)", diff --git a/main.py b/main.py index 1cd5588..a258f70 100755 --- a/main.py +++ b/main.py @@ -331,7 +331,7 @@ def InstallRootUengineImage(): if not os.path.exists: os.mkdir("/tmp/uengine-runner") write_txt("/tmp/uengine-runner/install.sh", "sudo dpkg -i /tmp/uengine-runner/u*.deb\nsudo apt install -f") - threading.Thread(target=os.system, args=["deepin-terminal -C \"wget -P '/tmp/uengine-runner' 'https://hub.fastgit.org/gfdgd-xi/uengine-runner/releases/download/U1.1.14/uengine-android-image_1.1.14_amd64.deb' && pkexec bash '/tmp/uengine-runner/install.sh'\""]).start() + threading.Thread(target=os.system, args=["deepin-terminal -C \"wget -P '/tmp/uengine-runner' 'https://hub.fastgit.xyz/gfdgd-xi/uengine-runner/releases/download/U1.2.15/uengine-android-image_1.2.15_amd64.deb' && pkexec bash '/tmp/uengine-runner/install.sh'\""]).start() def BuildRootUengineImage(): threading.Thread(target=os.system, args=["deepin-terminal -C \"bash '{}'\"".format(programPath + "/root-uengine.sh")]).start() diff --git a/new-deb-build/DEBIAN/control b/new-deb-build/DEBIAN/control index caaa56c..cb1b72c 100644 --- a/new-deb-build/DEBIAN/control +++ b/new-deb-build/DEBIAN/control @@ -1,9 +1,9 @@ Package: com.gitee.uengine.runner.spark Source: com.gitee.uengine.runner.spark -Version: 1.6.0 +Version: 1.6.1 Architecture: all -Maintainer: gfdgd xi <3025613752@qq.com>, actionchen<917981399@qq.com> -Depends: deepin-elf-verify (>= 0.0.16.7-1), python3, python3-tk, python3-pip, aapt, uengine, python3-setuptools, deepin-terminal, curl, python3-pil, python3-pil.imagetk, python3-requests, adb, translate-shell, python3-xlib, fonts-noto-cjk, python3-numpy, python3-matplotlib, wget, inotify-tools +Maintainer: gfdgd xi <3025613752@qq.com>, actionchen<917981399@qq.com>, 柚子, 为什么您不喜欢熊出没和阿布呢, 星空露光 +Depends: deepin-elf-verify (>= 0.0.16.7-1), python3, python3-tk, python3-pip, aapt, uengine, python3-setuptools, deepin-terminal, curl, python3-pil, python3-pil.imagetk, python3-requests, adb, translate-shell, python3-xlib, fonts-noto-cjk, python3-numpy, python3-matplotlib, wget, inotify-tools, aria2 Section: utils Priority: optional Conflicts: spark-uengine-runner, spark-uengine-apk-builder diff --git a/new-deb-build/DEBIAN/postinst b/new-deb-build/DEBIAN/postinst index b2ed248..dcb72ff 100755 --- a/new-deb-build/DEBIAN/postinst +++ b/new-deb-build/DEBIAN/postinst @@ -20,4 +20,4 @@ ln -s /opt/apps/com.gitee.uengine.runner.spark/files/root-uengine # 刷新图标缓存 #gtk-update-icon-cache /usr/share/icons/bloom # 向服务器返回安装数加1(不显示内容且忽略错误) -curl http://120.25.153.144/uengine-runner/Install.php?Version=1.6.0 -s > /dev/null | true \ No newline at end of file +curl http://120.25.153.144/uengine-runner/Install.php?Version=1.6.1 -s > /dev/null | true \ No newline at end of file diff --git a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/README.md b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/README.md new file mode 100644 index 0000000..8630a4e --- /dev/null +++ b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/README.md @@ -0,0 +1,109 @@ +# API 介绍 +# 必知 +1. 此 API 只支持可以运行 UEngine 的 Linux 上,Windows 上无法使用 +2. 部分函数需要 root 权限 +3. 这是 UEngine 运行器的函数重构,所以一些 UEngine 运行器上没有的 bug 可能在这个 API 里有 +## ProgramInformation +用于获取一些程序信息,详细如下(未特殊表明的是变量,否则是函数): +| 变量/函数名 | 变量/函数介绍 | +|:-:|:-:| +| programPath | 获取程序所在路径 | +| version | API 版本 | +| updateTime | 更新时间 | +| websize | 程序官网 | +| home | 用户 home(用户文件)目录 | +| developer | 参与的开发者列表 | +| language | 当前语言 | +| DesktopPath() | (函数)用户桌面目录 | + +## Check +用于检查 API 所需的东西是否完整,详细如下: +| 函数名 | 函数介绍 | +|:-:|:-:| +| CheckDepend() | 检查 API 所需的依赖是否完整 | + +## ROOT +用于检查 ROOT 方面问题,详细如下: +| 函数名 | 函数介绍 | +|:-:|:-:| +| GetRoot() | 检查程序/API是否以 ROOT 权限运行 | + +## APK +这是面向对象的写法,所以应用方式也不一样: +```python +import api +xxx = api.APK("APK 所在路径") +``` +具体函数介绍: +| 函数名 | 函数介绍 | +|:-:|:-:| +| xxx.install() | 安装这个 APK 包(需要 Root) | +| xxx.uninstall()| 卸载这个 APK 包(需要 Root) | +| xxx.information()| 获取从 aapt 获取到的 APK 信息 | +| xxx.activityName() | 获取 APK 的 Activity 信息 | +| xxx.packageName() | 获取 APK 包名 | +| xxx.chineseLabel() | 获取 APK 中文名称 | +| xxx.saveApkIcon("图标保存路径") | 保存 APK 的图标到指定路径 | +| xxx.version() | 获取 APK 版本号 | +| xxx.saveDesktopFile("图标保存路径", "快捷方式保存路径") | 保存支持 UEngine 启动的 APK 快捷方式 | +| xxx.run() | 运行该应用(需要保证已经安装) | +| xxx.buildDeb("deb 包保存路径", qianZhui) | 打包为 deb 包(“qianZhui”是布尔值,可略,True代表有前缀为“uengine-dc”,False代表没有前缀) | + +## UEngine +用于对 UEngine 进行一点点操控,详细如下: +| 函数名 | 函数介绍 | +|:-:|:-:| +| UengineAppManager() | 显示 UEngine 安装应用程序管理器 | +| OpenApp("应用包名", "应用Activity") | 运行指定的应用(需要保证程序已经安装) | +| UengineDataClean() | 清空 UEngine 数据(需要 Root) | +| RemoveUengineCheck() | 删除 UEngine 的检查脚本(需要 Root) | +| CPUCheck() | 检查 CPU 是否支持运行 UEngine | +| BuildUengineRootImage() | 构建 UEngine 的 Root 镜像 | +| OpenUengineRootData() | 打开 UEngine 数据目录 | +| InstallRootUengineImage() | 安装已经被 Root 过的 UEngine 镜像(需要 Root) | +| Services | 用于操控 UEngine 服务的类,见下(需要 Root) | +| InternetBridge | 用于操控 UEngine 网络桥接的类,见下(需要 Root) | +### Services +关于 UEngine 的服务控制: +| 函数名 | 函数介绍 | +|:-:|:-:| +| Services.Open() | 打开 UEngine 服务(需要 Root) | +| Services.Close() | 关闭 UEngine 服务(需要 Root) | +| Services.Restart() | 重启 UEngine 服务(需要 Root) | +### InternetBridge +关于 UEngine 的网络桥接控制: +| 函数名 | 函数介绍 | +|:-:|:-:| +| InternetBridge.Open() | 打开 UEngine 网络桥接(需要 Root) | +| InternetBridge.Close() | 关闭 UEngine 网络桥接(需要 Root) | +| InternetBridge.Restart() | 重启 UEngine 网络桥接(需要 Root) | +| InternetBridge.Reload() | 重新加载 UEngine 网络桥接(需要 Root) | +| InternetBridge.ForceReload() | 强制加载 UEngine 网络桥接(需要 Root) | +## Adb +用于对 Adb 的部分操控 +| 函数名 | 函数介绍 | +|:-:|:-:| +| Services | 用于操控 Adb 服务的类,见下 | +### Service +关于 Adb 的服务控制: +| 函数名 | 函数介绍 | +|:-:|:-:| +| Services.Open() | 打开 Adb 服务 | +| Services.Close() | 关闭 Adb 服务 | +| Services.Kill() | 杀死 Adb 进程 | +## File +关于文件的读取和写入,这是面向对象的写法,所以应用方式也不一样: +```python +import api +xxx = api.File("文件所在路径") +``` +| 函数名 | 函数介绍 | +|:-:|:-:| +| xxx.read() | 读取这个文件 | +| xxx.write("写入内容") | 写入这个文件 | + +## UengineRunner +用于 UEngine 运行器的部分操控(请保证安装了 UEngine 运行器) +| 函数名 | 函数介绍 | +|:-:|:-:| +| CleanHistory() | 清理 UEngine 运行器的历史记录 | \ No newline at end of file diff --git a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/__init__.py b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/__init__.py new file mode 100644 index 0000000..16bbad0 --- /dev/null +++ b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/__init__.py @@ -0,0 +1,356 @@ +import os +import random +import shutil +import zipfile +import traceback +import subprocess +from getxmlimg import getsavexml + +class ProgramInformation: + programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string + version = "1.6.0Alpha2" + updateTime = "2022年05月21日" + websize = ["https://gitee.com/gfdgd-xi/uengine-runner", "https://github.com/gfdgd-xi/uengine-runner"] + home = os.path.expanduser('~') + developer = ["gfdgd xi<3025613752@qq.com>", "为什么您不喜欢熊出没和阿布呢", "星空露光", "actionchen<917981399@qq.com>", "柚子"] + lang = os.getenv('LANG') + # 获取用户桌面目录 + def DesktopPath() -> "获取用户桌面目录": + for line in open(get_home() + "/.config/user-dirs.dirs"): # 以行来读取配置文件 + desktop_index = line.find("XDG_DESKTOP_DIR=\"") # 寻找是否有对应项,有返回 0,没有返回 -1 + if desktop_index != -1: # 如果有对应项 + break # 结束循环 + if desktop_index == -1: # 如果是提前结束,值一定≠-1,如果是没有提前结束,值一定=-1 + return -1 + else: + get = line[17:-2] # 截取桌面目录路径 + get_index = get.find("$HOME") # 寻找是否有对应的项,需要替换内容 + if get != -1: # 如果有 + get = get.replace("$HOME", get_home()) # 则把其替换为用户目录(~) + return get # 返回目录 + +# 判断程序以正确方式运行 +class Check: + def CheckDepend(): + depend = ["/usr/bin/uengine", "UEngine", "/usr/bin/adb", "adb", "/usr/bin/uengine-session-launch-helper", "UEngine", "/usr/bin/aapt", "aapt"] + for i in range(0, len(depend), 2): + if not os.path.exists(depend[i]): + print("依赖{}不存在".format(depend[i + 1])) + +class ROOT: + def GetRoot(): + return os.geteuid() == 0 + +class APK: + def __init__(self, apkPath): + self.apkPath = apkPath + def install(self): + os.system("pkexec /usr/bin/uengine-session-launch-helper -- uengine install --apk='{}'".format(self.apkPath)) + def uninstall(self): + os.system("pkexec /usr/bin/uengine-session-launch-helper -- uengine uninstall --pkg='{}'".format(self.packageName())) + def information(self): + return subprocess.getoutput("aapt dump badging '{}'".format(self.apkPath)) + def activityName(self): + info = self.information() + for line in info.split('\n'): + if "launchable-activity" in line: + line = line[0: line.index("label='")] + line = line.replace("launchable-activity: ", "") + line = line.replace("'", "") + line = line.replace(" ", "") + line = line.replace("name=", "") + line = line.replace("label=", "") + line = line.replace("icon=", "") + return line + # 获取 apk 包名 + def packageName(self): + info = self.information() + for line in info.split('\n'): + if "package:" in line: + line = line[0: line.index("versionCode='")] + line = line.replace("package:", "") + line = line.replace("name=", "") + line = line.replace("'", "") + line = line.replace(" ", "") + return line + # 获取软件的中文名称 + def chineseLabel(self) -> "获取软件的中文名称": + info = self.information() + for line in info.split('\n'): + if "application-label:" in line: + line = line.replace("application-label:", "") + line = line.replace("'", "") + return line + # 保存apk图标 + def saveApkIcon(self, iconSavePath) -> "保存 apk 文件的图标": + try: + if os.path.exists(iconSavePath): + os.remove(iconSavePath) + info = self.information() + for line in info.split('\n'): + if "application:" in line: + xmlpath = line.split(":")[-1].split()[-1].split("=")[-1].replace("'", "") + if xmlpath.endswith('.xml'): + xmlsave = getsavexml() + print(xmlpath) + xmlsave.savexml(self.apkPath, xmlpath, iconSavePath) + return + else: + zip = zipfile.ZipFile(self.apkPath) + iconData = zip.read(xmlpath) + with open(iconSavePath, 'w+b') as saveIconFile: + saveIconFile.write(iconData) + return + print("None Icon! Show defult icon") + shutil.copy(ProgramInformation.programPath + "/defult.png", iconSavePath) + except: + traceback.print_exc() + print("Error, show defult icon") + shutil.copy(ProgramInformation.programPath + "/defult.png", iconSavePath) + def version(self): + info = self.information() + for line in info.split('\n'): + if "package:" in line: + if "compileSdkVersion='" in line: + line = line.replace(line[line.index("compileSdkVersion='"): -1], "") + if "platform" in line: + line = line.replace(line[line.index("platform"): -1], "") + line = line.replace(line[0: line.index("versionName='")], "") + line = line.replace("versionName='", "") + line = line.replace("'", "") + line = line.replace(" ", "") + return line + def saveDesktopFile(self, desktopPath, iconPath): + showName = self.chineseLabel() + if showName == "" or showName == None: + showName = "未知应用" + self.saveApkIcon(iconPath) + things = '''[Desktop Entry] + Categories=app; + Encoding=UTF-8 + Exec=uengine launch --action=android.intent.action.MAIN --package={} --component={} + GenericName={} + Icon={} + MimeType= + Name={} + StartupWMClass={} + Terminal=false + Type=Application + '''.format(self.packageName(), self.activityName(), showName, iconPath, showName, showName) + File(desktopPath).write(things) + def run(self): + UEngine.OpenApp(self.packageName(), self.activityName()) + + def buildDeb(self, savePath, qianZhui = True): + tempPath = "/tmp/uengine-apk-builder-{}".format(int(random.randint(0, 1024))) + #RunCommandShow("echo '======================================New===================================='") + #RunCommandShow("echo '创建目录'") + os.makedirs("{}/DEBIAN".format(tempPath)) + os.makedirs("{}/usr/share/applications".format(tempPath)) + os.makedirs("{}/usr/share/uengine/apk".format(tempPath)) + os.makedirs("{}/usr/share/uengine/icons".format(tempPath)) + apkPackageName = self.packageName() + if qianZhui: + apkPackageNameNew = "uengine-dc-" + self.packageName().lower() + else: + apkPackageNameNew = self.packageName().lower() + apkPackageVersion = self.version() + if apkPackageVersion[0].upper() == "V": + package = list(apkPackageVersion) + package.pop(0) + apkPackageVersion = "".join(package) + apkChineseLabel = self.chineseLabel() + apkActivityName = self.activityName() + iconSavePath = "{}/usr/share/uengine/icons/{}.png".format(tempPath, apkPackageNameNew) + debControl = '''Package: {} +Version: {} +Architecture: all +Maintainer: {} +Depends: deepin-elf-verify (>= 0.0.16.7-1), uengine (>= 1.0.1) +Section: utils +Priority: optional +Description: {}\n'''.format(apkPackageNameNew, apkPackageVersion, apkChineseLabel, apkChineseLabel) + debPostinst = '''#!/bin/sh + +APK_DIR="/usr/share/uengine/apk" +APK_NAME="{}" +APK_PATH="$APK_DIR/$APK_NAME" +DESKTOP_FILE="{}" + + +if [ -f $APK_PATH ]; then + echo "Installing $APK_NAME" +else + echo "ERROR: $APK_NAME does not exist." + exit 0 +fi + +session_manager=`ps -ef | grep "uengine session-manager" | grep -v grep` +if test -z "$session_manager"; then + echo "ERROR: app install failed(session-manager is not running)." + sess_dir="/usr/share/uengine/session_install" + if [ ! -d $sess_dir ]; then + mkdir $sess_dir + chmod 777 $sess_dir + fi + apk_name=${{APK_PATH##*/}} + fileName="$sess_dir/$apk_name" + echo $DESKTOP_FILE > $fileName + abistr="" + if test -n "$abistr"; then + abi=`echo $abistr |awk -F \= '{{print $2}}'` + echo $abi >> $fileName + fi + chmod 766 $fileName +fi + +/usr/bin/uengine-session-launch-helper -- uengine install --apk="$APK_PATH" + +exit 0'''.format(apkPackageNameNew + ".apk", "/usr/share/applications/{}.desktop".format(apkPackageNameNew)) + debPrerm = '''#!/bin/sh + +APP_NAME="{}" +DESKTOP_FILE="{}" + +session_manager=`ps -ef | grep "uengine session-manager" | grep -v grep` +if test -z "$session_manager"; then + echo "ERROR: app uninstall failed(session-manager is not running)." + sess_dir="/usr/share/uengine/session_uninstall" + if [ ! -d $sess_dir ]; then + mkdir $sess_dir + chmod 777 $sess_dir + fi + fileName="$sess_dir/$APP_NAME" + echo $DESKTOP_FILE > $fileName + chmod 766 $fileName +fi + +echo "Uninstalling $APP_NAME" +/usr/bin/uengine-session-launch-helper -- uengine uninstall --pkg="$APP_NAME" + +exit 0'''.format(apkPackageName, "/usr/share/applications/{}.desktop".format(apkPackageNameNew)) + desktopFile = '''[Desktop Entry] +Categories=Other; +Exec=uengine launch --action=android.intent.action.MAIN --package={} --component={} +Icon=/usr/share/uengine/icons/{}.png +Terminal=false +Type=Application +GenericName={} +Name={} +''' + # RunCommandShow("echo '{}' > '{}/DEBIAN/control'".format(debControl, tempPath)) + #RunCommandShow("echo 正在写入文件:'{}/DEBIAN/control'".format(tempPath)) + File("{}/DEBIAN/control".format(tempPath)).write(debControl) + #RunCommandShow("echo 正在写入文件:'{}/DEBIAN/postinst'".format(tempPath)) + File("{}/DEBIAN/postinst".format(tempPath)).write(debPostinst) + #RunCommandShow("echo 正在写入文件:'{}/DEBIAN/prerm'".format(tempPath)) + File("{}/DEBIAN/prerm".format(tempPath)).write(debPrerm) + #RunCommandShow("echo 正在写入文件:'/usr/share/applications/{}.desktop'".format(apkPackageNameNew)) + # write_txt("{}/usr/share/applications/{}.desktop".format(tempPath, apkPackageNameNew), desktopFile) + self.saveDesktopFile("{}/usr/share/applications/{}.desktop".format(tempPath, apkPackageNameNew), + "{}/usr/share/uengine/icons/{}.png".format(tempPath, apkPackageNameNew)) + #BuildUengineDesktop(apkPackageName, apkActivityName, apkChineseLabel, + # "/usr/share/uengine/icons/{}.png".format(apkPackageNameNew), + # "{}/usr/share/applications/{}.desktop".format(tempPath, apkPackageNameNew)) + #RunCommandShow("echo '复制文件'") + #RunCommandShow("echo '写入 APK 软件图标'") + #SaveApkIcon(apkPath, iconSavePath) + self.saveApkIcon(iconSavePath) + #RunCommandShow("echo '复制 APK 文件'") + shutil.copy(self.apkPath, "{}/usr/share/uengine/apk/{}.apk".format(tempPath, apkPackageNameNew)) + #RunCommandShow("cp -rv '{}' '{}/usr/share/uengine/apk/{}.apk'".format(apkPath, tempPath, apkPackageNameNew)) + #RunCommandShow("echo '正在设置文件权限……'") + os.system("chmod 0775 -vR '{}/DEBIAN/postinst'".format(tempPath)) + os.system("chmod 0775 -vR '{}/DEBIAN/prerm'".format(tempPath)) + #RunCommandShow("echo '打包 deb 到桌面……'") + os.system( + "dpkg -b '{}' '{}'".format(tempPath, savePath)) + #RunCommandShow("echo '正在删除临时目录……'") + #shutil.rmtree(tempPath) + #RunCommandShow("rm -rfv '{}'".format(tempPath)) + #RunCommandShow("echo '完成!'") + #findApkHistory.append(apkPath) + #combobox1['value'] = findApkHistory + #write_txt(get_home() + "/.config/uengine-runner/FindApkBuildHistory.json", + # str(json.dumps(ListToDictionary(findApkHistory)))) # 将历史记录的数组转换为字典并写入 + #messagebox.showinfo(title="提示", message="打包完成") + #DisabledAndEnbled(False) + + +class UEngine: + def UengineAppManager(): + os.system("uengine launch --package=org.anbox.appmgr --component=org.anbox.appmgr.AppViewActivity") + def OpenApp(appPackage, appActivity): + os.system("uengine launch --package={} --component={}".format(appPackage, appActivity)) + # 清空 uengine 数据 + def UengineDataClean() -> "清空 uengine 数据": + shutil.rmtree("{}/.local/share/applications/uengine/".format(ProgramInformation.home)) + shutil.rmtree("/data/uengine") + def RemoveUengineCheck(): + os.remove("/usr/share/uengine/uengine-check-runnable.sh") + def CPUCheck(): + return subprocess.getoutput("uengine check-features") + def BuildUengineRootImage(): + os.system(ProgramInformation.programPath + "/root-uengine.sh") + def OpenUengineRootData(): + os.system("xdg-open /data/uengine/data/data") + def InstallRootUengineImage(): + if not os.path.exists: + os.mkdir("/tmp/uengine-runner") + File("/tmp/uengine-runner/install.sh").write("sudo dpkg -i /tmp/uengine-runner/u*.deb\nsudo apt install -f") + os.system("wget -P '/tmp/uengine-runner' 'https://hub.fastgit.org/gfdgd-xi/uengine-runner/releases/download/U1.2.15/uengine-android-image_1.2.15_amd64.deb' && pkexec bash '/tmp/uengine-runner/install.sh'") + class Services: + def Open(): + os.system("pkexec systemctl enable uengine-container uengine-session && systemctl start uengine-container uengine-session") + def Close(): + os.system("pkexec systemctl disable uengine-container uengine-session") + def Restart(): + os.system("pkexec systemctl restart uengine*") + class InternetBridge: + def Open(): + os.system("pkexec uengine-bridge.sh start") + def Close(): + os.system("pkexec uengine-bridge.sh stop") + def Restart(): + os.system("pkexec uengine-bridge.sh restart") + def Reload(): + os.system("pkexec uengine-bridge.sh reload") + def ForceReload(): + os.system("pkexec uengine-bridge.sh force-reload") + +class Adb: + class Service: + def Open(): + os.system("adb start-server") + def Close(): + os.system("adb kill-server") + def Kill(): + os.system("killall adb") + +class File: + def __init__(self, filePath): + self.filePath = filePath + def read(self): + f = open(self.filePath, "r") # 设置文件对象 + str = f.read() # 获取内容 + f.close() # 关闭文本对象 + return str # 返回结果 + def write(self, things) -> "写入文本文档": + TxtDir = os.path.dirname(self.filePath) + print(TxtDir) + if not os.path.exists(TxtDir): + os.makedirs(TxtDir, exist_ok=True) + file = open(self.filePath, 'w', encoding='UTF-8') # 设置文件对象 + file.write(things) # 写入文本 + file.close() # 关闭文本对象 + +class UengineRunner: + def CleanHistory(): + shutil.rmtree(ProgramInformation.home + "/.config/uengine-runner") + +if __name__ == "__main__": + print("本 API 不支持直接运行,请通过引入的方式使用此 API") + quit() + +if not ROOT.GetRoot(): + print("请获取 ROOT 权限以便更好的使用该 API") \ No newline at end of file diff --git a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/__pycache__/getxmlimg.cpython-37.pyc b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/__pycache__/getxmlimg.cpython-37.pyc new file mode 100644 index 0000000..79021ab Binary files /dev/null and b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/__pycache__/getxmlimg.cpython-37.pyc differ diff --git a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/defult.png b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/defult.png new file mode 100644 index 0000000..c836b68 Binary files /dev/null and b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/defult.png differ diff --git a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/getxmlimg.py b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/getxmlimg.py new file mode 100755 index 0000000..af59a70 --- /dev/null +++ b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/getxmlimg.py @@ -0,0 +1,118 @@ +import PIL.Image as Image +import PIL.ImageDraw as ImageDraw +import zipfile +import subprocess +import re + +class getsavexml(): + + def savexml(self,apkFilePath,xmlpath,iconSavePath): + cmddumpid = "aapt dump xmltree "+ apkFilePath + " " + xmlpath + print(cmddumpid) + xmltree = subprocess.getoutput(cmddumpid) + xmls = xmltree.splitlines() + # find strs ,print next line + def FindStrs(lines,strs): + i=0 + while i < len(lines): + if re.search(strs,lines[i]): + tmpstr = lines[i+1] + i += 1 + Resultstr = tmpstr.split(":")[-1].split("=")[-1].split("0x")[-1] + return Resultstr + else: + i += 1 + #从apk的信息中获取前后景图片的ID号 + backimgid = FindStrs(xmls,"background") + foreimgid = FindStrs(xmls,"foreground") + print(backimgid) + print(foreimgid) + + # 直接从apk resource文件获取前后两层图片路径及ID字符串 + resource = subprocess.getoutput("aapt dump --values resources " + apkFilePath + "| grep -iE -A1 " + "\"" + backimgid + "|" + foreimgid + "\"") + resourcelines = resource.splitlines() + print(resourcelines) + + # 从过滤出的字符串中获取所有相同ID的图片路径 + def Findpicpath(lines,imgid): + i=0 + Resultstr = [] + while i < len(lines): + if re.search(imgid,lines[i]) and re.search("string8",lines[i+1]) : + print(lines[i+1]) + tmpstr = lines[i+1].replace("\"","") + i += 1 + Resultstr.append(tmpstr.split()[-1]) + else: + i += 1 + return Resultstr + + #获取所有带前后图片ID的图片路径(相同背景或者前景的图片ID但分辨率不一样) + backimgs = Findpicpath(resourcelines,backimgid) + foreimgs = Findpicpath(resourcelines,foreimgid) + print(backimgs) + print(foreimgs) + #获取分辨率最高的图片路径 + def getmaxsize(imgs): + j = 0 + size=(0,0) + zipapk = zipfile.ZipFile(apkFilePath) + imgpath = "" + while j < len(imgs): + print(imgs[j]) + img = Image.open(zipapk.open(imgs[j])) + print(imgs[j]) + print(img.size) + if size < img.size: + size = img.size + imgpath = imgs[j] + j += 1 + return imgpath + + # 获取到文件列表后,进行比较分辨率,选取分辨率最高的张图片 + iconbackpath = getmaxsize(backimgs) + iconforepath = getmaxsize(foreimgs) + print(iconbackpath + " " + iconforepath) + + #从APK文件获取最终图片 + zipapk = zipfile.ZipFile(apkFilePath) + iconback = zipapk.open(iconbackpath) + iconfore = zipapk.open(iconforepath) + + + # 叠加图片,mask 设置前景为蒙版 + iconbackimg = Image.open(iconback).convert("RGBA") + iconforeimg = Image.open(iconfore).convert("RGBA") + iconbackimg.paste(iconforeimg,mask=iconforeimg) + + + # 圆角图片函数,网上拷贝的 + def circle_corner(img, radii): #把原图片变成圆角,这个函数是从网上找的,原址 https://www.pyget.cn/p/185266 + """ + 圆角处理 + :param img: 源图象。 + :param radii: 半径,如:30。 + :return: 返回一个圆角处理后的图象。 + """ + # 画圆(用于分离4个角) + circle = Image.new('L', (radii * 2, radii * 2), 0) # 创建一个黑色背景的画布 + draw = ImageDraw.Draw(circle) + draw.ellipse((0, 0, radii * 2, radii * 2), fill=255) # 画白色圆形 + # 原图 + img = img.convert("RGBA") + w, h = img.size + # 画4个角(将整圆分离为4个部分) + alpha = Image.new('L', img.size, 255) + alpha.paste(circle.crop((0, 0, radii, radii)), (0, 0)) # 左上角 + alpha.paste(circle.crop((radii, 0, radii * 2, radii)), (w - radii, 0)) # 右上角 + alpha.paste(circle.crop((radii, radii, radii * 2, radii * 2)), (w - radii, h - radii)) # 右下角 + alpha.paste(circle.crop((0, radii, radii, radii * 2)), (0, h - radii)) # 左下角 + # alpha.show() + img.putalpha(alpha) # 白色区域透明可见,黑色区域不可见 + return img + + # 圆角半径1/8边长,保存icon图片 + w,h = iconbackimg.size + iconimg = circle_corner(iconbackimg,int(w/8)) + iconimg.save(iconSavePath) + diff --git a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/root-uengine.sh b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/root-uengine.sh new file mode 100755 index 0000000..335f765 --- /dev/null +++ b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/api/root-uengine.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +#sudo apt install squashfs-tools + +mkdir -p ~/temp +cd ~/temp +echo "正在下载supersu" +aria2c -x 16 -s 16 -d ~/temp http://supersuroot.org/downloads/SuperSU-v2.82-201705271822.zip +cd .. +mkdir -p ~/temp/work/dabao/extract/DEBIAN +echo "正在解压supersu" +unzip ~/temp/SuperSU-v2.82-201705271822.zip -d ~/temp/work/su +WORKDIR=~/temp/work +cd "$WORKDIR" +echo "正在下载uengine-android-image" +apt download uengine-android-image +echo "正在解压uengine-android-image" +cd dabao +dpkg-deb -x $WORKDIR/uengine-android-image*.deb extract/ +dpkg-deb -e $WORKDIR/uengine-android-image*.deb extract/DEBIAN +cd .. +cp dabao/extract/usr/share/uengine/android.img android.img + +echo "正在解压android镜像" +sudo unsquashfs android.img + +sudo mkdir -p ./squashfs-root/system/app/SuperSU +sudo mkdir -p ./squashfs-root/system/bin/.ext/ + +echo "正在将supersu安装到android镜像" +sudo cp ./su/common/Superuser.apk ./squashfs-root/system/app/SuperSU/SuperSU.apk +sudo cp ./su/common/install-recovery.sh ./squashfs-root/system/etc/install-recovery.sh +sudo cp ./su/common/install-recovery.sh ./squashfs-root/system/bin/install-recovery.sh +sudo cp ./su/x64/su ./squashfs-root/system/xbin/su +sudo cp ./su/x64/su ./squashfs-root/system/bin/.ext/.su +sudo cp ./su/x64/su ./squashfs-root/system/xbin/daemonsu +sudo cp ./su/x64/supolicy ./squashfs-root/system/xbin/supolicy +sudo cp ./su/x64/libsupol.so ./squashfs-root/system/lib64/libsupol.so +sudo cp ./squashfs-root/system/bin/app_process64 ./squashfs-root/system/bin/app_process_init +sudo cp ./squashfs-root/system/bin/app_process64 ./squashfs-root/system/bin/app_process64_original +sudo cp ./squashfs-root/system/xbin/daemonsu ./squashfs-root/system/bin/app_process +sudo cp ./squashfs-root/system/xbin/daemonsu ./squashfs-root/system/bin/app_process64 + +sudo chmod +x ./squashfs-root/system/app/SuperSU/SuperSU.apk +sudo chmod +x ./squashfs-root/system/etc/install-recovery.sh +sudo chmod +x ./squashfs-root/system/bin/install-recovery.sh +sudo chmod +x ./squashfs-root/system/xbin/su +sudo chmod +x ./squashfs-root/system/bin/.ext/.su +sudo chmod +x ./squashfs-root/system/xbin/daemonsu +sudo chmod +x ./squashfs-root/system/xbin/supolicy +sudo chmod +x ./squashfs-root/system/lib64/libsupol.so +sudo chmod +x ./squashfs-root/system/bin/app_process_init +sudo chmod +x ./squashfs-root/system/bin/app_process64_original +sudo chmod +x ./squashfs-root/system/bin/app_process +sudo chmod +x ./squashfs-root/system/bin/app_process64 + +echo "正在打包android镜像" +sudo rm android.img +sudo mksquashfs squashfs-root android.img -b 131072 -comp xz -Xbcj ia64 + + +cp android.img dabao/extract/usr/share/uengine/android.img + +echo "正在打包uengine-android-image" +cd dabao/extract +find usr -type f -print0 |xargs -0 md5sum >md5sums +cd .. +mkdir build +dpkg-deb -b extract/ build/ + +cp build/*.deb ~/ + +echo "正在清理垃圾" +sudo rm -rf ~/temp + +echo "已在用户主目录生成新的安装包,安装后重启即可生效" \ No newline at end of file diff --git a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/information.json b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/information.json index 0edbe3a..1c3033c 100755 --- a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/information.json +++ b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/information.json @@ -4,7 +4,7 @@ "https://gitee.com/gfdgd-xi/uengine-runner", "https://github.com/gfdgd-xi/uengine-runner" ], - "Version": "1.6.0", + "Version": "1.6.1", "System": "Linux(deepin/UOS)", "Tips": [ "更多可见:https://gitee.com/gfdgd-xi/uengine-runner/wikis", @@ -22,6 +22,14 @@ "5、如果想要使用adb连接UEngine或其他手机,请使用 1.2.0 以前的版本。(如需连接UEngine请安装adb补丁)" ], "Update": [ + "V1.6.1:", + "※1、修复了打包 deb 包在 APK 的包名有大写时无法启动的问题", + "※2、提供新版本的 UEngine Root 镜像", + "※3、更新了 UEngine Root 的下载地址", + "※4、修复了本程序的“UEngine 键盘映射”无法启动的问题", + "5、把构建 UEngine Root 镜像修改为多线程下载(wget=>aria2)", + "6、提供了 UEngine 运行器的 API(可以从项目地址中获取)", + "7、补上遗漏的项目参与者“星空露光”,新加项目参与者“为什么您不喜欢熊出没和阿布呢”", "V1.6.0:", "※1、更换了新的图标", "※2、支持程序的评分和查看分数详情的功能(如果炸了我的服务器,这个就作废了)", @@ -147,6 +155,8 @@ "Contribute": [ "gfdgd xi<3025613752@qq.com>", "actionchen<917981399@qq.com>", - "柚子" + "柚子", + "为什么您不喜欢熊出没和阿布呢", + "星空露光" ] } \ No newline at end of file diff --git a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/root-uengine.sh b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/root-uengine.sh index 896b42d..a7edcda 100755 --- a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/root-uengine.sh +++ b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/root-uengine.sh @@ -1,11 +1,11 @@ #!/bin/bash -#sudo apt install squashfs-tools +sudo apt install squashfs-tools mkdir -p ~/temp cd ~/temp echo "正在下载supersu" -wget -P ~/temp http://supersuroot.org/downloads/SuperSU-v2.82-201705271822.zip +aria2c -x 16 -s 16 -d ~/temp http://supersuroot.org/downloads/SuperSU-v2.82-201705271822.zip cd .. mkdir -p ~/temp/work/dabao/extract/DEBIAN echo "正在解压supersu" diff --git a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/uengine-apk-builder b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/uengine-apk-builder index 2f5756f..6a963bd 100755 --- a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/uengine-apk-builder +++ b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/uengine-apk-builder @@ -2,8 +2,8 @@ # 使用系统默认的 python3 运行 ########################################################################################### # 作者:gfdgd xi -# 版本:1.5.3 -# 更新时间:2022年02月07日(要开学了) +# 版本:1.6.1 +# 更新时间:2022年04月30日(五一了) # 感谢:anbox、deepin 和 统信 # 基于 Python3 的 tkinter 构建 ########################################################################################### @@ -68,9 +68,9 @@ def BuildApkDeb(apkPath): RunCommandShow("echo '写入文件,因为写入过程过于复杂,不显示写入命令……'") apkPackageName = GetApkPackageName(apkPath, False) if qianZhui.get(): - apkPackageNameNew = GetApkPackageName(apkPath, True) + apkPackageNameNew = GetApkPackageName(apkPath, True).lower() else: - apkPackageNameNew = GetApkPackageName(apkPath, False) + apkPackageNameNew = GetApkPackageName(apkPath, False).lower() apkPackageVersion = GetApkVersion(apkPath) if apkPackageVersion[0].upper() == "V": package = list(apkPackageVersion) @@ -274,8 +274,8 @@ def GetApkPackageName(apkFilePath, setting): line = line.replace(" ", "") # 此较为特殊,因为需要判断用户是否要添加前缀 if setting: - return "uengine-dc-{}".format(line).lower() - return line.lower() + return "uengine-dc-{}".format(line) + return line def GetApkVersion(apkFilePath): info = GetApkInformation(apkFilePath) diff --git a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/uengine-keyboard b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/uengine-keyboard index da87fd1..5ec0b70 100755 --- a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/uengine-keyboard +++ b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/uengine-keyboard @@ -1,7 +1,7 @@ #!/usr/bin/env python3 ######################################### -# 版本:1.5.1 -# 更新时间:2021年10月06日 +# 版本:1.6.1 +# 更新时间:2022年10月06日 # Need: unix, python3-tk, python3-pip, pymouse, keyboard ######################################### import os @@ -57,7 +57,10 @@ def Mouse(key): print(keybo[key.name]["MousePlace"]) pyautogui.FAILSAFE = False #os.system(programPath + "/mouse.py {} {}".format(keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1])) - pyautogui.click(keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1]) + try: + pyautogui.click(keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1]) + except: + pass #pyautogui.click(1500, 800) #m.click(keybo[key.name]["MousePlace"][0],keybo[key.name]["MousePlace"][1]) @@ -72,6 +75,7 @@ def Setting(key): return False def ShowTips(): + global close try: if setting: settingLabelText.set('''设置方法:把鼠标移动带所需位置然后按下需要设置的按键即可({}x{}) @@ -90,15 +94,23 @@ def ShowTips(): 4、映射时会占用鼠标,所以在使用时最好不要使用鼠标;'''.format(pyautogui.position()[0], pyautogui.position()[1])) settingButton.configure(state=tk.NORMAL) time.sleep(0.1) - ShowTips() + if not close: + ShowTips() except: traceback.print_exc() + print(close) if not close: ShowTips() def Closing(): + global close close = True window.destroy() + #key.close() + #stop_thread(keys) + keyboard.unhook(Inputt) + sys.exit(0) + def Key(): keyboard.hook(Inputt) @@ -150,6 +162,7 @@ programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string iconPath = "{}/icon.png".format(os.path.split(os.path.realpath(__file__))[0]) keybo = json.loads(readtxt("{}/.config/uengine-keyboard/key.json".format(get_home()))) version = json.loads(readtxt("{}/information.json".format(programPath)))["Version"] +pyautogui.PAUSE = 0 ################### # 判断是不是 root @@ -214,7 +227,8 @@ settingButton.grid(row=0, column=1) win.pack(fill="both", expand="yes") #threaded.lock.allocate_lock() -threading.Thread(target=Key).start() +keys = threading.Thread(target=Key) +keys.start() threading.Thread(target=ShowTips).start() pyautogui.FAILSAFE = False '''def B(key): diff --git a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/uengine-runner b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/uengine-runner index da2ea10..a258f70 100755 --- a/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/uengine-runner +++ b/new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/uengine-runner @@ -3,10 +3,10 @@ ########################################################################################### # 作者:gfdgd xi<3025613752@qq.com> # 版本:1.6.1 -# 更新时间:2022年2月6日(要开学了) +# 更新时间:2022年5月21日(要开学了) # 感谢:anbox、deepin 和 UOS # 基于 Python3 的 tkinter 构建 -# 更新:gfdgd xi<3025613752@qq.com>、actionchen<917981399@qq.com> +# 更新:gfdgd xi<3025613752@qq.com>、actionchen<917981399@qq.com>、为什么您不喜欢熊出没和阿布呢 ########################################################################################### ################# # 引入所需的库 @@ -331,7 +331,7 @@ def InstallRootUengineImage(): if not os.path.exists: os.mkdir("/tmp/uengine-runner") write_txt("/tmp/uengine-runner/install.sh", "sudo dpkg -i /tmp/uengine-runner/u*.deb\nsudo apt install -f") - threading.Thread(target=os.system, args=["deepin-terminal -C \"wget -P '/tmp/uengine-runner' 'https://hub.fastgit.org/gfdgd-xi/uengine-runner/releases/download/U1.1.14/uengine-android-image_1.1.14_amd64.deb' && pkexec bash '/tmp/uengine-runner/install.sh'\""]).start() + threading.Thread(target=os.system, args=["deepin-terminal -C \"wget -P '/tmp/uengine-runner' 'https://hub.fastgit.xyz/gfdgd-xi/uengine-runner/releases/download/U1.2.15/uengine-android-image_1.2.15_amd64.deb' && pkexec bash '/tmp/uengine-runner/install.sh'\""]).start() def BuildRootUengineImage(): threading.Thread(target=os.system, args=["deepin-terminal -C \"bash '{}'\"".format(programPath + "/root-uengine.sh")]).start() diff --git a/root-uengine.sh b/root-uengine.sh index 896b42d..a7edcda 100755 --- a/root-uengine.sh +++ b/root-uengine.sh @@ -1,11 +1,11 @@ #!/bin/bash -#sudo apt install squashfs-tools +sudo apt install squashfs-tools mkdir -p ~/temp cd ~/temp echo "正在下载supersu" -wget -P ~/temp http://supersuroot.org/downloads/SuperSU-v2.82-201705271822.zip +aria2c -x 16 -s 16 -d ~/temp http://supersuroot.org/downloads/SuperSU-v2.82-201705271822.zip cd .. mkdir -p ~/temp/work/dabao/extract/DEBIAN echo "正在解压supersu" diff --git a/spark-uengine-runner.deb b/spark-uengine-runner.deb index 736db4a..bdcb6ae 100755 Binary files a/spark-uengine-runner.deb and b/spark-uengine-runner.deb differ diff --git a/uengine-keyboard b/uengine-keyboard index da87fd1..c696647 100755 --- a/uengine-keyboard +++ b/uengine-keyboard @@ -1,7 +1,7 @@ #!/usr/bin/env python3 ######################################### -# 版本:1.5.1 -# 更新时间:2021年10月06日 +# 版本:1.6.1 +# 更新时间:2022年10月06日 # Need: unix, python3-tk, python3-pip, pymouse, keyboard ######################################### import os @@ -57,7 +57,10 @@ def Mouse(key): print(keybo[key.name]["MousePlace"]) pyautogui.FAILSAFE = False #os.system(programPath + "/mouse.py {} {}".format(keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1])) - pyautogui.click(keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1]) + try: + pyautogui.click(keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1]) + except: + traceback.print_exc() #pyautogui.click(1500, 800) #m.click(keybo[key.name]["MousePlace"][0],keybo[key.name]["MousePlace"][1]) @@ -72,6 +75,7 @@ def Setting(key): return False def ShowTips(): + global close try: if setting: settingLabelText.set('''设置方法:把鼠标移动带所需位置然后按下需要设置的按键即可({}x{}) @@ -90,15 +94,23 @@ def ShowTips(): 4、映射时会占用鼠标,所以在使用时最好不要使用鼠标;'''.format(pyautogui.position()[0], pyautogui.position()[1])) settingButton.configure(state=tk.NORMAL) time.sleep(0.1) - ShowTips() + if not close: + ShowTips() except: traceback.print_exc() + print(close) if not close: ShowTips() def Closing(): + global close close = True window.destroy() + #key.close() + #stop_thread(keys) + keyboard.unhook(Inputt) + sys.exit(0) + def Key(): keyboard.hook(Inputt) @@ -150,6 +162,7 @@ programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string iconPath = "{}/icon.png".format(os.path.split(os.path.realpath(__file__))[0]) keybo = json.loads(readtxt("{}/.config/uengine-keyboard/key.json".format(get_home()))) version = json.loads(readtxt("{}/information.json".format(programPath)))["Version"] +pyautogui.PAUSE = 0 ################### # 判断是不是 root @@ -214,7 +227,8 @@ settingButton.grid(row=0, column=1) win.pack(fill="both", expand="yes") #threaded.lock.allocate_lock() -threading.Thread(target=Key).start() +keys = threading.Thread(target=Key) +keys.start() threading.Thread(target=ShowTips).start() pyautogui.FAILSAFE = False '''def B(key):