-
Notifications
You must be signed in to change notification settings - Fork 1
design #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
plugin update from internetwe use git protocol to do this for its
|
rootless supportshould stick with shizuku and libsu. These two share common functionality (the shell user permission). benefits:
drawbacks:
|
wasm or luashould stick with wasm, benefits:
drawbacks:
|
market / billing / online device limitation
different from ascript: different from lanren:
|
wasm vs native
we choose the native way currently, for more freedom |
GameBotDevToolAttempt to implement dev tool for GameBot, support connect to multiple devices, color/img picker in fetched screenshot, node inspect in fetched node tree, OCR and object detection test. So there must be a server on mobile, and user use a local front end to communicate. Front can be gui or web browser. It must support win, linux and macos. Similar debug tools exist in https://ascript.cn/, https://www.nspirit.cn/, and http://lrappsoft.com/. why not use tauri
why not use flutter
why not use kmp
why not use egui
why not use slint
why not use iced
why not use ribir
why not use relm4
web browser
|
plugin as future or thread or processfutureplugin entry is future, execute by tokio::spawn, so plugin is in same or different threads, and in same process. we force plugin developer to use async rust, but it's not nice, game bot doesn't need much concurrency. the ui part may need async runtime, or not. same as the thread way, we need dynamic loading, and has memory leak possibility. threadplugin entry is block function, execute by thread::spawn or tokio::spawn_blocking, so plugin is in separate thread in same process. to make plugin cancelable(stop/restart by user or plugin it self), for sync api, we need to pass cancel_token and insert check in critical api. for async api, plugin entry can use tokio::select! with cancel_token.
need to compile with ndk, extra environment requirement for plugin development. processplugin run in separate process. we can run command in kotlin or rust or startActivity with different process. but the last way consumes more memory(compose ui activity need 100MB). we don't need dynamic loading. we can easily start and stop process, and restart without memory leak possibility (assume we don't leak memory in our host).
we need more time for ipc, binder or socket or pipe or shared memory? host app may not need jni and rust, all in kotlin seems ok. |
rethink screenshotcurrently we use UiAutomation.takeScreenshot, it works with logical size and dpi change, performance is close to MediaProjection+ImageReader and better than looping screencap.
UIAutomation vs display projection: later is fasteroneplus ace2 14
02:41:11.453 D screenshot time 33ms 33ms
02:41:11.625 D screenshot time 41ms 40ms
02:41:11.814 D screenshot time 46ms 45ms
02:41:11.965 D screenshot time 31ms 30ms
02:41:12.133 D screenshot time 34ms 33ms
02:41:12.310 D screenshot time 31ms 30ms
02:41:12.466 D screenshot time 37ms 36ms
vs
02:42:57.466 E duration 6 direct: 1 size: 14192640
02:42:57.512 E duration 12 direct: 1 size: 14192640
02:42:57.519 E duration 6 direct: 1 size: 14192640
02:42:57.525 E duration 6 direct: 1 size: 14192640
02:42:57.531 E duration 5 direct: 1 size: 14192640
02:42:57.572 E duration 7 direct: 1 size: 14192640
02:42:57.617 E duration 12 direct: 1 size: 14192640
02:42:57.626 E duration 9 direct: 1 size: 14192640
02:42:57.631 E duration 5 direct: 1 size: 14192640
02:42:57.670 E duration 5 direct: 1 size: 14192640
02:42:57.711 E duration 7 direct: 1 size: 14192640
avd 7:
14:33:25.700 D screenshot time 14ms 13ms
14:33:25.776 D screenshot time 13ms 13ms
14:33:25.852 D screenshot time 13ms 13ms
14:33:25.932 D screenshot time 15ms 15ms
14:33:26.010 D screenshot time 15ms 15ms
14:33:26.092 D screenshot time 20ms 20ms
14:33:26.174 D screenshot time 19ms 19ms
vs
14:31:45.304 E duration 9 direct: 1 size: 10368000
14:31:45.345 E duration 8 direct: 1 size: 10368000
14:31:45.387 E duration 9 direct: 1 size: 10368000
14:31:45.396 E duration 9 direct: 1 size: 10368000
14:31:45.411 E duration 15 direct: 1 size: 10368000
14:31:45.455 E duration 10 direct: 1 size: 10368000
14:31:45.496 E duration 7 direct: 1 size: 10368000
14:31:45.504 E duration 8 direct: 1 size: 10368000
14:31:45.545 E duration 8 direct: 1 size: 10368000
14:31:45.584 E duration 6 direct: 1 size: 10368000
14:31:45.626 E duration 9 direct: 1 size: 10368000
genymotion 7:
02:47:28.587 D screenshot time 13ms 13ms
02:47:28.633 D screenshot time 15ms 15ms
02:47:28.678 D screenshot time 16ms 16ms
02:47:28.901 D screenshot time 191ms 191ms
02:47:28.947 D screenshot time 17ms 17ms
02:47:28.994 D screenshot time 17ms 17ms
02:47:29.043 D screenshot time 20ms 20ms
02:47:29.091 D screenshot time 18ms 18ms
02:47:29.143 D screenshot time 19ms 19ms
02:47:29.190 D screenshot time 18ms 17ms
02:47:29.234 D screenshot time 14ms 14ms
02:47:29.279 D screenshot time 16ms 15ms
02:47:29.325 D screenshot time 14ms 14ms
02:47:29.374 D screenshot time 20ms 19ms
vs
02:45:59.789 E duration 15 direct: 1 size: 3686400
02:45:59.801 E duration 12 direct: 1 size: 3686400
02:45:59.829 E duration 8 direct: 1 size: 3686400
02:45:59.843 E duration 8 direct: 1 size: 3686400
02:45:59.884 E duration 9 direct: 1 size: 3686400
02:45:59.913 E duration 10 direct: 1 size: 3686400
02:46:00.145 E duration 22 direct: 1 size: 3686400
02:46:00.160 E duration 15 direct: 1 size: 3686400
02:46:00.176 E duration 16 direct: 1 size: 3686400
02:46:00.187 E duration 11 direct: 1 size: 3686400
02:46:00.197 E duration 10 direct: 1 size: 3686400
02:46:00.205 E duration 8 direct: 1 size: 3686400
02:46:00.225 E duration 6 direct: 1 size: 3686400
02:46:00.241 E duration 6 direct: 1 size: 3686400
02:46:00.277 E duration 8 direct: 1 size: 3686400
leidian 9.0
14:36:59.657 D screenshot time 21ms 20ms
14:36:59.706 D screenshot time 19ms 19ms
14:36:59.753 D screenshot time 20ms 20ms
14:36:59.801 D screenshot time 20ms 19ms
14:36:59.846 D screenshot time 18ms 18ms
14:36:59.892 D screenshot time 18ms 18ms
14:36:59.939 D screenshot time 19ms 19ms
vs
14:37:39.690 E duration 17 direct: 1 size: 5760000
14:37:39.699 E duration 9 direct: 1 size: 5760000
14:37:39.723 E duration 18 direct: 1 size: 5760000
14:37:39.733 E duration 10 direct: 1 size: 5760000
14:37:39.740 E duration 7 direct: 1 size: 5760000
14:37:39.793 E duration 18 direct: 1 size: 5760000
14:37:39.802 E duration 9 direct: 1 size: 5760000
14:37:39.810 E duration 8 direct: 1 size: 5760000
14:37:39.819 E duration 9 direct: 1 size: 5760000 |
2 days for one bugphenomenon: trying the virtualDisplay+ImageReader way, but after fetching new screenshots for several minutes, there is no more. it's even magical that if we allocate bitmap or bytebuffer during fetching, i can only get 1 or 2 screenshots. attempts and thought:
final solution: we are not holding reference to display, so it's can be gc and stops producing new screenshots. but it works for a while! the more we allocating, the faster it getting gc. we should recheck scrcpy's code. it holding ref correctly. we are doing premature optimization! |
Uh oh!
There was an error while loading. Please reload this page.
GameBot is designed to work for years without human operations. GameBot should be self upgradable, because mobile games iterating fast. GameBot relies on AccessibilityService and MediaProjection, and use hidden api via HiddenApiRefinePlugin, and gain permission via Shizuku and libsu
plugin / hot update / hot fix / code push / dynamic loading / scripting
plain DexClassLoader/PathClassLoader
host apk --DexClassLoader/PathClassLoader--> plugin apk/jar/dex
compile andorid library into dex and load via DexClassLoader, the drawback is all dependencies must be bundled into host apk, library can't add new dependencies, and host apk almost can't use r8. library's resource can't be simply load, but kotlin i18n solutions can be used, like lyricist. fat jar solutions may help, like shadow
compile andrlid application into apk and load via PathClassLoader, this is what mediabox does. plugin can use new dependencies, but r8 almost unusable.
Shadow / Tinker
hacky and complicated, may be try BlackShadow
above two solutions violate google play policy:
flutter
shorebird
react native
react-native-code-push
above two solutions is complicated as GameBot need deep integration with android system api, so we need to export java/kotlin function into dart and js. we also need to ship their runtime library. can use rich ui component. flutter doesn't support x86. react native does't support 120fps
js embedded
rhino, used in autojs and it's forks
nodejs, used in autojs
boa
quickjs
deno
python embedded
jython
chaquopy
rustpython, compilable but runtime exception
lua embedded
luajava
mlua
wasm embedded
wasmtime
wasmer
above solutions are simpler and safer, but we need to export java/kotlin function into vm, if using compose instead of view, we need to implement some kind of serializable data structure. we need to transfer image byte into vm efficiently. first three solutions have zero compile time, but need to struggle with dynamic typing. for wasm, we can use rust, but have to drop support for 32 bit platforms.
lib size for x86_64:
simplar projects
kotlin/java: FGA, granblue, RobotHelper
js: hamibot, autojs6, autox, 自动精灵, EasyClick, 冰狐, aibote, 云控, aiwork
lua: 懒人精灵, 节点精灵, 触动精灵, 触摸精灵, 积木编程, 鱼叉助手, 飞天助手, 叉叉助手, autolua
python: ascript, aibote, 小派精灵
VBScript/Q: 按键精灵
rpa: 影刀, UiBot, ...
The text was updated successfully, but these errors were encountered: