mirror of
https://github.com/Cateners/tiny_computer.git
synced 2026-05-20 16:35:47 +08:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce5ad3b758 | ||
|
|
cf15e2e07d | ||
|
|
938745036d | ||
|
|
b3428555c6 | ||
|
|
2a19c5eb78 | ||
|
|
54a941da63 |
55
README.md
55
README.md
@@ -2,45 +2,42 @@
|
||||
|
||||
<img decoding="async" src="readme/cover0.png" width="50%">
|
||||
|
||||
即开即用的类PC环境,内置火狐浏览器和fcitx输入法等常用软件
|
||||
给所有安卓arm64设备的“PC应用引擎”平替
|
||||
|
||||
Click-to-run debian bookworm xfce on android for Chinese users, with fcitx pinyin input method preinstalled. No termux required.
|
||||
|
||||
## 特点
|
||||
|
||||
- 一键安装,即开即用
|
||||
- 来自kali-undercover的win10主题(仅xfce版本),友好的界面
|
||||
|
||||
<img decoding="async" src="readme/img1.png" width="50%">
|
||||
|
||||
- 提供常用软件的一键安装指令
|
||||
|
||||
<img decoding="async" src="readme/img2.png" width="50%">
|
||||
|
||||
- 可方便地改变屏幕缩放,不用担心屏幕过大或过小
|
||||
|
||||
<img decoding="async" src="readme/img3.gif" width="50%">
|
||||
|
||||
- 便捷访问设备文件,或通过设备SAF访问软件文件
|
||||
|
||||
<img decoding="async" src="readme/img4.png" width="50%">
|
||||
|
||||
- 提供终端和众多可调节参数供高级用户使用
|
||||
|
||||
<img decoding="async" src="readme/img5.png" width="50%">
|
||||
|
||||
## 原理
|
||||
|
||||
使用proot运行debian环境
|
||||
|
||||
内置[noVNC](https://github.com/novnc/noVNC)显示图形界面
|
||||
|
||||
初次启动由于解压的缘故要点时间
|
||||
以后点开就能用
|
||||
|
||||
只支持arm64安卓
|
||||
|
||||
## 项目结构
|
||||
|
||||
assets的文件来源如下:
|
||||
|
||||
- [proot](https://github.com/Cateners/proot), 使用[build-proot-android](https://github.com/green-green-avk/build-proot-android)脚本编译
|
||||
- [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)
|
||||
- [Tmoe Linux, debian包来源](https://github.com/2moe/tmoe)
|
||||
|
||||
其中tar、busybox和pulseaudio相关文件都是直接用了二进制文件。
|
||||
|
||||
更多信息可以在[这里](extra/readme)找到。
|
||||
|
||||
对debian容器进行了如下修改:
|
||||
- 使用tmoe安装了xfce环境和全套VNC;
|
||||
- 使用kali-undercover提供的Win10主题美化xfce;
|
||||
- (使用tmoe)安装了fcitx输入法和云拼音组件。按<Ctrl+空格>切换输入法。
|
||||
- 强烈建议**不要**使用安卓中文输入法直接输入中文,而是使用英文键盘通过容器的输入法输入中文,避免丢字错字。
|
||||
- 对noVNC进行[修改](https://github.com/Cateners/noVNC),添加了scale factor滑块控制缩放(scale_factor分支),添加了上下左右shift等按键(arrow_key分支),添加了强制显示原系统光标的功能(force_cursor分支),添加了中文翻译(translation_zh_cn分支);
|
||||
- 在主目录下可以方便地访问手机存储(如果提供了存储权限的话);
|
||||
- 启动时会尝试挂载手机的一些字体目录(AppFiles/Fonts、Fonts和/system/fonts), 如果这些目录下有字体文件的话会一并加载到系统中,无需额外安装;
|
||||
- 最后采用tar.xz压缩,用split命令分成了xa*等多个文件(低内存设备一次性拷贝大文件会导致软件闪退)。
|
||||
assets的文件来源信息可以在[这里](extra/readme.md)找到。
|
||||
|
||||
完整的容器制作过程可以在[这里](extra/build-tiny-rootfs.md)看到。
|
||||
|
||||
@@ -48,7 +45,7 @@ assets的文件来源如下:
|
||||
|
||||
lib目录:
|
||||
|
||||
- main.dart文件,页面布局,老实说已经有点乱了
|
||||
- main.dart文件,页面布局,有点乱
|
||||
- workflow.dart文件,逻辑部分,目前也还可以理解
|
||||
- Util 工具类
|
||||
- TermPty 一个终端
|
||||
|
||||
@@ -64,6 +64,13 @@ android {
|
||||
//checkReleaseBuilds false
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
pickFirst 'lib/arm64-v8a/libc++_shared.so'
|
||||
pickFirst 'lib/x86_64/libc++_shared.so'
|
||||
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
|
||||
pickFirst 'lib/arm64-v8a/libc++_shared.so'
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
|
||||
@@ -6,7 +6,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.3.0'
|
||||
classpath 'com.android.tools.build:gradle:7.3.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
56
extra/cross/install-box
Normal file
56
extra/cross/install-box
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo dpkg --add-architecture armhf
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
sudo apt install -y cmake gcc-arm-linux-gnueabihf libc6:armhf
|
||||
sudo apt reinstall -y libc6-dev
|
||||
|
||||
mkdir $HOME/.local/share/tiny/cross
|
||||
|
||||
rm -rf $HOME/.local/share/tiny/tmp
|
||||
mkdir $HOME/.local/share/tiny/tmp
|
||||
cd $HOME/.local/share/tiny/tmp
|
||||
|
||||
git clone https://mirror.ghproxy.com/https://github.com/ptitSeb/box86
|
||||
if [ $? -ne 0 ]; then
|
||||
git clone https://github.com/ptitSeb/box86
|
||||
if [ $? -ne 0 ]; then
|
||||
rm -rf $HOME/.local/share/tiny/tmp
|
||||
echo '仓库克隆失败...退出安装...'
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
git clone https://mirror.ghproxy.com/https://github.com/ptitSeb/box64
|
||||
if [ $? -ne 0 ]; then
|
||||
git clone https://github.com/ptitSeb/box64
|
||||
if [ $? -ne 0 ]; then
|
||||
rm -rf $HOME/.local/share/tiny/tmp
|
||||
echo '仓库克隆失败...退出安装...'
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
cd box86
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DARM64=1 -DBAD_SIGNAL=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
make -j
|
||||
cd ../..
|
||||
mv box86/build/box86 ../cross
|
||||
mv box86/x86lib ../cross
|
||||
|
||||
cd box64
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DARM64=1 -DBAD_SIGNAL=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
make -j
|
||||
cd ../..
|
||||
mv box64/build/box64 ../cross
|
||||
mv box64/x64lib ../cross
|
||||
|
||||
cd ..
|
||||
rm -rf tmp
|
||||
|
||||
echo '安装完成'
|
||||
35
extra/cross/install-dxvk
Normal file
35
extra/cross/install-dxvk
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
rm -rf $HOME/.local/share/tiny/tmp
|
||||
mkdir $HOME/.local/share/tiny/tmp
|
||||
cd $HOME/.local/share/tiny/tmp
|
||||
|
||||
MIRROR_SITE=https://mirror.ghproxy.com
|
||||
RELEASE_PAGE=https://github.com/doitsujin/dxvk/releases
|
||||
LATEST_DXVK_TAG=$(curl -L $RELEASE_PAGE | grep -oP 'Version \K[^"]*</h2>' | cut -d "<" -f 1 | head -n 1)
|
||||
if [ -z "$LATEST_DXVK_TAG" ]
|
||||
then
|
||||
LATEST_DXVK_TAG="2.3"
|
||||
fi
|
||||
LATEST_DXVK_NAME="dxvk-$LATEST_DXVK_TAG.tar.gz"
|
||||
LATEST_DXVK_LINK="https://github.com/doitsujin/dxvk/releases/download/v$LATEST_DXVK_TAG/$LATEST_DXVK_NAME"
|
||||
|
||||
wget $MIRROR_SITE/$LATEST_DXVK_LINK
|
||||
if [ $? -ne 0 ]; then
|
||||
wget $LATEST_DXVK_LINK
|
||||
if [ $? -ne 0 ]; then
|
||||
rm -rf $HOME/.local/share/tiny/tmp
|
||||
echo '下载失败...退出安装...'
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
wineboot
|
||||
tar xvf $LATEST_DXVK_NAME
|
||||
mv dxvk-$LATEST_DXVK_TAG/x32/* ~/.wine/drive_c/windows/syswow64
|
||||
mv dxvk-$LATEST_DXVK_TAG/x64/* ~/.wine/drive_c/windows/system32
|
||||
|
||||
cd ~
|
||||
rm -rf $HOME/.local/share/tiny/tmp
|
||||
|
||||
echo '安装完成,建议前往wine配置更新配置。'
|
||||
70
extra/cross/install-wine
Normal file
70
extra/cross/install-wine
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
|
||||
# Wine的64位依赖。box64会将amd64调用转换为arm64,所以只需安装arm64库即可
|
||||
# 依赖来自 dpkg-deb -I wine-stable-amd64_8.0.2~bookworm-1_amd64.deb
|
||||
sudo apt install -y libasound2:arm64 libc6:arm64 libglib2.0-0:arm64 libgphoto2-6:arm64 libgphoto2-port12:arm64 \
|
||||
libgstreamer-plugins-base1.0-0:arm64 libgstreamer1.0-0:arm64 libpcap0.8:arm64 libpulse0:arm64 libsane1:arm64 \
|
||||
libudev1:arm64 libunwind8:arm64 libusb-1.0-0:arm64 libx11-6:arm64 libxext6:arm64 ocl-icd-libopencl1:arm64 \
|
||||
libasound2-plugins:arm64 libncurses6:arm64 libcapi20-3:arm64 libcups2:arm64 libdbus-1-3:arm64 libfontconfig1:arm64 \
|
||||
libfreetype6:arm64 libglu1-mesa:arm64 libgnutls30:arm64 libgsm1:arm64 libgssapi-krb5-2:arm64 libjpeg62-turbo:arm64 \
|
||||
libkrb5-3:arm64 libodbc1:arm64 libosmesa6:arm64 libpng16-16:arm64 libsdl2-2.0-0:arm64 libv4l-0:arm64 \
|
||||
libxcomposite1:arm64 libxcursor1:arm64 libxfixes3:arm64 libxi6:arm64 libxinerama1:arm64 libxrandr2:arm64 \
|
||||
libxrender1:arm64 libxslt1.1:arm64 libxxf86vm1:arm64
|
||||
|
||||
# Wine的32位依赖。同理安装armhf而不是i386
|
||||
# 依赖来自 dpkg-deb -I wine-stable-i386_8.0.2~bookworm-1_i386.deb
|
||||
sudo apt install -y libasound2:armhf libc6:armhf libglib2.0-0:armhf libgphoto2-6:armhf libgphoto2-port12:armhf \
|
||||
libgstreamer-plugins-base1.0-0:armhf libgstreamer1.0-0:armhf libpcap0.8:armhf libpulse0:armhf libsane1:armhf \
|
||||
libudev1:armhf libusb-1.0-0:armhf libx11-6:armhf libxext6:armhf ocl-icd-libopencl1:armhf libasound2-plugins:armhf \
|
||||
libncurses6:armhf libcapi20-3:armhf libcups2:armhf libdbus-1-3:armhf libfontconfig1:armhf libfreetype6:armhf \
|
||||
libglu1-mesa:armhf libgnutls30:armhf libgsm1:armhf libgssapi-krb5-2:armhf libjpeg62-turbo:armhf libkrb5-3:armhf \
|
||||
libodbc1:armhf libosmesa6:armhf libpng16-16:armhf libsdl2-2.0-0:armhf libv4l-0:armhf libxcomposite1:armhf \
|
||||
libxcursor1:armhf libxfixes3:armhf libxi6:armhf libxinerama1:armhf libxrandr2:armhf libxrender1:armhf libxslt1.1:armhf \
|
||||
libxxf86vm1:armhf
|
||||
|
||||
# 其他测试时认为可能需要的依赖
|
||||
sudo apt install -y libvulkan1 libvulkan1:armhf
|
||||
|
||||
rm -rf $HOME/.local/share/tiny/tmp
|
||||
mkdir $HOME/.local/share/tiny/tmp
|
||||
cd $HOME/.local/share/tiny/tmp
|
||||
|
||||
MIRROR_SITE=https://mirror.ghproxy.com
|
||||
RELEASE_PAGE=https://github.com/Kron4ek/Wine-Builds/releases
|
||||
LATEST_WINE_TAG=proton-$(curl -L $RELEASE_PAGE | grep -oP 'Proton \K[^"]*</h2>' | cut -d "<" -f 1 | head -n 1) #proton
|
||||
#LATEST_WINE_TAG=$(curl -L $RELEASE_PAGE | grep -oP 'Wine \K[^"]*</h2>' | cut -d "<" -f 1 | head -n 1) #vanilla
|
||||
if [ -z "$LATEST_WINE_TAG" ] || [ "$LATEST_WINE_TAG" == "proton-" ]
|
||||
then
|
||||
LATEST_WINE_TAG=proton-8.0-4
|
||||
fi
|
||||
LATEST_WINE_NAME=wine-$LATEST_WINE_TAG-amd64.tar.xz
|
||||
LATEST_WINE_LINK=$RELEASE_PAGE/download/$LATEST_WINE_TAG/$LATEST_WINE_NAME
|
||||
|
||||
wget $MIRROR_SITE/$LATEST_WINE_LINK
|
||||
if [ $? -ne 0 ]; then
|
||||
wget $LATEST_WINE_LINK
|
||||
if [ $? -ne 0 ]; then
|
||||
rm -rf $HOME/.local/share/tiny/tmp
|
||||
echo '下载失败...退出安装...'
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
tar xvf $LATEST_WINE_NAME
|
||||
mv wine-$LATEST_WINE_TAG-amd64 ../cross/wine
|
||||
cd ..
|
||||
rm -rf tmp
|
||||
|
||||
echo '[Desktop Entry]
|
||||
Name=Wine 启动器
|
||||
Exec=wine64 start /unix %f
|
||||
Icon=wine
|
||||
Type=Application' > $HOME/.local/share/tiny/cross/wine.desktop
|
||||
chmod +x $HOME/.local/share/tiny/cross/wine.desktop
|
||||
|
||||
echo '安装完成,在启用wine后可以点击exe文件选择用wine启动。'
|
||||
echo '初次运行时会自动进行一段时间的初始化工作。'
|
||||
echo '程序的运行可能依赖一些配置或组件。比如,一些使用directx的游戏可能需要安装dxvk。'
|
||||
83
extra/cross/install-wine2
Normal file
83
extra/cross/install-wine2
Normal file
@@ -0,0 +1,83 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
|
||||
# Wine的64位依赖。box64会将amd64调用转换为arm64,所以只需安装arm64库即可
|
||||
# 依赖来自 dpkg-deb -I wine-stable-amd64_8.0.2~bookworm-1_amd64.deb
|
||||
sudo apt install -y libasound2:arm64 libc6:arm64 libglib2.0-0:arm64 libgphoto2-6:arm64 libgphoto2-port12:arm64 \
|
||||
libgstreamer-plugins-base1.0-0:arm64 libgstreamer1.0-0:arm64 libpcap0.8:arm64 libpulse0:arm64 libsane1:arm64 \
|
||||
libudev1:arm64 libunwind8:arm64 libusb-1.0-0:arm64 libx11-6:arm64 libxext6:arm64 ocl-icd-libopencl1:arm64 \
|
||||
libasound2-plugins:arm64 libncurses6:arm64 libcapi20-3:arm64 libcups2:arm64 libdbus-1-3:arm64 libfontconfig1:arm64 \
|
||||
libfreetype6:arm64 libglu1-mesa:arm64 libgnutls30:arm64 libgsm1:arm64 libgssapi-krb5-2:arm64 libjpeg62-turbo:arm64 \
|
||||
libkrb5-3:arm64 libodbc1:arm64 libosmesa6:arm64 libpng16-16:arm64 libsdl2-2.0-0:arm64 libv4l-0:arm64 \
|
||||
libxcomposite1:arm64 libxcursor1:arm64 libxfixes3:arm64 libxi6:arm64 libxinerama1:arm64 libxrandr2:arm64 \
|
||||
libxrender1:arm64 libxslt1.1:arm64 libxxf86vm1:arm64
|
||||
|
||||
# Wine的32位依赖。同理安装armhf而不是i386
|
||||
# 依赖来自 dpkg-deb -I wine-stable-i386_8.0.2~bookworm-1_i386.deb
|
||||
sudo apt install -y libasound2:armhf libc6:armhf libglib2.0-0:armhf libgphoto2-6:armhf libgphoto2-port12:armhf \
|
||||
libgstreamer-plugins-base1.0-0:armhf libgstreamer1.0-0:armhf libpcap0.8:armhf libpulse0:armhf libsane1:armhf \
|
||||
libudev1:armhf libusb-1.0-0:armhf libx11-6:armhf libxext6:armhf ocl-icd-libopencl1:armhf libasound2-plugins:armhf \
|
||||
libncurses6:armhf libcapi20-3:armhf libcups2:armhf libdbus-1-3:armhf libfontconfig1:armhf libfreetype6:armhf \
|
||||
libglu1-mesa:armhf libgnutls30:armhf libgsm1:armhf libgssapi-krb5-2:armhf libjpeg62-turbo:armhf libkrb5-3:armhf \
|
||||
libodbc1:armhf libosmesa6:armhf libpng16-16:armhf libsdl2-2.0-0:armhf libv4l-0:armhf libxcomposite1:armhf \
|
||||
libxcursor1:armhf libxfixes3:armhf libxi6:armhf libxinerama1:armhf libxrandr2:armhf libxrender1:armhf libxslt1.1:armhf \
|
||||
libxxf86vm1:armhf
|
||||
|
||||
rm -rf $HOME/.local/share/tiny/tmp
|
||||
mkdir $HOME/.local/share/tiny/tmp
|
||||
cd $HOME/.local/share/tiny/tmp
|
||||
|
||||
LNKA="https://mirrors.tuna.tsinghua.edu.cn/wine-builds/debian/dists/bookworm/main/binary-amd64/"
|
||||
DEB_A1="wine-stable-amd64_8.0.2~bookworm-1_amd64.deb"
|
||||
DEB_A2="wine-stable_8.0.2~bookworm-1_amd64.deb"
|
||||
|
||||
LNKB="https://mirrors.tuna.tsinghua.edu.cn/wine-builds/debian/dists/bookworm/main/binary-i386/"
|
||||
DEB_B1="wine-stable-i386_8.0.2~bookworm-1_i386.deb"
|
||||
|
||||
# Install amd64-wine (64-bit) alongside i386-wine (32-bit)
|
||||
echo -e "下载wine..."
|
||||
wget ${LNKA}${DEB_A1}
|
||||
wget ${LNKA}${DEB_A2}
|
||||
wget ${LNKB}${DEB_B1}
|
||||
|
||||
wget https://mirror.ghproxy.com/https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
|
||||
if [ $? -ne 0 ]; then
|
||||
wget https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
|
||||
if [ $? -ne 0 ]; then
|
||||
rm -rf $HOME/.local/share/tiny/tmp
|
||||
echo '下载失败...退出安装...'
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "解压wine..."
|
||||
dpkg-deb -x ${DEB_A1} wine-installer
|
||||
dpkg-deb -x ${DEB_A2} wine-installer
|
||||
dpkg-deb -x ${DEB_B1} wine-installer
|
||||
echo -e "安装wine..."
|
||||
mv wine-installer/opt/wine* ../cross/wine
|
||||
|
||||
mv winetricks ../cross
|
||||
chmod +x $HOME/.local/share/tiny/cross/winetricks
|
||||
cd ..
|
||||
rm -rf tmp
|
||||
|
||||
echo '[Desktop Entry]
|
||||
Name=Wine 启动器
|
||||
Exec=wine start /unix %f
|
||||
Icon=wine
|
||||
Type=Application' > $HOME/.local/share/tiny/cross/wine.desktop
|
||||
chmod +x $HOME/.local/share/tiny/cross/wine.desktop
|
||||
|
||||
echo '[Desktop Entry]
|
||||
Name=winetricks 实用工具
|
||||
Exec=winetricks
|
||||
Icon=wine
|
||||
Type=Application' > $HOME/.local/share/tiny/cross/winetricks.desktop
|
||||
chmod +x $HOME/.local/share/tiny/cross/winetricks.desktop
|
||||
|
||||
echo '安装完成,在启用wine后可以点击exe文件选择用wine启动。'
|
||||
echo '程序的运行可能依赖一些配置或组件。比如,一些使用directx的游戏可能需要安装dxvk。'
|
||||
echo '如果缺失可以尝试使用winetricks安装。请务必保持耐心。'
|
||||
24
extra/readme
24
extra/readme
@@ -1,24 +0,0 @@
|
||||
## 这个readme介绍assets文件夹中文件的制作方式。
|
||||
|
||||
### assets.zip中的文件:
|
||||
|
||||
#### [容器文件xa*](build-tiny-rootfs.md)
|
||||
|
||||
### patch.tar.gz中的文件:
|
||||
|
||||
#### extra/getifaddrs_bridge_client_lib.so:
|
||||
|
||||
在安卓13以上的系统中,proot容器无权使用默认的getifaddrs,而这个库包含了一个getifaddrs实现。
|
||||
|
||||
linux在需要数据时,使用socket通知位于安卓的getifaddrs_bridge_server,让getifaddrs_bridge_server执行getifaddrs函数,并将结构体数据序列化后发送回linux端,这边接收数据并反序列化还原成指针结构体。简单来说就是用安卓的getifaddrs代替linux的getifaddrs。
|
||||
|
||||
源码和编译信息在getifaddrs_bridge文件夹查看。
|
||||
|
||||
#### caj, edraw
|
||||
|
||||
这些分别是cajviewer,亿图图示的补丁
|
||||
|
||||
- 亿图图示补丁的库文件是在小小电脑上下载了Qt对应版本源码后编译得到的;
|
||||
- 编译进行了两次,第一次直接编译,可以得到Gui和Widgets两个库。第二次编译带上XcbQpa,虽然会编译失败,但在这之前就可以得到XcbQpa的库。
|
||||
|
||||
|
||||
43
extra/readme.md
Normal file
43
extra/readme.md
Normal file
@@ -0,0 +1,43 @@
|
||||
## 这个readme介绍assets文件夹中文件的制作方式。
|
||||
|
||||
### 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)
|
||||
|
||||
以上文件没有经过更改。
|
||||
一般是使用了仓库直接提供的二进制文件,或者是使用了仓库提供的patch编译而来。
|
||||
|
||||
- [proot](https://github.com/Cateners/proot), 使用[build-proot-android](https://github.com/green-green-avk/build-proot-android)脚本编译
|
||||
- [Tmoe Linux, debian包来源](https://github.com/2moe/tmoe),制作了[容器文件xa*](build-tiny-rootfs.md)
|
||||
- getifaddrs_bridge_server,见下面的介绍和getifaddrs_bridge子文件夹
|
||||
|
||||
### patch.tar.gz中的文件:
|
||||
|
||||
#### extra/getifaddrs_bridge_client_lib.so:
|
||||
|
||||
在安卓13以上的系统中,proot容器无权使用默认的getifaddrs,而这个库包含了一个getifaddrs实现。
|
||||
|
||||
linux在需要数据时,使用socket通知位于安卓的getifaddrs_bridge_server,让getifaddrs_bridge_server执行getifaddrs函数,并将结构体数据序列化后发送回linux端,这边接收数据并反序列化还原成指针结构体。简单来说就是用安卓的getifaddrs代替linux的getifaddrs。
|
||||
|
||||
源码和编译信息在getifaddrs_bridge文件夹查看。
|
||||
|
||||
#### extra/install-box, extra/install-wine:
|
||||
|
||||
这些是用于跨架构/跨系统支持的box86/box64和wine安装脚本。
|
||||
|
||||
#### caj, edraw
|
||||
|
||||
这些分别是cajviewer,亿图图示的补丁
|
||||
|
||||
- 亿图图示补丁的库文件是在小小电脑上下载了Qt对应版本源码后编译得到的;
|
||||
- 编译进行了两次,第一次直接编译,可以得到Gui和Widgets两个库。第二次编译带上XcbQpa,虽然会编译失败,但在这之前就可以得到XcbQpa的库。
|
||||
|
||||
#### wechat
|
||||
|
||||
微信的补丁。license, uos-lsb和uos-release来自星火的微信包或arch的wechat-uos打包(嗯,我忘记到底是哪的了。不过都差不多)。
|
||||
|
||||
libssl1.1来自debian官方源。deepin-elf-verifier是我打的空包。
|
||||
243
lib/main.dart
243
lib/main.dart
@@ -18,6 +18,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
//import 'dart:convert';
|
||||
|
||||
@@ -30,6 +31,7 @@ import 'package:permission_handler/permission_handler.dart';
|
||||
//import 'package:flutter/services.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:wakelock_plus/wakelock_plus.dart';
|
||||
import 'package:xterm/xterm.dart';
|
||||
//import 'package:xterm/flutter.dart';
|
||||
import 'package:tiny_computer/workflow.dart';
|
||||
@@ -103,7 +105,7 @@ class SettingPage extends StatefulWidget {
|
||||
|
||||
class _SettingPageState extends State<SettingPage> {
|
||||
|
||||
final List<bool> _expandState = [false, false, false, false, false, false];
|
||||
final List<bool> _expandState = [false, false, false, false, false, false, false, false];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -120,25 +122,6 @@ class _SettingPageState extends State<SettingPage> {
|
||||
headerBuilder: ((context, isExpanded) {
|
||||
return const ListTile(title: Text("高级设置"), subtitle: Text("修改后重启生效"));
|
||||
}), body: Padding(padding: const EdgeInsets.all(12), child: Column(children: [
|
||||
TextFormField(maxLines: null, initialValue: Util.getCurrentProp("name"), decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "容器名称"), onChanged: (value) async {
|
||||
await Util.setCurrentProp("name", value);
|
||||
//setState(() {});
|
||||
}),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
ValueListenableBuilder(valueListenable: G.bootTextChange, builder:(context, v, child) {
|
||||
return TextFormField(maxLines: null, initialValue: Util.getCurrentProp("boot"), decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "启动命令"), onChanged: (value) async {
|
||||
await Util.setCurrentProp("boot", value);
|
||||
});
|
||||
}),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
TextFormField(maxLines: null, initialValue: Util.getCurrentProp("vnc"), decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "vnc启动命令"), onChanged: (value) async {
|
||||
await Util.setCurrentProp("vnc", value);
|
||||
}),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
TextFormField(maxLines: null, initialValue: Util.getCurrentProp("vncUrl"), decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "网页跳转地址"), onChanged: (value) async {
|
||||
await Util.setCurrentProp("vncUrl", value);
|
||||
}),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
OutlinedButton(style: D.commandButtonStyle, child: const Text("重置启动命令"), onPressed: () {
|
||||
showDialog(context: context, builder: (context) {
|
||||
return AlertDialog(title: const Text("注意"), content: const Text("是否重置启动命令?"), actions: [
|
||||
@@ -154,6 +137,30 @@ class _SettingPageState extends State<SettingPage> {
|
||||
]);
|
||||
});
|
||||
}),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
TextFormField(maxLines: null, initialValue: Util.getCurrentProp("name"), decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "容器名称"), onChanged: (value) async {
|
||||
await Util.setCurrentProp("name", value);
|
||||
//setState(() {});
|
||||
}),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
ValueListenableBuilder(valueListenable: G.bootTextChange, builder:(context, v, child) {
|
||||
return TextFormField(maxLines: null, initialValue: Util.getCurrentProp("boot"), decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "启动命令"), onChanged: (value) async {
|
||||
await Util.setCurrentProp("boot", value);
|
||||
});
|
||||
}),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
TextFormField(maxLines: null, initialValue: Util.getCurrentProp("vnc"), decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "vnc启动命令"), onChanged: (value) async {
|
||||
await Util.setCurrentProp("vnc", value);
|
||||
}),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
const Divider(height: 2, indent: 8, endIndent: 8),
|
||||
SizedBox.fromSize(size: const Size.square(16)),
|
||||
const Text("你可以在当前所有同一网络下的设备(如:连接同一路由器的手机,电脑等)里使用小小电脑。\n\n将下面的链接复制到其他设备,在其他设备上把链接localhost字样改为当前设备的IP地址(可以通过快捷指令查看),然后使用浏览器打开链接即可。"),
|
||||
SizedBox.fromSize(size: const Size.square(16)),
|
||||
TextFormField(maxLines: null, initialValue: Util.getCurrentProp("vncUrl"), decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "网页跳转地址"), onChanged: (value) async {
|
||||
await Util.setCurrentProp("vncUrl", value);
|
||||
}),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
],))),
|
||||
ExpansionPanel(
|
||||
isExpanded: _expandState[1],
|
||||
@@ -233,20 +240,35 @@ class _SettingPageState extends State<SettingPage> {
|
||||
setState(() {});
|
||||
},),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
SwitchListTile(title: const Text("屏幕常亮"), value: Util.getGlobal("wakelock") as bool, onChanged:(value) {
|
||||
G.prefs.setBool("wakelock", value);
|
||||
WakelockPlus.toggle(enable: value);
|
||||
setState(() {});
|
||||
},),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
const Divider(height: 2, indent: 8, endIndent: 8),
|
||||
SizedBox.fromSize(size: const Size.square(16)),
|
||||
const Text("以下选项修改后将在下次启动软件时生效。"),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
SwitchListTile(title: const Text("开启时启动图形界面"), value: Util.getGlobal("autoLaunchVnc") as bool, onChanged:(value) {
|
||||
G.prefs.setBool("autoLaunchVnc", value);
|
||||
setState(() {});
|
||||
},),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
SwitchListTile(title: const Text("重新安装引导包"), subtitle: const Text("下次启动时生效"), value: Util.getGlobal("reinstallBootstrap") as bool, onChanged:(value) {
|
||||
SwitchListTile(title: const Text("重新安装引导包"), value: Util.getGlobal("reinstallBootstrap") as bool, onChanged:(value) {
|
||||
G.prefs.setBool("reinstallBootstrap", value);
|
||||
setState(() {});
|
||||
},),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
SwitchListTile(title: const Text("getifaddrs桥接"), subtitle: const Text("下次启动时生效"), value: Util.getGlobal("getifaddrsBridge") as bool, onChanged:(value) {
|
||||
SwitchListTile(title: const Text("getifaddrs桥接"), subtitle: const Text("修复安卓13设备getifaddrs无权限"), value: Util.getGlobal("getifaddrsBridge") as bool, onChanged:(value) {
|
||||
G.prefs.setBool("getifaddrsBridge", value);
|
||||
setState(() {});
|
||||
},),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
SwitchListTile(title: const Text("伪装系统为UOS"), subtitle: const Text("修复UOS微信无法启动"), value: Util.getGlobal("uos") as bool, onChanged:(value) {
|
||||
G.prefs.setBool("uos", value);
|
||||
setState(() {});
|
||||
},),
|
||||
],))),
|
||||
ExpansionPanel(
|
||||
isExpanded: _expandState[2],
|
||||
@@ -314,7 +336,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
}
|
||||
break;
|
||||
case false: {
|
||||
G.streamServerPty.write(const Utf8Encoder().convert("${String.fromCharCode(3)}exit\n"));
|
||||
G.streamServerPty.write(const Utf8Encoder().convert("\x03exit\n"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -383,7 +405,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
switch (value) {
|
||||
case true: {
|
||||
G.virglServerPty = Pty.start("/system/bin/sh");
|
||||
G.virglServerPty.write(const Utf8Encoder().convert("export CONTAINER_DIR=${G.dataPath}/containers/0\n${G.dataPath}/bin/virgl_test_server ${Util.getGlobal("defaultVirglCommand")}\nexit\n"));
|
||||
G.virglServerPty.write(const Utf8Encoder().convert("export CONTAINER_DIR=${G.dataPath}/containers/${G.currentContainer}\n${G.dataPath}/bin/virgl_test_server ${Util.getGlobal("defaultVirglCommand")}\nexit\n"));
|
||||
G.virglServerPty.exitCode.then((value) {
|
||||
G.isVirglServerStarted = false;
|
||||
setState(() {});
|
||||
@@ -391,7 +413,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
}
|
||||
break;
|
||||
case false: {
|
||||
G.virglServerPty.write(const Utf8Encoder().convert("${String.fromCharCode(3)}exit\n"));
|
||||
G.virglServerPty.write(const Utf8Encoder().convert("\x03exit\n"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -420,6 +442,172 @@ class _SettingPageState extends State<SettingPage> {
|
||||
],))),
|
||||
ExpansionPanel(
|
||||
isExpanded: _expandState[5],
|
||||
headerBuilder: ((context, isExpanded) {
|
||||
return const ListTile(title: Text("跨架构/跨系统支持"), subtitle: Text("实验性功能"),);
|
||||
}), body: Padding(padding: const EdgeInsets.all(12), child: Column(children: [
|
||||
const Text("""使用box86/box64运行x86/x64架构的程序,或使用wine运行windows程序。
|
||||
|
||||
运行windows程序需要经过架构和系统两层模拟,不要对运行速度抱有期待。程序崩溃也是常有的。
|
||||
|
||||
你需要耐心。即使图形界面什么也没显示。看看终端,还在继续输出吗?还是停止在某个报错?
|
||||
|
||||
如果不耐烦可以去看个广告消磨时间(bushi)
|
||||
|
||||
或者寻找该windows软件官方是否提供linux arm64版本。
|
||||
|
||||
给高级用户的注意事项:
|
||||
跨架构/跨系统提供类似binfmt_misc的支持。
|
||||
你可以直接执行x86或x64的elf(系统会自动调用box86/box64),也可以直接执行exe文件(系统会自动调用wine64)。
|
||||
前提是这些文件拥有可执行权限。"""),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
Wrap(alignment: WrapAlignment.center, spacing: 4.0, runSpacing: 4.0, children: [
|
||||
OutlinedButton(style: D.commandButtonStyle, child: const Text("安装box86和box64"), onPressed: () {
|
||||
Util.termWrite("bash ~/.local/share/tiny/extra/install-box");
|
||||
G.pageIndex.value = 0;
|
||||
}),
|
||||
OutlinedButton(style: D.commandButtonStyle, child: const Text("安装wine"), onPressed: () async {
|
||||
if (!await File("${G.dataPath}/tiny/cross/box64").exists()) {
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text("请先安装box86/box64"))
|
||||
);
|
||||
return;
|
||||
}
|
||||
Util.termWrite("bash ~/.local/share/tiny/extra/install-wine");
|
||||
G.pageIndex.value = 0;
|
||||
}),
|
||||
OutlinedButton(style: D.commandButtonStyle, child: const Text("安装dxvk"), onPressed: () async {
|
||||
if (!G.wasWineEnabled) {
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text("请启用wine后重试"))
|
||||
);
|
||||
return;
|
||||
}
|
||||
Util.termWrite("bash ~/.local/share/tiny/extra/install-dxvk");
|
||||
G.pageIndex.value = 0;
|
||||
}),
|
||||
OutlinedButton(style: D.commandButtonStyle, child: const Text("移除所有安装"), onPressed: () async {
|
||||
if (G.wasBoxEnabled) {
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text("请关闭跨架构支持后重试"))
|
||||
);
|
||||
return;
|
||||
}
|
||||
Util.termWrite("rm -rf ~/.local/share/tiny/cross");
|
||||
G.pageIndex.value = 0;
|
||||
}),
|
||||
OutlinedButton(style: D.commandButtonStyle, child: const Text("清空wine数据"), onPressed: () async {
|
||||
Util.termWrite("rm -rf ~/.wine");
|
||||
G.pageIndex.value = 0;
|
||||
}),
|
||||
]),
|
||||
SizedBox.fromSize(size: const Size.square(16)),
|
||||
const Divider(height: 2, indent: 8, endIndent: 8),
|
||||
SizedBox.fromSize(size: const Size.square(16)),
|
||||
const Text("""开启wine后的常用指令,点击后前往图形界面耐心等待。
|
||||
|
||||
任意程序启动参考时间:
|
||||
虎贲T7510 6GB 超过一分钟
|
||||
骁龙870 12GB 约10秒
|
||||
骁龙8gen3 不支持32位 可能不可用
|
||||
|
||||
初始化时间:
|
||||
可能比本软件初始化还长
|
||||
"""),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
Wrap(alignment: WrapAlignment.center, spacing: 4.0, runSpacing: 4.0, children: D.wineCommands.asMap().entries.map<Widget>(
|
||||
(e) {
|
||||
return OutlinedButton(style: D.commandButtonStyle, child: Text(e.value["name"]!), onPressed: () {
|
||||
Util.termWrite("${e.value["command"]!} &");
|
||||
G.pageIndex.value = 0;
|
||||
});
|
||||
}
|
||||
).toList()),
|
||||
SizedBox.fromSize(size: const Size.square(16)),
|
||||
const Divider(height: 2, indent: 8, endIndent: 8),
|
||||
SizedBox.fromSize(size: const Size.square(16)),
|
||||
const Text("以下选项修改后将在下次启动软件时生效。"),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
SwitchListTile(title: const Text("启用box86/box64"), subtitle: const Text("运行跨架构软件"), value: Util.getGlobal("isBoxEnabled") as bool, onChanged:(value) async {
|
||||
//检测box64是否存在,存在才开启
|
||||
if (value && !await File("${G.dataPath}/tiny/cross/box64").exists()) {
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text("请先安装box86/box64"))
|
||||
);
|
||||
return;
|
||||
}
|
||||
G.prefs.setBool("isBoxEnabled", value);
|
||||
if (!value && Util.getGlobal("isWineEnabled")) {
|
||||
G.prefs.setBool("isWineEnabled", false);
|
||||
}
|
||||
setState(() {});
|
||||
},),
|
||||
SwitchListTile(title: const Text("启用wine"), subtitle: const Text("运行windows exe软件"), value: Util.getGlobal("isWineEnabled") as bool, onChanged:(value) async {
|
||||
//检测wine是否存在且box64是否开启
|
||||
if (value && !(Util.getGlobal("isBoxEnabled") && await File("${G.dataPath}/tiny/cross/wine/bin/wine").exists())) {
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text("请先安装wine并启用box86/box64"))
|
||||
);
|
||||
return;
|
||||
}
|
||||
Util.execute(value ? """filename="${G.dataPath}/containers/${G.currentContainer}/home/tiny/.bashrc"
|
||||
command="export PATH=\\\$HOME/.local/share/tiny/cross/wine/bin:\\\$PATH # Auto-generated, do NOT edit"
|
||||
if ! ${G.dataPath}/busybox grep -qF "\$command" "\$filename"; then
|
||||
echo "\$command" >> "\$filename"
|
||||
fi""" : """filename="${G.dataPath}/containers/${G.currentContainer}/home/tiny/.bashrc"
|
||||
command="export PATH=\\\$HOME/.local/share/tiny/cross/wine/bin:\\\$PATH # Auto-generated, do NOT edit"
|
||||
if ${G.dataPath}/busybox grep -qF "\$command" "\$filename"; then
|
||||
command="export PATH=\\\$HOME/.local/share/tiny/cross/wine/bin:\\\$PATH \\\\# Auto-generated, do NOT edit"
|
||||
${G.dataPath}/busybox sed -i "\\\\#\$command#d" "\$filename"
|
||||
fi""");
|
||||
G.prefs.setBool("isWineEnabled", value);
|
||||
setState(() {});
|
||||
},),
|
||||
SizedBox.fromSize(size: const Size.square(16)),
|
||||
],))),
|
||||
ExpansionPanel(
|
||||
isExpanded: _expandState[6],
|
||||
headerBuilder: ((context, isExpanded) {
|
||||
return const ListTile(title: Text("高分辨率支持"), subtitle: Text("实验性功能"));
|
||||
}), body: Padding(padding: const EdgeInsets.all(12), child: Column(children: [
|
||||
const Text("""为更大的屏幕带来更高清的体验!
|
||||
|
||||
注意:
|
||||
选项开启后显示会变得很大,请在图形界面的左栏设置里手动调整缩放到一个你认为合适的值。
|
||||
|
||||
一些软件可能会存在显示问题,或者显示速度变慢。"""),
|
||||
SizedBox.fromSize(size: const Size.square(16)),
|
||||
TextFormField(maxLines: null, initialValue: Util.getGlobal("defaultHidpiOpt") as String, decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "HiDPI环境变量"), readOnly: Util.shouldWatchAds(D.adsRequired["changeHidpiOpt"]!),
|
||||
onTap: () {
|
||||
if (Util.shouldWatchAds(D.adsRequired["changeHidpiOpt"]!)) {
|
||||
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text("观看十二次视频广告永久解锁><"))
|
||||
);
|
||||
}
|
||||
},
|
||||
onChanged: (value) async {
|
||||
await G.prefs.setString("defaultHidpiOpt", value);
|
||||
},
|
||||
),
|
||||
SizedBox.fromSize(size: const Size.square(8)),
|
||||
SwitchListTile(title: const Text("高分辨率支持"), subtitle: const Text("下次启动时生效"), value: Util.getGlobal("isHidpiEnabled") as bool, onChanged:(value) {
|
||||
G.prefs.setBool("isHidpiEnabled", value);
|
||||
setState(() {});
|
||||
},),
|
||||
SizedBox.fromSize(size: const Size.square(16)),
|
||||
],))),
|
||||
ExpansionPanel(
|
||||
isExpanded: _expandState[7],
|
||||
headerBuilder: ((context, isExpanded) {
|
||||
return const ListTile(title: Text("广告记录"), subtitle: Text("在这里看广告"));
|
||||
}), body: Padding(padding: const EdgeInsets.all(12), child: Column(children: [
|
||||
@@ -1007,7 +1195,7 @@ SOFTWARE.
|
||||
}), body: const Padding(padding: EdgeInsets.all(8), child: Text("""
|
||||
除由Unity提供的广告功能外, 本软件不会收集你的隐私信息。
|
||||
|
||||
当然,你在容器系统内部安装或使用的软件行为就不受我控制了,所以我不对其负责。
|
||||
当然,你在容器系统内部安装或使用的软件行为(包括通过快捷指令)就不受我控制了,我不对其负责。
|
||||
|
||||
本软件申请的权限用于以下目的:
|
||||
文件相关权限:用于系统访问手机目录;
|
||||
@@ -1050,6 +1238,7 @@ SOFTWARE.
|
||||
终端最大行数修改: 观看6个广告
|
||||
推流参数修改: 观看8个广告
|
||||
启用virgl加速: 观看10个广告
|
||||
HiDPI环境变量修改: 观看12个广告
|
||||
|
||||
我设置了每天最多可以看5个广告。
|
||||
只要看满1个广告, 就可以在本次使用期间临时解锁全部功能。
|
||||
@@ -1110,7 +1299,7 @@ class LoadingPage extends StatelessWidget {
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 0, 0, 8),
|
||||
child: ValueListenableBuilder(valueListenable: G.updateText, builder:(context, value, child) {
|
||||
return Text(value, textScaleFactor: 2);
|
||||
return Text(value, textScaler: const TextScaler.linear(2));
|
||||
}),
|
||||
),
|
||||
const FakeLoadingStatus(),
|
||||
|
||||
@@ -43,6 +43,8 @@ import 'package:unity_ads_plugin/unity_ads_plugin.dart';
|
||||
|
||||
import 'package:clipboard/clipboard.dart';
|
||||
|
||||
import 'package:wakelock_plus/wakelock_plus.dart';
|
||||
|
||||
class Util {
|
||||
|
||||
static Future<void> copyAsset(String src, String dst) async {
|
||||
@@ -60,7 +62,7 @@ class Util {
|
||||
Pty pty = Pty.start(
|
||||
"/system/bin/sh"
|
||||
);
|
||||
pty.write(const Utf8Encoder().convert("$str\nexit \$!\n"));
|
||||
pty.write(const Utf8Encoder().convert("$str\nexit \$?\n"));
|
||||
return await pty.exitCode;
|
||||
}
|
||||
|
||||
@@ -88,8 +90,14 @@ class Util {
|
||||
//String defaultVirglCommand 默认virgl参数
|
||||
//String defaultVirglOpt 默认virgl环境变量
|
||||
//bool reinstallBootstrap = false 下次启动是否重装引导包
|
||||
//bool getifaddrsBridge = false 下次启动是否桥接getifaddrsBridge
|
||||
//bool getifaddrsBridge = false 下次启动是否桥接getifaddrs
|
||||
//bool uos = false 下次启动是否伪装UOS
|
||||
//bool isBoxEnabled = false 下次启动是否开启box86/box64
|
||||
//bool isWineEnabled = false 下次启动是否开启wine
|
||||
//bool virgl = false 下次启动是否启用virgl
|
||||
//bool wakelock = false 屏幕常亮
|
||||
//bool isHidpiEnabled = false 是否开启高分辨率
|
||||
//String defaultHidpiOpt 默认HiDPI环境变量
|
||||
//? int bootstrapVersion: 启动包版本
|
||||
//String[] containersInfo: 所有容器信息(json)
|
||||
//{name, boot:"\$DATA_DIR/bin/proot ...", vnc:"startnovnc", vncUrl:"...", commands:[{name:"更新和升级", command:"apt update -y && apt upgrade -y"},
|
||||
@@ -115,10 +123,16 @@ class Util {
|
||||
case "isStickyKey" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(true);
|
||||
case "reinstallBootstrap" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
|
||||
case "getifaddrsBridge" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
|
||||
case "uos" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
|
||||
case "isBoxEnabled" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
|
||||
case "isWineEnabled" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
|
||||
case "virgl" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
|
||||
case "wakelock" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
|
||||
case "isHidpiEnabled" : 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 "defaultVirglOpt" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("GALLIUM_DRIVER=virpipe MESA_GL_VERSION_OVERRIDE=4.0");
|
||||
case "defaultHidpiOpt" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("GDK_SCALE=2 QT_FONT_DPI=192");
|
||||
case "containersInfo" : return G.prefs.getStringList(key)!;
|
||||
case "adsBonus" : return b ? G.prefs.getStringList(key)! : (value){G.prefs.setStringList(key, value); return value;}([].cast<String>());
|
||||
}
|
||||
@@ -191,6 +205,7 @@ class Util {
|
||||
opr();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//来自xterms关于操作ctrl, shift, alt键的示例
|
||||
@@ -283,7 +298,7 @@ class TermPty {
|
||||
child: Scrollbar(child:
|
||||
SingleChildScrollView(
|
||||
child: Column(children: [
|
||||
const Text(":(\n发生了什么?", textScaleFactor: 2, style: ts, textAlign: TextAlign.center,),
|
||||
const Text(":(\n发生了什么?", textScaler: TextScaler.linear(2), style: ts, textAlign: TextAlign.center,),
|
||||
const Text("终端异常退出, 返回错误码9\n此错误通常是高版本安卓系统(12+)限制进程造成的, \n可以使用以下工具修复:", style: ts, textAlign: TextAlign.center),
|
||||
const SelectableText(helperLink, style: ts, textAlign: TextAlign.center),
|
||||
const Text("(复制链接到浏览器查看)", style: ts, textAlign: TextAlign.center),
|
||||
@@ -342,26 +357,45 @@ class D {
|
||||
static const commands = [{"name":"检查更新并升级", "command":"sudo apt update && sudo apt upgrade -y"},
|
||||
{"name":"查看系统信息", "command":"neofetch -L && neofetch --off"},
|
||||
{"name":"清屏", "command":"clear"},
|
||||
{"name":"查看IP", "command":"hostname -I | awk '{print \$NF}' # 如果显示无权限(Permission denied),请在全局设置里开启getifaddrs桥接"},
|
||||
{"name":"中断任务", "command":"\x03"},
|
||||
{"name":"安装图形处理软件Krita", "command":"sudo apt update && sudo apt install -y krita krita-l10n"},
|
||||
{"name":"卸载图形处理软件Krita", "command":"sudo apt autoremove --purge -y krita krita-l10n"},
|
||||
{"name":"卸载Krita", "command":"sudo apt autoremove --purge -y krita krita-l10n"},
|
||||
{"name":"安装视频剪辑软件Kdenlive", "command":"sudo apt update && sudo apt install -y kdenlive"},
|
||||
{"name":"卸载视频剪辑软件Kdenlive", "command":"sudo apt autoremove --purge -y kdenlive"},
|
||||
{"name":"卸载Kdenlive", "command":"sudo apt autoremove --purge -y kdenlive"},
|
||||
{"name":"安装科学计算软件Octave", "command":"sudo apt update && sudo apt install -y octave"},
|
||||
{"name":"卸载科学计算软件Octave", "command":"sudo apt autoremove --purge -y octave"},
|
||||
{"name":"安装WPS", "command":"wget https://wps-linux-personal.wpscdn.cn/wps/download/ep/Linux2019/11708/wps-office_11.1.0.11708_arm64.deb -O /tmp/wps.deb && sudo apt update && sudo apt install -y /tmp/wps.deb; rm /tmp/wps.deb"},
|
||||
{"name":"卸载Octave", "command":"sudo apt autoremove --purge -y octave"},
|
||||
{"name":"安装WPS", "command":"""wget \$(curl -L https://linux.wps.cn/ | grep -oP 'href="\\K[^"]*arm64\\.deb' | head -n 1) -O /tmp/wps.deb && sudo apt update && sudo apt install -y /tmp/wps.deb; rm /tmp/wps.deb"""},
|
||||
{"name":"卸载WPS", "command":"sudo apt autoremove --purge -y wps-office"},
|
||||
{"name":"安装CAJViewer", "command":"wget https://download.cnki.net/net.cnki.cajviewer_1.3.20-1_arm64.deb -O /tmp/caj.deb && sudo apt update && sudo apt install -y /tmp/caj.deb && bash /home/tiny/.local/share/tiny/caj/postinst; rm /tmp/caj.deb"},
|
||||
{"name":"卸载CAJViewer", "command":"sudo apt autoremove --purge -y net.cnki.cajviewer && bash /home/tiny/.local/share/tiny/caj/postrm"},
|
||||
{"name":"安装亿图图示", "command":"wget https://www.edrawsoft.cn/2download/aarch64/edrawmax_11.5.6-3_arm64.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 https://dldir1.qq.com/qqfile/qq/QQNT/fd2e886e/linuxqq_3.2.2-18394_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 -L https://cdn-go.cn/qq-web/im.qq.com_new/latest/rainbow/linuxQQDownload.js | grep -oP 'deb":"\\K[^"]*arm64\\.deb' | head -n 1) -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":"安装UOS微信", "command":"wget https://home-store-packages.uniontech.com/appstore/pool/appstore/c/com.tencent.weixin/com.tencent.weixin_2.1.9_arm64.deb -O /tmp/wechat.deb && sudo apt update && sudo apt install -y /tmp/wechat.deb /home/tiny/.local/share/tiny/wechat/deepin-elf-verify_all.deb /home/tiny/.local/share/tiny/wechat/libssl1.1_1.1.1n-0+deb10u6_arm64.deb && sed -i 's#/opt/apps/com.tencent.weixin/files/weixin/weixin#/opt/apps/com.tencent.weixin/files/weixin/weixin --no-sandbox#g' /opt/apps/com.tencent.weixin/files/weixin/weixin.sh && echo '该微信为UOS特供版,只有账号实名且在UOS系统上运行时可用。在使用前请前往全局设置开启UOS伪装。\n如果你使用微信只是为了传输文件,那么可以考虑使用支持SAF的文件管理器(如:质感文件),直接访问小小电脑所有文件。'; rm /tmp/wechat.deb"},
|
||||
{"name":"卸载UOS微信", "command":"sudo apt autoremove --purge -y com.tencent.weixin libssl1.1 deepin-elf-verify"},
|
||||
{"name":"安装钉钉", "command":"""wget \$(curl -L https://g.alicdn.com/dingding/h5-home-download/0.2.4/js/index.js | grep -oP 'url:"\\K[^"]*arm64\\.deb' | head -n 1) -O /tmp/dingtalk.deb && sudo apt update && sudo apt install -y /tmp/dingtalk.deb && sed -i 's#\\./com.alibabainc.dingtalk#\\./com.alibabainc.dingtalk --no-sandbox#g' /opt/apps/com.alibabainc.dingtalk/files/Elevator.sh; rm /tmp/dingtalk.deb"""},
|
||||
{"name":"卸载钉钉", "command":"sudo apt autoremove --purge -y com.alibabainc.dingtalk"},
|
||||
{"name":"修复无法编译C语言程序", "command":"sudo apt update && sudo apt reinstall -y libc6-dev"},
|
||||
{"name":"修复系统语言到中文", "command":"sudo localedef -c -i zh_CN -f UTF-8 zh_CN.UTF-8"},
|
||||
{"name":"启用回收站", "command":"sudo apt update && sudo apt install -y gvfs && echo '安装完成, 重启软件即可使用回收站。'"},
|
||||
{"name":"拉流测试", "command":"ffplay rtsp://127.0.0.1:8554/stream &"},
|
||||
{"name":"关机", "command":"stopvnc\nexit\nexit"},
|
||||
{"name":"???", "command":"timeout 8 cmatrix"}];
|
||||
|
||||
//默认wine快捷指令
|
||||
static const wineCommands = [{"name":"wine配置", "command":"wine64 winecfg"},
|
||||
{"name":"我的电脑", "command":"wine64 explorer"},
|
||||
{"name":"记事本", "command":"wine64 notepad"},
|
||||
{"name":"扫雷", "command":"wine64 winemine"},
|
||||
{"name":"注册表", "command":"wine64 regedit"},
|
||||
{"name":"控制面板", "command":"wine64 control"},
|
||||
{"name":"文件管理器", "command":"wine64 winefile"},
|
||||
{"name":"任务管理器", "command":"wine64 taskmgr"},
|
||||
{"name":"ie浏览器", "command":"wine64 iexplore"},
|
||||
{"name":"强制关闭wine", "command":"wineserver -k"}];
|
||||
|
||||
//默认小键盘
|
||||
static const termCommands = [
|
||||
{"name": "Esc", "key": TerminalKey.escape},
|
||||
@@ -411,13 +445,14 @@ class D {
|
||||
"changeTermMaxLines" : 6,
|
||||
"changeFFmpegCommand" : 8,
|
||||
"enableVirgl" : 10,
|
||||
"changeHidpiOpt" : 12,
|
||||
|
||||
"unlockOnce" : 1, //临时解锁需要看的广告数
|
||||
"unlockToday" : 2, //当日解锁需要看的广告数
|
||||
|
||||
};
|
||||
|
||||
static const String boot = "\$DATA_DIR/bin/proot -H --change-id=1000:1000 --pwd=/home/tiny --rootfs=\$CONTAINER_DIR --mount=/system --mount=/apex --kill-on-exit --mount=/storage:/storage --sysvipc -L --link2symlink --mount=/proc:/proc --mount=/dev:/dev --mount=\$CONTAINER_DIR/tmp:/dev/shm --mount=/dev/urandom:/dev/random --mount=/proc/self/fd:/dev/fd --mount=/proc/self/fd/0:/dev/stdin --mount=/proc/self/fd/1:/dev/stdout --mount=/proc/self/fd/2:/dev/stderr --mount=/dev/null:/dev/tty0 --mount=/dev/null:/proc/sys/kernel/cap_last_cap --mount=/storage/self/primary:/media/sd --mount=\$DATA_DIR/share:/home/tiny/公共 --mount=\$DATA_DIR/tiny:/home/tiny/.local/share/tiny --mount=/storage/self/primary/Fonts:/usr/share/fonts/wpsm --mount=/storage/self/primary/AppFiles/Fonts:/usr/share/fonts/yozom --mount=/system/fonts:/usr/share/fonts/androidm --mount=/storage/self/primary/Pictures:/home/tiny/图片 --mount=/storage/self/primary/Music:/home/tiny/音乐 --mount=/storage/self/primary/Movies:/home/tiny/视频 --mount=/storage/self/primary/Download:/home/tiny/下载 --mount=/storage/self/primary/DCIM:/home/tiny/照片 --mount=/storage/self/primary/Documents:/home/tiny/文档 --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/.tmoe-container.stat:/proc/stat --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/.tmoe-container.version:/proc/version --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/bus:/proc/bus --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/buddyinfo:/proc/buddyinfo --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/cgroups:/proc/cgroups --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/consoles:/proc/consoles --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/crypto:/proc/crypto --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/devices:/proc/devices --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/diskstats:/proc/diskstats --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/execdomains:/proc/execdomains --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/fb:/proc/fb --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/filesystems:/proc/filesystems --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/interrupts:/proc/interrupts --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/iomem:/proc/iomem --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/ioports:/proc/ioports --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/kallsyms:/proc/kallsyms --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/keys:/proc/keys --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/key-users:/proc/key-users --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/kpageflags:/proc/kpageflags --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/loadavg:/proc/loadavg --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/locks:/proc/locks --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/misc:/proc/misc --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/modules:/proc/modules --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/pagetypeinfo:/proc/pagetypeinfo --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/partitions:/proc/partitions --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/sched_debug:/proc/sched_debug --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/softirqs:/proc/softirqs --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/timer_list:/proc/timer_list --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/uptime:/proc/uptime --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/vmallocinfo:/proc/vmallocinfo --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/vmstat:/proc/vmstat --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/zoneinfo:/proc/zoneinfo /usr/bin/env -i HOSTNAME=TINY HOME=/home/tiny USER=tiny TERM=xterm-256color SDL_IM_MODULE=fcitx XMODIFIERS=@im=fcitx QT_IM_MODULE=fcitx GTK_IM_MODULE=fcitx TMOE_CHROOT=false TMOE_PROOT=true TMPDIR=/tmp MOZ_FAKE_NO_SANDBOX=1 DISPLAY=:4 PULSE_SERVER=tcp:127.0.0.1:4718 LANG=zh_CN.UTF-8 SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/games:/usr/local/games \$EXTRA_OPT /bin/bash -l";
|
||||
static const String boot = "\$DATA_DIR/bin/proot -H --change-id=1000:1000 --pwd=/home/tiny --rootfs=\$CONTAINER_DIR --mount=/system --mount=/apex --mount=/sys --kill-on-exit --mount=/storage:/storage --sysvipc -L --link2symlink --mount=/proc:/proc --mount=/dev:/dev --mount=\$CONTAINER_DIR/tmp:/dev/shm --mount=/dev/urandom:/dev/random --mount=/proc/self/fd:/dev/fd --mount=/proc/self/fd/0:/dev/stdin --mount=/proc/self/fd/1:/dev/stdout --mount=/proc/self/fd/2:/dev/stderr --mount=/dev/null:/dev/tty0 --mount=/dev/null:/proc/sys/kernel/cap_last_cap --mount=/storage/self/primary:/media/sd --mount=\$DATA_DIR/share:/home/tiny/公共 --mount=\$DATA_DIR/tiny:/home/tiny/.local/share/tiny --mount=/storage/self/primary/Fonts:/usr/share/fonts/wpsm --mount=/storage/self/primary/AppFiles/Fonts:/usr/share/fonts/yozom --mount=/system/fonts:/usr/share/fonts/androidm --mount=/storage/self/primary/Pictures:/home/tiny/图片 --mount=/storage/self/primary/Music:/home/tiny/音乐 --mount=/storage/self/primary/Movies:/home/tiny/视频 --mount=/storage/self/primary/Download:/home/tiny/下载 --mount=/storage/self/primary/DCIM:/home/tiny/照片 --mount=/storage/self/primary/Documents:/home/tiny/文档 --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/.tmoe-container.stat:/proc/stat --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/.tmoe-container.version:/proc/version --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/bus:/proc/bus --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/buddyinfo:/proc/buddyinfo --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/cgroups:/proc/cgroups --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/consoles:/proc/consoles --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/crypto:/proc/crypto --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/devices:/proc/devices --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/diskstats:/proc/diskstats --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/execdomains:/proc/execdomains --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/fb:/proc/fb --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/filesystems:/proc/filesystems --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/interrupts:/proc/interrupts --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/iomem:/proc/iomem --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/ioports:/proc/ioports --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/kallsyms:/proc/kallsyms --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/keys:/proc/keys --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/key-users:/proc/key-users --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/kpageflags:/proc/kpageflags --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/loadavg:/proc/loadavg --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/locks:/proc/locks --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/misc:/proc/misc --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/modules:/proc/modules --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/pagetypeinfo:/proc/pagetypeinfo --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/partitions:/proc/partitions --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/sched_debug:/proc/sched_debug --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/softirqs:/proc/softirqs --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/timer_list:/proc/timer_list --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/uptime:/proc/uptime --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/vmallocinfo:/proc/vmallocinfo --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/vmstat:/proc/vmstat --mount=\$CONTAINER_DIR/usr/local/etc/tmoe-linux/proot_proc/zoneinfo:/proc/zoneinfo \$EXTRA_MOUNT /usr/bin/env -i HOSTNAME=TINY HOME=/home/tiny USER=tiny TERM=xterm-256color SDL_IM_MODULE=fcitx XMODIFIERS=@im=fcitx QT_IM_MODULE=fcitx GTK_IM_MODULE=fcitx TMOE_CHROOT=false TMOE_PROOT=true TMPDIR=/tmp MOZ_FAKE_NO_SANDBOX=1 DISPLAY=:4 PULSE_SERVER=tcp:127.0.0.1:4718 LANG=zh_CN.UTF-8 SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/games:/usr/local/games \$EXTRA_OPT /bin/bash -l";
|
||||
|
||||
static final ButtonStyle commandButtonStyle = OutlinedButton.styleFrom(
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
@@ -463,6 +498,9 @@ class G {
|
||||
static ValueNotifier<bool> bootTextChange = ValueNotifier(true); //更改值,用于刷新启动命令
|
||||
static ValueNotifier<String> updateText = ValueNotifier("小小电脑"); //加载界面的说明文字
|
||||
|
||||
static bool wasBoxEnabled = false; //本次启动时是否启用了box86/64
|
||||
static bool wasWineEnabled = false; //本次启动时是否启用了wine
|
||||
|
||||
|
||||
static late SharedPreferences prefs;
|
||||
}
|
||||
@@ -685,6 +723,9 @@ done
|
||||
if (Util.shouldWatchAds(D.adsRequired["changeFFmpegCommand"]!)) {
|
||||
await G.prefs.remove("defaultFFmpegCommand");
|
||||
}
|
||||
if (Util.shouldWatchAds(D.adsRequired["changeHidpiOpt"]!)) {
|
||||
await G.prefs.remove("defaultHidpiOpt");
|
||||
}
|
||||
if (Util.shouldWatchAds(D.adsRequired["changeTermMaxLines"]!)) {
|
||||
await G.prefs.setInt("termMaxLines", 4095);
|
||||
}
|
||||
@@ -701,6 +742,8 @@ done
|
||||
await G.prefs.setBool("virgl", false);
|
||||
}
|
||||
|
||||
//设置屏幕常亮
|
||||
WakelockPlus.toggle(enable: Util.getGlobal("wakelock"));
|
||||
}
|
||||
|
||||
static Future<void> initTerminalForCurrent() async {
|
||||
@@ -726,11 +769,10 @@ done
|
||||
G.audioPty = Pty.start(
|
||||
"/system/bin/sh"
|
||||
);
|
||||
//pulseaudio也需要一个tmp文件夹,这里选择前面的cache,没有什么特别的原因,不行再换
|
||||
//pulseaudio还需要一个文件夹放配置,这里用share
|
||||
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
|
||||
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
|
||||
exit
|
||||
"""));
|
||||
@@ -738,11 +780,23 @@ exit
|
||||
}
|
||||
|
||||
static Future<void> launchCurrentContainer() async {
|
||||
String box86BinPath = "";
|
||||
String box64BinPath = "";
|
||||
String box86LibraryPath = "";
|
||||
String box64LibraryPath = "";
|
||||
String extraMount = ""; //mount options and other proot options
|
||||
String extraOpt = "";
|
||||
if (Util.getGlobal("getifaddrsBridge")) {
|
||||
Util.execute("${G.dataPath}/bin/getifaddrs_bridge_server ${G.dataPath}/containers/${G.currentContainer}/tmp/.getifaddrs-bridge");
|
||||
extraOpt += "LD_PRELOAD=/home/tiny/.local/share/tiny/extra/getifaddrs_bridge_client_lib.so ";
|
||||
}
|
||||
if (Util.getGlobal("isHidpiEnabled")) {
|
||||
extraOpt += "${Util.getGlobal("defaultHidpiOpt")} ";
|
||||
}
|
||||
if (Util.getGlobal("uos")) {
|
||||
extraMount += "--mount=\$DATA_DIR/tiny/wechat/uos-lsb:/etc/lsb-release --mount=\$DATA_DIR/tiny/wechat/uos-release:/usr/lib/os-release ";
|
||||
extraMount += "--mount=\$DATA_DIR/tiny/wechat/license/var/uos:/var/uos --mount=\$DATA_DIR/tiny/wechat/license/var/lib/uos-license:/var/lib/uos-license ";
|
||||
}
|
||||
if (Util.getGlobal("virgl")) {
|
||||
Util.execute("""
|
||||
export DATA_DIR=${G.dataPath}
|
||||
@@ -750,10 +804,33 @@ export CONTAINER_DIR=\$DATA_DIR/containers/${G.currentContainer}
|
||||
${G.dataPath}/bin/virgl_test_server ${Util.getGlobal("defaultVirglCommand")}""");
|
||||
extraOpt += "${Util.getGlobal("defaultVirglOpt")} ";
|
||||
}
|
||||
if (Util.getGlobal("isBoxEnabled")) {
|
||||
G.wasBoxEnabled = true;
|
||||
extraMount += "--x86=/home/tiny/.local/bin/box86 --x64=/home/tiny/.local/bin/box64 ";
|
||||
extraMount += "--mount=\$DATA_DIR/tiny/cross/box86:/home/tiny/.local/bin/box86 --mount=\$DATA_DIR/tiny/cross/box64:/home/tiny/.local/bin/box64 ";
|
||||
extraOpt += "BOX86_NOBANNER=1 BOX64_NOBANNER=1 ";
|
||||
}
|
||||
if (Util.getGlobal("isWineEnabled")) {
|
||||
G.wasWineEnabled = true;
|
||||
box86BinPath += "/home/tiny/.local/share/tiny/cross/wine/bin:";
|
||||
box64BinPath += "/home/tiny/.local/share/tiny/cross/wine/bin:";
|
||||
box86LibraryPath += "/home/tiny/.local/share/tiny/cross/wine/lib/wine/i386-unix:";
|
||||
box64LibraryPath += "/home/tiny/.local/share/tiny/cross/wine/lib/wine/x86_64-unix:";
|
||||
extraMount += "--wine=/home/tiny/.local/bin/wine64 ";
|
||||
extraMount += "--mount=\$DATA_DIR/tiny/cross/wine.desktop:/usr/share/applications/wine.desktop ";
|
||||
//extraMount += "--mount=\$DATA_DIR/tiny/cross/winetricks:/home/tiny/.local/bin/winetricks --mount=\$DATA_DIR/tiny/cross/winetricks.desktop:/usr/share/applications/winetricks.desktop ";
|
||||
}
|
||||
if (G.wasBoxEnabled) {
|
||||
extraOpt += "BOX86_PATH=$box86BinPath/home/tiny/.local/share/tiny/cross/bin ";
|
||||
extraOpt += "BOX64_PATH=$box64BinPath/home/tiny/.local/share/tiny/cross/bin ";
|
||||
extraOpt += "BOX86_LD_LIBRARY_PATH=$box86LibraryPath/home/tiny/.local/share/tiny/cross/x86lib ";
|
||||
extraOpt += "BOX64_LD_LIBRARY_PATH=$box64LibraryPath/home/tiny/.local/share/tiny/cross/x64lib ";
|
||||
}
|
||||
Util.termWrite(
|
||||
"""
|
||||
export DATA_DIR=${G.dataPath}
|
||||
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
|
||||
@@ -801,7 +878,8 @@ clear""");
|
||||
}
|
||||
return KeyEventResult.ignored;
|
||||
},
|
||||
child: WebViewWidget(controller: G.controller),
|
||||
child: GestureDetector(onSecondaryTap: () {
|
||||
}, child: WebViewWidget(controller: G.controller))
|
||||
);
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -6,13 +6,17 @@ import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import ffmpeg_kit_flutter_full_gpl
|
||||
import package_info_plus
|
||||
import path_provider_foundation
|
||||
import shared_preferences_foundation
|
||||
import url_launcher_macos
|
||||
import wakelock_plus
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
FFmpegKitFlutterPlugin.register(with: registry.registrar(forPlugin: "FFmpegKitFlutterPlugin"))
|
||||
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
|
||||
}
|
||||
|
||||
212
pubspec.lock
212
pubspec.lock
@@ -1,6 +1,14 @@
|
||||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -45,10 +53,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
|
||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.2"
|
||||
version: "1.18.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -57,6 +65,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dbus
|
||||
sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.10"
|
||||
equatable:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -114,10 +130,10 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
|
||||
sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
version: "3.0.1"
|
||||
flutter_pty:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -140,10 +156,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
|
||||
sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.2"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -156,18 +172,26 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: intl
|
||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
||||
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.18.1"
|
||||
version: "0.19.0"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.7"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
|
||||
sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "3.0.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -188,10 +212,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
|
||||
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
version: "1.10.0"
|
||||
package_info_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus
|
||||
sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.1"
|
||||
package_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_platform_interface
|
||||
sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -212,10 +252,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
|
||||
sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
version: "2.2.2"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -252,50 +292,66 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: permission_handler
|
||||
sha256: bc56bfe9d3f44c3c612d8d393bd9b174eb796d706759f9b495ac254e4294baa5
|
||||
sha256: "860c6b871c94c78e202dc69546d4d8fd84bd59faeb36f8fb9888668a53ff4f78"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.4.5"
|
||||
version: "11.1.0"
|
||||
permission_handler_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_android
|
||||
sha256: "59c6322171c29df93a22d150ad95f3aa19ed86542eaec409ab2691b8f35f9a47"
|
||||
sha256: "2f1bec180ee2f5665c22faada971a8f024761f632e93ddc23310487df52dcfa6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.3.6"
|
||||
version: "12.0.1"
|
||||
permission_handler_apple:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_apple
|
||||
sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5"
|
||||
sha256: "1a816084338ada8d574b1cb48390e6e8b19305d5120fe3a37c98825bacc78306"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.1.4"
|
||||
version: "9.2.0"
|
||||
permission_handler_html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_html
|
||||
sha256: "11b762a8c123dced6461933a88ea1edbbe036078c3f9f41b08886e678e7864df"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.0+2"
|
||||
permission_handler_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_platform_interface
|
||||
sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4"
|
||||
sha256: d87349312f7eaf6ce0adaf668daf700ac5b06af84338bd8b8574dfbd93ffe1a1
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.12.0"
|
||||
version: "4.0.2"
|
||||
permission_handler_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_windows
|
||||
sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098
|
||||
sha256: "1e8640c1e39121128da6b816d236e714d2cf17fac5a105dd6acdd3403a628004"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.3"
|
||||
version: "0.2.0"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.2"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59"
|
||||
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
version: "3.1.4"
|
||||
platform_info:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -308,10 +364,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
|
||||
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.6"
|
||||
version: "2.1.8"
|
||||
quiver:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -372,10 +428,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_web
|
||||
sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
|
||||
sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
version: "2.2.2"
|
||||
shared_preferences_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -401,18 +457,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
|
||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.0"
|
||||
version: "1.11.1"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
|
||||
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "2.1.2"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -433,10 +489,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
|
||||
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.0"
|
||||
version: "0.6.1"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -457,34 +513,34 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: url_launcher
|
||||
sha256: b1c9e98774adf8820c96fbc7ae3601231d324a7d5ebd8babe27b6dfac91357ba
|
||||
sha256: e9aa5ea75c84cf46b3db4eea212523591211c3cf2e13099ee4ec147f54201c86
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.1"
|
||||
version: "6.2.2"
|
||||
url_launcher_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_android
|
||||
sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def"
|
||||
sha256: c0766a55ab42cefaa728cabc951e82919ab41a3a4fee0aaa96176ca82da8cc51
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.0"
|
||||
version: "6.2.1"
|
||||
url_launcher_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_ios
|
||||
sha256: "4ac97281cf60e2e8c5cc703b2b28528f9b50c8f7cebc71df6bdf0845f647268a"
|
||||
sha256: "46b81e3109cbb2d6b81702ad3077540789a3e74e22795eb9f0b7d494dbaa72ea"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.0"
|
||||
version: "6.2.2"
|
||||
url_launcher_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_linux
|
||||
sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd"
|
||||
sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
version: "3.1.1"
|
||||
url_launcher_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -497,26 +553,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_platform_interface
|
||||
sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50"
|
||||
sha256: "4aca1e060978e19b2998ee28503f40b5ba6226819c2b5e3e4d1821e8ccd92198"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "2.3.0"
|
||||
url_launcher_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_web
|
||||
sha256: "7fd2f55fe86cea2897b963e864dc01a7eb0719ecc65fcef4c1cc3d686d718bb2"
|
||||
sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "2.2.3"
|
||||
url_launcher_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_windows
|
||||
sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc"
|
||||
sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
version: "3.1.1"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -525,62 +581,86 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
wakelock_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: wakelock_plus
|
||||
sha256: f268ca2116db22e57577fb99d52515a24bdc1d570f12ac18bb762361d43b043d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.4"
|
||||
wakelock_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: wakelock_plus_platform_interface
|
||||
sha256: "40fabed5da06caff0796dc638e1f07ee395fb18801fbff3255a2372db2d80385"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
|
||||
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.4-beta"
|
||||
version: "0.3.0"
|
||||
webview_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: webview_flutter
|
||||
sha256: "42393b4492e629aa3a88618530a4a00de8bb46e50e7b3993fedbfdc5352f0dbf"
|
||||
sha256: "60e23976834e995c404c0b21d3b9db37ecd77d3303ef74f8b8d7a7b19947fc04"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.4.2"
|
||||
version: "4.4.3"
|
||||
webview_flutter_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_android
|
||||
sha256: "8326ee235f87605a2bfc444a4abc897f4abc78d83f054ba7d3d1074ce82b4fbf"
|
||||
sha256: "161af93c2abaf94ef2192bffb53a3658b2d721a3bf99b69aa1e47814ee18cc96"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.12.1"
|
||||
version: "3.13.2"
|
||||
webview_flutter_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_platform_interface
|
||||
sha256: "6d9213c65f1060116757a7c473247c60f3f7f332cac33dc417c9e362a9a13e4f"
|
||||
sha256: dbe745ee459a16b6fec296f7565a8ef430d0d681001d8ae521898b9361854943
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.0"
|
||||
version: "2.9.0"
|
||||
webview_flutter_wkwebview:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_wkwebview
|
||||
sha256: accdaaa49a2aca2dc3c3230907988954cdd23fed0a19525d6c9789d380f4dc76
|
||||
sha256: "02d8f3ebbc842704b2b662377b3ee11c0f8f1bbaa8eab6398262f40049819160"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.9.4"
|
||||
version: "3.10.1"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3"
|
||||
sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.9"
|
||||
version: "5.2.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2"
|
||||
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "1.0.4"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.5.0"
|
||||
xterm:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -590,5 +670,5 @@ packages:
|
||||
source: hosted
|
||||
version: "3.5.0"
|
||||
sdks:
|
||||
dart: ">=3.1.0 <4.0.0"
|
||||
flutter: ">=3.13.0"
|
||||
dart: ">=3.2.0 <4.0.0"
|
||||
flutter: ">=3.16.0"
|
||||
|
||||
11
pubspec.yaml
11
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.11+1
|
||||
version: 1.0.12+3
|
||||
|
||||
environment:
|
||||
sdk: '>=3.1.0 <4.0.0'
|
||||
@@ -33,16 +33,17 @@ dependencies:
|
||||
xterm: ^3.5.0
|
||||
flutter_pty: ^0.4.0
|
||||
path_provider: ^2.1.0
|
||||
webview_flutter: ^4.2.3
|
||||
permission_handler: ^10.4.3
|
||||
webview_flutter: ^4.4.2
|
||||
permission_handler: ^11.0.1
|
||||
http: ^1.1.0
|
||||
retry: ^3.1.2
|
||||
url_launcher: ^6.1.12
|
||||
shared_preferences: ^2.2.1
|
||||
intl: ^0.18.1 #日期字符串转换
|
||||
intl: ^0.19.0 #日期字符串转换
|
||||
unity_ads_plugin: ^0.3.8
|
||||
clipboard: ^0.1.3
|
||||
ffmpeg_kit_flutter_full_gpl: ^6.0.3
|
||||
wakelock_plus: ^1.1.4
|
||||
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
@@ -58,7 +59,7 @@ dev_dependencies:
|
||||
# activated in the `analysis_options.yaml` file located at the root of your
|
||||
# package. See that file for information about deactivating specific lint
|
||||
# rules and activating additional ones.
|
||||
flutter_lints: ^2.0.0
|
||||
flutter_lints: ^3.0.1
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
BIN
readme/img1.png
Normal file
BIN
readme/img1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
BIN
readme/img2.png
Normal file
BIN
readme/img2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 265 KiB |
BIN
readme/img3.gif
Normal file
BIN
readme/img3.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 MiB |
BIN
readme/img4.png
Normal file
BIN
readme/img4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 128 KiB |
BIN
readme/img5.png
Normal file
BIN
readme/img5.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 326 KiB |
@@ -10,6 +10,11 @@ include(${EPHEMERAL_DIR}/generated_config.cmake)
|
||||
# https://github.com/flutter/flutter/issues/57146.
|
||||
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
|
||||
|
||||
# Set fallback configurations for older versions of the flutter tool.
|
||||
if (NOT DEFINED FLUTTER_TARGET_PLATFORM)
|
||||
set(FLUTTER_TARGET_PLATFORM "windows-x64")
|
||||
endif()
|
||||
|
||||
# === Flutter Library ===
|
||||
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
|
||||
|
||||
@@ -92,7 +97,7 @@ add_custom_command(
|
||||
COMMAND ${CMAKE_COMMAND} -E env
|
||||
${FLUTTER_TOOL_ENVIRONMENT}
|
||||
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
|
||||
windows-x64 $<CONFIG>
|
||||
${FLUTTER_TARGET_PLATFORM} $<CONFIG>
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_target(flutter_assemble DEPENDS
|
||||
|
||||
Reference in New Issue
Block a user