Compare commits

..

6 Commits

Author SHA1 Message Date
Caten
09bf75beed Change WPS command, remove alipay 2024-01-13 07:52:53 +08:00
Caten
b00ede9483 Merge pull request #9 from wyq0918dev/md3
Modify user interface to material3
2024-01-12 18:57:06 +08:00
王泳淇
b8393dacfd Modify user interface to material3 2024-01-12 16:27:32 +08:00
Caten
ce5ad3b758 Update code to v1.0.12+3 2024-01-07 08:32:56 +08:00
Caten
cf15e2e07d HiDPI options added 2024-01-06 18:44:58 +08:00
Caten
938745036d Update code to v1.0.12+2
wakelock, modified proot with binfmt-like feature, more wine scripts
2023-12-11 15:07:07 +08:00
19 changed files with 573 additions and 212 deletions

View File

@@ -64,6 +64,13 @@ android {
//checkReleaseBuilds false //checkReleaseBuilds false
abortOnError 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 { flutter {

View File

@@ -6,7 +6,7 @@ buildscript {
} }
dependencies { 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" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }

Binary file not shown.

Binary file not shown.

35
extra/cross/install-dxvk Normal file
View 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配置更新配置。'

View File

@@ -2,21 +2,46 @@
sudo apt update sudo apt update
sudo apt upgrade -y sudo apt upgrade -y
sudo apt install -y nano cabextract libfreetype6 libfreetype6:armhf libfontconfig libfontconfig:armhf libxext6 libxext6:armhf libxinerama-dev libxinerama-dev:armhf libxxf86vm1 libxxf86vm1:armhf libxrender1 libxrender1:armhf libxcomposite1 libxcomposite1:armhf libxrandr2 libxrandr2:armhf libxi6 libxi6:armhf libxcursor1 libxcursor1:armhf libvulkan-dev libvulkan-dev:armhf zenity
# 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 rm -rf $HOME/.local/share/tiny/tmp
mkdir $HOME/.local/share/tiny/tmp mkdir $HOME/.local/share/tiny/tmp
cd $HOME/.local/share/tiny/tmp cd $HOME/.local/share/tiny/tmp
MIRROR_SITE=https://mirror.ghproxy.com MIRROR_SITE=https://mirror.ghproxy.com
LATEST_WINE_NAME=$(curl -L https://github.com/Kron4ek/Wine-Builds/releases | grep "amd64\.tar\.xz" | grep "proton" | head -n 1 | awk '{print $NF}') RELEASE_PAGE=https://github.com/Kron4ek/Wine-Builds/releases
LATEST_WINE_TAG=$(echo $LATEST_WINE_NAME | cut -d "-" -f 2) 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 [ $LATEST_WINE_TAG == proton ]; then if [ -z "$LATEST_WINE_TAG" ] || [ "$LATEST_WINE_TAG" == "proton-" ]
LATEST_WINE_TAG=proton-$(echo $LATEST_WINE_NAME | cut -d "-" -f 3)-$(echo $LATEST_WINE_NAME | cut -d "-" -f 4) then
LATEST_WINE_TAG=proton-8.0-4
fi fi
LATEST_WINE_NAME=wine-$LATEST_WINE_TAG-amd64.tar.xz
LATEST_WINE_LINK=https://github.com/Kron4ek/Wine-Builds/releases/download/$LATEST_WINE_TAG/$LATEST_WINE_NAME LATEST_WINE_LINK=$RELEASE_PAGE/download/$LATEST_WINE_TAG/$LATEST_WINE_NAME
wget $MIRROR_SITE/$LATEST_WINE_LINK wget $MIRROR_SITE/$LATEST_WINE_LINK
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
@@ -28,52 +53,18 @@ if [ $? -ne 0 ]; then
fi fi
fi fi
wget $MIRROR_SITE/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
tar xvf $LATEST_WINE_NAME tar xvf $LATEST_WINE_NAME
mv wine-$LATEST_WINE_TAG-amd64 ../cross/wine mv wine-$LATEST_WINE_TAG-amd64 ../cross/wine
mv winetricks ../cross/winetricks-executable
chmod +x $HOME/.local/share/tiny/cross/winetricks-executable
cd .. cd ..
rm -rf tmp rm -rf tmp
echo '#!/bin/bash
export WINEPREFIX=~/.wine
box86 '"$HOME/.local/share/tiny/cross/wine/bin/wine "'"$@"' > $HOME/.local/share/tiny/cross/wine-executable
chmod +x $HOME/.local/share/tiny/cross/wine-executable
echo '#!/bin/bash
export WINEPREFIX=~/.wine
box64 '"$HOME/.local/share/tiny/cross/wine/bin/wine64 "'"$@"' > $HOME/.local/share/tiny/cross/wine64-executable
chmod +x $HOME/.local/share/tiny/cross/wine64-executable
echo '#!/bin/bash
export BOX64_NOBANNER=1 WINE=wine64 WINEPREFIX=~/.wine WINESERVER=~/.local/share/tiny/cross/wine/bin/wineserver
wine64 '"$HOME/.local/share/tiny/cross/winetricks-executable "'"$@"' > $HOME/.local/share/tiny/cross/winetricks64-executable
chmod +x $HOME/.local/share/tiny/cross/winetricks64-executable
echo '[Desktop Entry] echo '[Desktop Entry]
Name=Wine64 启动器 Name=Wine 启动器
Exec=wine64 start /unix %F Exec=wine64 start /unix %f
Icon=wine Icon=wine
Type=Application' > $HOME/.local/share/tiny/cross/wine64.desktop Type=Application' > $HOME/.local/share/tiny/cross/wine.desktop
chmod +x $HOME/.local/share/tiny/cross/wine64.desktop chmod +x $HOME/.local/share/tiny/cross/wine.desktop
echo '[Desktop Entry]
Name=Wine64 winetricks 实用工具
Exec=winetricks64
Icon=wine
Type=Application' > $HOME/.local/share/tiny/cross/winetricks64.desktop
chmod +x $HOME/.local/share/tiny/cross/winetricks64.desktop
echo '安装完成在启用wine后可以点击exe文件选择用wine启动。' echo '安装完成在启用wine后可以点击exe文件选择用wine启动。'
echo '初次运行时会自动进行一段时间的初始化工作。'
echo '程序的运行可能依赖一些配置或组件。比如一些使用directx的游戏可能需要安装dxvk。' echo '程序的运行可能依赖一些配置或组件。比如一些使用directx的游戏可能需要安装dxvk。'
echo '如果缺失可以尝试使用winetricks安装。请务必保持耐心。'

83
extra/cross/install-wine2 Normal file
View 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安装。请务必保持耐心。'

View File

@@ -2,15 +2,18 @@
### assets.zip中的文件 ### assets.zip中的文件
- [proot](https://github.com/Cateners/proot), 使用[build-proot-android](https://github.com/green-green-avk/build-proot-android)脚本编译
- [busybox](https://github.com/meefik/busybox) - [busybox](https://github.com/meefik/busybox)
- [mediamtx相关](https://github.com/bluenviron/mediamtx) - [mediamtx相关](https://github.com/bluenviron/mediamtx)
- [tar](https://github.com/Rprop/tar-android-static) - [tar](https://github.com/Rprop/tar-android-static)
- [Xserver XSDL, pulseaudio相关文件](https://github.com/pelya/commandergenius/tree/sdl_android/project/jni/application/xserver) - [Xserver XSDL, pulseaudio相关文件](https://github.com/pelya/commandergenius/tree/sdl_android/project/jni/application/xserver)
- [Tmoe Linux, debian包来源](https://github.com/2moe/tmoe) - [virgl](https://github.com/termux/termux-packages/tree/master/x11-packages/virglrenderer-android)
- [容器文件xa*](build-tiny-rootfs.md)
其中tar、busybox和pulseaudio相关文件都是直接用了二进制文件 以上文件没有经过更改
一般是使用了仓库直接提供的二进制文件或者是使用了仓库提供的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中的文件 ### patch.tar.gz中的文件
@@ -22,6 +25,10 @@ linux在需要数据时使用socket通知位于安卓的getifaddrs_bridge_ser
源码和编译信息在getifaddrs_bridge文件夹查看。 源码和编译信息在getifaddrs_bridge文件夹查看。
#### extra/install-box, extra/install-wine:
这些是用于跨架构/跨系统支持的box86/box64和wine安装脚本。
#### caj, edraw #### caj, edraw
这些分别是cajviewer亿图图示的补丁 这些分别是cajviewer亿图图示的补丁
@@ -29,4 +36,8 @@ linux在需要数据时使用socket通知位于安卓的getifaddrs_bridge_ser
- 亿图图示补丁的库文件是在小小电脑上下载了Qt对应版本源码后编译得到的 - 亿图图示补丁的库文件是在小小电脑上下载了Qt对应版本源码后编译得到的
- 编译进行了两次第一次直接编译可以得到Gui和Widgets两个库。第二次编译带上XcbQpa虽然会编译失败但在这之前就可以得到XcbQpa的库。 - 编译进行了两次第一次直接编译可以得到Gui和Widgets两个库。第二次编译带上XcbQpa虽然会编译失败但在这之前就可以得到XcbQpa的库。
#### wechat
微信的补丁。license, uos-lsb和uos-release来自星火的微信包或arch的wechat-uos打包我忘记到底是哪的了。不过都差不多
libssl1.1来自debian官方源。deepin-elf-verifier是我打的空包。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

View File

@@ -25,12 +25,14 @@ import 'dart:math';
//import 'package:flutter/services.dart'; //import 'package:flutter/services.dart';
import 'package:clipboard/clipboard.dart'; import 'package:clipboard/clipboard.dart';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter_pty/flutter_pty.dart'; import 'package:flutter_pty/flutter_pty.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
//import 'package:flutter/services.dart'; //import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
import 'package:xterm/xterm.dart'; import 'package:xterm/xterm.dart';
//import 'package:xterm/flutter.dart'; //import 'package:xterm/flutter.dart';
import 'package:tiny_computer/workflow.dart'; import 'package:tiny_computer/workflow.dart';
@@ -48,16 +50,25 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DynamicColorBuilder(
builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) {
return MaterialApp( return MaterialApp(
title: 'Tiny Computer', title: 'Tiny Computer',
theme: ThemeData( theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), colorScheme: lightDynamic,
useMaterial3: true,
//fontFamily: "FiraCode",
),
darkTheme: ThemeData(
colorScheme: darkDynamic,
useMaterial3: true, useMaterial3: true,
//fontFamily: "FiraCode", //fontFamily: "FiraCode",
), ),
home: const MyHomePage(title: 'Tiny Computer'), home: const MyHomePage(title: 'Tiny Computer'),
); );
} }
);
}
} }
@@ -104,7 +115,7 @@ class SettingPage extends StatefulWidget {
class _SettingPageState extends State<SettingPage> { class _SettingPageState extends State<SettingPage> {
final List<bool> _expandState = [false, false, false, false, false, false, false]; final List<bool> _expandState = [false, false, false, false, false, false, false, false];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -154,7 +165,7 @@ class _SettingPageState extends State<SettingPage> {
SizedBox.fromSize(size: const Size.square(8)), SizedBox.fromSize(size: const Size.square(8)),
const Divider(height: 2, indent: 8, endIndent: 8), const Divider(height: 2, indent: 8, endIndent: 8),
SizedBox.fromSize(size: const Size.square(16)), SizedBox.fromSize(size: const Size.square(16)),
const Text("你可以在当前所有同一网络下的设备(如:连接同一路由器的手机,电脑等)里使用小小电脑。\n\n将下面的链接复制到其他设备在其他设备上把链接localhost字样改为当前设备的IP地址可以通过快捷指令查看然后使用浏览器打开链接即可。"), const Text("你可以在当前所有同一网络下的设备(如:连接同一路由器的手机,电脑等)里使用小小电脑。\n\n将下面的链接复制到其他设备在其他设备上把链接localhost字样改为当前设备的IP地址可以通过快捷指令查看格式类似192.168.x.x),然后使用浏览器打开链接即可。"),
SizedBox.fromSize(size: const Size.square(16)), SizedBox.fromSize(size: const Size.square(16)),
TextFormField(maxLines: null, initialValue: Util.getCurrentProp("vncUrl"), decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "网页跳转地址"), onChanged: (value) async { TextFormField(maxLines: null, initialValue: Util.getCurrentProp("vncUrl"), decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "网页跳转地址"), onChanged: (value) async {
await Util.setCurrentProp("vncUrl", value); await Util.setCurrentProp("vncUrl", value);
@@ -239,8 +250,9 @@ class _SettingPageState extends State<SettingPage> {
setState(() {}); setState(() {});
},), },),
SizedBox.fromSize(size: const Size.square(8)), SizedBox.fromSize(size: const Size.square(8)),
SwitchListTile(title: const Text("开启时启动图形界面"), value: Util.getGlobal("autoLaunchVnc") as bool, onChanged:(value) { SwitchListTile(title: const Text("屏幕常亮"), value: Util.getGlobal("wakelock") as bool, onChanged:(value) {
G.prefs.setBool("autoLaunchVnc", value); G.prefs.setBool("wakelock", value);
WakelockPlus.toggle(enable: value);
setState(() {}); setState(() {});
},), },),
SizedBox.fromSize(size: const Size.square(8)), SizedBox.fromSize(size: const Size.square(8)),
@@ -248,6 +260,11 @@ class _SettingPageState extends State<SettingPage> {
SizedBox.fromSize(size: const Size.square(16)), SizedBox.fromSize(size: const Size.square(16)),
const Text("以下选项修改后将在下次启动软件时生效。"), const Text("以下选项修改后将在下次启动软件时生效。"),
SizedBox.fromSize(size: const Size.square(8)), 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("重新安装引导包"), 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); G.prefs.setBool("reinstallBootstrap", value);
setState(() {}); setState(() {});
@@ -329,7 +346,7 @@ class _SettingPageState extends State<SettingPage> {
} }
break; break;
case false: { case false: {
G.streamServerPty.write(const Utf8Encoder().convert("${String.fromCharCode(3)}exit\n")); G.streamServerPty.write(const Utf8Encoder().convert("\x03exit\n"));
} }
break; break;
} }
@@ -398,7 +415,7 @@ class _SettingPageState extends State<SettingPage> {
switch (value) { switch (value) {
case true: { case true: {
G.virglServerPty = Pty.start("/system/bin/sh"); 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.virglServerPty.exitCode.then((value) {
G.isVirglServerStarted = false; G.isVirglServerStarted = false;
setState(() {}); setState(() {});
@@ -406,7 +423,7 @@ class _SettingPageState extends State<SettingPage> {
} }
break; break;
case false: { case false: {
G.virglServerPty.write(const Utf8Encoder().convert("${String.fromCharCode(3)}exit\n")); G.virglServerPty.write(const Utf8Encoder().convert("\x03exit\n"));
} }
break; break;
} }
@@ -438,29 +455,27 @@ class _SettingPageState extends State<SettingPage> {
headerBuilder: ((context, isExpanded) { headerBuilder: ((context, isExpanded) {
return const ListTile(title: Text("跨架构/跨系统支持"), subtitle: Text("实验性功能"),); return const ListTile(title: Text("跨架构/跨系统支持"), subtitle: Text("实验性功能"),);
}), body: Padding(padding: const EdgeInsets.all(12), child: Column(children: [ }), body: Padding(padding: const EdgeInsets.all(12), child: Column(children: [
const Text("""你的梦想是在你的小小电脑上,运行着那些你熟悉的x86/x64或windows的程序。你不惧怕任何困难你勇敢地使用box86/box64或wine让你的梦想成为现实。但是你也要知道这是一条漫长而艰辛的道路你需要付出很多的代价。你的程序要经过两层的模拟就像穿越两个世界它们的速度会变得缓慢而沉重。你需要有足够的耐心即使你的眼前一片空白你的终端还在默默地工作。你要时刻关注它的输出看看它是否还在前进还是遇到了难以逾越的障碍。或者你也可以选择另一条路去寻找那些为linux arm64而生的程序它们或许能让你的梦想更加顺畅 const Text("""使用box86/box64运行x86/x64架构的程序或使用wine运行windows程序
你的选择就在下面,你只需勾选你想要的选项,然后重新启动你的小小电脑,你的梦想就会有所不同。
......人话:
使用box86/box64运行x86/x64架构的程序或使用wine运行windows程序。
运行windows程序需要经过架构和系统两层模拟不要对运行速度抱有期待。程序崩溃也是常有的。 运行windows程序需要经过架构和系统两层模拟不要对运行速度抱有期待。程序崩溃也是常有的。
你需要耐心。即使图形界面什么也没显示。看看终端,还在继续输出吗?还是停止在某个报错? 你需要耐心。即使图形界面什么也没显示。看看终端,还在继续输出吗?还是停止在某个报错?
如果不耐烦可以去看个广告消磨时间bushi
或者寻找该windows软件官方是否提供linux arm64版本。 或者寻找该windows软件官方是否提供linux arm64版本。
以下选项启用后下次启动时生效。 给高级用户的注意事项:
"""), 跨架构/跨系统提供类似binfmt_misc的支持。
SizedBox.fromSize(size: const Size.square(16)), 你可以直接执行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: [ Wrap(alignment: WrapAlignment.center, spacing: 4.0, runSpacing: 4.0, children: [
OutlinedButton(style: D.commandButtonStyle, child: const Text("安装box86和box64"), onPressed: () { OutlinedButton(style: D.commandButtonStyle, child: const Text("安装box86和box64"), onPressed: () {
Util.termWrite("bash ~/.local/share/tiny/extra/install-box"); Util.termWrite("bash ~/.local/share/tiny/extra/install-box");
G.pageIndex.value = 0; G.pageIndex.value = 0;
}), }),
OutlinedButton(style: D.commandButtonStyle, child: const Text("安装wine与winetricks"), onPressed: () async { OutlinedButton(style: D.commandButtonStyle, child: const Text("安装wine"), onPressed: () async {
if (!await File("${G.dataPath}/tiny/cross/box64").exists()) { if (!await File("${G.dataPath}/tiny/cross/box64").exists()) {
if (!context.mounted) return; if (!context.mounted) return;
ScaffoldMessenger.of(context).hideCurrentSnackBar(); ScaffoldMessenger.of(context).hideCurrentSnackBar();
@@ -472,6 +487,18 @@ class _SettingPageState extends State<SettingPage> {
Util.termWrite("bash ~/.local/share/tiny/extra/install-wine"); Util.termWrite("bash ~/.local/share/tiny/extra/install-wine");
G.pageIndex.value = 0; 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 { OutlinedButton(style: D.commandButtonStyle, child: const Text("移除所有安装"), onPressed: () async {
if (G.wasBoxEnabled) { if (G.wasBoxEnabled) {
if (!context.mounted) return; if (!context.mounted) return;
@@ -488,17 +515,33 @@ class _SettingPageState extends State<SettingPage> {
Util.termWrite("rm -rf ~/.wine"); Util.termWrite("rm -rf ~/.wine");
G.pageIndex.value = 0; G.pageIndex.value = 0;
}), }),
OutlinedButton(style: D.commandButtonStyle, child: const Text("配置wine"), onPressed: () async {
Util.termWrite("wine64 winecfg");
G.pageIndex.value = 0;
Workflow.launchBrowser();
}),
OutlinedButton(style: D.commandButtonStyle, child: const Text("启动winetricks"), onPressed: () async {
Util.termWrite("winetricks64");
G.pageIndex.value = 0;
Workflow.launchBrowser();
}),
]), ]),
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)), 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 { SwitchListTile(title: const Text("启用box86/box64"), subtitle: const Text("运行跨架构软件"), value: Util.getGlobal("isBoxEnabled") as bool, onChanged:(value) async {
//检测box64是否存在存在才开启 //检测box64是否存在存在才开启
@@ -518,7 +561,7 @@ class _SettingPageState extends State<SettingPage> {
},), },),
SwitchListTile(title: const Text("启用wine"), subtitle: const Text("运行windows exe软件"), value: Util.getGlobal("isWineEnabled") as bool, onChanged:(value) async { SwitchListTile(title: const Text("启用wine"), subtitle: const Text("运行windows exe软件"), value: Util.getGlobal("isWineEnabled") as bool, onChanged:(value) async {
//检测wine是否存在且box64是否开启 //检测wine是否存在且box64是否开启
if (value && !(Util.getGlobal("isBoxEnabled") && await File("${G.dataPath}/tiny/cross/wine64-executable").exists())) { if (value && !(Util.getGlobal("isBoxEnabled") && await File("${G.dataPath}/tiny/cross/wine/bin/wine").exists())) {
if (!context.mounted) return; if (!context.mounted) return;
ScaffoldMessenger.of(context).hideCurrentSnackBar(); ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
@@ -526,6 +569,16 @@ class _SettingPageState extends State<SettingPage> {
); );
return; 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); G.prefs.setBool("isWineEnabled", value);
setState(() {}); setState(() {});
},), },),
@@ -533,6 +586,38 @@ class _SettingPageState extends State<SettingPage> {
],))), ],))),
ExpansionPanel( ExpansionPanel(
isExpanded: _expandState[6], 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) { headerBuilder: ((context, isExpanded) {
return const ListTile(title: Text("广告记录"), subtitle: Text("在这里看广告")); return const ListTile(title: Text("广告记录"), subtitle: Text("在这里看广告"));
}), body: Padding(padding: const EdgeInsets.all(12), child: Column(children: [ }), body: Padding(padding: const EdgeInsets.all(12), child: Column(children: [
@@ -1120,7 +1205,7 @@ SOFTWARE.
}), body: const Padding(padding: EdgeInsets.all(8), child: Text(""" }), body: const Padding(padding: EdgeInsets.all(8), child: Text("""
除由Unity提供的广告功能外, 本软件不会收集你的隐私信息。 除由Unity提供的广告功能外, 本软件不会收集你的隐私信息。
当然,你在容器系统内部安装或使用的软件行为就不受我控制了,所以我不对其负责。 当然,你在容器系统内部安装或使用的软件行为(包括通过快捷指令)就不受我控制了,我不对其负责。
本软件申请的权限用于以下目的: 本软件申请的权限用于以下目的:
文件相关权限:用于系统访问手机目录; 文件相关权限:用于系统访问手机目录;
@@ -1163,6 +1248,7 @@ SOFTWARE.
终端最大行数修改: 观看6个广告 终端最大行数修改: 观看6个广告
推流参数修改: 观看8个广告 推流参数修改: 观看8个广告
启用virgl加速: 观看10个广告 启用virgl加速: 观看10个广告
HiDPI环境变量修改: 观看12个广告
我设置了每天最多可以看5个广告。 我设置了每天最多可以看5个广告。
只要看满1个广告, 就可以在本次使用期间临时解锁全部功能。 只要看满1个广告, 就可以在本次使用期间临时解锁全部功能。
@@ -1177,19 +1263,8 @@ SOFTWARE.
我注意到Unity提供了一些不那么合适的广告 我注意到Unity提供了一些不那么合适的广告
一般如果我看到这些广告就在后台直接禁了 一般如果我看到这些广告就在后台直接禁了
不过也可能有漏网之鱼 不过也可能有漏网之鱼
你们可以联系我禁掉 可以联系我禁掉
---下面是赛博乞讨环节---
(*>ω<*)
虽然感觉不太可能有人捐赠
但转念一想这个可能性不是比中彩票大多了吗
所以还是保留了下来
""")), """)),
const FractionallySizedBox(
widthFactor: 0.8,
child: Image(image: AssetImage("images/alipay.png"))
),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
launchUrl(Uri.parse("https://github.com/Cateners/tiny_computer"), mode: LaunchMode.externalApplication); launchUrl(Uri.parse("https://github.com/Cateners/tiny_computer"), mode: LaunchMode.externalApplication);
@@ -1223,7 +1298,7 @@ class LoadingPage extends StatelessWidget {
Padding( Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 8), padding: const EdgeInsets.fromLTRB(0, 0, 0, 8),
child: ValueListenableBuilder(valueListenable: G.updateText, builder:(context, value, child) { child: ValueListenableBuilder(valueListenable: G.updateText, builder:(context, value, child) {
return Text(value, textScaleFactor: 2); return Text(value, textScaler: const TextScaler.linear(2));
}), }),
), ),
const FakeLoadingStatus(), const FakeLoadingStatus(),
@@ -1440,7 +1515,6 @@ class _MyHomePageState extends State<MyHomePage> {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(isLoadingComplete?Util.getCurrentProp("name"):widget.title), title: Text(isLoadingComplete?Util.getCurrentProp("name"):widget.title),
), ),
body: isLoadingComplete?Column(mainAxisSize: MainAxisSize.min, children: [ body: isLoadingComplete?Column(mainAxisSize: MainAxisSize.min, children: [
@@ -1488,15 +1562,25 @@ class _MyHomePageState extends State<MyHomePage> {
}))]):const LoadingPage(), }))]):const LoadingPage(),
bottomNavigationBar: ValueListenableBuilder(valueListenable: G.pageIndex, builder:(context, value, child) { bottomNavigationBar: ValueListenableBuilder(valueListenable: G.pageIndex, builder:(context, value, child) {
return Visibility(visible: isLoadingComplete, return Visibility(visible: isLoadingComplete,
child: BottomNavigationBar(currentIndex: G.pageIndex.value, // child: BottomNavigationBar(currentIndex: G.pageIndex.value,
onTap: (index) { // 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: const [
NavigationDestination(icon: Icon(Icons.monitor), label: "终端"),
NavigationDestination(icon: Icon(Icons.video_settings), label: "控制")
],
onDestinationSelected: (index) {
G.pageIndex.value = index; G.pageIndex.value = index;
}, },
items: const [ ),
BottomNavigationBarItem(icon: Icon(Icons.monitor), label: "终端"),
BottomNavigationBarItem(icon: Icon(Icons.video_settings), label: "控制"),
],
)
);}), );}),
floatingActionButton: ValueListenableBuilder(valueListenable: G.pageIndex, builder:(context, value, child) { floatingActionButton: ValueListenableBuilder(valueListenable: G.pageIndex, builder:(context, value, child) {
return Visibility(visible: isLoadingComplete && (value == 0), return Visibility(visible: isLoadingComplete && (value == 0),

View File

@@ -43,6 +43,8 @@ import 'package:unity_ads_plugin/unity_ads_plugin.dart';
import 'package:clipboard/clipboard.dart'; import 'package:clipboard/clipboard.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
class Util { class Util {
static Future<void> copyAsset(String src, String dst) async { static Future<void> copyAsset(String src, String dst) async {
@@ -60,7 +62,7 @@ class Util {
Pty pty = Pty.start( Pty pty = Pty.start(
"/system/bin/sh" "/system/bin/sh"
); );
pty.write(const Utf8Encoder().convert("$str\nexit \$!\n")); pty.write(const Utf8Encoder().convert("$str\nexit \$?\n"));
return await pty.exitCode; return await pty.exitCode;
} }
@@ -88,11 +90,14 @@ class Util {
//String defaultVirglCommand 默认virgl参数 //String defaultVirglCommand 默认virgl参数
//String defaultVirglOpt 默认virgl环境变量 //String defaultVirglOpt 默认virgl环境变量
//bool reinstallBootstrap = false 下次启动是否重装引导包 //bool reinstallBootstrap = false 下次启动是否重装引导包
//bool getifaddrsBridge = false 下次启动是否桥接getifaddrsBridge //bool getifaddrsBridge = false 下次启动是否桥接getifaddrs
//bool uos = false 下次启动是否伪装UOS //bool uos = false 下次启动是否伪装UOS
//bool isBoxEnabled = false 下次启动是否开启box86/box64 //bool isBoxEnabled = false 下次启动是否开启box86/box64
//bool isWineEnabled = false 下次启动是否开启wine //bool isWineEnabled = false 下次启动是否开启wine
//bool virgl = false 下次启动是否启用virgl //bool virgl = false 下次启动是否启用virgl
//bool wakelock = false 屏幕常亮
//bool isHidpiEnabled = false 是否开启高分辨率
//String defaultHidpiOpt 默认HiDPI环境变量
//? int bootstrapVersion: 启动包版本 //? int bootstrapVersion: 启动包版本
//String[] containersInfo: 所有容器信息(json) //String[] containersInfo: 所有容器信息(json)
//{name, boot:"\$DATA_DIR/bin/proot ...", vnc:"startnovnc", vncUrl:"...", commands:[{name:"更新和升级", command:"apt update -y && apt upgrade -y"}, //{name, boot:"\$DATA_DIR/bin/proot ...", vnc:"startnovnc", vncUrl:"...", commands:[{name:"更新和升级", command:"apt update -y && apt upgrade -y"},
@@ -122,9 +127,12 @@ class Util {
case "isBoxEnabled" : 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 "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 "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 "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;}("--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 "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 "containersInfo" : return G.prefs.getStringList(key)!;
case "adsBonus" : return b ? G.prefs.getStringList(key)! : (value){G.prefs.setStringList(key, value); return value;}([].cast<String>()); case "adsBonus" : return b ? G.prefs.getStringList(key)! : (value){G.prefs.setStringList(key, value); return value;}([].cast<String>());
} }
@@ -197,6 +205,7 @@ class Util {
opr(); opr();
return null; return null;
} }
} }
//来自xterms关于操作ctrl, shift, alt键的示例 //来自xterms关于操作ctrl, shift, alt键的示例
@@ -289,7 +298,7 @@ class TermPty {
child: Scrollbar(child: child: Scrollbar(child:
SingleChildScrollView( SingleChildScrollView(
child: Column(children: [ 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 Text("终端异常退出, 返回错误码9\n此错误通常是高版本安卓系统(12+)限制进程造成的, \n可以使用以下工具修复:", style: ts, textAlign: TextAlign.center),
const SelectableText(helperLink, style: ts, textAlign: TextAlign.center), const SelectableText(helperLink, style: ts, textAlign: TextAlign.center),
const Text("(复制链接到浏览器查看)", style: ts, textAlign: TextAlign.center), const Text("(复制链接到浏览器查看)", style: ts, textAlign: TextAlign.center),
@@ -348,14 +357,15 @@ class D {
static const commands = [{"name":"检查更新并升级", "command":"sudo apt update && sudo apt upgrade -y"}, static const commands = [{"name":"检查更新并升级", "command":"sudo apt update && sudo apt upgrade -y"},
{"name":"查看系统信息", "command":"neofetch -L && neofetch --off"}, {"name":"查看系统信息", "command":"neofetch -L && neofetch --off"},
{"name":"清屏", "command":"clear"}, {"name":"清屏", "command":"clear"},
{"name":"查看IP", "command":"hostname -I | awk '{print \$NF}' # 如果显示无权限(Permission denied)请在全局设置里开启getifaddrs桥接"}, {"name":"查看IP", "command":"hostname -I # 如果显示无权限(Permission denied)请在全局设置里开启getifaddrs桥接"},
{"name":"中断任务", "command":"\x03"},
{"name":"安装图形处理软件Krita", "command":"sudo apt update && sudo apt install -y krita krita-l10n"}, {"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 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 update && sudo apt install -y octave"},
{"name":"卸载Octave", "command":"sudo apt autoremove --purge -y octave"}, {"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":"""wget --referer="https://www.wps.cn/product/wpslinux" \$(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":"卸载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":"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":"卸载CAJViewer", "command":"sudo apt autoremove --purge -y net.cnki.cajviewer && bash /home/tiny/.local/share/tiny/caj/postrm"},
@@ -372,7 +382,22 @@ class D {
{"name":"启用回收站", "command":"sudo apt update && sudo apt install -y gvfs && echo '安装完成, 重启软件即可使用回收站。'"}, {"name":"启用回收站", "command":"sudo apt update && sudo apt install -y gvfs && echo '安装完成, 重启软件即可使用回收站。'"},
{"name":"拉流测试", "command":"ffplay rtsp://127.0.0.1:8554/stream &"}, {"name":"拉流测试", "command":"ffplay rtsp://127.0.0.1:8554/stream &"},
{"name":"关机", "command":"stopvnc\nexit\nexit"}, {"name":"关机", "command":"stopvnc\nexit\nexit"},
{"name":"???", "command":"timeout 8 cmatrix"}]; {"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 = [ static const termCommands = [
{"name": "Esc", "key": TerminalKey.escape}, {"name": "Esc", "key": TerminalKey.escape},
@@ -398,7 +423,6 @@ class D {
{"name": "F10", "key": TerminalKey.f10}, {"name": "F10", "key": TerminalKey.f10},
{"name": "F11", "key": TerminalKey.f11}, {"name": "F11", "key": TerminalKey.f11},
{"name": "F12", "key": TerminalKey.f12}, {"name": "F12", "key": TerminalKey.f12},
]; ];
//看广告可以获得的奖励。 //看广告可以获得的奖励。
@@ -422,6 +446,7 @@ class D {
"changeTermMaxLines" : 6, "changeTermMaxLines" : 6,
"changeFFmpegCommand" : 8, "changeFFmpegCommand" : 8,
"enableVirgl" : 10, "enableVirgl" : 10,
"changeHidpiOpt" : 12,
"unlockOnce" : 1, //临时解锁需要看的广告数 "unlockOnce" : 1, //临时解锁需要看的广告数
"unlockToday" : 2, //当日解锁需要看的广告数 "unlockToday" : 2, //当日解锁需要看的广告数
@@ -475,6 +500,7 @@ class G {
static ValueNotifier<String> updateText = ValueNotifier("小小电脑"); //加载界面的说明文字 static ValueNotifier<String> updateText = ValueNotifier("小小电脑"); //加载界面的说明文字
static bool wasBoxEnabled = false; //本次启动时是否启用了box86/64 static bool wasBoxEnabled = false; //本次启动时是否启用了box86/64
static bool wasWineEnabled = false; //本次启动时是否启用了wine
static late SharedPreferences prefs; static late SharedPreferences prefs;
@@ -698,6 +724,9 @@ done
if (Util.shouldWatchAds(D.adsRequired["changeFFmpegCommand"]!)) { if (Util.shouldWatchAds(D.adsRequired["changeFFmpegCommand"]!)) {
await G.prefs.remove("defaultFFmpegCommand"); await G.prefs.remove("defaultFFmpegCommand");
} }
if (Util.shouldWatchAds(D.adsRequired["changeHidpiOpt"]!)) {
await G.prefs.remove("defaultHidpiOpt");
}
if (Util.shouldWatchAds(D.adsRequired["changeTermMaxLines"]!)) { if (Util.shouldWatchAds(D.adsRequired["changeTermMaxLines"]!)) {
await G.prefs.setInt("termMaxLines", 4095); await G.prefs.setInt("termMaxLines", 4095);
} }
@@ -714,6 +743,8 @@ done
await G.prefs.setBool("virgl", false); await G.prefs.setBool("virgl", false);
} }
//设置屏幕常亮
WakelockPlus.toggle(enable: Util.getGlobal("wakelock"));
} }
static Future<void> initTerminalForCurrent() async { static Future<void> initTerminalForCurrent() async {
@@ -750,12 +781,19 @@ exit
} }
static Future<void> launchCurrentContainer() async { static Future<void> launchCurrentContainer() async {
String extraMount = ""; String box86BinPath = "";
String box64BinPath = "";
String box86LibraryPath = "";
String box64LibraryPath = "";
String extraMount = ""; //mount options and other proot options
String extraOpt = ""; String extraOpt = "";
if (Util.getGlobal("getifaddrsBridge")) { if (Util.getGlobal("getifaddrsBridge")) {
Util.execute("${G.dataPath}/bin/getifaddrs_bridge_server ${G.dataPath}/containers/${G.currentContainer}/tmp/.getifaddrs-bridge"); 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 "; 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")) { 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/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 "; 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 ";
@@ -769,13 +807,25 @@ ${G.dataPath}/bin/virgl_test_server ${Util.getGlobal("defaultVirglCommand")}""")
} }
if (Util.getGlobal("isBoxEnabled")) { if (Util.getGlobal("isBoxEnabled")) {
G.wasBoxEnabled = true; 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 "; 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")) { if (Util.getGlobal("isWineEnabled")) {
extraOpt += "BOX86_PATH=/home/tiny/.local/share/tiny/cross/wine/bin/ BOX86_LD_LIBRARY_PATH=/home/tiny/.local/share/tiny/cross/wine/lib/wine/i386-unix/:/lib/i386-linux-gnu/:/lib/aarch64-linux-gnu/:/lib/arm-linux-gnueabihf/:/usr/lib/aarch64-linux-gnu/:/usr/lib/arm-linux-gnueabihf/:/usr/lib/i386-linux-gnu/:/home/tiny/.local/share/tiny/cross/x86lib/ "; G.wasWineEnabled = true;
extraOpt += "BOX64_PATH=/home/tiny/.local/share/tiny/cross/wine/bin/ BOX64_LD_LIBRARY_PATH=/home/tiny/.local/share/tiny/cross/wine/lib/wine/i386-unix/:/home/tiny/.local/share/tiny/cross/wine/lib/wine/x86_64-unix/:/lib/i386-linux-gnu/:/lib/x86_64-linux-gnu:/lib/aarch64-linux-gnu/:/lib/arm-linux-gnueabihf/:/usr/lib/aarch64-linux-gnu/:/usr/lib/arm-linux-gnueabihf/:/usr/lib/i386-linux-gnu/:/usr/lib/x86_64-linux-gnu/:/home/tiny/.local/share/tiny/cross/x64lib/ "; box86BinPath += "/home/tiny/.local/share/tiny/cross/wine/bin:";
extraMount += "--mount=\$DATA_DIR/tiny/cross/wine-executable:/home/tiny/.local/bin/wine --mount=\$DATA_DIR/tiny/cross/wine64-executable:/home/tiny/.local/bin/wine64 --mount=\$DATA_DIR/tiny/cross/wine64.desktop:/usr/share/applications/wine64.desktop "; box64BinPath += "/home/tiny/.local/share/tiny/cross/wine/bin:";
extraMount += "--mount=\$DATA_DIR/tiny/cross/winetricks64-executable:/home/tiny/.local/bin/winetricks64 --mount=\$DATA_DIR/tiny/cross/winetricks64.desktop:/usr/share/applications/winetricks64.desktop "; 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( Util.termWrite(
""" """

View File

@@ -6,9 +6,13 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <dynamic_color/dynamic_color_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) dynamic_color_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin");
dynamic_color_plugin_register_with_registrar(dynamic_color_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);

View File

@@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
dynamic_color
url_launcher_linux url_launcher_linux
) )

View File

@@ -5,14 +5,20 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import dynamic_color
import ffmpeg_kit_flutter_full_gpl import ffmpeg_kit_flutter_full_gpl
import package_info_plus
import path_provider_foundation import path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
import url_launcher_macos import url_launcher_macos
import wakelock_plus
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
FFmpegKitFlutterPlugin.register(with: registry.registrar(forPlugin: "FFmpegKitFlutterPlugin")) FFmpegKitFlutterPlugin.register(with: registry.registrar(forPlugin: "FFmpegKitFlutterPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
} }

View File

@@ -1,6 +1,14 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
args:
dependency: transitive
description:
name: args
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
url: "https://pub.dev"
source: hosted
version: "2.4.2"
async: async:
dependency: transitive dependency: transitive
description: description:
@@ -57,6 +65,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.1" version: "3.1.1"
dbus:
dependency: transitive
description:
name: dbus
sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
url: "https://pub.dev"
source: hosted
version: "0.7.10"
dynamic_color:
dependency: "direct main"
description:
name: dynamic_color
sha256: a866f1f8947bfdaf674d7928e769eac7230388a2e7a2542824fad4bb5b87be3b
url: "https://pub.dev"
source: hosted
version: "1.6.9"
equatable: equatable:
dependency: transitive dependency: transitive
description: description:
@@ -156,10 +180,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: intl name: intl
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
url: "https://pub.dev" url: "https://pub.dev"
source: hosted 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: lints:
dependency: transitive dependency: transitive
description: description:
@@ -192,6 +224,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.10.0" 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: path:
dependency: transitive dependency: transitive
description: description:
@@ -212,10 +260,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: path_provider_android name: path_provider_android
sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72 sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.1" version: "2.2.2"
path_provider_foundation: path_provider_foundation:
dependency: transitive dependency: transitive
description: description:
@@ -276,10 +324,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: permission_handler_html name: permission_handler_html
sha256: d96ff56a757b7f04fa825c469d296c5aebc55f743e87bd639fef91a466a24da8 sha256: "11b762a8c123dced6461933a88ea1edbbe036078c3f9f41b08886e678e7864df"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.1.0+1" version: "0.1.0+2"
permission_handler_platform_interface: permission_handler_platform_interface:
dependency: transitive dependency: transitive
description: description:
@@ -296,14 +344,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.2.0" version: "0.2.0"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted
version: "6.0.2"
platform: platform:
dependency: transitive dependency: transitive
description: description:
name: platform name: platform
sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59" sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.3" version: "3.1.4"
platform_info: platform_info:
dependency: transitive dependency: transitive
description: description:
@@ -316,10 +372,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: plugin_platform_interface name: plugin_platform_interface
sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.7" version: "2.1.8"
quiver: quiver:
dependency: transitive dependency: transitive
description: description:
@@ -465,34 +521,34 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: url_launcher name: url_launcher
sha256: b1c9e98774adf8820c96fbc7ae3601231d324a7d5ebd8babe27b6dfac91357ba sha256: e9aa5ea75c84cf46b3db4eea212523591211c3cf2e13099ee4ec147f54201c86
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.2.1" version: "6.2.2"
url_launcher_android: url_launcher_android:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_android name: url_launcher_android
sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def" sha256: c0766a55ab42cefaa728cabc951e82919ab41a3a4fee0aaa96176ca82da8cc51
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.2.0" version: "6.2.1"
url_launcher_ios: url_launcher_ios:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_ios name: url_launcher_ios
sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3 sha256: "46b81e3109cbb2d6b81702ad3077540789a3e74e22795eb9f0b7d494dbaa72ea"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.2.1" version: "6.2.2"
url_launcher_linux: url_launcher_linux:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_linux name: url_launcher_linux
sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd" sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.0" version: "3.1.1"
url_launcher_macos: url_launcher_macos:
dependency: transitive dependency: transitive
description: description:
@@ -505,26 +561,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_platform_interface name: url_launcher_platform_interface
sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50" sha256: "4aca1e060978e19b2998ee28503f40b5ba6226819c2b5e3e4d1821e8ccd92198"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" version: "2.3.0"
url_launcher_web: url_launcher_web:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_web name: url_launcher_web
sha256: "138bd45b3a456dcfafc46d1a146787424f8d2edfbf2809c9324361e58f851cf7" sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.1" version: "2.2.3"
url_launcher_windows: url_launcher_windows:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_windows name: url_launcher_windows
sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc" sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.0" version: "3.1.1"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@@ -533,6 +589,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.4" 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: web:
dependency: transitive dependency: transitive
description: description:
@@ -545,50 +617,58 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: webview_flutter name: webview_flutter
sha256: "42393b4492e629aa3a88618530a4a00de8bb46e50e7b3993fedbfdc5352f0dbf" sha256: "60e23976834e995c404c0b21d3b9db37ecd77d3303ef74f8b8d7a7b19947fc04"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.4.2" version: "4.4.3"
webview_flutter_android: webview_flutter_android:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_android name: webview_flutter_android
sha256: "8326ee235f87605a2bfc444a4abc897f4abc78d83f054ba7d3d1074ce82b4fbf" sha256: "161af93c2abaf94ef2192bffb53a3658b2d721a3bf99b69aa1e47814ee18cc96"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.12.1" version: "3.13.2"
webview_flutter_platform_interface: webview_flutter_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_platform_interface name: webview_flutter_platform_interface
sha256: "68e86162aa8fc646ae859e1585995c096c95fc2476881fa0c4a8d10f56013a5a" sha256: dbe745ee459a16b6fec296f7565a8ef430d0d681001d8ae521898b9361854943
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.8.0" version: "2.9.0"
webview_flutter_wkwebview: webview_flutter_wkwebview:
dependency: transitive dependency: transitive
description: description:
name: webview_flutter_wkwebview name: webview_flutter_wkwebview
sha256: accdaaa49a2aca2dc3c3230907988954cdd23fed0a19525d6c9789d380f4dc76 sha256: "02d8f3ebbc842704b2b662377b3ee11c0f8f1bbaa8eab6398262f40049819160"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.9.4" version: "3.10.1"
win32: win32:
dependency: transitive dependency: transitive
description: description:
name: win32 name: win32
sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f" sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.1.0" version: "5.2.0"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:
name: xdg_directories name: xdg_directories
sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
url: "https://pub.dev" url: "https://pub.dev"
source: hosted 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: xterm:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@@ -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 # 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 # 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. # of the product and file versions while build-number is used as the build suffix.
version: 1.0.12+1 version: 1.0.12+4
environment: environment:
sdk: '>=3.1.0 <4.0.0' sdk: '>=3.1.0 <4.0.0'
@@ -39,11 +39,12 @@ dependencies:
retry: ^3.1.2 retry: ^3.1.2
url_launcher: ^6.1.12 url_launcher: ^6.1.12
shared_preferences: ^2.2.1 shared_preferences: ^2.2.1
intl: ^0.18.1 #日期字符串转换 intl: ^0.19.0 #日期字符串转换
unity_ads_plugin: ^0.3.8 unity_ads_plugin: ^0.3.8
clipboard: ^0.1.3 clipboard: ^0.1.3
ffmpeg_kit_flutter_full_gpl: ^6.0.3 ffmpeg_kit_flutter_full_gpl: ^6.0.3
wakelock_plus: ^1.1.4
dynamic_color: ^1.6.9
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
@@ -78,7 +79,6 @@ flutter:
assets: assets:
- assets/ - assets/
- images/icon.png - images/icon.png
- images/alipay.png
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware # https://flutter.dev/assets-and-images/#resolution-aware

View File

@@ -10,6 +10,11 @@ include(${EPHEMERAL_DIR}/generated_config.cmake)
# https://github.com/flutter/flutter/issues/57146. # https://github.com/flutter/flutter/issues/57146.
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") 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 === # === Flutter Library ===
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
@@ -92,7 +97,7 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E env COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT} ${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
windows-x64 $<CONFIG> ${FLUTTER_TARGET_PLATFORM} $<CONFIG>
VERBATIM VERBATIM
) )
add_custom_target(flutter_assemble DEPENDS add_custom_target(flutter_assemble DEPENDS

View File

@@ -6,10 +6,13 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <dynamic_color/dynamic_color_plugin_c_api.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h> #include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
DynamicColorPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
PermissionHandlerWindowsPluginRegisterWithRegistrar( PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
UrlLauncherWindowsRegisterWithRegistrar( UrlLauncherWindowsRegisterWithRegistrar(

View File

@@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
dynamic_color
permission_handler_windows permission_handler_windows
url_launcher_windows url_launcher_windows
) )