diff --git a/.gitignore b/.gitignore index 59e0594..41e4115 100644 --- a/.gitignore +++ b/.gitignore @@ -48,5 +48,10 @@ app.*.map.json /backup assets/xa* +assets/patch.tar.gz + +android/app/src/main/jniLibs/* + +devtools_options.yaml lib/l10n/app_localizations* diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 44c68d6..8b722d7 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -22,7 +22,8 @@ android:icon="@mipmap/ic_launcher" android:usesCleartextTraffic="true" android:launchMode="singleInstance" - android:theme="@style/App.Theme"> + android:theme="@style/App.Theme" + android:extractNativeLibs="true"> - + android:targetActivity="com.gaurav.avnc.ui.vnc.IntentReceiverActivity" + android:exported="false"> @@ -100,7 +101,8 @@ android:name="com.termux.x11.LoriePreferences" android:supportsPictureInPicture="false" android:resizeableActivity="true" - android:process=":x11"> + android:process=":x11" + android:exported="false"> diff --git a/android/app/src/main/java/com/termux/x11/CmdEntryPoint.java b/android/app/src/main/java/com/termux/x11/CmdEntryPoint.java index fcfa11c..b737b76 100644 --- a/android/app/src/main/java/com/termux/x11/CmdEntryPoint.java +++ b/android/app/src/main/java/com/termux/x11/CmdEntryPoint.java @@ -234,7 +234,8 @@ public class CmdEntryPoint extends ICmdEntryInterface.Stub { String libPath = res != null ? res.getFile().replace("file:", "") : null; if (libPath != null) { try { - System.load(libPath); + //System.load(libPath); + System.loadLibrary("Xlorie"); } catch (Exception e) { Log.e("CmdEntryPoint", "Failed to dlopen " + libPath, e); System.err.println("Failed to load native library. Did you install the right apk? Try the universal one."); diff --git a/android/app/src/main/kotlin/com/example/tiny_computer/MainActivity.kt b/android/app/src/main/kotlin/com/example/tiny_computer/MainActivity.kt index 6ebbf3b..97198b5 100644 --- a/android/app/src/main/kotlin/com/example/tiny_computer/MainActivity.kt +++ b/android/app/src/main/kotlin/com/example/tiny_computer/MainActivity.kt @@ -66,6 +66,9 @@ class MainActivity: FlutterActivity() { startActivity(Intent(this, com.termux.x11.MainActivity::class.java)) result.success(0) } + "getNativeLibraryPath" -> { + result.success(getApplicationInfo().nativeLibraryDir) + } else -> { // 不支持的方法名 result.notImplemented() diff --git a/assets/assets.zip b/assets/assets.zip index 9b84a6a..21f6bca 100644 Binary files a/assets/assets.zip and b/assets/assets.zip differ diff --git a/assets/busybox b/assets/busybox deleted file mode 100644 index ae75449..0000000 Binary files a/assets/busybox and /dev/null differ diff --git a/assets/patch.tar.gz b/assets/patch.tar.gz deleted file mode 100644 index 22f50bb..0000000 Binary files a/assets/patch.tar.gz and /dev/null differ diff --git a/extra/cross/install-hangover b/extra/cross/install-hangover index 65ad899..742f2c1 100644 --- a/extra/cross/install-hangover +++ b/extra/cross/install-hangover @@ -49,7 +49,7 @@ done echo "正在安装Hangover..." tar xvf hangover.tar -sudo apt install -y ./hangover-wine_${latest_version}~bookworm_arm64.deb ./hangover-libarm64ecfex_${latest_version}_arm64.deb +sudo apt install -y ./hangover*.deb if [ $? -ne 0 ]; then cd /tmp rm -rf /tmp/hangover @@ -60,6 +60,19 @@ fi echo "正在初始化Wine..." wineboot --init +echo "正在安装DXVK..." +tar xvf dxvk-v*.tar.gz +mv dxvk-v*/x32 /home/tiny/.wine/drive_c/windows/syswow64 +mv dxvk-v*/arm64ec /home/tiny/.wine/drive_c/windows/system32 + +echo "自动配置 DLL 覆盖..." +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d8 /d native /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d9 /d native /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d10 /d native /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d10core /d native /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d11 /d native /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v dxgi /d native /f >/dev/null 2>&1 + echo "正在修复字体..." regedit "Z:\\home\\tiny\\.local\\share\\tiny\\extra\\chn_fonts.reg" && wine reg delete "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes" /va /f diff --git a/extra/cross/install-hangover-stable b/extra/cross/install-hangover-stable index af4b060..20a35d3 100644 --- a/extra/cross/install-hangover-stable +++ b/extra/cross/install-hangover-stable @@ -5,7 +5,7 @@ sudo apt update sudo apt upgrade -y hangover_url="https://github.com/AndreRH/hangover/releases/download/hangover-9.20.1/hangover_9.20.1_debian12_bookworm_arm64.tar" -latest_version="10.9" +latest_version="10.6.1" mirror_sites=( "https://gh.llkk.cc/" @@ -35,7 +35,7 @@ done echo "正在安装Hangover..." tar xvf hangover.tar -sudo apt install -y ./hangover-wine_${latest_version}~bookworm_arm64.deb ./hangover-libarm64ecfex_${latest_version}_arm64.deb +sudo apt install -y ./hangover*.deb if [ $? -ne 0 ]; then cd /tmp rm -rf /tmp/hangover @@ -46,6 +46,19 @@ fi echo "正在初始化Wine..." wineboot --init +echo "正在安装DXVK..." +tar xvf dxvk-v*.tar.gz +mv dxvk-v*/x32 /home/tiny/.wine/drive_c/windows/syswow64 +mv dxvk-v*/arm64ec /home/tiny/.wine/drive_c/windows/system32 + +echo "自动配置 DLL 覆盖..." +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d8 /d native /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d9 /d native /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d10 /d native /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d10core /d native /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v d3d11 /d native /f >/dev/null 2>&1 +WINEDLLOVERRIDES="d3d8=n,d3d9=n,d3d10=n,d3d10core=n,d3d11=n,dxgi=n" wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v dxgi /d native /f >/dev/null 2>&1 + echo "正在修复字体..." regedit "Z:\\home\\tiny\\.local\\share\\tiny\\extra\\chn_fonts.reg" && wine reg delete "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes" /va /f diff --git a/extra/readme.md b/extra/readme.md index b38b349..dea4a5b 100644 --- a/extra/readme.md +++ b/extra/readme.md @@ -3,7 +3,6 @@ ### assets.zip中的文件: - [busybox](https://github.com/meefik/busybox) -- [mediamtx相关](https://github.com/bluenviron/mediamtx) - [tar](https://github.com/Rprop/tar-android-static) - [Xserver XSDL, pulseaudio相关文件](https://github.com/pelya/commandergenius/tree/sdl_android/project/jni/application/xserver) - [virgl](https://github.com/termux/termux-packages/tree/master/x11-packages/virglrenderer-android) diff --git a/lib/main.dart b/lib/main.dart index a4e4bcc..635dc36 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -485,7 +485,7 @@ sed -i -E "s@^(VNC_RESOLUTION)=.*@\\1=${w}x${h}@" \$(command -v startvnc)"""); Text(AppLocalizations.of(context)!.hangoverDescription), const SizedBox.square(dimension: 8), Wrap(alignment: WrapAlignment.center, spacing: 4.0, runSpacing: 4.0, children: [ - OutlinedButton(style: D.commandButtonStyle, child: Text("${AppLocalizations.of(context)!.installHangoverStable}(10.9)"), onPressed: () async { + OutlinedButton(style: D.commandButtonStyle, child: Text("${AppLocalizations.of(context)!.installHangoverStable}(10.6.1)"), onPressed: () async { Util.termWrite("bash ~/.local/share/tiny/extra/install-hangover-stable"); G.pageIndex.value = 0; }), @@ -494,7 +494,7 @@ sed -i -E "s@^(VNC_RESOLUTION)=.*@\\1=${w}x${h}@" \$(command -v startvnc)"""); G.pageIndex.value = 0; }), OutlinedButton(style: D.commandButtonStyle, child: Text(AppLocalizations.of(context)!.uninstallHangover), onPressed: () async { - Util.termWrite("sudo apt autoremove --purge -y hangover-wine hangover-libarm64ecfex"); + Util.termWrite("sudo apt autoremove --purge -y hangover*"); G.pageIndex.value = 0; }), OutlinedButton(style: D.commandButtonStyle, child: Text(AppLocalizations.of(context)!.clearWineData), onPressed: () async { @@ -1196,100 +1196,122 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - bool bannerAdsFailedToLoad = false; - - //安装完成了吗? - //完成后从加载界面切换到主界面 bool isLoadingComplete = false; @override - Widget build(BuildContext context) { + void initState() { + super.initState(); + _initializeWorkflow(); + SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky, overlays: []); + } - G.homePageStateContext = context; - - if (!isLoadingComplete) { - Workflow.workflow().then((value) { - setState(() { - isLoadingComplete = true; - }); + Future _initializeWorkflow() async { + await Workflow.workflow(); + if (mounted) { + setState(() { + isLoadingComplete = true; }); } + } - - SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky,overlays: []); + @override + Widget build(BuildContext context) { + G.homePageStateContext = context; return Scaffold( appBar: AppBar( - title: Text(isLoadingComplete?Util.getCurrentProp("name"):widget.title), + title: Text(isLoadingComplete ? Util.getCurrentProp("name") : widget.title), ), - body: isLoadingComplete? - ValueListenableBuilder(valueListenable: G.pageIndex, builder: (context, value, child) { - return IndexedStack(index: G.pageIndex.value, children: const [TerminalPage(), Padding( - padding: EdgeInsets.all(8), - child: AspectRatioMax1To1(child: Scrollbar(child: SingleChildScrollView(restorationId: "control-scroll", child: Column( - children: [ - Padding( - padding: EdgeInsets.all(16), - child: FractionallySizedBox( - widthFactor: 0.4, - child: Image( - image: AssetImage("images/icon.png") - ) + body: isLoadingComplete + ? ValueListenableBuilder( + valueListenable: G.pageIndex, + builder: (context, value, child) { + return IndexedStack( + index: G.pageIndex.value, + children: const [ + TerminalPage(), + Padding( + padding: EdgeInsets.all(8), + child: AspectRatioMax1To1( + child: Scrollbar( + child: SingleChildScrollView( + restorationId: "control-scroll", + child: Column( + children: [ + Padding( + padding: EdgeInsets.all(16), + child: FractionallySizedBox( + widthFactor: 0.4, + child: Image(image: AssetImage("images/icon.png")), + ), + ), + FastCommands(), + Padding( + padding: EdgeInsets.all(8), + child: Card( + child: Padding( + padding: EdgeInsets.all(8), + child: Column( + children: [ + SettingPage(), + SizedBox.square(dimension: 8), + InfoPage(openFirstInfo: false), + ], + ), + ), + ), + ), + ], + ), + ), + ), + ), ), - ), - FastCommands(), - Padding(padding: EdgeInsets.all(8), child: Card(child: Padding(padding: EdgeInsets.all(8), child: - Column(children: [ - SettingPage(), - SizedBox.square(dimension: 8), - InfoPage(openFirstInfo: false) - ]) - ))) - ] - )))) - )]); - }):const LoadingPage(), - bottomNavigationBar: ValueListenableBuilder(valueListenable: G.pageIndex, builder:(context, value, child) { - return Visibility(visible: isLoadingComplete, - // child: BottomNavigationBar(currentIndex: G.pageIndex.value, - // onTap: (index) { - // G.pageIndex.value = index; - // }, - // items: const [ - // BottomNavigationBarItem(icon: Icon(Icons.monitor), label: "终端"), - // BottomNavigationBarItem(icon: Icon(Icons.video_settings), label: "控制"), - // ], - // ) - child: NavigationBar( - selectedIndex: G.pageIndex.value, - destinations: [ - NavigationDestination(icon: Icon(Icons.monitor), label: AppLocalizations.of(context)!.terminal), - NavigationDestination(icon: Icon(Icons.video_settings), label: AppLocalizations.of(context)!.control) - ], - onDestinationSelected: (index) { - G.pageIndex.value = index; - }, - ), - );} + ], + ); + }, + ) + : const LoadingPage(), + bottomNavigationBar: ValueListenableBuilder( + valueListenable: G.pageIndex, + builder: (context, value, child) { + return Visibility( + visible: isLoadingComplete, + child: NavigationBar( + selectedIndex: G.pageIndex.value, + destinations: [ + NavigationDestination(icon: const Icon(Icons.monitor), label: AppLocalizations.of(context)!.terminal), + NavigationDestination(icon: const Icon(Icons.video_settings), label: AppLocalizations.of(context)!.control), + ], + onDestinationSelected: (index) { + G.pageIndex.value = index; + }, + ), + ); + }, + ), + floatingActionButton: ValueListenableBuilder( + valueListenable: G.pageIndex, + builder: (context, value, child) { + return Visibility( + visible: isLoadingComplete && (value == 0), + child: FloatingActionButton( + tooltip: AppLocalizations.of(context)!.enterGUI, + onPressed: () { + if (G.wasX11Enabled) { + Workflow.launchX11(); + } else if (G.wasAvncEnabled) { + Workflow.launchAvnc(); + } else { + Workflow.launchBrowser(); + } + }, + child: const Icon(Icons.play_arrow), + ), + ); + }, ), - floatingActionButton: ValueListenableBuilder(valueListenable: G.pageIndex, builder:(context, value, child) { - return Visibility(visible: isLoadingComplete && (value == 0), - child: FloatingActionButton( - tooltip: AppLocalizations.of(context)!.enterGUI, - onPressed: () { - if (G.wasX11Enabled) { - Workflow.launchX11(); - } else if (G.wasAvncEnabled) { - Workflow.launchAvnc(); - } else { - Workflow.launchBrowser(); - } - }, - child: const Icon(Icons.play_arrow), - ) - ); - }), // This trailing comma makes auto-formatting nicer for build methods. ); } } diff --git a/lib/workflow.dart b/lib/workflow.dart index 052c1c8..2ef6599 100644 --- a/lib/workflow.dart +++ b/lib/workflow.dart @@ -121,7 +121,7 @@ class Util { case "useAvnc" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(true); case "useX11" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false); case "defaultFFmpegCommand" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("-hide_banner -an -max_delay 1000000 -r 30 -f android_camera -camera_index 0 -i 0:0 -vf scale=iw/2:-1 -rtsp_transport udp -f rtsp rtsp://127.0.0.1:8554/stream"); - case "defaultVirglCommand" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("--socket-path=\$CONTAINER_DIR/tmp/.virgl_test"); + case "defaultVirglCommand" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("--use-egl-surfaceless --use-gles --socket-path=\$CONTAINER_DIR/tmp/.virgl_test"); case "defaultVirglOpt" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("GALLIUM_DRIVER=virpipe"); case "defaultTurnipOpt" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("MESA_LOADER_DRIVER_OVERRIDE=zink VK_ICD_FILENAMES=/home/tiny/.local/share/tiny/extra/freedreno_icd.aarch64.json TU_DEBUG=noconform"); case "defaultHidpiOpt" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("GDK_SCALE=2 QT_FONT_DPI=192"); @@ -191,6 +191,11 @@ class Util { return null; } + //获取预制可执行文件路径 + static String elf(String value) { + return "applib/libexec_$value.so"; + } + } //来自xterms关于操作ctrl, shift, alt键的示例 @@ -404,7 +409,7 @@ rm /tmp/wps.deb"""}, {"name":"卸载CAJViewer", "command":"sudo apt autoremove --purge -y net.cnki.cajviewer && bash /home/tiny/.local/share/tiny/caj/postrm"}, {"name":"安装亿图图示", "command":"wget https://cc-download.wondershare.cc/business/prd/edrawmax_13.1.0-1_arm64_binner.deb -O /tmp/edraw.deb && sudo apt update && sudo apt install -y /tmp/edraw.deb && bash /home/tiny/.local/share/tiny/edraw/postinst; rm /tmp/edraw.deb"}, {"name":"卸载亿图图示", "command":"sudo apt autoremove --purge -y edrawmax libldap-2.4-2"}, - {"name":"安装QQ", "command":"""wget \$(curl -s https://im.qq.com/rainbow/linuxQQDownload | grep -o 'https://[^"]+arm64[^"]+deb') -O /tmp/qq.deb && sudo apt update && sudo apt install -y /tmp/qq.deb && sed -i 's#Exec=/opt/QQ/qq %U#Exec=/opt/QQ/qq --no-sandbox %U#g' /usr/share/applications/qq.desktop; rm /tmp/qq.deb"""}, + {"name":"安装QQ", "command":"""wget \$(curl -s https://im.qq.com/rainbow/linuxQQDownload | grep -oP '"armDownloadUrl":{[^}]*"deb":"\\K[^"]+') -O /tmp/qq.deb && sudo apt update && sudo apt install -y /tmp/qq.deb && sed -i 's#Exec=/opt/QQ/qq %U#Exec=/opt/QQ/qq --no-sandbox %U#g' /usr/share/applications/qq.desktop; rm /tmp/qq.deb"""}, {"name":"卸载QQ", "command":"sudo apt autoremove --purge -y linuxqq"}, {"name":"安装微信", "command":"wget https://dldir1v6.qq.com/weixin/Universal/Linux/WeChatLinux_arm64.deb -O /tmp/wechat.deb && sudo apt update && sudo apt install -y /tmp/wechat.deb && echo '安装完成。如果你使用微信只是为了传输文件,那么可以考虑使用支持SAF的文件管理器(如:质感文件),直接访问小小电脑所有文件。'; rm /tmp/wechat.deb"}, {"name":"卸载微信", "command":"sudo apt autoremove --purge -y wechat"}, @@ -571,6 +576,10 @@ class Workflow { static Future setupBootstrap() async { //用来共享数据文件的文件夹 Util.createDirFromString("${G.dataPath}/share"); + //用来存放可执行文件的文件夹 + Util.createDirFromString("${G.dataPath}/bin"); + //用来存放库的文件夹 + Util.createDirFromString("${G.dataPath}/lib"); //挂载到/dev/shm的文件夹 Util.createDirFromString("${G.dataPath}/tmp"); //给proot的tmp文件夹,虽然我不知道为什么proot要这个 @@ -590,24 +599,31 @@ class Workflow { "assets/patch.tar.gz", "${G.dataPath}/patch.tar.gz", ); - //dddd - await Util.copyAsset( - "assets/busybox", - "${G.dataPath}/busybox", - ); await Util.execute( """ export DATA_DIR=${G.dataPath} +export LD_LIBRARY_PATH=\$DATA_DIR/lib cd \$DATA_DIR -chmod +x busybox -\$DATA_DIR/busybox unzip -o assets.zip +ln -sf ../applib/libexec_busybox.so \$DATA_DIR/bin/busybox +ln -sf ../applib/libexec_busybox.so \$DATA_DIR/bin/xz +ln -sf ../applib/libexec_busybox.so \$DATA_DIR/bin/gzip +ln -sf ../applib/libexec_proot.so \$DATA_DIR/bin/proot +ln -sf ../applib/libexec_tar.so \$DATA_DIR/bin/tar +ln -sf ../applib/libexec_virgl_test_server.so \$DATA_DIR/bin/virgl_test_server +ln -sf ../applib/libexec_getifaddrs_bridge_server.so \$DATA_DIR/bin/getifaddrs_bridge_server +ln -sf ../applib/libbusybox.so \$DATA_DIR/lib/libbusybox.so.1.36.1 +ln -sf ../applib/libtalloc.so \$DATA_DIR/lib/libtalloc.so.2 +ln -sf ../applib/libvirglrenderer.so \$DATA_DIR/lib/libvirglrenderer.so +ln -sf ../applib/libepoxy.so \$DATA_DIR/lib/libepoxy.so +ln -sf ../applib/libproot-loader32.so \$DATA_DIR/lib/loader32 +ln -sf ../applib/libproot-loader.so \$DATA_DIR/lib/loader + +\$DATA_DIR/bin/busybox unzip -o assets.zip chmod -R +x bin/* chmod -R +x libexec/proot/* chmod 1777 tmp -ln -sf \$DATA_DIR/busybox \$DATA_DIR/bin/xz -ln -sf \$DATA_DIR/busybox \$DATA_DIR/bin/gzip \$DATA_DIR/bin/tar zxf patch.tar.gz -\$DATA_DIR/busybox rm -rf assets.zip patch.tar.gz +\$DATA_DIR/bin/busybox rm -rf assets.zip patch.tar.gz """); } @@ -630,13 +646,14 @@ ln -sf \$DATA_DIR/busybox \$DATA_DIR/bin/gzip await Util.execute( """ export DATA_DIR=${G.dataPath} +export LD_LIBRARY_PATH=\$DATA_DIR/lib export CONTAINER_DIR=\$DATA_DIR/containers/0 export EXTRA_OPT="" cd \$DATA_DIR export PATH=\$DATA_DIR/bin:\$PATH export PROOT_TMP_DIR=\$DATA_DIR/proot_tmp -export PROOT_LOADER=\$DATA_DIR/libexec/proot/loader -export PROOT_LOADER_32=\$DATA_DIR/libexec/proot/loader32 +export PROOT_LOADER=\$DATA_DIR/applib/libproot-loader.so +export PROOT_LOADER_32=\$DATA_DIR/applib/libproot-loader32.so #export PROOT_L2S_DIR=\$CONTAINER_DIR/.l2s \$DATA_DIR/bin/proot --link2symlink sh -c "cat xa* | \$DATA_DIR/bin/tar x -J --delay-directory-restore --preserve-permissions -v -C containers/0" #Script from proot-distro @@ -645,7 +662,7 @@ echo "aid_\$(id -un):x:\$(id -u):\$(id -g):Termux:/:/sbin/nologin" >> "\$CONTAIN echo "aid_\$(id -un):*:18446:0:99999:7:::" >> "\$CONTAINER_DIR/etc/shadow" id -Gn | tr ' ' '\\n' > tmp1 id -G | tr ' ' '\\n' > tmp2 -\$DATA_DIR/busybox paste tmp1 tmp2 > tmp3 +\$DATA_DIR/bin/busybox paste tmp1 tmp2 > tmp3 local group_name group_id cat tmp3 | while read -r group_name group_id; do echo "aid_\${group_name}:x:\${group_id}:root,aid_\$(id -un)" >> "\$CONTAINER_DIR/etc/group" @@ -653,7 +670,7 @@ cat tmp3 | while read -r group_name group_id; do echo "aid_\${group_name}:*::root,aid_\$(id -un)" >> "\$CONTAINER_DIR/etc/gshadow" fi done -\$DATA_DIR/busybox rm -rf xa* tmp1 tmp2 tmp3 +\$DATA_DIR/bin/busybox rm -rf xa* tmp1 tmp2 tmp3 """); //一些数据初始化 //$DATA_DIR是数据文件夹, $CONTAINER_DIR是容器根目录 @@ -678,12 +695,7 @@ done G.prefs = await SharedPreferences.getInstance(); - //限制一天内观看视频广告不超过5次 - final String currentDate = DateFormat("yyyy-MM-dd").format(DateTime.now()); - if (currentDate != (Util.getGlobal("lastDate") as String)) { - await G.prefs.setString("lastDate", currentDate); - //await G.prefs.setInt("adsWatchedToday", 0); - } + await Util.execute("ln -sf ${await D.androidChannel.invokeMethod("getNativeLibraryPath", {})} ${G.dataPath}/applib"); //如果没有这个key,说明是初次启动 if (!G.prefs.containsKey("defaultContainer")) { @@ -734,9 +746,10 @@ sed -i -E "s@^(VNC_RESOLUTION)=.*@\\1=${w}x${h}@" \$(command -v startvnc)"""; ); G.audioPty!.write(const Utf8Encoder().convert(""" export DATA_DIR=${G.dataPath} -\$DATA_DIR/busybox sed "s/4713/${Util.getGlobal("defaultAudioPort") as int}/g" \$DATA_DIR/bin/pulseaudio.conf > \$DATA_DIR/bin/pulseaudio.conf.tmp +export LD_LIBRARY_PATH=\$DATA_DIR/lib +\$DATA_DIR/bin/busybox sed "s/4713/${Util.getGlobal("defaultAudioPort") as int}/g" \$DATA_DIR/bin/pulseaudio.conf > \$DATA_DIR/bin/pulseaudio.conf.tmp rm -rf \$DATA_DIR/pulseaudio_tmp/* -TMPDIR=\$DATA_DIR/pulseaudio_tmp HOME=\$DATA_DIR/pulseaudio_tmp XDG_CONFIG_HOME=\$DATA_DIR/pulseaudio_tmp LD_LIBRARY_PATH=\$DATA_DIR/bin \$DATA_DIR/bin/pulseaudio -F \$DATA_DIR/bin/pulseaudio.conf.tmp +TMPDIR=\$DATA_DIR/pulseaudio_tmp HOME=\$DATA_DIR/pulseaudio_tmp XDG_CONFIG_HOME=\$DATA_DIR/pulseaudio_tmp LD_LIBRARY_PATH=\$DATA_DIR/bin:\$LD_LIBRARY_PATH /system/bin/linker64 \$DATA_DIR/bin/pulseaudio -F \$DATA_DIR/bin/pulseaudio.conf.tmp exit """)); await G.audioPty?.exitCode; @@ -759,6 +772,7 @@ exit if (Util.getGlobal("virgl")) { Util.execute(""" export DATA_DIR=${G.dataPath} +export LD_LIBRARY_PATH=\$DATA_DIR/lib export CONTAINER_DIR=\$DATA_DIR/containers/${G.currentContainer} ${G.dataPath}/bin/virgl_test_server ${Util.getGlobal("defaultVirglCommand")}"""); extraOpt += "${Util.getGlobal("defaultVirglOpt")} "; @@ -777,14 +791,15 @@ ${G.dataPath}/bin/virgl_test_server ${Util.getGlobal("defaultVirglCommand")}""") Util.termWrite( """ export DATA_DIR=${G.dataPath} +export LD_LIBRARY_PATH=\$DATA_DIR/lib export CONTAINER_DIR=\$DATA_DIR/containers/${G.currentContainer} export EXTRA_MOUNT="$extraMount" export EXTRA_OPT="$extraOpt" #export PROOT_L2S_DIR=\$DATA_DIR/containers/0/.l2s cd \$DATA_DIR export PROOT_TMP_DIR=\$DATA_DIR/proot_tmp -export PROOT_LOADER=\$DATA_DIR/libexec/proot/loader -export PROOT_LOADER_32=\$DATA_DIR/libexec/proot/loader32 +export PROOT_LOADER=\$DATA_DIR/applib/libproot-loader.so +export PROOT_LOADER_32=\$DATA_DIR/applib/libproot-loader32.so ${Util.getCurrentProp("boot")} ${G.postCommand} ${(Util.getGlobal("autoLaunchVnc") as bool)?((Util.getGlobal("useX11") as bool)?"""mkdir -p "\$HOME/.vnc" && bash /etc/X11/xinit/Xsession &> "\$HOME/.vnc/x.log" &""":Util.getCurrentProp("vnc")):""} diff --git a/pubspec.yaml b/pubspec.yaml index 68d613e..054de5e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.0.22+17 +version: 1.0.23+18 environment: sdk: '>=3.1.0 <4.0.0' @@ -33,17 +33,17 @@ dependencies: xterm: ^4.0.0 flutter_pty: ^0.4.2 path_provider: ^2.1.5 - webview_flutter: ^4.11.0 + webview_flutter: ^4.13.0 permission_handler: ^12.0.0 - http: ^1.3.0 + http: ^1.4.0 retry: ^3.1.2 url_launcher: ^6.3.1 shared_preferences: ^2.5.3 clipboard: ^0.1.3 - wakelock_plus: ^1.3.1 + wakelock_plus: ^1.3.2 dynamic_color: ^1.7.0 - network_info_plus: ^6.1.3 - device_info_plus: ^11.3.3 + network_info_plus: ^6.1.4 + device_info_plus: ^11.4.0 flutter_localizations: sdk: flutter intl: any