170 Commits

Author SHA1 Message Date
b3d853dec3 Shamrock: support original for Image 2024-01-30 00:49:33 +08:00
e0a4aad3cd Shamrock: fix QuickOperation 2024-01-30 00:38:14 +08:00
328e656859 Shamrock: try fix #214 2024-01-30 00:25:32 +08:00
c97f79335a Shamrock: Support /set_group_comment_face 2024-01-28 23:45:05 +08:00
e07e75747a Shamrock: Support big face and bubble face 2024-01-28 23:22:06 +08:00
9482641c38 Shamrock: fix #213 2024-01-28 22:38:54 +08:00
a485e72ddf Shamrock: Adjusting the xposed API for KSP 2024-01-28 15:38:36 +08:00
c7265ba628 Shamrock: Remove outdated dependencies and add new APIs 2024-01-27 21:06:39 +08:00
c39c2a172f Shamrock: Fix #199 2024-01-25 15:13:27 +08:00
64b7b00253 Shamrock: Failed to modify UID and obtain result 0 2024-01-23 00:49:31 +08:00
ec132d224e Shamrock: 为请求事件增加user_uid #150 2024-01-23 00:36:44 +08:00
9c9fbfa753 Merge remote-tracking branch 'origin/master' 2024-01-23 00:26:29 +08:00
4b5932b319 Shamrock: fix #190 2024-01-23 00:26:11 +08:00
0c91028469 Shamrock: fix 9.0.15 crash 2024-01-20 14:56:29 +08:00
48b720bdd7 Merge remote-tracking branch 'origin/master' 2024-01-20 03:03:07 +08:00
2038d81ce8 Shamrock: 调整包拦截策略 2024-01-20 03:02:55 +08:00
81be383b5f revert 2024-01-18 20:05:18 +08:00
0fb88e3e44 give more love to 2024-01-18 16:51:44 +08:00
e92b04ad0f Shamrock: fix build error #201 2024-01-18 09:58:16 +08:00
160d1a11ac Shamrock: #201 2024-01-18 09:49:56 +08:00
b9cfe73eae Shamrock: fix #150 2024-01-17 04:53:07 +08:00
8d6d984849 Shamrock: 尝试修复重复Client连接 #187 2024-01-17 04:15:24 +08:00
25fe9fab37 Shamrock: fix 9.0.8 2024-01-17 03:52:49 +08:00
ba7058a838 add retryCnt 2024-01-14 16:24:37 +08:00
0858395e60 add retryCnt 2024-01-14 15:49:44 +08:00
fdd769d9ff should fix #176 2024-01-10 00:17:53 +08:00
f47ae69653 Merge pull request #193 from MrXiaoM/fix-group-ban
支持全员禁言通知事件
2024-01-07 15:13:43 +08:00
f311ae3797 Merge pull request #194 from MrXiaoM/fix-group-title-change
修复群头衔更改通知报错
2024-01-07 15:13:19 +08:00
5a941f889f add group-title-change notify busiId 2024-01-07 04:39:42 +08:00
69e50c6f93 fix group title change notice on 8.9.80 2024-01-07 04:38:45 +08:00
f7ac3a5d23 whole group ban notice support (go-cqhttp) 2024-01-07 03:52:29 +08:00
b6b54a805e more debug log when error 2024-01-07 03:31:49 +08:00
131f56a468 Shamrock: fix #191 2024-01-06 18:53:42 +08:00
e45e9e7fa0 Merge pull request #189 from super1207/patch-3
fix groupid get
2024-01-05 10:46:32 +08:00
cac0aad1f2 fix groupid get 2024-01-04 19:40:01 +08:00
2c1bd9e726 Shamrock: fix #186 2024-01-04 00:30:36 +08:00
2645e8f451 Merge remote-tracking branch 'origin/master' 2024-01-03 17:45:43 +08:00
e92c227bba Shamrock: 对QQ9支持,并尝试修复#181 2024-01-03 17:45:32 +08:00
a31fe92c0b feat: 获取频道列表接口 (TODO 状态 返回空数组) 2024-01-01 19:01:38 +08:00
70cb876439 Merge remote-tracking branch 'origin/master' 2024-01-01 19:00:48 +08:00
9aa4c37354 fix: WebSocket 部分操作未正常返回数据 (close #182) 2024-01-01 19:00:28 +08:00
d44150ea1a Shamrock: 在获取某些字段错误时,将字段值定义为0 #150 2024-01-01 00:42:47 +08:00
0360c81bee Shamrock: fix #173 2024-01-01 00:40:55 +08:00
cb904c1f1c Shamrock: fix #179 2024-01-01 00:38:44 +08:00
bc754db959 Merge remote-tracking branch 'origin/master' 2024-01-01 00:37:35 +08:00
8df799a6e4 Shamrock: fix #180 2024-01-01 00:37:12 +08:00
71dd9469ca Merge pull request #178 from super1207/patch-2
fix cq code parse
2023-12-27 20:00:49 +09:00
79788d2cdc fix cq code parse 2023-12-26 19:53:00 +08:00
c28c9981c4 Shamrock: 修复QQ收藏异常 2023-12-23 05:13:16 +08:00
8fadd0016a Shamrock: fix #171 #165 2023-12-23 05:06:37 +08:00
77504d68fd Shamrock: 支持获取QQ收藏的列表 /fav/get_item_list 2023-12-23 04:47:11 +08:00
1490450178 Shamrock: 支持获取指定QQ收藏的内容 /fav/get_item_content 2023-12-23 04:16:11 +08:00
88beaf8b6f Shamrock: 支持添加QQ收藏(图片) /fav/add_image_msg 2023-12-22 14:19:56 +08:00
df25b0bc76 Shamrock: 支持添加QQ收藏(文本) /fav/add_rich_media_msg 2023-12-22 03:08:46 +08:00
d07eea7766 Shamrock: Shamrock更新后自动重新启动 2023-12-22 02:26:39 +08:00
5000453002 Shamrock: 完成QQ收藏数据分析 2023-12-21 02:25:20 +08:00
35c82fcc51 Shamrock: fix #169 2023-12-21 00:55:56 +08:00
89a4912ed7 Shamrock: fix #166 2023-12-20 18:58:17 +08:00
aeabc66067 Shamrock: 兼容性正反向HTTP调整 2023-12-20 18:52:24 +08:00
ccbfc9a1e1 Shamrock: fix #159 2023-12-19 22:11:22 +08:00
31936feb98 Merge remote-tracking branch 'origin/master' 2023-12-19 22:10:03 +08:00
538db69754 Shamrock: fix #159 2023-12-19 22:09:23 +08:00
25ea5bd6a8 Merge pull request #162 from callng/master
`Shamrock`: Upgrade build tools
2023-12-19 22:07:32 +08:00
460cd84258 Shamrock: Upgrade build tools 2023-12-19 21:13:28 +08:00
3f9613c43c Shamrock: 输出心跳日志 2023-12-19 21:07:28 +08:00
34eccda233 Shamrock: Määritetty tunnus ei vaadi suuraakkosia 2023-12-19 01:21:08 +08:00
741d2c7a84 Shamrock: fix #117 2023-12-19 01:13:39 +08:00
6ee5ceb321 Shamrock: fix #155 2023-12-18 21:15:56 +08:00
6107ec6ffb Shamrock: fix #156 2023-12-17 11:40:05 +08:00
4ef014a8ac Shamrock: fix card event and kickme operation 2023-12-13 15:09:46 +08:00
135a7c2f56 Shamrock: 优化构建流程 2023-12-13 01:23:40 +08:00
420f11784d Shamrock: fix field error 2023-12-13 00:22:06 +08:00
951e7462c4 Shamrock: add shut_up_timestamp field to get_group_member_list 2023-12-13 00:18:57 +08:00
1b0550b5e1 readme: fix broken link 2023-12-12 17:17:31 +08:00
919c4a7d80 Shamrock: fix #149 again 2023-12-12 11:11:21 +08:00
dcb2b0a26f Shamrock: fix #149 2023-12-12 10:28:24 +08:00
d388e5df0c Shamrock: fix #149 2023-12-11 14:29:07 +08:00
5776524579 Shamrock: 好友请求系统消息 2023-12-10 18:40:33 +08:00
1d0a0731fb Shamrock: 修复群消息撤回事件群号获取错误 2023-12-10 01:57:38 +08:00
4dafa75944 Shamrock: 修复群禁言事件群号获取错误 #148 2023-12-10 01:21:38 +08:00
85cdc86b07 Merge pull request #144 from PisLuanyao/master
`Clover.cpp`: NoxAppPlayer里的鸡脚so
2023-12-10 01:09:21 +08:00
cd19426d1b Clover.cpp: NoxAppPlayer
稍微动了一下,方便看,希望没搞错
2023-12-09 19:14:22 +08:00
48b1b40e1c Clover.cpp: NoxAppPlayer
也许是无效的?
2023-12-09 18:56:00 +08:00
50d469cc45 Clover.cpp: NoxAppPlayer
夜神模拟器里的鸡脚so
2023-12-09 18:41:53 +08:00
37f74d5284 Shamrock: 优化检测逻辑 2023-12-09 16:18:30 +08:00
adb7b12c16 Shamrock: feat 群打卡 2023-12-08 21:52:35 +08:00
27791cc848 Shamrock: fix friend request type typo 2023-12-08 12:54:34 +08:00
bd45523e25 Shamrock: 修正被动WebSocket日志 2023-12-07 23:44:55 +08:00
c0f2242679 Shamrock: 修复防止系统打盹错误 2023-12-07 00:24:06 +08:00
c309a2b3ed Shamrock: fix 部分事件日志错误打印 2023-12-06 16:42:00 +08:00
48c9048a00 Merge branch 'master' of github.com:whitechi73/OpenShamrock 2023-12-06 15:53:11 +08:00
4d2f7a794b Shamrock: 补充群成员信息area、age和level字段 2023-12-06 15:53:01 +08:00
ab6e431872 Merge remote-tracking branch 'origin/master' 2023-12-06 09:44:20 +08:00
9423df2670 Shamrock: 修复回复类型id错误 2023-12-06 09:44:10 +08:00
a2b3e42eee Shamrock: fix #125 2023-12-06 00:52:57 +08:00
d9a045bbf0 Shamrock: 修复构建 2023-12-05 18:26:15 +08:00
42ca17339e Shamrock: 不处理发给自己的消息 2023-12-05 18:24:22 +08:00
003c4d4456 Shamrock: 修复群戳一戳丶群打卡获取的群号错误 2023-12-04 19:42:46 +08:00
ec39aa7bc3 Shamrock: fix #124 2023-12-04 15:07:33 +08:00
4e3870a512 Shamrock: fix #124 2023-12-04 12:58:53 +08:00
97534b01a6 Merge pull request #121 from Miuzarte/patch-1
go-cqhttp like card and nickname field
2023-12-03 12:43:16 +08:00
61bed61bfb go-cqhttp like card and nickname field 2023-12-03 02:15:17 +08:00
a0ff4782db Merge remote-tracking branch 'origin/master' 2023-12-02 23:55:57 +08:00
41dd1de8f8 Shamrock: try fix #120 2023-12-02 23:55:48 +08:00
fa6634d6af Shamrock: fix #111 and add group sign event 2023-12-02 22:59:37 +08:00
6201d12f5f Shamrock: error fix 2023-12-02 18:08:35 +08:00
b2adc5cedf Shamrock: fix #106 2023-12-02 17:54:53 +08:00
0bb871bf01 Shamrock: fix #115 2023-12-02 17:36:34 +08:00
dc969440ee Shamrock: fix #116 2023-12-02 16:21:16 +08:00
b9b6e133d0 Shamrock: fix #117 2023-12-02 16:19:05 +08:00
b5a9884448 Shamrock: fix 群头衔推送 2023-12-02 11:11:22 +08:00
bffb7caf04 Shamrock: A60's PING-PONG 2023-12-02 09:51:39 +08:00
2c3466b4c3 Shamrock: fix 96 crash 2023-12-01 19:30:48 +08:00
007e5fef2f Merge branch 'master' of github.com:whitechi73/OpenShamrock 2023-12-01 15:22:04 +08:00
48773cc47c Shamrock: JSON メッセージのクラッシュと QQ ミュージックのカバーを修正 2023-12-01 15:21:58 +08:00
b2ad4438ab Shamrock: fix #114 2023-12-01 14:47:33 +08:00
2fdcfe332b Shamrock: fix #109 2023-11-30 22:38:44 +08:00
7d8772ebf6 Shamrock: スーパーアンチチェックのオフを許可 2023-11-30 21:36:57 +08:00
2a75160ef8 Merge remote-tracking branch 'origin/master' 2023-11-30 21:33:43 +08:00
76bd58d984 Shamrock: スーパーアンチチェックのオフを許可 2023-11-30 21:33:32 +08:00
39120bdeae Shamrock: fix 群精华消息推送 2023-11-30 19:04:25 +08:00
7b07698f7b Shamrock: fix #110 2023-11-30 12:27:07 +08:00
5c10a5a04e Shamrock: 支持篮球超表情, 新猜拳超表情 2023-11-30 10:28:12 +08:00
3a0dc41329 Shamrock: 支持NTQQ骰子消息(new_dice) 2023-11-29 22:11:36 +08:00
64c800c945 Merge remote-tracking branch 'origin/master' 2023-11-29 10:11:35 +08:00
ecb3cea5a5 Shamrock: fix #105 2023-11-29 10:11:24 +08:00
8e0ae6f85b Shamrock: fix #104 2023-11-28 23:49:21 +08:00
9d893b481d Shamrock: fix group ban user_id error 2023-11-28 17:33:33 +08:00
85aaa54e4e Shamrock: friend poke event detail fix #103 2023-11-28 17:19:08 +08:00
c6dad5677c Shamrock: #103 2023-11-28 17:10:19 +08:00
80a4a208b9 Shamrock: 尝试修复 #98 2023-11-27 12:06:02 +08:00
ae663e6b2e Shamrock: 中二通事 2023-11-27 01:13:40 +08:00
780f3577a5 Shamrock: optimize clover.cpp 2023-11-27 00:42:15 +08:00
3518f974cc Shamrock: bypass emu detection 2023-11-27 00:28:43 +08:00
911b003f7f Shamrock: Modify required fields according to the document 2023-11-27 00:23:02 +08:00
69bc80e9b3 Merge branch 'master' of github.com:whitechi73/OpenShamrock 2023-11-27 00:18:56 +08:00
da0b74db1a Shamrock: fix #92 2023-11-27 00:18:51 +08:00
7212938df3 Shamrock: fix troopowneruin 2023-11-26 22:34:00 +08:00
ae1e78b267 Merge remote-tracking branch 'origin/master' 2023-11-26 22:29:18 +08:00
b7266e490f Shamrock: アンチシミュレータ検出 2023-11-26 22:29:11 +08:00
6b4a429821 Shamrock: fix forward msg nesting(x 2023-11-26 22:06:26 +08:00
4a4507dfcd Shamrock: add switch of anti trace 2023-11-26 19:28:36 +08:00
f63bcabf1b Shamrock: 添加native检测绕过模板 2023-11-26 18:32:55 +08:00
4932b36ee1 Shamrock: fix: グループリクエストイベントの通知と処理ロジックを最適化する 2023-11-26 12:59:48 +08:00
8c307c4f6e Shamrock: fix #90 2023-11-25 20:28:14 +08:00
8d8846fafb Shamrock: 复皆如何推送,遗类也。 2023-11-25 20:05:32 +08:00
544e216ddb Merge remote-tracking branch 'origin/master' 2023-11-25 19:55:09 +08:00
4fedab719b Shamrock: Support télécharger un fichier obtenir un ID de fichier 2023-11-25 19:55:00 +08:00
75a567d5cd Shamrock: fix 重複したグループ参加イベントを削除する 2023-11-25 19:47:35 +08:00
1a814e565a Shamrock: fix #89 2023-11-25 18:50:48 +08:00
5ea260c24b Shamrock: #89 2023-11-25 18:31:08 +08:00
2d57dc021d Merge branch 'master' of github.com:whitechi73/OpenShamrock 2023-11-25 13:51:21 +08:00
dabe2ea886 Shamrock: グループファイルのハッシュ値が増加する 2023-11-25 13:51:16 +08:00
673902e514 Shamrock: fix typo 2023-11-25 13:33:06 +08:00
5062ff7c3a Shamrock: ログスライス #78 2023-11-25 11:53:39 +08:00
0de6f851a6 Merge remote-tracking branch 'origin/master' 2023-11-25 11:29:26 +08:00
c758b1576d Shamrock: アクティブWebSocketハートビートの修復 2023-11-25 11:29:06 +08:00
5ba8bd11e2 Shamrock: essence, card change and title change event 2023-11-25 02:09:16 +08:00
679b7619ce Shamrock: wsハートビート間隔の制御をサポート 2023-11-25 00:42:10 +08:00
282233131a Shamrock: fix 非常に奇妙なフォームデータの問題 2023-11-24 15:18:50 +08:00
edf857bcb6 Shamrock: _send_group_notice 2023-11-24 13:21:22 +08:00
cd1d1e928a Merge branch 'master' of github.com:whitechi73/OpenShamrock 2023-11-24 01:00:59 +08:00
45d6421153 Shamrock: _get_group_notice 2023-11-24 01:00:53 +08:00
8c6f529b4b Merge pull request #76 from DouchChunFeng/master
有个空格
2023-11-24 00:24:57 +08:00
b23620b5ef Shamrock: get_essence_msg_list 2023-11-24 00:21:05 +08:00
e09e00fcd3 有个空格 2023-11-24 00:06:50 +08:00
0d35d5834b Shamrock: 金メダル免除、システムレベルの保活をサポートする 2023-11-23 23:53:11 +08:00
ee8dc75be3 Shamrock: fix: implement request type event 2023-11-23 19:33:50 +08:00
5f91be547e Shamrock: fix group apply flag error 2023-11-23 18:15:20 +08:00
7439622cd6 Shamrock: fix #73 2023-11-23 12:51:26 +08:00
340 changed files with 10162 additions and 3583 deletions

View File

@ -6,7 +6,7 @@ labels: bug
---
警告: 在进一步操作之前,请检查下列选项。如果您忽视此模板或者没有提供关键信息,您的 Issue 将直接被关闭
- 确保您使用的是 [最新开发版本](https://github.com/whitechi73/Shamrock/actions/workflows/build-apk.yml) 的 Shamrock.
- 确保您使用的是 [最新开发版本](https://github.com/whitechi73/OpenShamrock/actions/workflows/build-apk.yml) 的 Shamrock.
- 确保您的问题尚未在 Issues 列表中提出.
- 确保您的问题不是由于您的代码错误导致的.
@ -22,5 +22,6 @@ labels: bug
- Shamrock 版本:
- Android 版本:
- LSPosed 框架版本:
- 设备的制造商和型号:
- 设备的 CPU 架构:

View File

@ -7,7 +7,7 @@ labels: enhancement
警告: 在进一步操作之前,请检查下列选项。如果您忽视此模板或者没有提供关键信息,您的 Issue 将直接被关闭
- 确保您使用的是 [最新开发版本](https://github.com/whitechi73/Shamrock/actions/workflows/build-apk.yml) 的 Shamrock.
- 确保您使用的是 [最新开发版本](https://github.com/whitechi73/OpenShamrock/actions/workflows/build-apk.yml) 的 Shamrock.
- 确保您的功能请求尚未在 Issues 列表中提出.
- 确保您的功能请求是与 Shamrock 相关的,且可以实现.

View File

@ -13,24 +13,38 @@ on:
jobs:
build:
name: Build APK
name: Build Shamrock
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v3
with:
distribution: "temurin"
fetch-depth: 0
- name: Setup JDK 17
uses: actions/setup-java@v4.0.0
with:
java-version: 17
cache: 'gradle'
distribution: "adopt"
- name: Setup cmake
run: |
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "cmake;3.22.1" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
echo "sdk.dir=${ANDROID_HOME}" > local.properties
- name: Cache Gradle Dependencies
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
!~/.gradle/caches/build-cache-*
key: gradle-deps-core-${{ hashFiles('**/build.gradle.kts') }}
restore-keys: gradle-deps
- name: Setup Gradle
uses: gradle/gradle-build-action@v2.9.0
- name: Cache Gradle Build
uses: actions/cache@v3
with:
path: |
~/.gradle/caches/build-cache-*
~/.gradle/buildOutputCleanup/cache.properties
key: gradle-builds-core-${{ github.sha }}
restore-keys: gradle-builds
- name: Build with Gradle
run: |
@ -46,42 +60,41 @@ jobs:
KEY_ALIAS: ${{ secrets.SIGN_ALIAS }}
KEY_PASSWORD: ${{ secrets.SIGN_KEY_PASSWORD }}
- name: Install aapt
run: sudo apt-get update && sudo apt-get install -y aapt
- name: Set Shamrock Version
run: |
apk_file=${{ env.APK_FILE_ALL }}
apk_dump=$(aapt dump badging "$apk_file")
version_name=$(sed -n "s/.*versionName='\([^']*\)'.*/\1/p" <<< "$apk_dump")
echo "SHAMROCK_VERSION=$version_name" >> $GITHUB_ENV
version_name_all=$(basename -s .apk "${{ env.APK_FILE_ALL }}")
version_name_arm64=$(basename -s .apk "${{ env.APK_FILE_ARM64 }}")
version_name_x86_64=$(basename -s .apk "${{ env.APK_FILE_X86_64 }}")
echo "SHAMROCK_VERSION_ALL=$version_name_all" >> $GITHUB_ENV
echo "SHAMROCK_VERSION_ARM64=$version_name_arm64" >> $GITHUB_ENV
echo "SHAMROCK_VERSION_x86_64=$version_name_x86_64" >> $GITHUB_ENV
- name: Show Artifacts SHA256
run: |
echo "### Build Success :rocket:" >> $GITHUB_STEP_SUMMARY
echo "|ABI|SHA256|" >> $GITHUB_STEP_SUMMARY
echo "|:--------:|:----------|" >> $GITHUB_STEP_SUMMARY
all=($(sha256sum ${{ env.APK_FILE_ALL }}))
all=($(sha256sum "${{ env.APK_FILE_ALL }}"))
echo "|all|$all" >> $GITHUB_STEP_SUMMARY
arm64=($(sha256sum ${{ env.APK_FILE_ARM64 }}))
arm64=($(sha256sum "${{ env.APK_FILE_ARM64 }}"))
echo "|arm64|$arm64" >> $GITHUB_STEP_SUMMARY
x86_64=($(sha256sum ${{ env.APK_FILE_X86_64 }}))
x86_64=($(sha256sum "${{ env.APK_FILE_X86_64 }}"))
echo "|x86_64|$x86_64" >> $GITHUB_STEP_SUMMARY
- name: Upload ALL APK RELEASE
uses: actions/upload-artifact@v3
with:
name: Shamrock-v${{ env.SHAMROCK_VERSION }}-all
path: ${{ env.APK_FILE_ALL }}
name: "${{ env.SHAMROCK_VERSION_ALL }}"
path: "${{ env.APK_FILE_ALL }}"
- name: Upload ARM64 APK RELEASE
uses: actions/upload-artifact@v3
with:
name: Shamrock-v${{ env.SHAMROCK_VERSION }}-arm64
path: ${{ env.APK_FILE_ARM64 }}
name: "${{ env.SHAMROCK_VERSION_ARM64 }}"
path: "${{ env.APK_FILE_ARM64 }}"
- name: Upload X86_64 APK RELEASE
uses: actions/upload-artifact@v3
with:
name: Shamrock-v${{ env.SHAMROCK_VERSION }}-x86_64
path: ${{ env.APK_FILE_X86_64 }}
name: "${{ env.SHAMROCK_VERSION_x86_64 }}"
path: "${{ env.APK_FILE_X86_64 }}"

View File

@ -1,57 +0,0 @@
name: "CodeQL"
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
schedule:
- cron: '24 7 * * 4'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
timeout-minutes: 360
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp', 'java' ]
steps:
- name: Checkout repository
uses: actions/checkout@v3.6.0
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
- name: Setup JDK 17
uses: actions/setup-java@v3.12.0
with:
distribution: "temurin"
java-version: 17
- name: Setup Gradle
uses: gradle/gradle-build-action@v2.8.0
- name: Setup cmake
run: |
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "cmake;3.22.1" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
echo "sdk.dir=${ANDROID_HOME}" > local.properties
- name: Build
run: |
chmod +x ./gradlew
./gradlew :app:assembleAppRelease
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

View File

@ -1,73 +0,0 @@
name: Shamrock Release
on:
push:
tags:
- 'v*'
jobs:
build:
name: Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v3
with:
distribution: "temurin"
java-version: 17
cache: 'gradle'
- name: Setup cmake
run: |
echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "cmake;3.22.1" --sdk_root=${ANDROID_SDK_ROOT} &> /dev/null
echo "sdk.dir=${ANDROID_HOME}" > local.properties
- name: Setup Gradle
uses: gradle/gradle-build-action@v2.9.0
- name: Build with Gradle
run: |
echo ${{ secrets.SIGN_KEYSTORE_BASE64 }} | base64 -d > keystore.jks
chmod +x ./gradlew
./gradlew :app:assembleRelease --build-cache --parallel --daemon --warning-mode all --stacktrace
echo "APK_FILE_ALL=$(find app/build/outputs/apk/app/release -name '*.apk')" >> $GITHUB_ENV
echo "APK_FILE_ARM64=$(find app/build/outputs/apk/arm64/release -name '*.apk')" >> $GITHUB_ENV
echo "APK_FILE_X86_64=$(find app/build/outputs/apk/x64/release -name '*.apk')" >> $GITHUB_ENV
env:
KEYSTORE_PATH: "../keystore.jks"
KEYSTORE_PASSWORD: ${{ secrets.SIGN_KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.SIGN_ALIAS }}
KEY_PASSWORD: ${{ secrets.SIGN_KEY_PASSWORD }}
- name: Install aapt
run: sudo apt-get update && sudo apt-get install -y aapt
- name: Set Shamrock Version
run: |
apk_file=${{ env.APK_FILE_ALL }}
apk_dump=$(aapt dump badging "$apk_file")
version_name=$(sed -n "s/.*versionName='\([^']*\)'.*/\1/p" <<< "$apk_dump")
echo "SHAMROCK_VERSION=$version_name" >> $GITHUB_ENV
- name: Show Artifacts SHA256
run: |
echo "### Build Success :rocket:" >> $GITHUB_STEP_SUMMARY
echo "|ABI|SHA256|" >> $GITHUB_STEP_SUMMARY
echo "|:--------:|:----------|" >> $GITHUB_STEP_SUMMARY
all=($(sha256sum ${{ env.APK_FILE_ALL }}))
echo "|all|$all" >> $GITHUB_STEP_SUMMARY
arm64=($(sha256sum ${{ env.APK_FILE_ARM64 }}))
echo "|arm64|$arm64" >> $GITHUB_STEP_SUMMARY
x86_64=($(sha256sum ${{ env.APK_FILE_X86_64 }}))
echo "|x86_64|$x86_64" >> $GITHUB_STEP_SUMMARY
- name: Release
uses: marvinpinto/action-automatic-releases@latest
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
automatic_release_tag: Shamrock v${{ env.SHAMROCK_VERSION }}
files: |
${{ env.APK_FILE_ALL }}
${{ env.APK_FILE_ARM64 }}
${{ env.APK_FILE_X86_64 }}

View File

@ -10,16 +10,17 @@
![][onebot-12]
[![][license]](LICENSE)
[下载][download-link] | [部署][deploy-link] | [接口][api-link] | [文档][docs-link] | [加群][group-link]
[下载][download-link] | [部署][deploy-link] | [接口][api-link] | [文档][docs-link]
</div>
## 简介
☘ 基于 Xposed 实现 OneBot 标准的 QQ 机器人框架,原作者[**fuqiuluo**](https://github.com/fuqiuluo)已脱离开发接下来由白池接手哦本项目为OpenShamrock不会有任何收费行为欢迎大家的加入
☘ 基于 Lsposed(**Non**-Riru) 实现 OneBot 标准的 QQ 机器人框架,原作者[**fuqiuluo**](https://github.com/fuqiuluo)已脱离开发接下来由白池接手哦本项目为OpenShamrock不会有任何收费行为欢迎大家的加入
> 本项目仅提供学习与交流用途请在24小时内删除。
> 本项目目的是研究 Xposed 和 LSPosed 框架的使用。 Epic 框架开发相关知识。
> Riru可能导致封禁请减少使用。
> 如有违反法律,请联系删除。
> 请勿在任何平台宣传,宣扬,转发本项目,请勿恶意修改企业安装包造成相关企业产生损失,如有违背,必将追责到底。
> 官方论坛,[点我直达](https://forum.libfekit.so/)
@ -29,8 +30,6 @@
- 一键移植:本项目基于 go-cqhttp 的文档进行开发实现。
- 平行部署:可多平台部署,未来将会支持 Docker 部署的教程。
> 若您追求小而轻便的Bot服务, [Chronocat](https://chronocat.vercel.app/)是您的不二之选。
## 权限声明
> 如出现未在此处声明的权限,请警惕 Shamrock 是否被修改/植入恶意代码
@ -45,7 +44,7 @@
## 贡献说明
<img src="https://github.com/whitechi73/OpenShamrock/assets/98259561/f04d60bc-ec40-41fc-bc15-62c146f1a1f1" width="160px"> **我可爱吗?欢迎你的到来,这里是一个很大的地方,有着无限可能,主要是有你啦!**
<img src="https://github.com/whitechi73/OpenShamrock/assets/98259561/f04d60bc-ec40-41fc-bc15-62c146f1a1f1" width="160px" alt="Shamrock"> **我可爱吗?欢迎你的到来,这里是一个很大的地方,有着无限可能,主要是有你啦!**
## 开源协议
@ -96,9 +95,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
[docs-link]: https://whitechi73.github.io/OpenShamrock/
[group-link]: https://whitechi73.github.io/OpenShamrock/group.html
[hook-system]: https://github.com/whitechi73/OpenShamrock/wiki/perm_hook_android
[hook-system]: https://github.com/whitechi73/OpenShamrock/blob/master/xposed/src/main/java/moe/fuqiuluo/shamrock/xposed/loader/KeepAlive.kt
[voice-support]: https://whitechi73.github.io/OpenShamrock/advanced/voice.html

1
annotations/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -0,0 +1,9 @@
plugins {
id("java-library")
id("org.jetbrains.kotlin.jvm")
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

View File

@ -0,0 +1,8 @@
package moe.fuqiuluo.symbols
@Retention(AnnotationRetention.SOURCE)
@Target(AnnotationTarget.CLASS)
annotation class OneBotHandler(
val actionName: String,
val alias: Array<String> = []
)

View File

@ -0,0 +1,13 @@
package moe.fuqiuluo.symbols
enum class Process {
ALL,
MAIN,
MSF
}
@Target(AnnotationTarget.CLASS)
annotation class XposedHook(
val process: Process = Process.ALL,
val priority: Int = 10
)

View File

@ -1,35 +1,29 @@
import com.android.build.api.dsl.ApplicationExtension
fun gitCommitHash(): String {
val builder = ProcessBuilder("git", "rev-parse", "--short", "HEAD")
val process = builder.start()
val reader = process.inputReader()
val hash = reader.readText().trim()
return if (hash.isNotEmpty()) ".$hash" else ""
}
import java.io.ByteArrayOutputStream
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
kotlin("plugin.serialization") version "1.8.10"
kotlin("plugin.serialization") version "1.9.21"
}
android {
namespace = "moe.fuqiuluo.shamrock"
ndkVersion = "25.1.8937393"
compileSdk = 33
compileSdk = 34
defaultConfig {
applicationId = "moe.fuqiuluo.shamrock"
minSdk = 24
targetSdk = 33
versionCode = (System.currentTimeMillis() / 1000).toInt()
versionName = "1.0.6-dev" + gitCommitHash()
minSdk = 27
targetSdk = 34
versionCode = getVersionCode()
versionName = "1.0.8" + ".r${getGitCommitCount()}." + getVersionName()
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
@Suppress("UnstableApiUsage")
externalNativeBuild {
cmake {
cppFlags += ""
@ -50,8 +44,7 @@ android {
android.applicationVariants.all {
outputs.map { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl }
.forEach {
val abi = it.outputFileName.split("-")[1].split(".apk")[0]
val abiName = when (abi) {
val abiName = when (val abi = it.outputFileName.split("-")[1].split(".apk")[0]) {
"app" -> "all"
"x64" -> "x86_64"
else -> abi
@ -69,6 +62,7 @@ android {
println("Full architecture and full compilation.")
abiFilters.add("arm64-v8a")
abiFilters.add("x86_64")
abiFilters.add("x86")
}
}
create("arm64") {
@ -98,7 +92,7 @@ android {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.3"
kotlinCompilerExtensionVersion = "1.5.4"
}
packaging {
jniLibs {
@ -133,6 +127,11 @@ android {
}
configureAppSigningConfigsForRelease(project)
packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
}
fun configureAppSigningConfigsForRelease(project: Project) {
@ -154,15 +153,47 @@ fun configureAppSigningConfigsForRelease(project: Project) {
release {
signingConfig = signingConfigs.findByName("release")
}
debug {
signingConfig = signingConfigs.findByName("release")
}
}
}
}
fun getGitCommitCount(): Int {
val out = ByteArrayOutputStream()
exec {
commandLine("git", "rev-list", "--count", "HEAD")
standardOutput = out
}
return out.toString().trim().toInt()
}
fun getGitCommitHash(): String {
val out = ByteArrayOutputStream()
exec {
commandLine("git", "rev-parse", "--short", "HEAD")
standardOutput = out
}
return out.toString().trim()
}
fun getVersionCode(): Int {
return (System.currentTimeMillis() / 1000L).toInt()
}
fun getVersionName(): String {
return getGitCommitHash()
}
dependencies {
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
implementation("androidx.activity:activity-compose:1.7.2")
implementation(platform("androidx.compose:compose-bom:2023.06.01"))
val composeBom = platform("androidx.compose:compose-bom:2023.10.01")
implementation(composeBom)
DEPENDENCY_ANDROIDX.forEach {
implementation(it)
}
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
@ -171,31 +202,26 @@ dependencies {
implementation("com.google.accompanist:accompanist-pager:0.31.5+")
//noinspection GradleDynamicVersion
implementation("com.google.accompanist:accompanist-systemuicontroller:0.31.5+")
//noinspection GradleDynamicVersion useless
// implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0+")
implementation("io.coil-kt:coil:2.4.0")
implementation("io.coil-kt:coil-compose:2.4.0")
implementation("org.jetbrains.kotlinx:kotlinx-io-jvm:0.1.16")
val ktorVersion = "2.3.3"
implementation("io.ktor:ktor-server-core:$ktorVersion")
implementation("io.ktor:ktor-server-host-common:$ktorVersion")
implementation("io.ktor:ktor-server-status-pages:$ktorVersion")
implementation("io.ktor:ktor-server-netty:$ktorVersion")
implementation("io.ktor:ktor-server-content-negotiation:$ktorVersion")
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-cio:$ktorVersion")
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
//implementation("io.ktor:ktor-serialization-kotlinx-protobuf:$ktorVersion")
implementation(kotlinx("io-jvm", "0.1.16"))
implementation(ktor("server", "core"))
implementation(ktor("server", "host-common"))
implementation(ktor("server", "status-pages"))
implementation(ktor("server", "netty"))
implementation(ktor("server", "content-negotiation"))
implementation(ktor("client", "core"))
implementation(ktor("client", "content-negotiation"))
implementation(ktor("client", "cio"))
implementation(ktor("serialization", "kotlinx-json"))
implementation(project(":xposed"))
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.06.01"))
androidTestImplementation(platform("androidx.compose:compose-bom:2023.10.01"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")

View File

@ -3,10 +3,6 @@
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:name=".app.MyApplication"
@ -18,6 +14,7 @@
android:supportsRtl="true"
android:theme="@style/Theme.Shamrock"
android:zygotePreloadName="@string/app_name"
android:multiArch="true"
tools:targetApi="31">
<activity
android:name=".MainActivity"
@ -47,7 +44,7 @@
android:value="基于 Xposed 实现 OneBot 标准的 QQ 机器人框架" />
<meta-data
android:name="xposedminversion"
android:value="23" />
android:value="93" />
<meta-data
android:name="xposedscope"
android:resource="@array/xposed_scope" />

View File

@ -9,52 +9,61 @@ inline void replace_string(std::string& str, const std::string& from, const std:
}
}
inline int utf8_next_len(const std::string& str, size_t offset)
{
uint8_t c = (uint8_t)str[offset];
if (c >= 0xFC)
return 6;
else if (c >= 0xF8)
return 5;
else if (c >= 0xF0)
return 4;
else if (c >= 0xE0)
return 3;
else if (c >= 0xC0)
return 2;
else if (c > 0x00)
return 1;
else
return 0;
}
void decode_cqcode(const std::string& code, std::vector<std::unordered_map<std::string, std::string>>& dest) {
std::string cache;
bool is_start = false;
std::string key_tmp;
std::unordered_map<std::string, std::string> kv;
for(int i = 0; i < code.size(); i++) {
auto c = code[i];
if (c == '[') {
for(size_t i = 0; i < code.size(); i++) {
int utf8_char_len = utf8_next_len(code, i);
if(utf8_char_len == 0) {
continue;
}
std::string_view c(&code[i],utf8_char_len);
if (c == "[") {
if (is_start) {
throw illegal_code();
} else {
if (!cache.empty()) {
std::unordered_map<std::string, std::string> kv;
replace_string(cache, "&#91;", "[");
replace_string(cache, "&#93;", "]");
replace_string(cache, "&amp;", "&");
kv.emplace("_type", "text");
kv.emplace("text", cache);
dest.push_back(kv);
cache.clear();
}
auto c1 = code[i + 1];
if (c1 == 'C') {
i++;
auto c2 = code[i + 1];
if(c2 == 'Q') {
i++;
auto c3 = code[i + 1];
if (c3 == ':') {
i++;
is_start = true;
} else {
cache += c;
cache += c1;
cache += c2;
continue;
}
} else {
cache += c;
cache += c1;
continue;
}
} else {
std::string_view cq_flag(&code[i],4);
if(cq_flag == "[CQ:"){
is_start = true;
i += 3;
}else{
cache += c;
continue;
}
}
}
else if (c == '=') {
else if (c == "=") {
if (is_start) {
if (cache.empty()) {
throw illegal_code();
@ -70,17 +79,17 @@ void decode_cqcode(const std::string& code, std::vector<std::unordered_map<std::
cache += c;
}
}
else if (c == ',') {
else if (c == ",") {
if (is_start) {
if (kv.count("_type") == 0 && !cache.empty()) {
kv.emplace("_type", cache);
cache.clear();
} else {
if (!key_tmp.empty()) {
replace_string(cache, "&amp;", "&");
replace_string(cache, "&#91;", "[");
replace_string(cache, "&#93;", "]");
replace_string(cache, "&#44;", ",");
replace_string(cache, "&amp;", "&");
kv.emplace(key_tmp, cache);
cache.clear();
key_tmp.clear();
@ -90,15 +99,17 @@ void decode_cqcode(const std::string& code, std::vector<std::unordered_map<std::
cache += c;
}
}
else if (c == ']') {
else if (c == "]") {
if (is_start) {
if (!cache.empty()) {
if (!key_tmp.empty()) {
replace_string(cache, "&amp;", "&");
replace_string(cache, "&#91;", "[");
replace_string(cache, "&#93;", "]");
replace_string(cache, "&#44;", ",");
replace_string(cache, "&amp;", "&");
kv.emplace(key_tmp, cache);
} else {
kv.emplace("_type", cache);
}
dest.push_back(kv);
kv.clear();
@ -112,10 +123,14 @@ void decode_cqcode(const std::string& code, std::vector<std::unordered_map<std::
}
else {
cache += c;
i += (utf8_char_len - 1);
}
}
if (!cache.empty()) {
std::unordered_map<std::string, std::string> kv;
replace_string(cache, "&#91;", "[");
replace_string(cache, "&#93;", "]");
replace_string(cache, "&amp;", "&");
kv.emplace("_type", "text");
kv.emplace("text", cache);
dest.push_back(kv);

View File

@ -12,7 +12,7 @@
extern "C"
JNIEXPORT jstring JNICALL
Java_moe_fuqiuluo_shamrock_xposed_actions_PullConfig_testNativeLibrary(JNIEnv *env, jobject thiz) {
Java_moe_fuqiuluo_shamrock_xposed_hooks_PullConfig_testNativeLibrary(JNIEnv *env, jobject thiz) {
return env->NewStringUTF("加载Shamrock库成功~");
}
@ -37,6 +37,26 @@ Java_moe_fuqiuluo_shamrock_utils_MD5_genFileMd5Hex(JNIEnv *env, jobject thiz, js
return env->NewStringUTF(md5Hex.c_str());
}
extern "C"
JNIEXPORT jbyteArray JNICALL
Java_moe_fuqiuluo_shamrock_utils_MD5_genFileMd5(JNIEnv *env, jobject thiz, jstring file_path) {
auto cPathStr = env->GetStringUTFChars(file_path, nullptr);
std::filesystem::path filePath(cPathStr);
if (!std::filesystem::exists(filePath)) {
jclass exClass = env->FindClass("java/io/FileNotFoundException");
env->ThrowNew(exClass, "目标文件不存在");
env->DeleteLocalRef(exClass);
return nullptr;
}
auto file = std::ifstream(filePath.c_str(), std::ios::binary);
MD5 md5;
md5.update(file);
auto md5Bytes = md5.digest();
auto jByteArray = env->NewByteArray(16);
env->SetByteArrayRegion(jByteArray, 0, 16, reinterpret_cast<const jbyte*>(md5Bytes));
return jByteArray;
}
extern "C"
JNIEXPORT jstring JNICALL
Java_moe_fuqiuluo_shamrock_utils_MD5_getMd5Hex(JNIEnv *env, jobject thiz, jbyteArray bytes) {

View File

@ -52,6 +52,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource
@ -84,6 +85,7 @@ import moe.fuqiuluo.shamrock.ui.tools.getShamrockVersion
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
CompositionLocalProvider(
LocalIndication provides NoIndication
@ -120,6 +122,7 @@ private fun AppMainView() {
val coreVersion = remember { mutableStateOf(getShamrockVersion(context)) }
val coreName = remember { mutableStateOf("Xposed") }
val voiceSwitch = remember { mutableStateOf(false) }
@Suppress("LocalVariableName") val LocalString = LocalString.init()
if (!AppRuntime.isInit) {
AppRuntime.state = remember {
@ -140,23 +143,22 @@ private fun AppMainView() {
mutableStateOf("2854200454")
}
it.nick = remember {
mutableStateOf("测试昵称")
mutableStateOf(LocalString.testName)
}
}
AppRuntime.requestCount = remember { mutableIntStateOf(0) }
AppRuntime.isInit = false
AppRuntime.isInit = true
}
val ctx = LocalContext.current
@Suppress("LocalVariableName") val LocalString = LocalString
LaunchedEffect(isFined.value) {
if (isFined.value) {
AppRuntime.log("日志框架激活成功,开放操作许可。")
AppRuntime.log(LocalString.logCentralLoadSuccessfully)
Toast.makeText(ctx, LocalString.frameworkYes, Toast.LENGTH_SHORT).show()
} else {
AppRuntime.log("日志框架处于未激活状态,请检查。")
AppRuntime.log(LocalString.logCentralLoadFailed)
Toast.makeText(ctx, LocalString.frameworkNo, Toast.LENGTH_SHORT).show()
}
}

View File

@ -224,6 +224,16 @@ object ShamrockConfig {
preferences.edit().putBoolean("debug", v).apply()
}
fun isAntiTrace(ctx: Context): Boolean {
val preferences = ctx.getSharedPreferences("config", 0)
return preferences.getBoolean("anti_qq_trace", true)
}
fun setAntiTrace(ctx: Context, v: Boolean) {
val preferences = ctx.getSharedPreferences("config", 0)
preferences.edit().putBoolean("anti_qq_trace", v).apply()
}
fun isInjectPacket(ctx: Context): Boolean {
val preferences = ctx.getSharedPreferences("config", 0)
return preferences.getBoolean("inject_packet", false)
@ -239,6 +249,11 @@ object ShamrockConfig {
return preferences.getBoolean("enable_auto_start", false)
}
fun enableAliveReply(ctx: Context): Boolean {
val preferences = ctx.getSharedPreferences("config", 0)
return preferences.getBoolean("alive_reply", false)
}
fun allowShell(ctx: Context): Boolean {
val preferences = ctx.getSharedPreferences("config", 0)
return preferences.getBoolean("shell", false)
@ -249,6 +264,11 @@ object ShamrockConfig {
preferences.edit().putBoolean("enable_auto_start", v).apply()
}
fun setAliveReply(ctx: Context, v: Boolean) {
val preferences = ctx.getSharedPreferences("config", 0)
preferences.edit().putBoolean("alive_reply", v).apply()
}
fun setShellStatus(ctx: Context, v: Boolean) {
val preferences = ctx.getSharedPreferences("config", 0)
preferences.edit().putBoolean("shell", v).apply()
@ -259,19 +279,19 @@ object ShamrockConfig {
return preferences.getBoolean("enable_self_msg", false)
}
fun enableSyncMsgAsSentMsg(ctx: Context): Boolean {
val preferences = ctx.getSharedPreferences("config", 0)
return preferences.getBoolean("enable_sync_msg_as_sent_msg", false)
}
fun setEnableSelfMsg(ctx: Context, v: Boolean) {
val preferences = ctx.getSharedPreferences("config", 0)
preferences.edit().putBoolean("enable_self_msg", v).apply()
}
fun isEchoNumber(ctx: Context): Boolean {
fun setEnableSyncMsgAsSentMsg(ctx: Context, v: Boolean) {
val preferences = ctx.getSharedPreferences("config", 0)
return preferences.getBoolean("echo_number", false)
}
fun setEchoNumber(ctx: Context, v: Boolean) {
val preferences = ctx.getSharedPreferences("config", 0)
preferences.edit().putBoolean("echo_number", v).apply()
preferences.edit().putBoolean("enable_sync_msg_as_sent_msg", v).apply()
}
fun getConfigMap(ctx: Context): Map<String, Any?> {
@ -293,12 +313,15 @@ object ShamrockConfig {
"ssl_pwd" to preferences.getString("ssl_pwd", ""),
"inject_packet" to preferences.getBoolean("inject_packet", false),
"debug" to preferences.getBoolean("debug", false),
"auto_clear" to preferences.getBoolean("auto_clear", false),
"anti_qq_trace" to preferences.getBoolean("anti_qq_trace", true),
//"auto_clear" to preferences.getBoolean("auto_clear", false),
"ssl_private_pwd" to preferences.getString("ssl_private_pwd", ""),
"key_store" to preferences.getString("key_store", ""),
"enable_self_msg" to preferences.getBoolean("enable_self_msg", false),
"echo_number" to preferences.getBoolean("echo_number", false),
"shell" to preferences.getBoolean("shell", false),
"alive_reply" to preferences.getBoolean("alive_reply", false),
"enable_sync_msg_as_sent_msg" to preferences.getBoolean("enable_sync_msg_as_sent_msg", false),
)
}

View File

@ -50,6 +50,7 @@ import moe.fuqiuluo.shamrock.ui.app.AppRuntime
import moe.fuqiuluo.shamrock.ui.app.Level
import moe.fuqiuluo.shamrock.ui.app.ShamrockConfig
import moe.fuqiuluo.shamrock.ui.theme.GlobalColor
import moe.fuqiuluo.shamrock.ui.theme.LocalString
import moe.fuqiuluo.shamrock.ui.theme.ThemeColor
import moe.fuqiuluo.shamrock.ui.tools.InputDialog
@ -70,7 +71,7 @@ fun DashboardFragment(
AccountCard(nick, uin)
InformationCard(ctx)
APIInfoCard(ctx)
FunctionCard(scope, ctx, "功能设置")
FunctionCard(scope, ctx, LocalString.functionSetting)
SSLCard(ctx)
}
}
@ -80,7 +81,7 @@ private fun SSLCard(ctx: Context) {
ActionBox(
modifier = Modifier.padding(top = 12.dp),
painter = painterResource(id = R.drawable.baseline_security_24),
title = "SSL配置"
title = LocalString.sslSetting
) {
Column {
Divider(
@ -277,9 +278,7 @@ private fun APIInfoCard(
text = authToken,
hint = "请填写鉴权token",
error = "输入的参数不合法",
checker = {
it.length in 0 .. 36
},
checker = { true },
confirm = {
ShamrockConfig.setToken(ctx, authToken.value)
AppRuntime.log("设置鉴权Token为[${authToken.value}]。")

View File

@ -1,6 +1,6 @@
package moe.fuqiuluo.shamrock.ui.fragment
import android.widget.Toast
import android.content.Context
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.absolutePadding
import androidx.compose.foundation.layout.fillMaxSize
@ -22,6 +22,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import moe.fuqiuluo.shamrock.R
import moe.fuqiuluo.shamrock.ui.app.AppRuntime
import moe.fuqiuluo.shamrock.ui.app.Level
import moe.fuqiuluo.shamrock.ui.app.ShamrockConfig
import moe.fuqiuluo.shamrock.ui.theme.GlobalColor
import moe.fuqiuluo.shamrock.ui.theme.LocalString
@ -46,10 +47,11 @@ fun LabFragment() {
}
NoticeTextDialog(
openDialog = showNoticeDialog,
title = "温馨提示",
text = "实验室功能会导致一些奇怪的问题,请谨慎使用!"
title = LocalString.warnTitle,
text = LocalString.labWarning
)
val LocalString = LocalString
ActionBox(
modifier = Modifier.padding(top = 12.dp),
painter = painterResource(id = R.drawable.baseline_preview_24),
@ -63,19 +65,19 @@ fun LabFragment() {
)
Function(
title = "中二病模式",
desc = "也许会导致奇怪的问题,大抵就是你看不懂罢了。",
title = LocalString.b2Mode,
desc = LocalString.b2ModeDesc,
descColor = it,
isSwitch = ShamrockConfig.is2B(ctx)
) {
ShamrockConfig.set2B(ctx, it)
scope.toast(ctx, "重启生效哦!")
scope.toast(ctx, LocalString.restartToast)
return@Function true
}
Function(
title = "显示调试日志",
desc = "会导致日志刷屏。",
title = LocalString.showDebugLog,
desc = LocalString.showDebugLogDesc,
descColor = it,
isSwitch = ShamrockConfig.isDebug(ctx)
) {
@ -90,7 +92,92 @@ fun LabFragment() {
modifier = Modifier.padding(top = 12.dp),
painter = painterResource(id = R.drawable.round_logo_dev_24),
title = "实验功能"
) {
) { color ->
Column {
Divider(
modifier = Modifier,
color = GlobalColor.Divider,
thickness = 0.2.dp
)
/*
Function(
title = "自动清理QQ垃圾",
desc = "也许会导致奇怪的问题(无效)。",
descColor = color,
isSwitch = ShamrockConfig.isAutoClean(ctx)
) {
ShamrockConfig.setAutoClean(ctx, it)
ShamrockConfig.pushUpdate(ctx)
return@Function false
}*/
Function(
title = "自回复测试",
desc = "发送[ping],机器人发送一个具有调试信息的返回。",
descColor = color,
isSwitch = ShamrockConfig.enableAliveReply(ctx)
) {
ShamrockConfig.setAliveReply(ctx, it)
return@Function true
}
Function(
title = "开启Shell接口",
desc = "可能导致设备被入侵,请勿随意开启。",
descColor = color,
isSwitch = ShamrockConfig.allowShell(ctx)
) {
ShamrockConfig.setShellStatus(ctx, it)
return@Function true
}
Function(
title = "自动唤醒QQ",
desc = "QQ进程死亡时重新打开QQ进程前提本进程存活。",
descColor = color,
isSwitch = ShamrockConfig.enableAutoStart(ctx)
) {
ShamrockConfig.setAutoStart(ctx, it)
return@Function true
}
kotlin.runCatching {
ctx.getSharedPreferences("shared_config", Context.MODE_WORLD_READABLE)
}.onSuccess {
Function(
title = LocalString.persistentText,
desc = LocalString.persistentTextDesc,
descColor = color,
isSwitch = it.getBoolean("persistent", false)
) { v ->
it.edit().putBoolean("persistent", v).apply()
scope.toast(ctx, LocalString.restartSysToast)
return@Function true
}
Function(
title = "禁用Doze模式",
desc = "禁止系统进入节能模式。",
descColor = color,
isSwitch = it.getBoolean("hook_doze", false)
) { value ->
it.edit().putBoolean("hook_doze", value).apply()
scope.toast(ctx, LocalString.restartSysToast)
return@Function true
}
}.onFailure {
AppRuntime.log("无法启用附加选项LSPosed模块未激活或者不支持XSharedPreferences", Level.WARN)
}
}
}
ActionBox(
modifier = Modifier.padding(top = 12.dp),
painter = painterResource(id = R.drawable.sharp_lock_24),
title = "安全性设置"
) { color ->
Column {
Divider(
modifier = Modifier,
@ -99,20 +186,9 @@ fun LabFragment() {
)
Function(
title = "自动清理QQ垃圾",
desc = "也许会导致奇怪的问题(无效)。",
descColor = it,
isSwitch = ShamrockConfig.isAutoClean(ctx)
) {
ShamrockConfig.setAutoClean(ctx, it)
ShamrockConfig.pushUpdate(ctx)
return@Function false
}
Function(
title = "拦截QQ无用收包",
desc = "测试阶段,可能导致网络异常或掉线。",
descColor = it,
title = LocalString.injectPacket,
desc = LocalString.injectPacketDesc,
descColor = color,
isSwitch = ShamrockConfig.isInjectPacket(ctx)
) {
ShamrockConfig.setInjectPacket(ctx, it)
@ -121,26 +197,31 @@ fun LabFragment() {
}
Function(
title = "自动唤醒QQ",
desc = "QQ进程死亡时重新打开QQ进程前提本进程存活。",
descColor = it,
isSwitch = ShamrockConfig.enableAutoStart(ctx)
title = LocalString.antiTrace,
desc = LocalString.antiTraceDesc,
descColor = color,
isSwitch = ShamrockConfig.isAntiTrace(ctx)
) {
ShamrockConfig.setAutoStart(ctx, it)
ShamrockConfig.setAntiTrace(ctx, it)
ShamrockConfig.pushUpdate(ctx)
return@Function true
}
Function(
title = "开启Shell接口",
desc = "可能导致设备被入侵,请勿随意开启。",
descColor = it,
isSwitch = ShamrockConfig.allowShell(ctx)
) {
ShamrockConfig.setShellStatus(ctx, it)
return@Function true
kotlin.runCatching {
ctx.getSharedPreferences("shared_config", Context.MODE_WORLD_READABLE)
}.onSuccess {
Function(
title = "反检测加强",
desc = "可能导致某些设备频繁闪退",
descColor = color,
isSwitch = it.getBoolean("super_anti", false)
) { v ->
it.edit().putBoolean("super_anti", v).apply()
scope.toast(ctx, LocalString.restartToast)
return@Function true
}
}
}
}
ActionBox(
@ -161,7 +242,11 @@ fun LabFragment() {
descColor = it,
isSwitch = AppRuntime.state.supportVoice.value
) {
if(AppRuntime.state.supportVoice.value) {
scope.toast(ctx, "关闭请手动删除文件。")
} else {
scope.toast(ctx, "请按照Github提示手动操作。")
}
return@Function false
}
}
@ -190,6 +275,17 @@ fun LabFragment() {
return@Function true
}
Function(
title = "同步消息推送类型异换",
desc = "推送来自同号异设备消息,将同步消息作为自发消息推送。",
descColor = it,
isSwitch = ShamrockConfig.enableSyncMsgAsSentMsg(ctx)
) {
ShamrockConfig.setEnableSyncMsgAsSentMsg(ctx, it)
ShamrockConfig.pushUpdate(ctx)
return@Function true
}
/*
Function(
title = "使用纯数字ECHO",

View File

@ -7,7 +7,7 @@ import android.content.Intent
import android.os.Bundle
import androidx.core.content.ContextCompat.startActivity
import io.ktor.client.request.get
import io.ktor.client.request.header
import io.ktor.client.request.parameter
import io.ktor.client.request.url
import io.ktor.client.statement.bodyAsText
import io.ktor.http.HttpStatusCode
@ -16,9 +16,9 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
import moe.fuqiuluo.shamrock.remote.entries.CommonResult
import moe.fuqiuluo.shamrock.remote.entries.CurrentAccount
import moe.fuqiuluo.shamrock.remote.entries.Status
import moe.fuqiuluo.shamrock.remote.structures.CommonResult
import moe.fuqiuluo.shamrock.remote.structures.CurrentAccount
import moe.fuqiuluo.shamrock.remote.structures.Status
import moe.fuqiuluo.shamrock.tools.GlobalClient
import moe.fuqiuluo.shamrock.ui.app.AppRuntime.AccountInfo
import moe.fuqiuluo.shamrock.ui.app.AppRuntime.log
@ -58,7 +58,8 @@ object DashboardInitializer {
url("http://127.0.0.1:$servicePort/get_account_info")
val token = ShamrockConfig.getToken(context)
if (token.isNotBlank()) {
header("Authorization", "Bearer $token")
//header("Authorization", "Bearer $token")
parameter("access_token", token)
}
}.let {
if (it.status == HttpStatusCode.OK) {

View File

@ -6,7 +6,9 @@ package moe.fuqiuluo.shamrock.ui.theme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import moe.fuqiuluo.shamrock.R
private val LocalStringDefault = Default()
@ -69,6 +71,24 @@ private open class Chūnibyō: Default() {
"执明起,至除免于灾祸。\n" +
"元冥浩浩,非凡不可动之。"
labWarning = "寒酥降矣,梅熟日久,莫不可测。"
logTitle = "无极"
testName = "未名之人"
logCentralLoadSuccessfully = "无极开,天地始纷争。"
logCentralLoadFailed = "无极闭,天地始归宁。"
functionSetting = "天地法则"
sslSetting = "天行御令"
warnTitle = "仙人指路"
b2Mode = "通仙之路"
b2ModeDesc = "凡人勿近"
restartToast = "复关喏哉!"
showDebugLog = "窥探天机"
showDebugLogDesc = "迷失自我,走火入魔"
antiTrace = "鬼影迷踪"
antiTraceDesc = "唐门绝学,已有取死之道"
injectPacket = "遮匿无用之禀"
injectPacketDesc = "试于试之,逆则魂飞魄散"
persistentText = "丹书铁券"
persistentTextDesc = "由天地之起也,须复动之。"
}
}
@ -84,7 +104,25 @@ private open class Default: VarString(
"同时声明本项目仅用于学习与交流请于24小时内删除。\n" +
"同时开源贡献者均享受免责条例。",
labWarning = "实验室功能可能会导致出乎意料的BUG!",
"日志"
logTitle = "日志",
testName = "测试昵称",
logCentralLoadSuccessfully = "日志框架激活成功,开放操作许可。",
logCentralLoadFailed = "日志框架处于未激活状态,请检查。",
functionSetting = "功能设置",
sslSetting = "SSL配置",
warnTitle = "温馨提示",
b2Mode = "中二病模式",
b2ModeDesc = "也许会导致奇怪的问题,大抵就是你看不懂罢了。",
restartToast = "重启生效哦!",
restartSysToast = "重启系统生效哦!",
showDebugLog = "显示调试日志",
showDebugLogDesc = "会导致日志刷屏。",
antiTrace = "防止调用栈检测",
antiTraceDesc = "防止QQ进行堆栈跟踪检测需要重新启动QQ。",
injectPacket = "拦截QQ无用收包",
injectPacketDesc = "测试阶段,可能导致网络异常或掉线。",
persistentText = "免死金牌",
persistentTextDesc = "由系统复活QQ和Shamrock需要重新启动系统。"
)
open class VarString(
@ -99,5 +137,43 @@ open class VarString(
var labWarning: String,
var logTitle: String
)
var logTitle: String,
var testName: String,
var logCentralLoadSuccessfully: String,
var logCentralLoadFailed: String,
var functionSetting: String,
var sslSetting: String,
var warnTitle: String,
var b2Mode: String,
var b2ModeDesc: String,
var restartToast: String,
var restartSysToast: String,
var showDebugLog: String,
var showDebugLogDesc: String,
var antiTrace: String,
var antiTraceDesc: String,
var injectPacket: String,
var injectPacketDesc: String,
var persistentText: String,
var persistentTextDesc: String
) {
private var inited = false
@Composable
fun init(): VarString {
if (inited) return this
inited = true
return this
}
}

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#9D9D9D"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M20,8h-3L17,6.21c0,-2.61 -1.91,-4.94 -4.51,-5.19C9.51,0.74 7,3.08 7,6v2L4,8v14h16L20,8zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM9,8L9,6c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v2L9,8z"/>
</vector>

View File

@ -1,7 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.application") version "8.1.2" apply false
id("org.jetbrains.kotlin.android") version "1.8.10" apply false
id("com.android.library") version "8.1.2" apply false
//id("io.realm.kotlin") version "1.11.0" apply false
}
id("com.android.application") version "8.2.0" apply false
id("org.jetbrains.kotlin.android") version "1.9.20" apply false
id("com.android.library") version "8.2.0" apply false
}

10
buildSrc/build.gradle.kts Normal file
View File

@ -0,0 +1,10 @@
plugins {
kotlin("jvm") version "1.9.21"
}
repositories {
mavenCentral()
}
dependencies {
}

View File

@ -0,0 +1,26 @@
val DEPENDENCY_ANDROIDX = arrayOf(
"androidx.core:core-ktx:1.12.0",
"androidx.appcompat:appcompat:1.6.1",
"com.google.android.material:material:1.11.0",
"androidx.exifinterface:exifinterface:1.3.7",
"androidx.lifecycle:lifecycle-runtime-ktx:2.6.1",
"androidx.activity:activity-compose:1.7.2",
)
const val DEPENDENCY_JSON5K = "io.github.xn32:json5k:0.3.0"
const val DEPENDENCY_PROTOBUF = "com.google.protobuf:protobuf-java:3.24.0"
const val DEPENDENCY_JAVA_WEBSOCKET = "org.java-websocket:Java-WebSocket:1.5.4"
fun room(name: String) = "androidx.room:room-$name:${Versions.roomVersion}"
fun kotlinx(name: String, version: String) = "org.jetbrains.kotlinx:kotlinx-$name:$version"
fun ktor(target: String, name: String): String {
return "io.ktor:ktor-$target-$name:${Versions.ktorVersion}"
}
object Versions {
const val roomVersion = "2.5.0"
const val ktorVersion = "2.3.3"
}

View File

@ -21,4 +21,6 @@ kotlin.code.style=official
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
android.default.buildFeatures.aidl=true
android.default.buildFeatures.aidl=true
kotlin.experimental.tryK2=true
ksp.incremental=false

Binary file not shown.

View File

@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
zipStorePath=wrapper/dists

3
gradlew vendored
View File

@ -83,7 +83,8 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum

1
processor/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -0,0 +1,18 @@
plugins {
kotlin("jvm")
id("com.google.devtools.ksp") version "1.9.21-1.0.15"
}
ksp {
arg("autoserviceKsp.verify", "true")
arg("autoserviceKsp.verbose", "true")
}
dependencies {
implementation(project(":annotations"))
implementation("com.google.auto.service:auto-service-annotations:1.1.1")
implementation("com.google.devtools.ksp:symbol-processing-api:1.9.21-1.0.15")
implementation("com.squareup:kotlinpoet:1.14.2")
ksp("dev.zacsweers.autoservice:auto-service-ksp:1.1.0")
}

View File

21
processor/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View File

@ -0,0 +1,84 @@
@file:OptIn(KspExperimental::class)
@file:Suppress("LocalVariableName", "UNCHECKED_CAST")
package moe.fuqiuluo.ksp.impl
import com.google.devtools.ksp.KspExperimental
import com.google.devtools.ksp.getAnnotationsByType
import com.google.devtools.ksp.getClassDeclarationByName
import com.google.devtools.ksp.processing.CodeGenerator
import com.google.devtools.ksp.processing.Dependencies
import com.google.devtools.ksp.processing.KSPLogger
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.symbol.ClassKind
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSVisitorVoid
import com.google.devtools.ksp.validate
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import moe.fuqiuluo.symbols.OneBotHandler
class OneBotHandlerProcessor(
private val codeGenerator: CodeGenerator,
private val logger: KSPLogger
): SymbolProcessor {
override fun process(resolver: Resolver): List<KSAnnotated> {
val ActionManagerNode = resolver.getClassDeclarationByName("moe.fuqiuluo.shamrock.remote.action.ActionManager")
if (ActionManagerNode == null) {
logger.error("OneBotHandlerProcessor: ActionManager not found")
return emptyList()
}
val symbols = resolver.getSymbolsWithAnnotation(OneBotHandler::class.qualifiedName!!)
val unableToProcess = symbols.filterNot { it.validate() }
val oneBotHandlers = (symbols.filter {
it is KSClassDeclaration && it.validate() && it.classKind == ClassKind.OBJECT
} as Sequence<KSClassDeclaration>).toList()
if (oneBotHandlers.isNotEmpty()) {
ActionManagerNode.accept(ActionManagerVisitor(oneBotHandlers), Unit)
}
return unableToProcess.toList()
}
inner class ActionManagerVisitor(
private val actionHandlers: List<KSClassDeclaration>
): KSVisitorVoid() {
override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {
val packageName = classDeclaration.packageName.asString()
// generate kotlin `init { }`
val fileSpec = FileSpec.builder(packageName, classDeclaration.qualifiedName?.asString() ?: run {
throw IllegalStateException("ActionManagerVisitor: classDeclaration.qualifiedName is null")
}).addFunction(FunSpec.builder("initManager").apply {
actionHandlers.forEach { handler ->
// fetch the params of the annotation
val annotation = handler.getAnnotationsByType(OneBotHandler::class).first()
val actionName = annotation.actionName
val alias = annotation.alias
alias.forEach { name ->
addStatement("actionMap[\"$name\"] = ${handler.simpleName.asString()}")
}
addStatement("actionMap[\"$actionName\"] = ${handler.simpleName.asString()}")
}
}.build()).apply {
addImport("moe.fuqiuluo.shamrock.remote.action.ActionManager", "actionMap")
actionHandlers.forEach {
addImport(it.packageName.asString(), it.simpleName.asString())
}
}.build()
codeGenerator.createNewFile(
dependencies = Dependencies(aggregating = false),
packageName = packageName,
fileName = "Auto" + classDeclaration.simpleName.asString()
).use { outputStream ->
outputStream.writer().use {
fileSpec.writeTo(it)
}
}
}
}
}

View File

@ -0,0 +1,111 @@
@file:Suppress("UNCHECKED_CAST", "LocalVariableName", "PrivatePropertyName")
@file:OptIn(KspExperimental::class)
package moe.fuqiuluo.ksp.impl
import com.google.devtools.ksp.KspExperimental
import com.google.devtools.ksp.getAnnotationsByType
import com.google.devtools.ksp.getClassDeclarationByName
import com.google.devtools.ksp.processing.CodeGenerator
import com.google.devtools.ksp.processing.Dependencies
import com.google.devtools.ksp.processing.KSPLogger
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.symbol.ClassKind
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSVisitorVoid
import com.google.devtools.ksp.validate
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import moe.fuqiuluo.symbols.Process
import moe.fuqiuluo.symbols.XposedHook
class XposedHookProcessor(
private val codeGenerator: CodeGenerator,
private val logger: KSPLogger
): SymbolProcessor {
override fun process(resolver: Resolver): List<KSAnnotated> {
val symbols = resolver.getSymbolsWithAnnotation(XposedHook::class.qualifiedName!!)
val unableToProcess = symbols.filterNot { it.validate() }
val actions = (symbols.filter {
it is KSClassDeclaration && it.validate() && it.classKind == ClassKind.CLASS
} as Sequence<KSClassDeclaration>).toList()
if (actions.isNotEmpty()) {
val firstActions = arrayListOf<KSClassDeclaration>()
val serviceActions = arrayListOf<KSClassDeclaration>()
actions.forEach {
val priority = it.getAnnotationsByType(XposedHook::class).first().priority
if (priority >= 10) {
serviceActions.add(it)
} else {
firstActions.add(it)
}
}
val context = ClassName("android.content", "Context")
val packageName = "moe.fuqiuluo.shamrock.xposed.hooks"
val fileSpec = FileSpec.builder(packageName, "AutoActionLoader").addFunction(FunSpec.builder("runFirstActions")
.addParameter("ctx", context)
.apply {
firstActions.forEach { handler ->
val annotation = handler.getAnnotationsByType(XposedHook::class).first()
val process = annotation.process
val className = handler.simpleName.asString()
if (process == Process.MAIN) {
addStatement("if (PlatformUtils.isMainProcess()) ")
} else if (process == Process.MSF) {
addStatement("if (PlatformUtils.isMsfProcess()) ")
}
addStatement("$className().invoke(ctx)")
}
}.build()
).addFunction(FunSpec.builder("runServiceActions")
.addParameter("ctx", context).apply {
serviceActions.forEach { handler ->
val annotation = handler.getAnnotationsByType(XposedHook::class).first()
val process = annotation.process
val className = handler.simpleName.asString()
if (process == Process.MAIN) {
addStatement("if (PlatformUtils.isMainProcess()) ")
} else if (process == Process.MSF) {
addStatement("if (PlatformUtils.isMsfProcess()) ")
}
addStatement("$className().invoke(ctx)")
}
}.build()
).apply {
firstActions.forEach {
addImport(it.packageName.asString(), it.simpleName.asString())
}
serviceActions.forEach {
addImport(it.packageName.asString(), it.simpleName.asString())
}
addImport("moe.fuqiuluo.shamrock.utils", "PlatformUtils")
}.build()
codeGenerator.createNewFile(
dependencies = Dependencies(aggregating = false),
packageName = packageName,
fileName = "AutoActionLoader"
).use { outputStream ->
outputStream.writer().use {
fileSpec.writeTo(it)
}
}
}
return unableToProcess.toList()
}
inner class ActionLoaderVisitor(
private val firstActions: List<KSClassDeclaration>,
private val serviceActions: List<KSClassDeclaration>,
): KSVisitorVoid() {
override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {
}
}
}

View File

@ -0,0 +1,17 @@
package moe.fuqiuluo.ksp.providers
import com.google.auto.service.AutoService
import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
import com.google.devtools.ksp.processing.SymbolProcessorProvider
import moe.fuqiuluo.ksp.impl.OneBotHandlerProcessor
@AutoService(SymbolProcessorProvider::class)
class OneBotHandlerProcessorProvider: SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
return OneBotHandlerProcessor(
environment.codeGenerator,
environment.logger
)
}
}

View File

@ -0,0 +1,14 @@
package moe.fuqiuluo.ksp.providers
import com.google.auto.service.AutoService
import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
import com.google.devtools.ksp.processing.SymbolProcessorProvider
import moe.fuqiuluo.ksp.impl.XposedHookProcessor
@AutoService(SymbolProcessorProvider::class)
class XposedHookProcessorProvider: SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
return XposedHookProcessor(environment.codeGenerator, environment.logger)
}
}

1
protobuf/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

41
protobuf/build.gradle.kts Normal file
View File

@ -0,0 +1,41 @@
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
kotlin("plugin.serialization") version "1.9.21"
}
android {
namespace = "moe.whitechi73.protobuf"
compileSdk = 34
defaultConfig {
minSdk = 24
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation(DEPENDENCY_PROTOBUF)
implementation(kotlinx("serialization-protobuf", "1.6.2"))
implementation(kotlinx("serialization-json", "1.6.2"))
}

View File

21
protobuf/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View File

@ -0,0 +1,128 @@
@file:OptIn(ExperimentalSerializationApi::class)
@file:Suppress("ArrayInDataClass")
package moe.whitechi73.protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class WeiyunAddRichMediaReq(
@ProtoNumber(1) val commInfo: WeiyunCollectCommInfo? = null,
@ProtoNumber(2) val summary: WeiyunRichMediaSummary? = null,
@ProtoNumber(3) val richMediaContent: List<WeiyunRichMediaContent>? = null,
@ProtoNumber(4) val needShareUrl: Boolean = false,
)
@Serializable
data class WeiyunRichMediaSummary(
@ProtoNumber(1) val title: String? = null,
@ProtoNumber(2) val subTitle: String = "",
@ProtoNumber(3) val brief: String = "",
@ProtoNumber(4) val picList: List<WeiyunPicInfo>? = null,
@ProtoNumber(5) val contentType: UInt = UInt.MIN_VALUE,
@ProtoNumber(6) val originalUri: String = "",
@ProtoNumber(7) val publisher: String = "",
@ProtoNumber(8) val richMediaVersion: UInt = UInt.MIN_VALUE,
)
@Serializable
data class WeiyunRichMediaContent(
@ProtoNumber(1) val richMedia: WeiyunRichMedia? = null,
@ProtoNumber(2) val rawData: ByteArray? = null,
@ProtoNumber(3) val bizDataList: List<ByteArray>? = null,
@ProtoNumber(4) val picList: List<WeiyunPicInfo>? = null,
@ProtoNumber(5) val fileList: List<WeiyunFileInfo>? = null,
)
@Serializable
data class WeiyunFileInfo(
@ProtoNumber(1) val src: UInt = UInt.MIN_VALUE,
@ProtoNumber(2) val uid: ULong = ULong.MIN_VALUE,
@ProtoNumber(3) val bid: UInt = UInt.MIN_VALUE,
@ProtoNumber(4) val fid: String = "",
@ProtoNumber(5) val name: String = "",
@ProtoNumber(6) val size: ULong = ULong.MIN_VALUE,
@ProtoNumber(7) val md5: ByteArray? = null,
@ProtoNumber(8) val sha1: ByteArray? = null,
@ProtoNumber(9) val category: UInt = UInt.MIN_VALUE,
)
@Serializable
data class WeiyunRichMedia(
@ProtoNumber(1) val sections: List<WeiyunSection>? = null
)
@Serializable
data class WeiyunSection(
@ProtoNumber(1) val items: List<WeiyunItem>? = null
)
@Serializable
data class WeiyunItem(
@ProtoNumber(1) val itemType: UInt = UInt.MIN_VALUE,
@ProtoNumber(2) val paragraph: WeiyunParagraph? = null,
@ProtoNumber(3) val anchor: WeiyunAnchor? = null,
@ProtoNumber(4) val picInfo: WeiyunPicInfo? = null,
)
@Serializable
data class WeiyunPicInfo(
@ProtoNumber(1) val uri: String = "",
@ProtoNumber(2) val md5: ByteArray? = null,
@ProtoNumber(3) val sha1: ByteArray? = null,
@ProtoNumber(4) val name: String = "",
@ProtoNumber(5) val note: String = "",
@ProtoNumber(6) val width: UInt = UInt.MIN_VALUE,
@ProtoNumber(7) val height: UInt = UInt.MIN_VALUE,
@ProtoNumber(8) val size: ULong = ULong.MIN_VALUE,
@ProtoNumber(9) val type: UInt = UInt.MIN_VALUE,
@ProtoNumber(10) val owner: WeiyunAuthor? = null,
@ProtoNumber(11) val picId: String = "",
)
@Serializable
data class WeiyunAnchor(
@ProtoNumber(1) val url: String = "",
@ProtoNumber(2) val desc: String = "",
)
@Serializable
data class WeiyunParagraph(
@ProtoNumber(1) val content: String = "",
@ProtoNumber(2) val style: WeiyunStyle? = null,
)
@Serializable
data class WeiyunStyle(
@ProtoNumber(1) val color: String = "#FFFFFF",
@ProtoNumber(2) val fontFamily: String = "",
@ProtoNumber(3) val fontWeight: String = "normal",
@ProtoNumber(4) val fontSize: String = "",
)
@Serializable
data class WeiyunCollectCommInfo(
@ProtoNumber(1) val bid: UInt = UInt.MIN_VALUE,
@ProtoNumber(2) val category: UInt = UInt.MIN_VALUE,
@ProtoNumber(3) val author: WeiyunAuthor? = null,
@ProtoNumber(4) val createTime: ULong = ULong.MIN_VALUE,
@ProtoNumber(5) val seq: ULong = ULong.MIN_VALUE,
@ProtoNumber(6) val bizKey: String = "",
@ProtoNumber(7) val bizDataList: List<ByteArray>? = null,
@ProtoNumber(8) val shareUrl: String = "",
@ProtoNumber(9) val originalAppId: UInt = UInt.MIN_VALUE,
@ProtoNumber(10) val customGroupId: UInt = UInt.MIN_VALUE,
@ProtoNumber(11) val modifyTime: ULong = ULong.MIN_VALUE,
@ProtoNumber(12) val qzoneUgcKey: String = "",
)
@Serializable
data class WeiyunAuthor(
@ProtoNumber(1) val type: UInt = UInt.MIN_VALUE,
@ProtoNumber(2) val numId: ULong = ULong.MIN_VALUE,
@ProtoNumber(3) val strId: String = "",
@ProtoNumber(4) val groupId: ULong = ULong.MIN_VALUE,
@ProtoNumber(5) val groupName: String = "",
)

View File

@ -0,0 +1,13 @@
@file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class WeiyunAddRichMediaResp(
@ProtoNumber(1) val cid: String = "",
@ProtoNumber(2) val collectTime: ULong = ULong.MIN_VALUE,
@ProtoNumber(3) val shareUrl: String = "",
)

View File

@ -0,0 +1,10 @@
package moe.whitechi73.protobuf.fav
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class WeiyunComm(
@ProtoNumber(1) val req: WeiyunCommonReq? = null,
@ProtoNumber(2) val resp: WeiyunCommonResp? = null
)

View File

@ -0,0 +1,15 @@
@file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class WeiyunCommonReq (
@ProtoNumber(2000) val getFavListReq: WeiyunGetFavListReq? = null,
@ProtoNumber(2001) val getFavContentReq: WeiyunGetFavContentReq? = null,
@ProtoNumber(2009) val addRichMediaReq: WeiyunAddRichMediaReq? = null,
@ProtoNumber(2010) val fastUploadResourceReq: WeiyunFastUploadResourceReq? = null,
)

View File

@ -0,0 +1,14 @@
@file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class WeiyunCommonResp(
@ProtoNumber(20000) val getFavListResp: WeiyunGetFavListResp? = null,
@ProtoNumber(20001) val getFavContentResp: WeiyunGetFavContentResp? = null,
@ProtoNumber(20009) val addRichMediaResp: WeiyunAddRichMediaResp? = null,
@ProtoNumber(20010) val fastUploadResourceResp: WeiyunFastUploadResourceResp? = null,
)

View File

@ -0,0 +1,14 @@
@file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class WeiyunFastUploadResourceReq(
@ProtoNumber(1) val picInfoList: List<WeiyunPicInfo>? = null,
@ProtoNumber(2) val fileInfoList: List<WeiyunFileInfo>? = null,
@ProtoNumber(3) val hostFlag: UInt = UInt.MIN_VALUE,
@ProtoNumber(4) val httpsFlag: UInt = UInt.MIN_VALUE,
)

View File

@ -0,0 +1,39 @@
@file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class WeiyunFastUploadResourceResp(
@ProtoNumber(1) val picResultList: List<WeiyunFastUploadPicResult>? = null,
@ProtoNumber(2) val fileResultList: List<WeiyunFastUploadFileResult>? = null,
)
@Serializable
data class WeiyunFastUploadPicResult(
@ProtoNumber(1) val result: UInt = UInt.MIN_VALUE,
@ProtoNumber(2) val picInfo: WeiyunPicInfo? = null,
)
@Serializable
data class WeiyunFastUploadFileResult(
@ProtoNumber(1) val result: UInt = UInt.MIN_VALUE,
@ProtoNumber(2) val picInfo: WeiyunPicInfo? = null,
@ProtoNumber(3) val uploadFileInfo: WeiyunUploadFileInfo? = null,
@ProtoNumber(4) val notRetransmission: UInt = UInt.MIN_VALUE,
@ProtoNumber(5) val failedTips: String = "",
)
@Serializable
data class WeiyunUploadFileInfo(
@ProtoNumber(1) val fileId: String = "",
@ProtoNumber(2) val sha1: ByteArray? = null,
@ProtoNumber(3) val checkKey: ByteArray? = null,
@ProtoNumber(4) val host: String = "",
@ProtoNumber(5) val port: UInt = UInt.MIN_VALUE,
@ProtoNumber(6) val httpsHost: String = "",
@ProtoNumber(7) val httpsPort: UInt = UInt.MIN_VALUE,
)

View File

@ -0,0 +1,11 @@
@file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class WeiyunGetFavContentReq(
@ProtoNumber(1) var cidList: List<String> = emptyList(),
)

View File

@ -0,0 +1,50 @@
@file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class WeiyunGetFavContentResp(
@ProtoNumber(1) val content: List<WeiyunContent>? = null
)
@Serializable
data class WeiyunContent(
@ProtoNumber(1) val text: WeiyunTextContent? = null,
@ProtoNumber(2) val link: WeiyunLinkContent? = null,
@ProtoNumber(3) val galley: WeiyunGalleyContent? = null,
@ProtoNumber(4) val audio: WeiyunAudioContent? = null,
@ProtoNumber(5) val video: WeiyunVideoContent? = null,
@ProtoNumber(6) val file: WeiyunFileContent? = null,
@ProtoNumber(7) val location: WeiyunLocationContent? = null,
@ProtoNumber(8) val richMedia: WeiyunRichMediaContent? = null,
)
@Serializable
data class WeiyunTextContent(
@ProtoNumber(1) val data: String,
@ProtoNumber(2) val hasEmoji: Boolean = false
)
@Serializable
class WeiyunLinkContent
@Serializable
class WeiyunGalleyContent
@Serializable
data class WeiyunAudioContent(
@ProtoNumber(1) val data: ByteArray,
)
@Serializable
class WeiyunVideoContent
@Serializable
class WeiyunFileContent
@Serializable
class WeiyunLocationContent

View File

@ -0,0 +1,19 @@
@file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class WeiyunGetFavListReq(
@ProtoNumber(1) val type: UInt = UInt.MIN_VALUE,
@ProtoNumber(2) val bid: UInt = UInt.MIN_VALUE,
@ProtoNumber(3) val category: UInt = UInt.MIN_VALUE,
@ProtoNumber(4) val startTime: ULong = ULong.MIN_VALUE,
@ProtoNumber(5) val orderType: UInt = UInt.MIN_VALUE,
@ProtoNumber(6) val startPos: UInt = UInt.MIN_VALUE,
@ProtoNumber(7) val pageSize: UInt = UInt.MIN_VALUE,
@ProtoNumber(8) val syncPolicy: UInt = UInt.MIN_VALUE,
@ProtoNumber(9) val reqSource: UInt = UInt.MIN_VALUE,
)

View File

@ -0,0 +1,41 @@
@file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class WeiyunGetFavListResp(
@ProtoNumber(1) val collections: List<WeiyunCollection>? = null,
@ProtoNumber(2) val totalCnt: UInt = UInt.MIN_VALUE,
@ProtoNumber(3) val result: UInt = UInt.MIN_VALUE,
)
@Serializable
data class WeiyunCollection(
@ProtoNumber(1) val cid: String = "",
@ProtoNumber(2) val type: Int = Int.MIN_VALUE,
@ProtoNumber(3) val status: Int = Int.MIN_VALUE,
@ProtoNumber(4) val author: WeiyunAuthor? = null,
@ProtoNumber(5) val bid: UInt = UInt.MIN_VALUE,
@ProtoNumber(6) val srcAppId: UInt = UInt.MIN_VALUE,
@ProtoNumber(7) val srcAppVer: String = "",
@ProtoNumber(8) val category: UInt = UInt.MIN_VALUE,
@ProtoNumber(9) val createTime: ULong = ULong.MIN_VALUE,
@ProtoNumber(10) val collectTime: ULong = ULong.MIN_VALUE,
@ProtoNumber(11) val modifyTime: ULong = ULong.MIN_VALUE,
@ProtoNumber(12) val seq: ULong = ULong.MIN_VALUE,
@ProtoNumber(13) val bizKey: String = "",
@ProtoNumber(14) val bizDataList: List<ByteArray>? = null,
@ProtoNumber(15) val summary: String = "",
@ProtoNumber(16) val starMark: Boolean = false,
@ProtoNumber(17) val starTime: ULong = ULong.MIN_VALUE,
@ProtoNumber(18) val shareUrl: String = "",
@ProtoNumber(19) val originalAppId: UInt = UInt.MIN_VALUE,
@ProtoNumber(20) val customGroupId: UInt = UInt.MIN_VALUE,
@ProtoNumber(21) val securityBeat: UInt = UInt.MIN_VALUE,
@ProtoNumber(22) val qzoneUgcKey: String = "",
)

View File

@ -0,0 +1,30 @@
@file:OptIn(ExperimentalSerializationApi::class)
@file:Suppress("ArrayInDataClass")
package moe.whitechi73.protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class WeiyunMsgHead(
@ProtoNumber(1) val uin: ULong = ULong.MIN_VALUE,
@ProtoNumber(2) val seq: UInt = UInt.MIN_VALUE,
@ProtoNumber(3) val type: UInt = UInt.MIN_VALUE,
@ProtoNumber(4) val cmd: UInt = UInt.MIN_VALUE,
@ProtoNumber(5) val appId: UInt = UInt.MIN_VALUE,
@ProtoNumber(6) val version: UInt = UInt.MIN_VALUE,
@ProtoNumber(7) val netType: UInt = UInt.MIN_VALUE,
@ProtoNumber(8) val clientIp: String? = null,
@ProtoNumber(9) val encrypt: UInt = UInt.MIN_VALUE,
@ProtoNumber(10) val keyType: UInt = UInt.MIN_VALUE,
@ProtoNumber(11) val key: ByteArray? = null,
@ProtoNumber(14) val majorVersion: UInt = UInt.MIN_VALUE,
@ProtoNumber(15) val minorVersion: UInt = UInt.MIN_VALUE,
@ProtoNumber(101) val retCode: UInt = UInt.MIN_VALUE,
@ProtoNumber(102) val retMsg: String? = null,
@ProtoNumber(103) val promptMsg: String? = null,
@ProtoNumber(111) val totalSpace: ULong = ULong.MIN_VALUE,
@ProtoNumber(112) val usedSpace: ULong = ULong.MIN_VALUE,
)

View File

@ -0,0 +1,20 @@
package moe.whitechi73.protobuf.group_file_common
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class FolderInfo(
@SerialName("folder_id") @ProtoNumber(1) val folderId: String = "",
@SerialName("parent_folder_id") @ProtoNumber(2) val parentFolderId: String = "",
@SerialName("folder_name") @ProtoNumber(3) val folderName: String = "",
@SerialName("create_time") @ProtoNumber(4) val createTime: UInt = UInt.MIN_VALUE,
@SerialName("modify_time") @ProtoNumber(5) val modifyTime: UInt = UInt.MIN_VALUE,
@SerialName("creator_uin") @ProtoNumber(6) val createUin: ULong = ULong.MIN_VALUE,
@SerialName("creator_name") @ProtoNumber(7) val creatorName: String? = null,
@SerialName("total_file_cnt") @ProtoNumber(8) val totalFileCnt: UInt = UInt.MIN_VALUE,
@SerialName("modifier_uin") @ProtoNumber(9) val modifyUin: ULong? = null,
@SerialName("modifier_name") @ProtoNumber(10) val modifierName: String? = null,
@SerialName("used_space") @ProtoNumber(11) val usedSpace: ULong = ULong.MIN_VALUE,
)

View File

@ -0,0 +1,57 @@
@file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.message
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class MessageBody(
@ProtoNumber(1) val msgHead: MessageHead? = null,
@ProtoNumber(2) val contentHead: MessageContentHead? = null,
@ProtoNumber(3) val richMsg: RichMessage? = null,
)
@Serializable
data class RichMessage(
@ProtoNumber(1) val elements: MessageElementList? = null,
@ProtoNumber(2) val rawBuffer: ByteArray? = null,
)
@Serializable
data class MessageElementList(
@ProtoNumber(2) val elements: List<MessageElement>? = null
)
@Serializable
data class MessageElement(
@ProtoNumber(51) val json: JsonElement? = null,
)
@Serializable
data class JsonElement(
@ProtoNumber(1) val data: ByteArray? = null,
)
@Serializable
data class MessageHead(
@ProtoNumber(1) val peer: Long = Long.MIN_VALUE,
@ProtoNumber(2) val peerUid: String? = null,
@ProtoNumber(3) val flag: Int = Int.MIN_VALUE,
@ProtoNumber(5) val receiver: Long? = null,
@ProtoNumber(6) val receiverUid: String? = null,
)
@Serializable
data class MessageContentHead(
@ProtoNumber(1) val msgType: Int = Int.MIN_VALUE,
@ProtoNumber(2) val msgSubType: Int = Int.MIN_VALUE,
@ProtoNumber(4) val u1: Long = Long.MIN_VALUE,
@ProtoNumber(5) val msgSeq: Long = Long.MIN_VALUE,
@ProtoNumber(6) val msgTime: Long? = null,
@ProtoNumber(7) val u2: Int? = null,
@ProtoNumber(11) val u3: Long? = null,
@ProtoNumber(12) val msgRandom: Long = Long.MIN_VALUE,
@ProtoNumber(14) val u4: Long? = null,
@ProtoNumber(28) val u5: Long? = null,
)

View File

@ -0,0 +1,14 @@
@file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.oidb
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class TrpcOidb(
@ProtoNumber(1) val cmd: Int = Int.MIN_VALUE,
@ProtoNumber(2) val service: Int = Int.MIN_VALUE,
@ProtoNumber(4) val buffer: ByteArray,
@ProtoNumber(12) val flag: Int = Int.MIN_VALUE,
)

View File

@ -0,0 +1,87 @@
@file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.oidb.cmd0x6d7
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
import moe.whitechi73.protobuf.group_file_common.FolderInfo
@Serializable
data class Oidb0x6d7ReqBody(
@ProtoNumber(1) val createFolder: CreateFolderReq? = null,
@ProtoNumber(2) val deleteFolder: DeleteFolderReq? = null,
@ProtoNumber(3) val moveFolder: MoveFolderReq? = null,
@ProtoNumber(4) val renameFolder: RenameFolderReq? = null,
)
@Serializable
data class CreateFolderReq(
@ProtoNumber(1) val groupCode: ULong = ULong.MIN_VALUE,
@ProtoNumber(2) val appId: UInt = UInt.MIN_VALUE,
@ProtoNumber(3) val parentFolderId: String = "",
@ProtoNumber(4) val folderName: String = "",
)
@Serializable
data class DeleteFolderReq(
@ProtoNumber(1) val groupCode: ULong = ULong.MIN_VALUE,
@ProtoNumber(2) val appId: UInt = UInt.MIN_VALUE,
@ProtoNumber(3) val folderId: String = "",
)
@Serializable
data class MoveFolderReq(
@ProtoNumber(1) val groupCode: ULong = ULong.MIN_VALUE,
@ProtoNumber(2) val appId: UInt = UInt.MIN_VALUE,
@ProtoNumber(3) val folderId: String = "",
@ProtoNumber(4) val parentFolderId: String = "",
@ProtoNumber(5) val destFolderId: String = "",
)
@Serializable
data class RenameFolderReq(
@ProtoNumber(1) val groupCode: ULong = ULong.MIN_VALUE,
@ProtoNumber(2) val appId: UInt = UInt.MIN_VALUE,
@ProtoNumber(3) val folderId: String = "",
@ProtoNumber(4) val folderName: String = "",
)
@Serializable
data class Oidb0x6d7RespBody(
@ProtoNumber(1) val createFolder: CreateFolderResp? = null,
@ProtoNumber(2) val deleteFolder: DeleteFolderResp? = null,
@ProtoNumber(3) val moveFolder: MoveFolderResp? = null,
@ProtoNumber(4) val renameFolder: RenameFolderResp? = null,
)
@Serializable
data class CreateFolderResp(
@ProtoNumber(1) val retCode: Int = Int.MIN_VALUE,
@ProtoNumber(2) val retMsg: String = "",
@ProtoNumber(3) val clientWording: String = "",
@ProtoNumber(4) val folderInfo: FolderInfo? = null,
)
@Serializable
data class DeleteFolderResp(
@ProtoNumber(1) val retCode: Int = Int.MIN_VALUE,
@ProtoNumber(2) val retMsg: String = "",
@ProtoNumber(3) val clientWording: String = "",
)
@Serializable
data class MoveFolderResp(
@ProtoNumber(1) val retCode: Int = Int.MIN_VALUE,
@ProtoNumber(2) val retMsg: String = "",
@ProtoNumber(3) val clientWording: String = "",
@ProtoNumber(4) val folderInfo: FolderInfo? = null,
)
@Serializable
data class RenameFolderResp(
@ProtoNumber(1) val retCode: Int = Int.MIN_VALUE,
@ProtoNumber(2) val retMsg: String = "",
@ProtoNumber(3) val clientWording: String = "",
@ProtoNumber(4) val folderInfo: FolderInfo? = null,
)

View File

@ -0,0 +1,14 @@
package moe.whitechi73.protobuf.oidb.cmd0x9082
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class Oidb0x9082(
@ProtoNumber(2) val peer: ULong = ULong.MIN_VALUE,
@ProtoNumber(3) val msgSeq: ULong = ULong.MIN_VALUE,
@ProtoNumber(4) val faceIndex: String = "",
@ProtoNumber(5) val flag: UInt = UInt.MIN_VALUE,
@ProtoNumber(6) val u1: UInt = UInt.MIN_VALUE,
@ProtoNumber(7) val u2: UInt = UInt.MIN_VALUE,
)

View File

@ -0,0 +1,16 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class C2CCommonTipsEvent(
@ProtoNumber(7) val params: List<PokeParam>? = null,
@ProtoNumber(8) val xmlTips: String? = null,
)
@Serializable
data class PokeParam(
@ProtoNumber(1) val key: String = "",
@ProtoNumber(2) val value: String = "",
)

View File

@ -0,0 +1,21 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class C2CRecallEvent(
@ProtoNumber(1) val head: C2CRecallHead? = null,
)
@Serializable
data class C2CRecallHead(
@ProtoNumber(1) val operator: String? = null,
@ProtoNumber(13) val wording: RecallWording? = null,
@ProtoNumber(20) val msgSeq: Long = Long.MIN_VALUE,
)
@Serializable
data class RecallWording(
@ProtoNumber(2) val wording: String? = null
)

View File

@ -0,0 +1,6 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
// by GroupCommonTipsEvent

View File

@ -0,0 +1,19 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class FriendApplyEvent(
@ProtoNumber(1) val head: FriendApplyHead? = null,
)
@Serializable
data class FriendApplyHead(
@ProtoNumber(2) val applierUid: String = "",
@ProtoNumber(7) val srcId: Int = Int.MIN_VALUE,
@ProtoNumber(8) val subSrc: Int = Int.MIN_VALUE,
@ProtoNumber(10) val applyMsg: String? = null,
@ProtoNumber(11) val source: String? = null,
)

View File

@ -0,0 +1,11 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class GroupAdminChangeEvent(
@ProtoNumber(1) val groupCode: Long,
@ProtoNumber(4) val operation: GroupAdminChangedOperation? = null
)

View File

@ -0,0 +1,16 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class GroupAdminChangedOperation(
@ProtoNumber(1) val unsetInfo: GroupAdminSetInfo? = null,
@ProtoNumber(2) val setInfo: GroupAdminSetInfo? = null,
)
@Serializable
data class GroupAdminSetInfo(
@ProtoNumber(1) val targetUid: String? = null,
@ProtoNumber(2) val operation: Int? = null,
)

View File

@ -0,0 +1,11 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class GroupApplyEvent(
@ProtoNumber(1) val groupCode: Long = Long.MIN_VALUE,
@ProtoNumber(3) val applierUid: String = "",
@ProtoNumber(5) val applyMsg: String? = null,
)

View File

@ -0,0 +1,22 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class GroupBanEvent(
@ProtoNumber(1) val groupCode: ULong = ULong.MIN_VALUE,
@ProtoNumber(4) val operatorUid: String = "",
@ProtoNumber(5) val target: GroupBanTarget? = null,
)
@Serializable
data class GroupBanTarget(
@ProtoNumber(3) val target: GroupBanInfo? = null,
)
@Serializable
data class GroupBanInfo(
@ProtoNumber(1) val targetUid: String? = null,
@ProtoNumber(2) val rawDuration: UInt = UInt.MIN_VALUE,
)

View File

@ -0,0 +1,27 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class GroupCommonTipsEvent(
@ProtoNumber(4) val groupCode: ULong = ULong.MIN_VALUE,
@ProtoNumber(5) val uniqueTitleChangeDetail: List<GroupUniqueTitleChangeDetail>? = null,
@ProtoNumber(11) val recallDetails: GroupRecallDetails? = null,
@ProtoNumber(26) val baseTips: List<GroupBaseTips>? = null,
@ProtoNumber(33) val essenceMsgInfo: List<EssenceMsgInfo>? = null,
@ProtoNumber(37) val msgSeq: ULong = ULong.MIN_VALUE,
)
@Serializable
data class EssenceMsgInfo(
@ProtoNumber(4) val type: UInt = UInt.MIN_VALUE,
@ProtoNumber(5) val sender: ULong = ULong.MIN_VALUE,
@ProtoNumber(6) val operator: ULong = ULong.MIN_VALUE,
)
@Serializable
data class GroupBaseTips(
@ProtoNumber(2) val type: UInt = UInt.MIN_VALUE,
@ProtoNumber(7) val params: List<PokeParam>? = null
)

View File

@ -0,0 +1,10 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class GroupInviteEvent(
@ProtoNumber(1) val groupCode: Long,
@ProtoNumber(5) val inviterUid: String,
)

View File

@ -0,0 +1,16 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class GroupInvitedApplyEvent(
@ProtoNumber(2) val applyInfo: GroupInvitedApplyInfo? = null,
)
@Serializable
data class GroupInvitedApplyInfo(
@ProtoNumber(1) val type: Int = Int.MIN_VALUE,
@ProtoNumber(3) val groupCode: Long = Long.MIN_VALUE,
@ProtoNumber(5) val applierUid: String = "",
)

View File

@ -0,0 +1,12 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class GroupListChangeEvent(
@ProtoNumber(1) val groupCode: Long = Long.MIN_VALUE,
@ProtoNumber(3) val memberUid: String = "",
@ProtoNumber(4) val type: Int = Int.MIN_VALUE,
@ProtoNumber(5) val operatorUid: String = "",
)

View File

@ -0,0 +1,18 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class GroupRecallDetails(
@ProtoNumber(1) val operatorUid: String = "",
@ProtoNumber(3) val msgInfo: RecalledMessageInfo? = null,
@ProtoNumber(9) val wording: RecallWording? = null
)
@Serializable
data class RecalledMessageInfo(
@ProtoNumber(1) val msgSeq: ULong,
@ProtoNumber(2) val msgTime: ULong,
@ProtoNumber(6) val senderUid: String,
)

View File

@ -0,0 +1,10 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class GroupUniqueTitleChangeDetail(
@ProtoNumber(2) val wording: String = "",
@ProtoNumber(5) val targetUin: ULong = ULong.MIN_VALUE,
)

View File

@ -0,0 +1,26 @@
package moe.whitechi73.protobuf.push
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
import moe.whitechi73.protobuf.message.MessageBody
@Serializable
data class MessagePush(
@ProtoNumber(1) val msgBody: MessageBody? = null,
@ProtoNumber(4) val clientInfo: MessagePushClientInfo? = null,
)
@Serializable
data class MessagePushClientInfo(
@ProtoNumber(1) val clientIp: String? = null,
@ProtoNumber(3) val liteHead: MessagePushLiteHead? = null
)
@Serializable
data class MessagePushLiteHead(
@ProtoNumber(2) val msgType: Int = Int.MIN_VALUE,
@ProtoNumber(3) val msgSeq: ULong = ULong.MIN_VALUE,
@ProtoNumber(4) val msgRandom: ULong = ULong.MIN_VALUE,
@ProtoNumber(6) val msgSubType: Int = Int.MIN_VALUE,
@ProtoNumber(8) val sender: ULong = ULong.MIN_VALUE,
)

View File

@ -5,10 +5,10 @@ plugins {
android {
namespace = "moe.fuqiuluo.qqinterface"
compileSdk = 33
compileSdk = 34
defaultConfig {
minSdk = 24
minSdk = 27
consumerProguardFiles("consumer-rules.pro")
}
@ -32,7 +32,7 @@ android {
}
dependencies {
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.9.0")
DEPENDENCY_ANDROIDX.forEach {
implementation(it)
}
}

View File

@ -0,0 +1,10 @@
package KQQ;
import com.qq.jce.JceStruct;
public final class BatchResponse extends JceStruct {
public byte[] buffer;
public int result;
public int seq;
public int type;
}

View File

@ -0,0 +1,9 @@
package KQQ;
import com.qq.jce.JceStruct;
import java.util.ArrayList;
public final class RespBatchProcess extends JceStruct {
public ArrayList<BatchResponse> batch_response_list;
}

View File

@ -33,7 +33,7 @@ public class MMKV implements SharedPreferences, SharedPreferences.Editor {
return null;
}
public SharedPreferences.Editor putBoolean(String str, boolean z) {
public SharedPreferences.Editor putBoolean(String s, boolean z) {
return this;
}

View File

@ -19,4 +19,11 @@ public class QQSysFaceUtil {
public static String getFaceDescription(int localId) {
return "";
}
public static String getPrueFaceDescription(String str) {
if (str == null) {
return null;
}
return str.startsWith("/") ? str.substring(1) : str;
}
}

View File

@ -0,0 +1,7 @@
package com.tencent.mobileqq.filemanager.api;
import com.tencent.mobileqq.qroute.QRouteApi;
public interface IFileManagerUtil extends QRouteApi {
byte[] getSHA(String str);
}

View File

@ -21,6 +21,10 @@ public abstract class PBField<T> {
return new PBBytesField(byteStringMicro, false);
}
public static PBFloatField initFloat(float paramFloat) {
return new PBFloatField(paramFloat, false);
}
public static PBBoolField initBool(boolean z) {
return new PBBoolField(z, false);
}

View File

@ -0,0 +1,13 @@
package com.tencent.mobileqq.pb;
public class PBFloatField extends PBPrimitiveField<Float> {
public PBFloatField(float i2, boolean z) {
}
public int get() {
return 0;
}
public void set(int i2) {
}
}

View File

@ -1,6 +1,8 @@
package com.tencent.mobileqq.pb;
public class PBStringField extends PBPrimitiveField<String>{
public static PBStringField __repeatHelper__;
public PBStringField(String str, boolean z) {
}

View File

@ -0,0 +1,32 @@
package com.tencent.mobileqq.pskey.oidb.cmd0x102a;
import com.tencent.mobileqq.pb.MessageMicro;
import com.tencent.mobileqq.pb.PBField;
import com.tencent.mobileqq.pb.PBInt64Field;
import com.tencent.mobileqq.pb.PBRepeatField;
import com.tencent.mobileqq.pb.PBRepeatMessageField;
import com.tencent.mobileqq.pb.PBStringField;
import com.tencent.mobileqq.pb.PBUInt32Field;
public class oidb_cmd0x102a {
public static class GetPSkeyRequest extends MessageMicro<GetPSkeyRequest> {
static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[]{10, 16}, new String[]{"domains", "flag"}, new Object[]{"", 0}, GetPSkeyRequest.class);
public final PBRepeatField<String> domains = PBField.initRepeat(PBStringField.__repeatHelper__);
public final PBUInt32Field flag = PBField.initUInt32(0);
}
public static class GetPSkeyResponse extends MessageMicro<GetPSkeyResponse> {
static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[]{10}, new String[]{"private_keys"}, new Object[]{null}, GetPSkeyResponse.class);
public final PBRepeatMessageField<PSKey> private_keys = PBField.initRepeatMessage(PSKey.class);
}
public static class PSKey extends MessageMicro<PSKey> {
static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[]{10, 18, 24, 34, 40}, new String[]{"domain", "key", "key_expire", "uskey", "uskey_expire"}, new Object[]{"", "", 0L, "", 0L}, PSKey.class);
public final PBStringField domain = PBField.initString("");
public final PBStringField key = PBField.initString("");
public final PBInt64Field key_expire = PBField.initInt64(0);
public final PBStringField uskey = PBField.initString("");
public final PBInt64Field uskey_expire = PBField.initInt64(0);
}
}

View File

@ -154,7 +154,7 @@ public interface IAddFriendTempApi extends QRouteApi {
// void sendDelSingleSystemMsg(structmsg.StructMsg paramStructMsg, String paramString, int paramInt, long paramLong, AppInterface paramAppInterface);
void sendFriendSystemMsgAction(int msg_type, long msg_seq, long req_uin, int sub_type, int src_id, int sub_src_id, int group_msg_type, structmsg$SystemMsgActionInfo action_info, int system_msg_action_type, structmsg$StructMsg paramStructMsg, boolean isUncommonlyUsedFrd, AppInterface paramAppInterface);
void sendFriendSystemMsgAction(int msg_type, long msg_seq, long req_uin, int sub_type, int src_id, int sub_src_id, int group_msg_type, structmsg.SystemMsgActionInfo action_info, int system_msg_action_type, structmsg.StructMsg paramStructMsg, boolean isUncommonlyUsedFrd, AppInterface paramAppInterface);
void sendFriendSystemMsgReadedReport(AppInterface paramAppInterface);

View File

@ -0,0 +1,51 @@
package com.tencent.mobileqq.transfile;
public class HttpNetReq extends NetReq {
public static final int HTTP_GET = 0;
public static final int HTTP_POST = 1;
public IFlowDecoder decoder;
public DnsParseCallback mDnsParseCallback;
public boolean mHaveIpConnect;
public String mHostForHttpsVerify;
public int mHttpMethod;
public boolean mIsHostIP;
public boolean mIsHttps;
public boolean mIsPreStructPic;
public boolean mIsSync;
public boolean mNeedIpConnect;
public boolean mNeedNotReferer;
public boolean mNeedRedirectCallback;
public String mReqUrl;
public TimeoutParam mTimeoutParam;
public boolean mUseCmwapConnectionTypeFromDpc;
public String[] mWhiteListContentType;
public interface DecoderState {
public static final int STATE_END = 2;
public static final int STATE_INIT = 0;
public static final int STATE_RUNNING = 1;
}
public interface DnsParseCallback {
void end();
void start();
}
public interface IFlowDecoder {
byte[] decode(byte[] bArr);
boolean isFinish();
void reset();
}
public HttpNetReq() {
this.mHttpMethod = 0;
this.mNeedIpConnect = false;
this.mHaveIpConnect = false;
this.mNeedRedirectCallback = false;
this.mUseCmwapConnectionTypeFromDpc = false;
this.mNeedNotReferer = false;
}
}

View File

@ -0,0 +1,7 @@
package com.tencent.mobileqq.transfile;
public interface INetEngineListener {
void onResp(NetResp netResp);
void onUpdateProgeress(NetReq netReq, long j2, long j3);
}

View File

@ -0,0 +1,5 @@
package com.tencent.mobileqq.transfile;
public interface NetFailedListener {
void onFailed(NetResp netResp);
}

View File

@ -0,0 +1,89 @@
package com.tencent.mobileqq.transfile;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
public class NetReq {
public static final int PRIOTY_HIGH = 0;
public static final int PRIOTY_LOW = 2;
public static final int PRIOTY_NORMAL = 1;
public boolean bAcceptNegativeContentLength;
public int mBusiProtoType;
public INetEngineListener mCallback;
public boolean mCanPrintUrl;
public int mContinuErrorLimit;
public int mContinueConnReusedErrorLimit;
public long mDelayTime;
public long mEndDownOffset;
public long mExcuteTimeLimit;
public NetFailedListener mFailedListener;
public int mFileType;
public HostParseToIp mHostParseToIp;
public boolean mIsNetChgAsError;
public boolean mIsRenameInEngine;
public String mKey;
public String mMsgId;
public String mOutPath;
public OutputStream mOutStream;
public int mPrioty;
public Object mPrivate;
public HashMap<String, String> mReqProperties;
public NetResp mResp;
public byte[] mSendData;
public List<ServerAddr> mServerList;
public long mStartDownOffset;
public boolean mSupportBreakResume;
public String mTempPath;
public boolean mUseByteArrayPool;
public boolean mUseRaf;
private Object mUserData;
public long taskStartTime;
public interface HostParseToIp {
List<ServerAddr> getIpByHost(String str);
}
public NetReq() {
this.mStartDownOffset = 0L;
this.mEndDownOffset = 0L;
this.mIsRenameInEngine = true;
this.mDelayTime = 0L;
this.mExcuteTimeLimit = 480000L;
this.mContinuErrorLimit = 8;
this.mContinueConnReusedErrorLimit = 5;
this.mIsNetChgAsError = false;
this.mPrioty = 1;
this.mResp = null;
this.mCanPrintUrl = true;
this.bAcceptNegativeContentLength = true;
this.mUseByteArrayPool = false;
this.mKey = null;
this.taskStartTime = -1L;
this.mReqProperties = new HashMap<>();
}
public long getTaskCostTime() {
return System.currentTimeMillis() - taskStartTime;
}
public synchronized Object getUserData() {
return mUserData;
}
public boolean isWriteToFile() {
return this.mOutPath != null;
}
public boolean isWriteToStream() {
return this.mOutStream != null;
}
public boolean saveRecvDataInTransLayer() {
return this.mOutPath != null || this.mOutStream != null;
}
public synchronized void setUserData(Object obj) {
this.mUserData = obj;
}
}

View File

@ -0,0 +1,72 @@
package com.tencent.mobileqq.transfile;
import java.util.HashMap;
public class NetResp {
public static final String KEY_FIRST_USE_IP = "firstserverip";
public static final String KEY_RAW_REQ_HTTP_HEADER = "param_reqHeader";
public static final String KEY_RAW_RESP_HTTP_HEADER = "param_rspHeader";
public static final String KEY_REASON = "netresp_param_reason";
public static final String KEY_USE_SERVER_IP = "serverip";
public static final String KEY_USE_URL = "param_url";
public static final int RESULT_DOWNLOADING = 3;
public static final int RESULT_FAIL = 1;
public static final int RESULT_NOT_SET = 2;
public static final int RESULT_OK = 0;
public long inQueueCost;
public long mConsumeTime;
public int mErrCode;
public String mErrDesc;
public int mHttpCode;
public long mLastReqStartTime;
public int mRedirectCount;
public long mRedirectTime;
public NetReq mReq;
public byte[] mRespData;
public HashMap<String, String> mRespProperties;
public int mResult;
public long mTotalBlockLen;
public long mTotalFileLen;
public int mTryTime;
public long mWrittenBlockLen;
public long reqCost;
public NetResp(NetReq netReq) {
this.mResult = 2;
this.mTotalFileLen = 0L;
this.mTotalBlockLen = 0L;
this.mWrittenBlockLen = 0L;
this.mConsumeTime = 0L;
this.mTryTime = 0;
this.mRespProperties = new HashMap<>();
this.mRedirectCount = 0;
this.mRedirectTime = 0L;
this.reqCost = 0L;
this.inQueueCost = 0L;
this.mReq = netReq;
this.mLastReqStartTime = System.currentTimeMillis();
}
public void reset() {
this.mResult = 2;
this.mErrCode = 0;
this.mErrDesc = "";
this.mHttpCode = 0;
this.mTotalFileLen = 0L;
this.mTotalBlockLen = 0L;
this.mWrittenBlockLen = 0L;
this.mConsumeTime = 0L;
this.mTryTime = 0;
this.mRespData = null;
this.mRespProperties.clear();
}
public void setResult(int i2, int i3, String str, HashMap<String, String> hashMap) {
this.mResult = i2;
this.mErrCode = i3;
this.mErrDesc = str;
if (hashMap != null) {
this.mRespProperties.putAll(hashMap);
}
}
}

View File

@ -0,0 +1,72 @@
package com.tencent.mobileqq.transfile;
public class TimeoutParam {
public static final int TIMEOUT_STEP = 2000;
private int connectTimeoutBias;
public int connectTimeoutFor2G;
public int connectTimeoutFor3G;
public int connectTimeoutForWifi;
public int readTimeoutFor2G;
public int readTimeoutFor3G;
public int readTimeoutForWifi;
public TimeoutParam() {
this.readTimeoutFor2G = 40000;
this.readTimeoutFor3G = 30000;
this.readTimeoutForWifi = 20000;
this.connectTimeoutFor2G = 20000;
this.connectTimeoutFor3G = 15000;
this.connectTimeoutForWifi = 10000;
this.connectTimeoutBias = 0;
}
public void adjustConnectTimeout(int i2) {
this.connectTimeoutBias = i2 * 2000;
}
public int getConnectTimeout(int i2) {
if (i2 != 1) {
if (i2 == 3) {
return this.connectTimeoutFor3G + this.connectTimeoutBias;
}
if (i2 != 4 && i2 != 5) {
return this.connectTimeoutFor2G + this.connectTimeoutBias;
}
}
return this.connectTimeoutForWifi + this.connectTimeoutBias;
}
public int getReadTimeout(int i2) {
if (i2 != 1) {
if (i2 == 3) {
return this.readTimeoutFor3G;
}
if (i2 != 4 && i2 != 5) {
return this.readTimeoutFor2G;
}
}
return this.readTimeoutForWifi;
}
//public TimeoutParam clone() {
// IPatchRedirector iPatchRedirector = $redirector_;
// return (iPatchRedirector == null || !iPatchRedirector.hasPatch((short) 4)) ? new TimeoutParam(this) : (TimeoutParam) iPatchRedirector.redirect((short) 4, (Object) this);
//}
TimeoutParam(TimeoutParam timeoutParam) {
this.readTimeoutFor2G = 40000;
this.readTimeoutFor3G = 30000;
this.readTimeoutForWifi = 20000;
this.connectTimeoutFor2G = 20000;
this.connectTimeoutFor3G = 15000;
this.connectTimeoutForWifi = 10000;
this.connectTimeoutBias = 0;
this.readTimeoutFor2G = timeoutParam.readTimeoutFor2G;
this.readTimeoutFor3G = timeoutParam.readTimeoutFor3G;
this.readTimeoutForWifi = timeoutParam.readTimeoutForWifi;
this.connectTimeoutFor2G = timeoutParam.connectTimeoutFor2G;
this.connectTimeoutFor3G = timeoutParam.connectTimeoutFor3G;
this.connectTimeoutForWifi = timeoutParam.connectTimeoutForWifi;
}
}

View File

@ -0,0 +1,15 @@
package com.tencent.mobileqq.transfile.api;
import com.tencent.mobileqq.transfile.NetReq;
import com.tencent.mobileqq.transfile.NetResp;
import mqq.app.api.IRuntimeService;
@Deprecated
public interface IHttpEngineService extends IRuntimeService {
void cancelReq(NetReq netReq);
void sendReq(NetReq netReq);
NetResp sendReqSync(NetReq netReq);
}

View File

@ -0,0 +1,14 @@
package com.tencent.mobileqq.transfile.api;
import com.tencent.mobileqq.qroute.QRouteApi;
import com.tencent.mobileqq.transfile.NetReq;
public interface IOldHttpEngineProcessor extends QRouteApi {
//void cancelMsg(HttpMsg httpMsg);
void cancelReq(NetReq netReq);
//int sendMsg(HttpMsg httpMsg);
void sendReq(NetReq netReq);
}

View File

@ -0,0 +1,97 @@
package com.tencent.mobileqq.troop.api;
import com.tencent.mobileqq.qroute.QRouteApi;
public interface ITroopHandlerNameApi extends QRouteApi {
String getTroopAddFriendHandlerName();
String getTroopAioNotifyHandlerName();
String getTroopAnnouncementHandlerName();
String getTroopAnonymousHandlerName();
String getTroopAppHandlerName();
String getTroopAssociationHandlerName();
String getTroopAvatarHandlerName();
String getTroopBatchInfoHandlerName();
String getTroopClockInHandlerName();
String getTroopCommonlyUsedHandlerName();
String getTroopConfigHandlerName();
String getTroopEssenceHandlerName();
String getTroopFansHandlerName();
String getTroopFeeHandlerName();
String getTroopGagHandlerName();
String getTroopGameHandlerName();
String getTroopHomeworkHandlerName();
String getTroopHonorHandlerName();
String getTroopInfoExtHandlerName();
String getTroopInfoHandlerName();
String getTroopListHandlerName();
String getTroopLuckyCharacterHandlerName();
String getTroopManagerBizHandlerName();
String getTroopMemberCardHandlerName();
String getTroopMemberInfoHandlerName();
String getTroopMemberLevelHandlerName();
String getTroopMemberListHandlerName();
String getTroopMemberMngHandlerName();
String getTroopMessageHandlerName();
String getTroopMngHandlerName();
String getTroopModifyHandlerName();
String getTroopNavigateMessageHandlerName();
String getTroopNotificationHandlerName();
String getTroopOnlineMemberHandlerName();
String getTroopOnlinePushHandlerName();
String getTroopPhotoHandlerName();
String getTroopPushHandlerName();
String getTroopRecommendHandlerName();
String getTroopRedDotHandlerName();
String getTroopRoamSettingHandlerName();
String getTroopRobotHandlerName();
String getTroopSettingHandlerName();
String getTroopShowExternalHandlerName();
String getTroopSurveyHandlerName();
String getTroopTokenHandlerName();
String getTroopTrpcHandlerName();
}

View File

@ -1,10 +1,32 @@
package com.tencent.qqnt.kernel.nativeinterface;
/* compiled from: P */
/* loaded from: classes4.dex */
public enum DeviceType {
KUNKNOWN,
KPHONE,
KPAD,
KCOMPUTER
public final class DeviceType {
private static final DeviceType[] $VALUES;
public static final DeviceType KCOMPUTER;
public static final DeviceType KPAD;
public static final DeviceType KPHONE;
public static final DeviceType KUNKNOWN;
static {
DeviceType deviceType = new DeviceType("KUNKNOWN", 0);
KUNKNOWN = deviceType;
DeviceType deviceType2 = new DeviceType("KPHONE", 1);
KPHONE = deviceType2;
DeviceType deviceType3 = new DeviceType("KPAD", 2);
KPAD = deviceType3;
DeviceType deviceType4 = new DeviceType("KCOMPUTER", 3);
KCOMPUTER = deviceType4;
$VALUES = new DeviceType[]{deviceType, deviceType2, deviceType3, deviceType4};
}
DeviceType(String str, int i2) {
}
public static DeviceType valueOf(String str) {
return null;
}
public static DeviceType[] values() {
return (DeviceType[]) $VALUES.clone();
}
}

View File

@ -0,0 +1,4 @@
package com.tencent.qqnt.kernel.nativeinterface;
public class GuildInteractiveNotificationItem {
}

View File

@ -0,0 +1,4 @@
package com.tencent.qqnt.kernel.nativeinterface;
public enum GuildMsgAbFlag {
}

View File

@ -0,0 +1,4 @@
package com.tencent.qqnt.kernel.nativeinterface;
public class GuildNotificationAbstractInfo {
}

View File

@ -42,6 +42,12 @@ public interface IKernelMsgListener {
void onGroupTransferInfoUpdate(GroupFileListResult groupFileListResult);
void onGuildInteractiveUpdate(GuildInteractiveNotificationItem guildInteractiveNotificationItem);
void onGuildMsgAbFlagChanged(GuildMsgAbFlag guildMsgAbFlag);
void onGuildNotificationAbstractUpdate(GuildNotificationAbstractInfo guildNotificationAbstractInfo);
void onHitCsRelatedEmojiResult(DownloadRelateEmojiResultInfo downloadRelateEmojiResultInfo);
void onHitEmojiKeywordResult(HitRelatedEmojiWordsResult hitRelatedEmojiWordsResult);

View File

@ -0,0 +1,100 @@
package com.tencent.qqnt.kernel.nativeinterface;
public class InitSessionConfig {
String a2;
String appid;
String clientVer;
String d2;
String d2Key;
String defaultFileDownloadPath;
InitSessionDesktopPathConfig desktopPathConfig;
DeviceType deviceType;
String extDataPath;
String gproDBName;
String machineId;
InitSessionMobilePathConfig mobilePathConfig;
String platVer;
PlatformType platform;
RDeliveryConfig rdeliveryConfig;
String selfUid;
long selfUin;
String sysPath;
String userPath;
public String getA2() {
return null;
}
public String getAppid() {
return null;
}
public String getClientVer() {
return null;
}
public String getD2() {
return null;
}
public String getD2Key() {
return null;
}
public String getDefaultFileDownloadPath() {
return null;
}
public InitSessionDesktopPathConfig getDesktopPathConfig() {
return null;
}
public DeviceType getDeviceType() {
return null;
}
public String getExtDataPath() {
return null;
}
public String getGproDBName() {
return null;
}
public String getMachineId() {
return null;
}
public InitSessionMobilePathConfig getMobilePathConfig() {
return null;
}
public String getPlatVer() {
return null;
}
public PlatformType getPlatform() {
return null;
}
public RDeliveryConfig getRdeliveryConfig() {
return null;
}
public String getSelfUid() {
return null;
}
public long getSelfUin() {
return 0;
}
public String getSysPath() {
return null;
}
public String getUserPath() {
return null;
}
}

Some files were not shown because too many files have changed in this diff Show More