├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── enhancement.yml └── workflows │ └── release.yml ├── .gitignore ├── AppIdMap.txt ├── LICENSE ├── README.md ├── app ├── build.gradle ├── libs │ ├── api-82-sources.jar │ └── api-82.jar ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── xposed_init │ ├── java │ └── tkaxv7s │ │ └── xposed │ │ └── sesame │ │ ├── data │ │ ├── BaseTask.java │ │ ├── ConfigV2.java │ │ ├── Model.java │ │ ├── ModelConfig.java │ │ ├── ModelField.java │ │ ├── ModelFields.java │ │ ├── ModelTask.java │ │ ├── ModelType.java │ │ ├── RunType.java │ │ ├── RuntimeInfo.java │ │ ├── ViewAppInfo.java │ │ └── modelFieldExt │ │ │ ├── BooleanModelField.java │ │ │ ├── ChoiceModelField.java │ │ │ ├── EmptyModelField.java │ │ │ ├── IntegerModelField.java │ │ │ ├── ListModelField.java │ │ │ ├── MapModelField.java │ │ │ ├── SelectModelField.java │ │ │ ├── StringModelField.java │ │ │ └── TextModelField.java │ │ ├── entity │ │ ├── AlipayBeach.java │ │ ├── AlipayReserve.java │ │ ├── AlipayUser.java │ │ ├── AreaCode.java │ │ ├── CooperateUser.java │ │ ├── FriendWatch.java │ │ ├── IdAndName.java │ │ ├── KVNode.java │ │ └── RpcEntity.java │ │ ├── hook │ │ ├── ApplicationHook.java │ │ ├── FriendManager.java │ │ └── Toast.java │ │ ├── model │ │ ├── base │ │ │ ├── ModelOrder.java │ │ │ └── TaskCommon.java │ │ ├── common │ │ │ └── rpcCall │ │ │ │ └── BaseTaskRpcCall.java │ │ ├── normal │ │ │ ├── answerAI │ │ │ │ ├── AnswerAI.java │ │ │ │ ├── AnswerAIInterface.java │ │ │ │ └── GenAI.java │ │ │ ├── base │ │ │ │ └── BaseModel.java │ │ │ └── webDav │ │ │ │ └── WebDav.java │ │ └── task │ │ │ ├── ancientTree │ │ │ ├── AncientTree.java │ │ │ └── AncientTreeRpcCall.java │ │ │ ├── antBookRead │ │ │ ├── AntBookRead.java │ │ │ └── AntBookReadRpcCall.java │ │ │ ├── antCooperate │ │ │ ├── AntCooperate.java │ │ │ └── AntCooperateRpcCall.java │ │ │ ├── antFarm │ │ │ ├── AntFarm.java │ │ │ ├── AntFarmRpcCall.java │ │ │ └── DadaDailyRpcCall.java │ │ │ ├── antForest │ │ │ ├── AntForestRpcCall.java │ │ │ ├── AntForestV2.java │ │ │ └── EcoLifeRpcCall.java │ │ │ ├── antMember │ │ │ ├── AntMember.java │ │ │ └── AntMemberRpcCall.java │ │ │ ├── antOcean │ │ │ ├── AntOcean.java │ │ │ └── AntOceanRpcCall.java │ │ │ ├── antOrchard │ │ │ ├── AntOrchard.java │ │ │ └── AntOrchardRpcCall.java │ │ │ ├── antSports │ │ │ ├── AntSports.java │ │ │ └── AntSportsRpcCall.java │ │ │ ├── antStall │ │ │ ├── AntStall.java │ │ │ └── AntStallRpcCall.java │ │ │ ├── consumeGold │ │ │ ├── ConsumeGold.java │ │ │ └── ConsumeGoldRpcCall.java │ │ │ ├── gameCenter │ │ │ ├── GameCenter.java │ │ │ └── GameCenterRpcCall.java │ │ │ ├── greenFinance │ │ │ ├── GreenFinance.java │ │ │ └── GreenFinanceRpcCall.java │ │ │ ├── kbMember │ │ │ ├── KBMember.java │ │ │ └── KBMemberRpcCall.java │ │ │ ├── omegakoiTown │ │ │ ├── OmegakoiTown.java │ │ │ └── OmegakoiTownRpcCall.java │ │ │ ├── otherTask │ │ │ ├── OtherTask.java │ │ │ └── OtherTaskRpcCall.java │ │ │ ├── readingDada │ │ │ ├── ReadingDada.java │ │ │ └── ReadingDadaRpcCall.java │ │ │ ├── reserve │ │ │ ├── Reserve.java │ │ │ └── ReserveRpcCall.java │ │ │ ├── sesameCredit │ │ │ ├── SesameCredit.java │ │ │ └── SesameCreditRpcCall.java │ │ │ └── welfareCenter │ │ │ ├── WelfareCenter.java │ │ │ └── WelfareCenterRpcCall.java │ │ ├── rpc │ │ ├── NewRpcBridge.java │ │ ├── OldRpcBridge.java │ │ └── RpcBridge.java │ │ ├── ui │ │ ├── ChoiceDialog.java │ │ ├── HtmlViewerActivity.java │ │ ├── ListAdapter.java │ │ ├── ListDialog.java │ │ ├── MainActivity.java │ │ ├── MyWebView.java │ │ ├── OptionsAdapter.java │ │ ├── SettingsActivity.java │ │ └── StringDialog.java │ │ └── util │ │ ├── BeachIdMap.java │ │ ├── ClassUtil.java │ │ ├── CooperationIdMap.java │ │ ├── FileUtil.java │ │ ├── HanziToPinyin.java │ │ ├── JsonUtil.java │ │ ├── LanguageUtil.java │ │ ├── ListUtil.java │ │ ├── Log.java │ │ ├── NotificationUtil.java │ │ ├── PermissionUtil.java │ │ ├── RandomUtil.java │ │ ├── ReserveIdMap.java │ │ ├── Statistics.java │ │ ├── StringUtil.java │ │ ├── ThreadUtil.java │ │ ├── TimeUtil.java │ │ ├── TypeUtil.java │ │ └── UserIdMap.java │ └── res │ ├── drawable │ ├── button.xml │ ├── button_main.xml │ ├── farm.xml │ ├── forest.xml │ ├── friend.xml │ ├── github.xml │ ├── logo.png │ ├── main.png │ ├── other.xml │ ├── setting.xml │ └── unactivated.png │ ├── layout │ ├── activity_html_viewer.xml │ ├── activity_main.xml │ ├── activity_settings.xml │ ├── dialog_list.xml │ └── list_item.xml │ ├── values-zh-rCN │ └── strings.xml │ └── values │ ├── arrays.xml │ ├── colors.xml │ ├── dimen.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew └── settings.gradle /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: 问题与 BUG 反馈 2 | description: 问题反馈应当使用此模板进行提交 3 | labels: [ bug ] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | ### 请在下方填写问题发生的具体原因和复现步骤。 9 | 10 | 发生异常、崩溃、闪退或功能性问题,必须提交问题 Log (日志),没有 Log 的 issues 将直接被关闭。 11 | - type: input 12 | attributes: 13 | label: | 14 | 程序版本 / 框架版本 / 模块版本 15 | description: 请填写当前使用的 程序版本 (例如:10.5.8)、框架版本 (例如:LSPosed 1.8.4) 及 模块版本 (例如:1.1.1) 16 | validations: 17 | required: true 18 | - type: input 19 | attributes: 20 | label: | 21 | 系统版本 / Android版本 22 | description: 这里填写当前使用的 系统版本 (例如:MIUI、ColorOS、OxygenOS、PE/原生) 及 Android版本 (例如:Android 10、Android 11、Android 12) 23 | validations: 24 | required: true 25 | - type: textarea 26 | attributes: 27 | label: 详细描述问题发生的具体原因 28 | description: 请在下方详细描述问题发生的具体场景、复现步骤和经过,以便我们能够按照你所描述的步骤复现这个问题。 29 | validations: 30 | required: true 31 | - type: textarea 32 | attributes: 33 | label: 提供模块问题 Log 或必要 Log 34 | description: 闪退需提交闪退(crash)日志,无响应需提交无响应(ANR)日志,功能性问题需提交运行时(runtime)日志。 35 | value: | 36 |
展开查看

37 | 
38 |         (此处粘贴问题 Log)
39 | 
40 |         
41 | 42 | validations: 43 | required: true 44 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 使用问题 4 | url: https://github.com/TKaxv-7S/Sesame-TK/discussions/ 5 | about: 请使用 GitHub Discussion 的“提问”分区讨论使用上的问题。 -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement.yml: -------------------------------------------------------------------------------- 1 | name: 功能建议 2 | description: 功能建议使用此模板进行提交 3 | labels: [ enhancement ] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | ### 请在下方填写功能需求或建议。 9 | - type: dropdown 10 | attributes: 11 | label: 增强类型 12 | options: 13 | - 功能型增强 14 | - 优化型增强 15 | - 强迫症增强 16 | validations: 17 | required: true 18 | - type: textarea 19 | attributes: 20 | label: 具体描述 21 | description: 请在下方详细描述功能需求或建议。 22 | validations: 23 | required: true -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Android CI 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | build: 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v3 14 | with: 15 | fetch-depth: 0 16 | 17 | - name: set up JDK 11 18 | uses: actions/setup-java@v3 19 | with: 20 | java-version: '11' 21 | distribution: 'temurin' 22 | cache: gradle 23 | 24 | - name: Grant execute permission for gradlew 25 | run: chmod +x gradlew 26 | 27 | - name: Build with Gradle 28 | run: ./gradlew assembleRelease -P version=${{ github.ref_name }} 29 | 30 | - name: Sign Normal APK 31 | id: sign_normal_apk 32 | uses: ilharp/sign-android-release@v1 33 | with: 34 | releaseDir: app/build/outputs/apk/normal/release/ 35 | signingKey: ${{ secrets.ANDROID_SIGNING_KEY }} 36 | keyAlias: ${{ secrets.ANDROID_KEY_ALIAS }} 37 | keyStorePassword: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} 38 | keyPassword: ${{ secrets.ANDROID_KEY_PASSWORD }} 39 | buildToolsVersion: 31.0.0 40 | 41 | - name: Sign Compatible APK 42 | id: sign_compatible_apk 43 | uses: ilharp/sign-android-release@v1 44 | with: 45 | releaseDir: app/build/outputs/apk/compatible/release/ 46 | signingKey: ${{ secrets.ANDROID_SIGNING_KEY }} 47 | keyAlias: ${{ secrets.ANDROID_KEY_ALIAS }} 48 | keyStorePassword: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} 49 | keyPassword: ${{ secrets.ANDROID_KEY_PASSWORD }} 50 | buildToolsVersion: 31.0.0 51 | 52 | - name: Upload Normal to Release 53 | uses: termux/upload-release-action@v4.2.0 54 | with: 55 | asset_name: Sesame-Normal-${{ github.event.release.tag_name }}.apk 56 | file: ${{ steps.sign_normal_apk.outputs.signedFile }} 57 | repo_token: ${{ secrets.GITHUB_TOKEN }} 58 | tag: ${{ github.ref }} 59 | overwrite: true 60 | checksums: sha256 61 | checksums_file_name: CHECKSUMS-Sesame-Normal-${{ github.event.release.tag_name }}.%algo% 62 | 63 | - name: Upload Compatible to Release 64 | uses: termux/upload-release-action@v4.2.0 65 | with: 66 | asset_name: Sesame-Compatible-${{ github.event.release.tag_name }}.apk 67 | file: ${{ steps.sign_compatible_apk.outputs.signedFile }} 68 | repo_token: ${{ secrets.GITHUB_TOKEN }} 69 | tag: ${{ github.ref }} 70 | overwrite: true 71 | checksums: sha256 72 | checksums_file_name: CHECKSUMS-Sesame-Compatible-${{ github.event.release.tag_name }}.%algo% 73 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | release/ 20 | 21 | # Local configuration file (sdk path, etc) 22 | local.properties 23 | 24 | # Proguard folder generated by Eclipse 25 | proguard/ 26 | 27 | # Log Files 28 | *.log 29 | 30 | # Android Studio Navigation editor temp files 31 | .navigation/ 32 | 33 | # Android Studio captures folder 34 | captures/ 35 | 36 | # IntelliJ 37 | *.iml 38 | .idea/ 39 | 40 | # Keystore files 41 | # Uncomment the following line if you do not want to check your keystore files in. 42 | #*.jks 43 | 44 | # External native build folder generated in Android Studio 2.2 and later 45 | .externalNativeBuild 46 | 47 | # Google Services (e.g. APIs or Firebase) 48 | google-services.json 49 | 50 | # Freeline 51 | freeline.py 52 | freeline/ 53 | freeline_project_description.json 54 | 55 | # fastlane 56 | fastlane/report.xml 57 | fastlane/Preview.html 58 | fastlane/screenshots 59 | fastlane/test_output 60 | fastlane/readme.md 61 | 62 | Xposed-Modules-Repo/ 63 | plugin/ -------------------------------------------------------------------------------- /AppIdMap.txt: -------------------------------------------------------------------------------- 1 | 10000003:充值中心 2 | 10000009:爱心捐赠 3 | 20000001:null 4 | 20000003:账单 5 | 20000014:我的银行卡 6 | 20000019:余额 7 | 20000032:余额宝 8 | 20000033:余额提现 9 | 20000038:关联账户认证/身份认证 10 | 20000042:null 11 | 20000047:null 12 | 20000067:? 13 | 20000076:账单 14 | 20000111:? 15 | 20000120:饿了么外卖 16 | 20000123:个人收钱 17 | 20000134:股票 18 | 20000142:娱乐宝 19 | 20000160:支付宝会员 20 | 20000165:理财 21 | 20000180:借呗 22 | 20000193:生活缴费 23 | 20000199:花呗 24 | 20000218:黄金 25 | 20000241:车险服务 26 | 20000691:我的客服 27 | 20000725:设置 28 | 20000754:我的快递 29 | 20000793:基金 30 | 20000909:args error 31 | 20000936:蚂蚁保险 32 | 20001045:args error 33 | 60000002:蚂蚁森林 34 | 60000010:? 35 | 60000071:天天有料 36 | 60000081:商家服务 37 | 60000123:args error 38 | 60000127:args error 39 | 60000148:财富号 40 | 60000161:支付宝会员周周乐 41 | 63300018:? 42 | 66666673:风险测试/风险类型 43 | 66666674:蚂蚁庄园 44 | 66666698:标签系统/标签和随笔 45 | 66666708:余利宝 46 | 66666721:财富有料 47 | 66666735:基金组合 48 | 66666741:上证指数讨论区 49 | 66666755:好医保 50 | 66666783:爱攒油加油站 51 | 66666819:还贷管家 52 | 66666823:? 53 | 66666825:财富标签页/我的理财标签 54 | 66666828:知识课堂 55 | 66666866:收益曲线 56 | 66666883:网商贷 57 | 66666886:蚂蚁森林合种 58 | 66666897:工资理财 59 | 68686987:网贷 60 | 68687015:办理赔 61 | 68687031:智能理财助理 62 | 68687049:蚂蚁心愿 63 | 68687058:null 64 | 68687109:null 65 | 68687129:行走积分赛 66 | 68687131:养老金 67 | 68687158:支付宝积分猜涨跌 68 | 68687197:null 69 | 68687233:股票工具 70 | 68687242:尊享理财 71 | 68687249:大盘晴雨表 72 | 68687279:null 73 | 68687357:null 74 | 77700124:余额宝 75 | 77700126:互相宝 76 | 77700130:花呗账单 77 | 77700144:扫码点单 78 | 77700152:信用卡还款 79 | 77700173:标注高德地图(在高德地图上标注我的商铺) 80 | 77700174:财富王者 81 | 77700199:财富SHOW 82 | 77700223:笔笔攒 83 | 77700234:模拟炒股 84 | 77700252:市场投资情绪 85 | 77700253:资金管理 86 | 77700257:收钱有奖 87 | 77700279:校园生活 88 | 77700292:收入统计 89 | 77700296:? 90 | 98000012:? 91 | 2013062600000474:new 92 | 2016122804685366:new 93 | 2017081908285290:new 94 | 2018030502317554:new 95 | 2018040402504128:new 96 | 2018051160096372:new 97 | 2018052460226391:new 98 | 2018071160524903:new 99 | 2018091361395351:new 100 | 2018110662035452:new 101 | 2018110762040932:new 102 | 2018112962211021:new 103 | 2018122762703259:new 104 | 2019010462802084:new 105 | 2019012963182381:new 106 | 2019021363229455:new 107 | 2019030863479637:new 108 | 2019031563521845:new 109 | 2019032763709372:new 110 | 2019032863733398:new 111 | 2019040963856084:new 112 | 2019042364288308:new 113 | 2019060465478294:new 114 | 2019060565481471:new 115 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sesame-TK 2 | 3 | [![License](https://img.shields.io/github/license/TKaxv-7S/Sesame-TK.svg)](LICENSE) 4 | [![Latest Release](https://img.shields.io/github/release/TKaxv-7S/Sesame-TK.svg)](../../releases) 5 | [![All Releases Download](https://img.shields.io/github/downloads/TKaxv-7S/Sesame-TK/total.svg)](../../releases) 6 | 7 | ### 特别感谢这个项目的上一位维护者[@constanline](https://github.com/constanline),以及更早的维护者[@pansong291](https://github.com/pansong291)与其他维护者们 8 | ### 如果您开发了新功能,觉得开发的功能还不错,同时愿意贡献PR,非常欢迎,也非常感谢大家为这个项目的付出! 9 | 10 | ### 旧版本在 [XQuickEnergy](https://github.com/TKaxv-7S/XQuickEnergy) 11 | 12 | ## 主要功能 13 | 感谢蚂蚁森林对绿化事业的贡献。快速收取蚂蚁森林能量,也为祖国的绿化事业出一份微薄之力~ 14 | 15 | ### 版本特点 16 | 1. 重构 系统架构,**功能与配置全部模块化**,以后添加功能**无需再开发配置页面,大幅降低开发门槛,并极大节省开发成本**,欢迎有兴趣的朋友参与开发,开发指南见[维基](https://github.com/TKaxv-7S/Sesame-TK/wiki)或如下图所示,非常欢迎大家提[PR](https://github.com/TKaxv-7S/Sesame-TK/pulls) 17 | ![Sesame-TK开发指南](https://github.com/TKaxv-7S/Sesame-TK/assets/22593101/4d8451fe-2b7f-4f19-9439-b0afbf683510) 18 | 2. 重构 **森林收能量代码**,大幅提升能量多的账号收取效率 19 | 3. 重构 配置模块,**所有配置需要重新配置**,新配置文件名称为**config_v2.json**,旧配置文件未删除,可作参考 20 | 4. 修改 配置界面,模块列表改为左侧垂直布局 21 | 5. 添加 定时唤醒与定时执行逻辑,在基础设置中可配置多个定时执行或定时唤醒时间 22 | 6. 修复 一些逻辑问题 23 | 24 | ***目前没有大小号、号码切换的计划*** 25 | 26 | ## 使用说明 27 | 28 | 1. 本APP是为了学习研究用,不得进行任何形式的转发,发布,传播。 29 | 2. 请于24小时内卸载本APP。若使用期间造成任何损失,作者不负任何责任。 30 | 3. 本APP不篡改,不修改,不获取任何个人信息及其支付宝信息。 31 | 4. 本APP使用者因为违反本声明的规定而触犯中华人民共和国法律的,一切后果自负,作者不承担任何责任。 32 | 5. 凡以任何方式直接、间接使用APP者,视为自愿接受本声明的约束。 33 | 6. 本APP如无意中侵犯了某个媒体或个人的知识产权,请来信或来电告之,作者将立即删除。 34 | 35 | ## 授权说明 36 | 本项目基于 [constanline版XQuickEnergy](https://github.com/constanline/XQuickEnergy) 与 [pansong291版XQuickEnergy](https://github.com/pansong291/XQuickEnergy) 开发,遵循 Apache-2.0 协议 37 | 38 | 所有图片由 ༒激༙྇流༙྇泉༙྇༒ 授权使用 39 | 40 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | def version = project.getProperties().get("version") 5 | if (version == null || "unspecified".equalsIgnoreCase(version)) { 6 | version = "TEST" 7 | } 8 | 9 | compileSdk 34 10 | defaultConfig { 11 | applicationId "tkaxv7s.xposed.sesame" 12 | minSdk 23 13 | //noinspection ExpiredTargetSdkVersion 14 | targetSdk 31 15 | versionCode 80 16 | versionName version 17 | } 18 | ext { 19 | applicationName = "Sesame" 20 | applicationType = "Normal" 21 | } 22 | flavorDimensions.add("default") 23 | productFlavors { 24 | normal { 25 | dimension "default" 26 | ext.applicationType = "Normal" 27 | } 28 | compatible { 29 | dimension "default" 30 | ext.applicationType = "Compatible" 31 | } 32 | } 33 | buildTypes { 34 | release { 35 | minifyEnabled false 36 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 37 | } 38 | } 39 | namespace 'tkaxv7s.xposed.sesame' 40 | applicationVariants.configureEach { variant -> 41 | variant.outputs.configureEach { output -> 42 | def outputFile = output.outputFile 43 | if (outputFile != null && outputFile.name.endsWith('.apk')) { 44 | if (variant.buildType.name == 'release') { 45 | output.outputFileName = "${applicationName}-${variant.productFlavors[0].ext.applicationType}-${defaultConfig.versionName}.apk" 46 | } 47 | } 48 | } 49 | } 50 | } 51 | 52 | dependencies { 53 | compileOnly 'de.robv.android.xposed:api:82' 54 | compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.32' 55 | annotationProcessor group: 'org.projectlombok', name: 'lombok', version: '1.18.32' 56 | implementation 'com.elvishew:xlog:1.11.0' 57 | implementation 'com.squareup.okhttp3:okhttp:4.12.0' // 核心库 58 | 59 | normalImplementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.17.1' 60 | normalImplementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.17.1' 61 | normalImplementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.17.1' 62 | 63 | compatibleImplementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.13.5' 64 | compatibleImplementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.13.5' 65 | compatibleImplementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.13.5' 66 | 67 | } 68 | -------------------------------------------------------------------------------- /app/libs/api-82-sources.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongleo1/Sesame-X/5073875d175359ce6f6b6a10b4563ca0835fa60a/app/libs/api-82-sources.jar -------------------------------------------------------------------------------- /app/libs/api-82.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongleo1/Sesame-X/5073875d175359ce6f6b6a10b4563ca0835fa60a/app/libs/api-82.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\tools\adt-bundle-windows-x86_64-20131030\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | 22 | 23 | 26 | 27 | 30 | 31 | 34 | 35 | 38 | 39 | 40 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 65 | 66 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /app/src/main/assets/xposed_init: -------------------------------------------------------------------------------- 1 | tkaxv7s.xposed.sesame.hook.ApplicationHook 2 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/BaseTask.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data; 2 | 3 | import android.os.Build; 4 | import lombok.Getter; 5 | import tkaxv7s.xposed.sesame.util.Log; 6 | import tkaxv7s.xposed.sesame.util.ThreadUtil; 7 | 8 | import java.util.Map; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | public abstract class BaseTask { 13 | 14 | @Getter 15 | private final Runnable runnable; 16 | 17 | @Getter 18 | private volatile Thread thread; 19 | 20 | private final Map childTaskMap = new ConcurrentHashMap<>(); 21 | 22 | public BaseTask() { 23 | this.runnable = init(); 24 | this.thread = null; 25 | } 26 | 27 | public String getId() { 28 | return toString(); 29 | } 30 | 31 | public abstract Boolean check(); 32 | 33 | public abstract Runnable init(); 34 | 35 | public synchronized Boolean hasChildTask(String childId) { 36 | return childTaskMap.containsKey(childId); 37 | } 38 | 39 | public synchronized BaseTask getChildTask(String childId) { 40 | return childTaskMap.get(childId); 41 | } 42 | 43 | public synchronized void addChildTask(BaseTask childTask) { 44 | String childId = childTask.getId(); 45 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 46 | childTaskMap.compute(childId, (key, value) -> { 47 | if (value != null) { 48 | value.stopTask(); 49 | } 50 | childTask.startTask(); 51 | return childTask; 52 | }); 53 | } else { 54 | BaseTask oldTask = childTaskMap.get(childId); 55 | if (oldTask != null) { 56 | oldTask.stopTask(); 57 | } 58 | childTask.startTask(); 59 | childTaskMap.put(childId, childTask); 60 | } 61 | } 62 | 63 | public synchronized void removeChildTask(String childId) { 64 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 65 | childTaskMap.compute(childId, (key, value) -> { 66 | if (value != null) { 67 | ThreadUtil.shutdownAndWait(value.getThread(), -1, TimeUnit.SECONDS); 68 | } 69 | return null; 70 | }); 71 | } else { 72 | BaseTask oldTask = childTaskMap.get(childId); 73 | if (oldTask != null) { 74 | ThreadUtil.shutdownAndWait(oldTask.getThread(), -1, TimeUnit.SECONDS); 75 | } 76 | childTaskMap.remove(childId); 77 | } 78 | } 79 | 80 | public synchronized Integer countChildTask() { 81 | return childTaskMap.size(); 82 | } 83 | 84 | public Boolean startTask() { 85 | return startTask(false); 86 | } 87 | 88 | public synchronized Boolean startTask(Boolean force) { 89 | if (thread != null && thread.isAlive()) { 90 | if (!force) { 91 | return false; 92 | } 93 | stopTask(); 94 | } 95 | thread = new Thread(runnable); 96 | try { 97 | if (check()) { 98 | thread.start(); 99 | for (BaseTask childTask : childTaskMap.values()) { 100 | if (childTask != null) { 101 | childTask.startTask(); 102 | } 103 | } 104 | return true; 105 | } 106 | } catch (Exception e) { 107 | Log.printStackTrace(e); 108 | } 109 | return false; 110 | } 111 | 112 | public synchronized void stopTask() { 113 | if (thread != null && thread.isAlive()) { 114 | ThreadUtil.shutdownAndWait(thread, 5, TimeUnit.SECONDS); 115 | } 116 | for (BaseTask childTask : childTaskMap.values()) { 117 | if (childTask != null) { 118 | ThreadUtil.shutdownAndWait(childTask.getThread(), -1, TimeUnit.SECONDS); 119 | } 120 | } 121 | thread = null; 122 | childTaskMap.clear(); 123 | } 124 | 125 | public static BaseTask newInstance() { 126 | return new BaseTask() { 127 | @Override 128 | public Runnable init() { 129 | return () -> {}; 130 | } 131 | 132 | @Override 133 | public Boolean check() { 134 | return true; 135 | } 136 | }; 137 | } 138 | 139 | public static BaseTask newInstance(String id) { 140 | return new BaseTask() { 141 | @Override 142 | public String getId() { 143 | return id; 144 | } 145 | 146 | @Override 147 | public Runnable init() { 148 | return () -> {}; 149 | } 150 | 151 | @Override 152 | public Boolean check() { 153 | return true; 154 | } 155 | }; 156 | } 157 | 158 | public static BaseTask newInstance(String id, Runnable runnable) { 159 | return new BaseTask() { 160 | @Override 161 | public String getId() { 162 | return id; 163 | } 164 | 165 | @Override 166 | public Runnable init() { 167 | return runnable; 168 | } 169 | 170 | @Override 171 | public Boolean check() { 172 | return true; 173 | } 174 | }; 175 | } 176 | 177 | } 178 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/Model.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data; 2 | 3 | import lombok.Getter; 4 | import tkaxv7s.xposed.sesame.model.base.ModelOrder; 5 | import tkaxv7s.xposed.sesame.util.Log; 6 | 7 | import java.util.*; 8 | import java.util.concurrent.ConcurrentHashMap; 9 | 10 | public abstract class Model { 11 | 12 | private static final Map modelConfigMap = new LinkedHashMap<>(); 13 | 14 | private static final Map readOnlyModelConfigMap = Collections.unmodifiableMap(modelConfigMap); 15 | 16 | private static final Map, Model> modelMap = new ConcurrentHashMap<>(); 17 | 18 | private static final List> modelClazzList = ModelOrder.getClazzList(); 19 | 20 | @Getter 21 | private static final Model[] modelArray = new Model[modelClazzList.size()]; 22 | 23 | private static final List modelList = new LinkedList<>(Arrays.asList(modelArray)); 24 | 25 | private static final List readOnlyModelList = Collections.unmodifiableList(modelList); 26 | 27 | public ModelType getType() { 28 | return ModelType.NORMAL; 29 | } 30 | 31 | public abstract String setName(); 32 | 33 | public abstract ModelFields setFields(); 34 | 35 | public void config() {} 36 | 37 | public void destroy() {} 38 | 39 | public static Map getModelConfigMap() { 40 | return readOnlyModelConfigMap; 41 | } 42 | 43 | public static Boolean hasTask(Class taskClazz) { 44 | return modelMap.containsKey(taskClazz); 45 | } 46 | 47 | @SuppressWarnings("unchecked") 48 | public static T getTask(Class taskClazz) { 49 | return (T) modelMap.get(taskClazz); 50 | } 51 | 52 | public static List getModelList() { 53 | return readOnlyModelList; 54 | } 55 | 56 | public static synchronized void initAllModel() { 57 | destroyAllModel(); 58 | for (int i = 0, len = modelClazzList.size(); i < len; i++) { 59 | Class taskClazz = modelClazzList.get(i); 60 | try { 61 | Model task = taskClazz.newInstance(); 62 | ModelConfig modelConfig = new ModelConfig(task); 63 | modelArray[i] = task; 64 | modelMap.put(taskClazz, task); 65 | modelConfigMap.put(modelConfig.getCode(), modelConfig); 66 | } catch (IllegalAccessException | InstantiationException e) { 67 | Log.printStackTrace(e); 68 | } 69 | } 70 | for (Model model : modelArray) { 71 | try { 72 | model.config(); 73 | } catch (Exception e) { 74 | Log.printStackTrace(e); 75 | } 76 | } 77 | } 78 | 79 | public static synchronized void destroyAllModel() { 80 | for (int i = 0, len = modelArray.length; i < len; i++) { 81 | Model task = modelArray[i]; 82 | if (task != null) { 83 | try { 84 | task.destroy(); 85 | } catch (Exception e) { 86 | Log.printStackTrace(e); 87 | } 88 | modelArray[i] = null; 89 | } 90 | modelMap.clear(); 91 | modelConfigMap.clear(); 92 | } 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/ModelConfig.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.util.Map; 7 | 8 | @Data 9 | public final class ModelConfig implements Serializable { 10 | 11 | private static final long serialVersionUID = 1L; 12 | 13 | //private final Type dataType; 14 | 15 | private String code; 16 | 17 | private String name; 18 | 19 | private final ModelFields fields = new ModelFields(); 20 | 21 | public ModelConfig() { 22 | //dataType = TypeUtil.getTypeArgument(this.getClass().getGenericSuperclass(), 0); 23 | } 24 | 25 | public ModelConfig(Model model) { 26 | this(); 27 | this.code = model.getClass().getSimpleName(); 28 | this.name = model.setName(); 29 | addFields(model.setFields()); 30 | } 31 | 32 | public void addFields(ModelFields newFields) { 33 | fields.clear(); 34 | if (newFields != null) { 35 | for (Map.Entry entry : newFields.entrySet()) { 36 | ModelField modelField = entry.getValue(); 37 | if (modelField != null) { 38 | fields.put(modelField.getCode(), modelField); 39 | } 40 | } 41 | } 42 | } 43 | 44 | public Boolean hasModelField(String fieldCode) { 45 | return fields.containsKey(fieldCode); 46 | } 47 | 48 | public ModelField getModelField(String fieldCode) { 49 | return fields.get(fieldCode); 50 | } 51 | 52 | /*public void removeModelField(String fieldCode) { 53 | fields.remove(fieldCode); 54 | }*/ 55 | 56 | /*public Boolean addModelField(ModelField modelField) { 57 | fields.put(modelField.getCode(), modelField); 58 | return true; 59 | }*/ 60 | 61 | @SuppressWarnings("unchecked") 62 | public T getModelFieldExt(String fieldCode) { 63 | return (T) fields.get(fieldCode); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/ModelField.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.view.Gravity; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.LinearLayout; 9 | import android.widget.TextView; 10 | import android.widget.Toast; 11 | import com.fasterxml.jackson.annotation.JsonIgnore; 12 | import lombok.Data; 13 | import tkaxv7s.xposed.sesame.R; 14 | 15 | import java.io.Serializable; 16 | 17 | /** 18 | * @author xiong 19 | */ 20 | @Data 21 | public abstract class ModelField implements Serializable { 22 | 23 | @JsonIgnore 24 | private String code; 25 | 26 | @JsonIgnore 27 | private String name; 28 | 29 | protected volatile Object value; 30 | 31 | @JsonIgnore 32 | protected Object defaultValue; 33 | 34 | public ModelField() { 35 | } 36 | 37 | public ModelField(Object value) { 38 | this.defaultValue = value; 39 | setValue(value); 40 | } 41 | 42 | public ModelField(Object value, Object defaultValue) { 43 | this.defaultValue = defaultValue; 44 | setValue(value); 45 | } 46 | 47 | public ModelField(String code, String name, Object value) { 48 | this.code = code; 49 | this.name = name; 50 | this.defaultValue = value; 51 | setValue(value); 52 | } 53 | 54 | public void reset() { 55 | value = defaultValue; 56 | } 57 | 58 | @JsonIgnore 59 | public String getConfigValue() { 60 | return String.valueOf(getValue()); 61 | } 62 | 63 | public void setConfigValue(String value) { 64 | setValue(value); 65 | } 66 | 67 | @JsonIgnore 68 | public View getView(Context context) { 69 | TextView btn = new TextView(context); 70 | btn.setText(getName()); 71 | btn.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 72 | btn.setTextColor(Color.parseColor("#008175")); 73 | btn.setBackground(context.getResources().getDrawable(R.drawable.button)); 74 | btn.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); 75 | btn.setMinHeight(150); 76 | btn.setMaxHeight(180); 77 | btn.setPaddingRelative(40, 0, 40, 0); 78 | btn.setAllCaps(false); 79 | btn.setOnClickListener(v -> { 80 | onClickListener(context, btn); 81 | }); 82 | return btn; 83 | } 84 | 85 | protected View createView(Context context){ 86 | View view = new View(context); 87 | return view; 88 | } 89 | 90 | // 抽象方法,由子类实现点击事件 91 | protected void onClickListener(Context context, View v) { 92 | Toast.makeText(context, "无配置项", Toast.LENGTH_SHORT).show(); 93 | } 94 | 95 | ; 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/ModelFields.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data; 2 | 3 | import java.util.LinkedHashMap; 4 | 5 | //@Data 6 | public final class ModelFields extends LinkedHashMap { 7 | 8 | //private BooleanModelField enable = new BooleanModelField("enable", "开启", true); 9 | 10 | public void addField(ModelField modelField) { 11 | put(modelField.getCode(), modelField); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/ModelTask.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data; 2 | 3 | import android.os.Build; 4 | import lombok.Getter; 5 | import tkaxv7s.xposed.sesame.util.Log; 6 | import tkaxv7s.xposed.sesame.util.ThreadUtil; 7 | 8 | import java.util.Map; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | public abstract class ModelTask extends Model { 13 | 14 | @Getter 15 | private final Runnable runnable; 16 | 17 | @Getter 18 | private volatile Thread thread; 19 | 20 | private final Map childTaskMap = new ConcurrentHashMap<>(); 21 | 22 | public ModelTask() { 23 | this.runnable = this::run; 24 | this.thread = null; 25 | } 26 | 27 | public String getId() { 28 | return toString(); 29 | } 30 | 31 | public ModelType getType() { 32 | return ModelType.TASK; 33 | } 34 | 35 | public abstract String setName(); 36 | 37 | public abstract ModelFields setFields(); 38 | 39 | public abstract Boolean check(); 40 | 41 | public abstract void run(); 42 | 43 | public synchronized Boolean hasChildTask(String childId) { 44 | return childTaskMap.containsKey(childId); 45 | } 46 | 47 | public synchronized BaseTask getChildTask(String childId) { 48 | return childTaskMap.get(childId); 49 | } 50 | 51 | public synchronized void addChildTask(BaseTask childTask) { 52 | String childId = childTask.getId(); 53 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 54 | childTaskMap.compute(childId, (key, value) -> { 55 | if (value != null) { 56 | value.stopTask(); 57 | } 58 | childTask.startTask(); 59 | return childTask; 60 | }); 61 | } else { 62 | BaseTask oldTask = childTaskMap.get(childId); 63 | if (oldTask != null) { 64 | oldTask.stopTask(); 65 | } 66 | childTask.startTask(); 67 | childTaskMap.put(childId, childTask); 68 | } 69 | } 70 | 71 | public synchronized void removeChildTask(String childId) { 72 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 73 | childTaskMap.compute(childId, (key, value) -> { 74 | if (value != null) { 75 | ThreadUtil.shutdownAndWait(value.getThread(), -1, TimeUnit.SECONDS); 76 | } 77 | return null; 78 | }); 79 | } else { 80 | BaseTask oldTask = childTaskMap.get(childId); 81 | if (oldTask != null) { 82 | ThreadUtil.shutdownAndWait(oldTask.getThread(), -1, TimeUnit.SECONDS); 83 | } 84 | childTaskMap.remove(childId); 85 | } 86 | } 87 | 88 | public synchronized Integer countChildTask() { 89 | return childTaskMap.size(); 90 | } 91 | 92 | public Boolean startTask() { 93 | return startTask(false); 94 | } 95 | 96 | public synchronized Boolean startTask(Boolean force) { 97 | if (thread != null && thread.isAlive()) { 98 | if (!force) { 99 | return false; 100 | } 101 | stopTask(); 102 | } 103 | thread = new Thread(runnable); 104 | try { 105 | if (check()) { 106 | thread.start(); 107 | for (BaseTask childTask : childTaskMap.values()) { 108 | if (childTask != null) { 109 | childTask.startTask(); 110 | } 111 | } 112 | return true; 113 | } 114 | } catch (Exception e) { 115 | Log.printStackTrace(e); 116 | } 117 | return false; 118 | } 119 | 120 | public synchronized void stopTask() { 121 | if (thread != null && thread.isAlive()) { 122 | ThreadUtil.shutdownAndWait(thread, 5, TimeUnit.SECONDS); 123 | } 124 | for (BaseTask childTask : childTaskMap.values()) { 125 | if (childTask != null) { 126 | ThreadUtil.shutdownAndWait(childTask.getThread(), -1, TimeUnit.SECONDS); 127 | } 128 | } 129 | thread = null; 130 | childTaskMap.clear(); 131 | } 132 | 133 | public static void startAllTask() { 134 | startAllTask(false); 135 | } 136 | 137 | public static void startAllTask(Boolean force) { 138 | for (Model model : getModelArray()) { 139 | if (model != null) { 140 | if (ModelType.TASK == model.getType()) { 141 | if (((ModelTask) model).startTask(force)) { 142 | try { 143 | Thread.sleep(80); 144 | } catch (InterruptedException e) { 145 | Log.printStackTrace(e); 146 | } 147 | } 148 | } 149 | } 150 | } 151 | } 152 | 153 | public static void stopAllTask() { 154 | for (Model model : getModelArray()) { 155 | if (model != null) { 156 | if (ModelType.TASK == model.getType()) { 157 | ((ModelTask) model).stopTask(); 158 | } 159 | } 160 | } 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/ModelType.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public enum ModelType { 7 | 8 | NORMAL(0, "普通模块"), 9 | 10 | TASK(1, "任务模块"), 11 | 12 | ; 13 | 14 | private final Integer code; 15 | 16 | private final String name; 17 | 18 | ModelType(Integer code, String name) { 19 | this.code = code; 20 | this.name = name; 21 | } 22 | 23 | private static final Map MAP; 24 | 25 | static { 26 | MAP = new HashMap<>(); 27 | ModelType[] values = ModelType.values(); 28 | for (ModelType value : values) { 29 | MAP.put(value.code, value); 30 | } 31 | } 32 | 33 | public static ModelType getByCode(Integer code) { 34 | return MAP.get(code); 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/RunType.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import lombok.Getter; 7 | 8 | @Getter 9 | public enum RunType { 10 | 11 | DISABLE(0, "已关闭"), 12 | 13 | MODEL(1, "已激活"), 14 | 15 | PACKAGE(2, "已加载"), 16 | 17 | ; 18 | 19 | private final Integer code; 20 | 21 | private final String name; 22 | 23 | RunType(Integer code, String name) { 24 | this.code = code; 25 | this.name = name; 26 | } 27 | 28 | private static final Map MAP; 29 | 30 | static { 31 | MAP = new HashMap<>(); 32 | RunType[] values = RunType.values(); 33 | for (RunType value : values) { 34 | MAP.put(value.code, value); 35 | } 36 | } 37 | 38 | public static RunType getByCode(Integer code) { 39 | return MAP.get(code); 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/RuntimeInfo.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data; 2 | 3 | import org.json.JSONException; 4 | import org.json.JSONObject; 5 | 6 | import java.util.Objects; 7 | 8 | import tkaxv7s.xposed.sesame.util.FileUtil; 9 | import tkaxv7s.xposed.sesame.util.UserIdMap; 10 | import tkaxv7s.xposed.sesame.util.Log; 11 | 12 | /** 13 | * @author Constanline 14 | * @since 2023/08/18 15 | */ 16 | public class RuntimeInfo { 17 | private static final String TAG = RuntimeInfo.class.getSimpleName(); 18 | 19 | private static RuntimeInfo instance; 20 | 21 | private final String userId; 22 | 23 | private JSONObject joAll; 24 | 25 | private JSONObject joCurrent; 26 | 27 | public enum RuntimeInfoKey { 28 | ForestPauseTime 29 | } 30 | 31 | public static RuntimeInfo getInstance() { 32 | if (instance == null || !Objects.equals(instance.userId, UserIdMap.getCurrentUid())) { 33 | instance = new RuntimeInfo(); 34 | } 35 | return instance; 36 | } 37 | 38 | private RuntimeInfo() { 39 | userId = UserIdMap.getCurrentUid(); 40 | String content = FileUtil.readFromFile(FileUtil.runtimeInfoFile()); 41 | try { 42 | joAll = new JSONObject(content); 43 | } catch (Exception ignored) { 44 | joAll = new JSONObject(); 45 | } 46 | try { 47 | if (!joAll.has(userId)) { 48 | joAll.put(userId, new JSONObject()); 49 | } 50 | } catch (Exception ignored) { 51 | } 52 | try { 53 | joCurrent = joAll.getJSONObject(userId); 54 | } catch (Exception ignored) { 55 | joCurrent = new JSONObject(); 56 | } 57 | } 58 | 59 | public void save() { 60 | FileUtil.write2File(joAll.toString(), FileUtil.runtimeInfoFile()); 61 | } 62 | 63 | public Object get(RuntimeInfoKey key) throws JSONException { 64 | return joCurrent.opt(key.name()); 65 | } 66 | 67 | public String getString(String key) { 68 | return joCurrent.optString(key); 69 | } 70 | 71 | public Long getLong(String key, long def) { 72 | return joCurrent.optLong(key, def); 73 | } 74 | 75 | public boolean getBool(String key, boolean def) { 76 | return joCurrent.optBoolean(key, def); 77 | } 78 | 79 | public String getString(RuntimeInfoKey key) { 80 | return joCurrent.optString(key.name()); 81 | } 82 | 83 | public Long getLong(RuntimeInfoKey key) { 84 | return joCurrent.optLong(key.name(), 0L); 85 | } 86 | 87 | public void put(RuntimeInfoKey key, Object value) { 88 | put(key.name(), value); 89 | } 90 | 91 | public void put(String key, Object value) { 92 | try { 93 | joCurrent.put(key, value); 94 | joAll.put(userId, joCurrent); 95 | } catch (JSONException e) { 96 | Log.i(TAG, "put err:"); 97 | Log.printStackTrace(TAG, e); 98 | } 99 | save(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/ViewAppInfo.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data; 2 | 3 | import android.content.ContentResolver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.pm.ApplicationInfo; 7 | import android.content.pm.PackageInfo; 8 | import android.content.pm.PackageManager; 9 | import android.net.Uri; 10 | import android.os.Bundle; 11 | import lombok.Getter; 12 | import lombok.Setter; 13 | import tkaxv7s.xposed.sesame.R; 14 | 15 | public final class ViewAppInfo { 16 | 17 | @Getter 18 | private static Context context = null; 19 | 20 | @Getter 21 | private static String appTitle = ""; 22 | 23 | @Getter 24 | private static String appVersion = ""; 25 | 26 | @Setter 27 | @Getter 28 | private static RunType runType = RunType.DISABLE; 29 | 30 | public static void init(Context context) { 31 | ViewAppInfo.context = context; 32 | appTitle = context.getString(R.string.app_name); 33 | try { 34 | PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); 35 | appVersion = packageInfo.versionName; 36 | appTitle = appTitle + " " + appVersion; 37 | } catch (PackageManager.NameNotFoundException ignored) { 38 | } 39 | checkRunType(); 40 | } 41 | 42 | public static RunType checkRunType() { 43 | if (runType != null) { 44 | return runType; 45 | } 46 | try { 47 | if (context == null) { 48 | return runType = RunType.DISABLE; 49 | } 50 | ContentResolver contentResolver = context.getContentResolver(); 51 | Uri uri = Uri.parse("content://me.weishu.exposed.CP/"); 52 | Bundle result = null; 53 | try { 54 | result = contentResolver.call(uri, "active", null, null); 55 | } catch (RuntimeException e) { 56 | // TaiChi is killed, try invoke 57 | try { 58 | Intent intent = new Intent("me.weishu.exp.ACTION_ACTIVE"); 59 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 60 | context.startActivity(intent); 61 | } catch (Throwable e1) { 62 | return runType = RunType.DISABLE; 63 | } 64 | } 65 | if (result == null) { 66 | result = contentResolver.call(uri, "active", null, null); 67 | } 68 | 69 | if (result == null) { 70 | return runType = RunType.DISABLE; 71 | } 72 | if (result.getBoolean("active", false)) { 73 | return runType = RunType.MODEL; 74 | } 75 | return runType = RunType.DISABLE; 76 | } catch (Throwable ignored) { 77 | } 78 | return runType = RunType.DISABLE; 79 | } 80 | 81 | public static void setRunTypeByCode(Integer runTypeCode) { 82 | RunType newRunType = RunType.getByCode(runTypeCode); 83 | if (newRunType == null) { 84 | newRunType = RunType.DISABLE; 85 | } 86 | ViewAppInfo.runType = newRunType; 87 | } 88 | 89 | /** 90 | * 判断当前应用是否是debug状态 91 | */ 92 | public static boolean isApkInDebug() { 93 | try { 94 | ApplicationInfo info = context.getApplicationInfo(); 95 | return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 96 | } catch (Exception e) { 97 | return false; 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/modelFieldExt/BooleanModelField.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data.modelFieldExt; 2 | 3 | 4 | import android.content.Context; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.LinearLayout; 8 | import android.widget.Switch; 9 | import tkaxv7s.xposed.sesame.data.ModelField; 10 | import tkaxv7s.xposed.sesame.util.JsonUtil; 11 | 12 | public class BooleanModelField extends ModelField { 13 | 14 | public BooleanModelField(String code, String name, Boolean value) { 15 | super(code, name, value); 16 | } 17 | 18 | @Override 19 | public void setValue(Object value) { 20 | if (value == null) { 21 | value = defaultValue; 22 | } 23 | this.value = JsonUtil.parseObject(value, Boolean.class); 24 | } 25 | 26 | @Override 27 | public Boolean getValue() { 28 | return (Boolean) value; 29 | } 30 | 31 | @Override 32 | public View getView(Context context) { 33 | Switch sw = new Switch(context); 34 | sw.setText(getName()); 35 | sw.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 36 | sw.setMinHeight(150); 37 | sw.setMaxHeight(180); 38 | sw.setPaddingRelative(40, 0, 40, 0); 39 | sw.setChecked(getValue()); 40 | sw.setOnClickListener(v -> setValue(((Switch) v).isChecked())); 41 | return sw; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/modelFieldExt/ChoiceModelField.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data.modelFieldExt; 2 | 3 | 4 | import android.content.Context; 5 | import android.graphics.Color; 6 | import android.view.Gravity; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.Button; 10 | import android.widget.LinearLayout; 11 | 12 | import com.fasterxml.jackson.annotation.JsonIgnore; 13 | 14 | import tkaxv7s.xposed.sesame.R; 15 | import tkaxv7s.xposed.sesame.data.ModelField; 16 | import tkaxv7s.xposed.sesame.ui.ChoiceDialog; 17 | import tkaxv7s.xposed.sesame.util.JsonUtil; 18 | 19 | public class ChoiceModelField extends ModelField { 20 | 21 | private CharSequence[] choiceArray; 22 | 23 | public ChoiceModelField(String code, String name, Integer value) { 24 | super(code, name, value); 25 | } 26 | 27 | public ChoiceModelField(String code, String name, Integer value, CharSequence[] choiceArray) { 28 | super(code, name, value); 29 | this.choiceArray = choiceArray; 30 | } 31 | 32 | @JsonIgnore 33 | public CharSequence[] getChoiceArray() { 34 | return choiceArray; 35 | } 36 | 37 | @Override 38 | public void setValue(Object value) { 39 | if (value == null) { 40 | value = defaultValue; 41 | } 42 | this.value = JsonUtil.parseObject(value, Integer.class); 43 | } 44 | 45 | @Override 46 | public Integer getValue() { 47 | return (Integer) value; 48 | } 49 | 50 | @Override 51 | public View getView(Context context) { 52 | Button btn = new Button(context); 53 | btn.setText(getName()); 54 | btn.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 55 | btn.setTextColor(Color.parseColor("#008175")); 56 | btn.setBackground(context.getResources().getDrawable(R.drawable.button)); 57 | btn.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); 58 | btn.setMinHeight(150); 59 | btn.setMaxHeight(180); 60 | btn.setPaddingRelative(40, 0, 40, 0); 61 | btn.setAllCaps(false); 62 | btn.setOnClickListener(v -> ChoiceDialog.show(v.getContext(), ((Button) v).getText(), this)); 63 | return btn; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/modelFieldExt/EmptyModelField.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data.modelFieldExt; 2 | 3 | import android.app.AlertDialog; 4 | import android.content.Context; 5 | import android.graphics.Color; 6 | import android.view.Gravity; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.Button; 10 | import android.widget.LinearLayout; 11 | import android.widget.Toast; 12 | import com.fasterxml.jackson.annotation.JsonIgnore; 13 | import tkaxv7s.xposed.sesame.R; 14 | import tkaxv7s.xposed.sesame.data.ModelField; 15 | 16 | public class EmptyModelField extends ModelField { 17 | 18 | private final Runnable clickListener; 19 | 20 | public EmptyModelField(String code, String name) { 21 | super(code, name, null); 22 | this.clickListener = null; 23 | } 24 | 25 | public EmptyModelField(String code, String name, Runnable clickListener) { 26 | super(code, name, null); 27 | this.clickListener = clickListener; 28 | } 29 | 30 | @Override 31 | public void setValue(Object value) { 32 | } 33 | 34 | @Override 35 | public Object getValue() { 36 | return null; 37 | } 38 | 39 | @JsonIgnore 40 | public View getView(Context context) { 41 | Button btn = new Button(context); 42 | btn.setText(getName()); 43 | btn.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 44 | btn.setTextColor(Color.parseColor("#008175")); 45 | btn.setBackground(context.getResources().getDrawable(R.drawable.button)); 46 | btn.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); 47 | btn.setMinHeight(150); 48 | btn.setMaxHeight(180); 49 | btn.setPaddingRelative(40, 0, 40, 0); 50 | btn.setAllCaps(false); 51 | if (clickListener != null) { 52 | btn.setOnClickListener(v -> { 53 | // 创建 AlertDialog.Builder 对象 54 | new AlertDialog.Builder(context) 55 | .setTitle(R.string.alert) 56 | .setMessage(R.string.are_you_sure) 57 | .setPositiveButton(R.string.ok, (dialog, id) -> clickListener.run()) 58 | .setNegativeButton(R.string.cancel, (dialog, id) -> { 59 | dialog.dismiss(); 60 | }) 61 | .create() 62 | .show(); 63 | }); 64 | } else { 65 | btn.setOnClickListener(v -> Toast.makeText(context, "无配置项", Toast.LENGTH_SHORT).show()); 66 | } 67 | return btn; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/modelFieldExt/IntegerModelField.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data.modelFieldExt; 2 | 3 | 4 | import android.content.Context; 5 | import android.graphics.Color; 6 | import android.view.Gravity; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.Button; 10 | import android.widget.LinearLayout; 11 | import tkaxv7s.xposed.sesame.R; 12 | import tkaxv7s.xposed.sesame.data.ModelField; 13 | import tkaxv7s.xposed.sesame.ui.StringDialog; 14 | import tkaxv7s.xposed.sesame.util.Log; 15 | 16 | public class IntegerModelField extends ModelField { 17 | 18 | private Integer minLimit; 19 | 20 | private Integer maxLimit; 21 | 22 | public IntegerModelField(String code, String name, Integer value) { 23 | super(code, name, value); 24 | } 25 | 26 | public IntegerModelField(String code, String name, Integer value, Integer minLimit, Integer maxLimit) { 27 | super(code, name, value); 28 | this.minLimit = minLimit; 29 | this.maxLimit = maxLimit; 30 | } 31 | 32 | @Override 33 | public void setValue(Object value) { 34 | Integer newValue; 35 | if (value == null) { 36 | newValue = (Integer) defaultValue; 37 | } else { 38 | newValue = Integer.parseInt(value.toString()); 39 | } 40 | if (minLimit != null) { 41 | newValue = Math.max(minLimit, newValue); 42 | } 43 | if (maxLimit != null) { 44 | newValue = Math.min(maxLimit, newValue); 45 | } 46 | this.value = newValue; 47 | } 48 | 49 | @Override 50 | public Integer getValue() { 51 | return (Integer) value; 52 | } 53 | 54 | @Override 55 | public View getView(Context context) { 56 | Button btn = new Button(context); 57 | btn.setText(getName()); 58 | btn.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 59 | btn.setTextColor(Color.parseColor("#008175")); 60 | btn.setBackground(context.getResources().getDrawable(R.drawable.button)); 61 | btn.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); 62 | btn.setMinHeight(150); 63 | btn.setMaxHeight(180); 64 | btn.setPaddingRelative(40, 0, 40, 0); 65 | btn.setAllCaps(false); 66 | btn.setOnClickListener(v -> StringDialog.showEditDialog(v.getContext(), ((Button) v).getText(), this)); 67 | return btn; 68 | } 69 | 70 | public static class MultiplyIntegerModelField extends IntegerModelField { 71 | 72 | private final Integer multiple; 73 | 74 | public MultiplyIntegerModelField(String code, String name, Integer value, Integer minLimit, Integer maxLimit, Integer multiple) { 75 | super(code, name, value, minLimit, maxLimit); 76 | this.multiple = multiple; 77 | } 78 | 79 | @Override 80 | public void setConfigValue(String value) { 81 | if (value == null) { 82 | setValue(null); 83 | return; 84 | } 85 | try { 86 | setValue(Integer.parseInt(value) * multiple); 87 | } catch (Exception e) { 88 | Log.printStackTrace(e); 89 | setValue(null); 90 | } 91 | } 92 | 93 | @Override 94 | public String getConfigValue() { 95 | return String.valueOf(getValue() / multiple); 96 | } 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/modelFieldExt/ListModelField.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data.modelFieldExt; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.view.Gravity; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.Button; 9 | import android.widget.LinearLayout; 10 | import com.fasterxml.jackson.core.type.TypeReference; 11 | import tkaxv7s.xposed.sesame.R; 12 | import tkaxv7s.xposed.sesame.data.ModelField; 13 | import tkaxv7s.xposed.sesame.ui.StringDialog; 14 | import tkaxv7s.xposed.sesame.util.JsonUtil; 15 | 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | 19 | public class ListModelField extends ModelField { 20 | 21 | private static final TypeReference> typeReference = new TypeReference>() { 22 | }; 23 | 24 | public ListModelField(String code, String name, List value) { 25 | super(code, name, value); 26 | } 27 | 28 | @Override 29 | public void setValue(Object value) { 30 | if (value == null) { 31 | value = defaultValue; 32 | } 33 | this.value = JsonUtil.parseObject(value, typeReference); 34 | } 35 | 36 | @Override 37 | public List getValue() { 38 | return (List) value; 39 | } 40 | 41 | @Override 42 | public View getView(Context context) { 43 | Button btn = new Button(context); 44 | btn.setText(getName()); 45 | btn.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 46 | btn.setTextColor(Color.parseColor("#008175")); 47 | btn.setBackground(context.getResources().getDrawable(R.drawable.button)); 48 | btn.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); 49 | btn.setMinHeight(150); 50 | btn.setMaxHeight(180); 51 | btn.setPaddingRelative(40, 0, 40, 0); 52 | btn.setAllCaps(false); 53 | btn.setOnClickListener(v -> StringDialog.showEditDialog(v.getContext(), ((Button) v).getText(), this)); 54 | return btn; 55 | } 56 | 57 | public static class ListJoinCommaToStringModelField extends ListModelField { 58 | 59 | public ListJoinCommaToStringModelField(String code, String name, List value) { 60 | super(code, name, value); 61 | } 62 | 63 | @Override 64 | public void setConfigValue(String value) { 65 | if (value == null) { 66 | setValue(null); 67 | return; 68 | } 69 | List list = new ArrayList<>(); 70 | for (String str : value.split(",")) { 71 | if (!str.isEmpty()) { 72 | list.add(str); 73 | } 74 | } 75 | setValue(list); 76 | } 77 | 78 | @Override 79 | public String getConfigValue() { 80 | return String.join(",", getValue()); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/modelFieldExt/MapModelField.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data.modelFieldExt; 2 | 3 | import com.fasterxml.jackson.core.type.TypeReference; 4 | import tkaxv7s.xposed.sesame.data.ModelField; 5 | import tkaxv7s.xposed.sesame.util.JsonUtil; 6 | 7 | import java.util.Map; 8 | 9 | public class MapModelField extends ModelField { 10 | 11 | private static final TypeReference> typeReference = new TypeReference>() { 12 | }; 13 | 14 | public MapModelField(String code, String name, Map value) { 15 | super(code, name, value); 16 | } 17 | 18 | @Override 19 | public void setValue(Object value) { 20 | if (value == null) { 21 | value = defaultValue; 22 | } 23 | this.value = JsonUtil.parseObject(value, typeReference); 24 | } 25 | 26 | @Override 27 | public Map getValue() { 28 | return (Map) value; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/modelFieldExt/SelectModelField.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data.modelFieldExt; 2 | 3 | 4 | import android.content.Context; 5 | import android.graphics.Color; 6 | import android.view.Gravity; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.Button; 10 | import android.widget.LinearLayout; 11 | import com.fasterxml.jackson.annotation.JsonIgnore; 12 | import com.fasterxml.jackson.core.type.TypeReference; 13 | import tkaxv7s.xposed.sesame.R; 14 | import tkaxv7s.xposed.sesame.data.ModelField; 15 | import tkaxv7s.xposed.sesame.entity.IdAndName; 16 | import tkaxv7s.xposed.sesame.entity.KVNode; 17 | import tkaxv7s.xposed.sesame.ui.ListDialog; 18 | import tkaxv7s.xposed.sesame.util.JsonUtil; 19 | 20 | import java.util.LinkedHashMap; 21 | import java.util.List; 22 | import java.util.Map; 23 | 24 | /** 25 | * 数据结构说明 26 | * KVNode, Boolean> 27 | * Map 表示已选择的数据与已经设置的数量映射关系,如果未设置数量,则默认为0 28 | * Boolean 表示是否需要设置数量 29 | * List 需要选择的数据 30 | */ 31 | public class SelectModelField extends ModelField { 32 | 33 | private static final TypeReference, Boolean>> typeReference = new TypeReference, Boolean>>() { 34 | }; 35 | 36 | private List idAndNameList; 37 | 38 | public SelectModelField(String code, String name, KVNode, Boolean> value, List idAndNameList) { 39 | super(code, name, value); 40 | this.idAndNameList = idAndNameList; 41 | } 42 | 43 | @JsonIgnore 44 | public List getIdAndNameList() { 45 | return idAndNameList; 46 | } 47 | 48 | @Override 49 | public void setValue(Object value) { 50 | if (value == null) { 51 | value = defaultValue; 52 | } 53 | this.value = JsonUtil.parseObject(value, typeReference); 54 | } 55 | 56 | @Override 57 | public KVNode, Boolean> getValue() { 58 | return (KVNode, Boolean>) value; 59 | } 60 | 61 | @Override 62 | public View getView(Context context) { 63 | Button btn = new Button(context); 64 | btn.setText(getName()); 65 | btn.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 66 | btn.setTextColor(Color.parseColor("#008175")); 67 | btn.setBackground(context.getResources().getDrawable(R.drawable.button)); 68 | btn.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); 69 | btn.setMinHeight(150); 70 | btn.setMaxHeight(180); 71 | btn.setPaddingRelative(40, 0, 40, 0); 72 | btn.setAllCaps(false); 73 | btn.setOnClickListener(v -> ListDialog.show(v.getContext(), ((Button) v).getText(), this)); 74 | return btn; 75 | } 76 | 77 | public static class SelectOneModelField extends SelectModelField { 78 | 79 | public SelectOneModelField(String code, String name, KVNode, Boolean> value, List idAndNameList) { 80 | super(code, name, value, idAndNameList); 81 | } 82 | 83 | @Override 84 | public View getView(Context context) { 85 | Button btn = new Button(context); 86 | btn.setText(getName()); 87 | btn.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 88 | btn.setTextColor(Color.parseColor("#008175")); 89 | btn.setBackground(context.getResources().getDrawable(R.drawable.button)); 90 | btn.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); 91 | btn.setMinHeight(150); 92 | btn.setPaddingRelative(40, 0, 40, 0); 93 | btn.setAllCaps(false); 94 | btn.setOnClickListener(v -> ListDialog.show(v.getContext(), ((Button) v).getText(), this, ListDialog.ListType.RADIO)); 95 | return btn; 96 | } 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/modelFieldExt/StringModelField.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data.modelFieldExt; 2 | 3 | 4 | import android.content.Context; 5 | import android.graphics.Color; 6 | import android.view.Gravity; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.Button; 10 | import android.widget.LinearLayout; 11 | import tkaxv7s.xposed.sesame.R; 12 | import tkaxv7s.xposed.sesame.data.ModelField; 13 | import tkaxv7s.xposed.sesame.ui.StringDialog; 14 | 15 | public class StringModelField extends ModelField { 16 | 17 | public StringModelField(String code, String name, String value) { 18 | super(code, name, value); 19 | } 20 | 21 | @Override 22 | public void setValue(Object value) { 23 | if (value == null) { 24 | value = defaultValue; 25 | } 26 | this.value = String.valueOf(value); 27 | } 28 | 29 | @Override 30 | public String getValue() { 31 | return (String) value; 32 | } 33 | 34 | @Override 35 | public View getView(Context context) { 36 | Button btn = new Button(context); 37 | btn.setText(getName()); 38 | btn.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 39 | btn.setTextColor(Color.parseColor("#008175")); 40 | btn.setBackground(context.getResources().getDrawable(R.drawable.button)); 41 | btn.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); 42 | btn.setMinHeight(150); 43 | btn.setMaxHeight(180); 44 | btn.setPaddingRelative(40, 0, 40, 0); 45 | btn.setAllCaps(false); 46 | btn.setOnClickListener(v -> StringDialog.showEditDialog(v.getContext(), ((Button) v).getText(), this)); 47 | return btn; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/data/modelFieldExt/TextModelField.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.data.modelFieldExt; 2 | 3 | 4 | import android.content.Context; 5 | import android.graphics.Color; 6 | import android.view.Gravity; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.Button; 10 | import android.widget.LinearLayout; 11 | import android.widget.TextView; 12 | import com.fasterxml.jackson.annotation.JsonIgnore; 13 | import tkaxv7s.xposed.sesame.R; 14 | import tkaxv7s.xposed.sesame.data.ModelField; 15 | import tkaxv7s.xposed.sesame.ui.StringDialog; 16 | 17 | public class TextModelField extends ModelField { 18 | 19 | public TextModelField(String code, String name, String value) { 20 | super(code, name, value); 21 | } 22 | 23 | @Override 24 | public void setValue(Object value) { 25 | if (value == null) { 26 | value = defaultValue; 27 | } 28 | this.value = String.valueOf(value); 29 | } 30 | 31 | @Override 32 | public String getValue() { 33 | return (String) value; 34 | } 35 | 36 | @JsonIgnore 37 | public View getView(Context context) { 38 | Button btn = new Button(context); 39 | btn.setText(getName()); 40 | btn.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 41 | btn.setTextColor(Color.parseColor("#008175")); 42 | btn.setBackground(context.getResources().getDrawable(R.drawable.button)); 43 | btn.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); 44 | btn.setMinHeight(150); 45 | btn.setMaxHeight(180); 46 | btn.setPaddingRelative(40, 0, 40, 0); 47 | btn.setAllCaps(false); 48 | btn.setOnClickListener(v -> StringDialog.showReadDialog(v.getContext(), ((Button) v).getText(), this)); 49 | return btn; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/entity/AlipayBeach.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.entity; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Set; 7 | 8 | import tkaxv7s.xposed.sesame.util.BeachIdMap; 9 | 10 | public class AlipayBeach extends IdAndName { 11 | private static List list; 12 | 13 | public AlipayBeach(String i, String n) { 14 | id = i; 15 | name = n; 16 | } 17 | 18 | public static List getList() { 19 | if (list == null || BeachIdMap.shouldReload) { 20 | list = new ArrayList<>(); 21 | Set> idSet = BeachIdMap.getIdMap().entrySet(); 22 | for (Map.Entry entry : idSet) { 23 | list.add(new AlipayBeach(entry.getKey(), entry.getValue())); 24 | } 25 | } 26 | return list; 27 | } 28 | 29 | public static void remove(String id) { 30 | getList(); 31 | for (int i = 0; i < list.size(); i++) { 32 | if (list.get(i).id.equals(id)) { 33 | list.remove(i); 34 | break; 35 | } 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/entity/AlipayReserve.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.entity; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Set; 7 | 8 | import tkaxv7s.xposed.sesame.util.ReserveIdMap; 9 | 10 | public class AlipayReserve extends IdAndName { 11 | private static List list; 12 | 13 | public AlipayReserve(String i, String n) { 14 | id = i; 15 | name = n; 16 | } 17 | 18 | public static List getList() { 19 | if (list == null || ReserveIdMap.shouldReload) { 20 | list = new ArrayList<>(); 21 | Set> idSet = ReserveIdMap.getIdMap().entrySet(); 22 | for (Map.Entry entry : idSet) { 23 | list.add(new AlipayReserve(entry.getKey(), entry.getValue())); 24 | } 25 | } 26 | return list; 27 | } 28 | 29 | public static void remove(String id) { 30 | getList(); 31 | for (int i = 0; i < list.size(); i++) { 32 | if (list.get(i).id.equals(id)) { 33 | list.remove(i); 34 | break; 35 | } 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/entity/AlipayUser.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.entity; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Set; 7 | 8 | import tkaxv7s.xposed.sesame.util.UserIdMap; 9 | 10 | public class AlipayUser extends IdAndName { 11 | private static List list; 12 | 13 | public AlipayUser(String i, String n) { 14 | id = i; 15 | name = n; 16 | } 17 | 18 | public static List getList() { 19 | if (list == null || UserIdMap.shouldReload) { 20 | list = new ArrayList<>(); 21 | Set> idSet = UserIdMap.getIdMap().entrySet(); 22 | for (Map.Entry entry : idSet) { 23 | list.add(new AlipayUser(entry.getKey(), entry.getValue())); 24 | } 25 | } 26 | return list; 27 | } 28 | 29 | public static void remove(String id) { 30 | getList(); 31 | for (int i = 0; i < list.size(); i++) { 32 | if (list.get(i).id.equals(id)) { 33 | list.remove(i); 34 | break; 35 | } 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/entity/AreaCode.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.entity; 2 | 3 | import org.json.JSONArray; 4 | import org.json.JSONException; 5 | import org.json.JSONObject; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import tkaxv7s.xposed.sesame.util.FileUtil; 11 | import tkaxv7s.xposed.sesame.util.Log; 12 | 13 | public class AreaCode extends IdAndName { 14 | private static final String TAG = AreaCode.class.getSimpleName(); 15 | private static List list; 16 | 17 | public AreaCode(String i, String n) { 18 | id = i; 19 | name = n; 20 | } 21 | 22 | public static List getList() { 23 | if (list == null) { 24 | String cityCode = FileUtil.readFromFile(FileUtil.getCityCodeFile()); 25 | JSONArray ja; 26 | try { 27 | ja = new JSONArray(cityCode); 28 | } catch (Throwable e) { 29 | cityCode = "[" + 30 | "{\"cityCode\":\"320100\",\"cityName\":\"南京市\"}," + 31 | "{\"cityCode\":\"330100\",\"cityName\":\"杭州市\"}," + 32 | "{\"cityCode\":\"350100\",\"cityName\":\"福州市\"}," + 33 | "{\"cityCode\":\"370100\",\"cityName\":\"济南市\"}," + 34 | "{\"cityCode\":\"430100\",\"cityName\":\"长沙市\"}," + 35 | "{\"cityCode\":\"440100\",\"cityName\":\"广州市\"}" + 36 | "]"; 37 | try { 38 | ja = new JSONArray(cityCode); 39 | } catch (JSONException ex) { 40 | ja = new JSONArray(); 41 | } 42 | } 43 | 44 | list = new ArrayList<>(); 45 | try { 46 | for (int i = 0; i < ja.length(); i++) { 47 | JSONObject jo = ja.getJSONObject(i); 48 | list.add(new AreaCode(jo.getString("cityCode"), jo.getString("cityName"))); 49 | } 50 | } catch (Throwable th) { 51 | Log.printStackTrace(TAG, th); 52 | } 53 | } 54 | return list; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/entity/CooperateUser.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.entity; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Set; 7 | 8 | import tkaxv7s.xposed.sesame.util.CooperationIdMap; 9 | 10 | public class CooperateUser extends IdAndName { 11 | private static List list; 12 | 13 | public CooperateUser(String i, String n) { 14 | id = i; 15 | name = n; 16 | } 17 | 18 | public static List getList() { 19 | if (list == null || CooperationIdMap.shouldReload) { 20 | list = new ArrayList<>(); 21 | Set> idSet = CooperationIdMap.getIdMap().entrySet(); 22 | for (Map.Entry entry : idSet) { 23 | list.add(new CooperateUser(entry.getKey(), entry.getValue())); 24 | } 25 | } 26 | return list; 27 | } 28 | 29 | public static void remove(String id) { 30 | getList(); 31 | for (int i = 0; i < list.size(); i++) { 32 | if (list.get(i).id.equals(id)) { 33 | list.remove(i); 34 | break; 35 | } 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/entity/FriendWatch.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.entity; 2 | 3 | import org.json.JSONObject; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import tkaxv7s.xposed.sesame.util.FileUtil; 9 | import tkaxv7s.xposed.sesame.util.UserIdMap; 10 | import tkaxv7s.xposed.sesame.util.Log; 11 | import tkaxv7s.xposed.sesame.util.StringUtil; 12 | 13 | /** 14 | * @author Constanline 15 | * @since 2023/08/08 16 | */ 17 | public class FriendWatch extends IdAndName { 18 | 19 | private static final String TAG = FriendWatch.class.getSimpleName(); 20 | 21 | public String startTime; 22 | 23 | public int allGet; 24 | 25 | public int weekGet; 26 | 27 | public FriendWatch(String id, String name) { 28 | this.id = id; 29 | this.name = name; 30 | } 31 | 32 | @Override 33 | public int compareTo(IdAndName o) { 34 | FriendWatch another = (FriendWatch) o; 35 | if (this.weekGet > another.weekGet) { 36 | return -1; 37 | } else if (this.weekGet < another.weekGet) { 38 | return 1; 39 | } 40 | return super.compareTo(o); 41 | } 42 | 43 | public static List getList() { 44 | ArrayList list = new ArrayList<>(); 45 | String strFriendWatch = FileUtil.readFromFile(FileUtil.getFriendWatchFile()); 46 | try { 47 | JSONObject joFriendWatch; 48 | if (StringUtil.isEmpty(strFriendWatch)) { 49 | joFriendWatch = new JSONObject(); 50 | } else { 51 | joFriendWatch = new JSONObject(strFriendWatch); 52 | } 53 | for (String id : UserIdMap.getFriendIds()) { 54 | JSONObject friend = joFriendWatch.optJSONObject(id); 55 | if (friend == null) { 56 | friend = new JSONObject(); 57 | } 58 | String name = UserIdMap.getNameById(id); 59 | FriendWatch friendWatch = new FriendWatch(id, name); 60 | friendWatch.startTime = friend.optString("startTime", "无"); 61 | friendWatch.weekGet = friend.optInt("weekGet", 0); 62 | friendWatch.allGet = friend.optInt("allGet", 0) + friendWatch.weekGet; 63 | String showText = name + "(开始统计时间:" + friendWatch.startTime + ")\n\n"; 64 | showText = showText + "周收:" + friendWatch.weekGet + " 总收:" + friendWatch.allGet; 65 | friendWatch.name = showText; 66 | list.add(friendWatch); 67 | } 68 | } catch (Throwable t) { 69 | Log.i(TAG, "FriendWatch getList: "); 70 | Log.printStackTrace(TAG, t); 71 | try { 72 | FileUtil.write2File(new JSONObject().toString(), FileUtil.getFriendWatchFile()); 73 | } catch (Exception e) { 74 | Log.printStackTrace(e); 75 | } 76 | } 77 | 78 | return list; 79 | } 80 | } -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/entity/IdAndName.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.entity; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import tkaxv7s.xposed.sesame.util.HanziToPinyin; 7 | 8 | public abstract class IdAndName implements Comparable { 9 | 10 | public String name; 11 | 12 | public String id; 13 | 14 | private ArrayList pinyin; 15 | 16 | public ArrayList getPinyin() { 17 | if (pinyin != null) { 18 | return pinyin; 19 | } 20 | ArrayList list = HanziToPinyin.getInstance().get(name); 21 | pinyin = new ArrayList<>(list.size()); 22 | for (HanziToPinyin.Token token : list) { 23 | pinyin.add(token.target); 24 | } 25 | return pinyin; 26 | } 27 | 28 | @Override 29 | public int compareTo(IdAndName o) { 30 | List list1 = this.getPinyin(); 31 | List list2 = o.getPinyin(); 32 | int i = 0; 33 | while (i < list1.size() && i < list2.size()) { 34 | if (list1.get(i).compareTo(list2.get(i)) != 0) { 35 | return list1.get(i).compareTo(list2.get(i)); 36 | } 37 | i++; 38 | } 39 | return list1.size() - list2.size(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/entity/KVNode.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.Data; 6 | 7 | @Data 8 | public class KVNode implements Serializable { 9 | 10 | private K key; 11 | 12 | private V value; 13 | 14 | public KVNode() { 15 | } 16 | 17 | public KVNode(K key, V value) { 18 | this.key = key; 19 | this.value = value; 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/entity/RpcEntity.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.entity; 2 | 3 | import lombok.Getter; 4 | 5 | @Getter 6 | public class RpcEntity { 7 | 8 | private final Thread requestThread; 9 | 10 | private final String requestMethod; 11 | 12 | private final String requestData; 13 | 14 | private volatile Boolean hasResult = false; 15 | 16 | private volatile Boolean hasError = false; 17 | 18 | private volatile Object responseObject; 19 | 20 | private volatile String responseString; 21 | 22 | public RpcEntity(String requestMethod, String requestData) { 23 | this.requestThread = Thread.currentThread(); 24 | this.requestMethod = requestMethod; 25 | this.requestData = requestData; 26 | } 27 | 28 | public RpcEntity() { 29 | this(null, null); 30 | } 31 | 32 | public void setResponseObject(Object result, String resultStr) { 33 | this.hasResult = true; 34 | this.responseObject = result; 35 | this.responseString = resultStr; 36 | } 37 | 38 | public void setError() { 39 | this.hasError = true; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/hook/Toast.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.hook; 2 | 3 | import android.content.Context; 4 | import android.os.Handler; 5 | 6 | import tkaxv7s.xposed.sesame.model.normal.base.BaseModel; 7 | import tkaxv7s.xposed.sesame.util.Log; 8 | 9 | public class Toast { 10 | private static final String TAG = Toast.class.getSimpleName(); 11 | 12 | public static void show(CharSequence cs) { 13 | show(cs, false); 14 | } 15 | 16 | public static void show(CharSequence cs, boolean force) { 17 | Context context = ApplicationHook.getContext(); 18 | if (context != null && (force || BaseModel.getShowToast().getValue())) { 19 | show(context, ApplicationHook.getMainHandler(), cs); 20 | } 21 | } 22 | 23 | public static void show(Context context, Handler handler, CharSequence cs) { 24 | try { 25 | handler.post(() -> { 26 | try { 27 | android.widget.Toast toast = android.widget.Toast.makeText(context, cs, android.widget.Toast.LENGTH_SHORT); 28 | toast.setGravity(toast.getGravity(), toast.getXOffset(), BaseModel.getToastOffsetY().getValue()); 29 | toast.show(); 30 | } catch (Throwable t) { 31 | Log.i(TAG, "show.run err:"); 32 | Log.printStackTrace(TAG, t); 33 | } 34 | }); 35 | } catch (Throwable t) { 36 | Log.i(TAG, "show err:"); 37 | Log.printStackTrace(TAG, t); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/base/ModelOrder.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.base; 2 | 3 | import tkaxv7s.xposed.sesame.data.Model; 4 | import tkaxv7s.xposed.sesame.model.normal.answerAI.AnswerAI; 5 | import tkaxv7s.xposed.sesame.model.normal.base.BaseModel; 6 | import tkaxv7s.xposed.sesame.model.task.ancientTree.AncientTree; 7 | import tkaxv7s.xposed.sesame.model.task.antCooperate.AntCooperate; 8 | import tkaxv7s.xposed.sesame.model.task.antFarm.AntFarm; 9 | import tkaxv7s.xposed.sesame.model.task.antForest.AntForestV2; 10 | import tkaxv7s.xposed.sesame.model.task.antMember.AntMember; 11 | import tkaxv7s.xposed.sesame.model.task.antOcean.AntOcean; 12 | import tkaxv7s.xposed.sesame.model.task.antOrchard.AntOrchard; 13 | import tkaxv7s.xposed.sesame.model.task.antSports.AntSports; 14 | import tkaxv7s.xposed.sesame.model.task.antStall.AntStall; 15 | import tkaxv7s.xposed.sesame.model.task.gameCenter.GameCenter; 16 | import tkaxv7s.xposed.sesame.model.task.greenFinance.GreenFinance; 17 | import tkaxv7s.xposed.sesame.model.task.kbMember.KBMember; 18 | import tkaxv7s.xposed.sesame.model.task.otherTask.OtherTask; 19 | import tkaxv7s.xposed.sesame.model.task.reserve.Reserve; 20 | import tkaxv7s.xposed.sesame.model.task.sesameCredit.SesameCredit; 21 | import tkaxv7s.xposed.sesame.model.task.welfareCenter.WelfareCenter; 22 | 23 | import java.util.Arrays; 24 | import java.util.Collections; 25 | import java.util.List; 26 | 27 | public class ModelOrder { 28 | 29 | private static final Class[] array = new Class[]{ 30 | BaseModel.class 31 | , AntForestV2.class 32 | , AntCooperate.class 33 | , AntFarm.class 34 | , Reserve.class 35 | , AntOrchard.class 36 | , AncientTree.class 37 | , AntSports.class 38 | , AntMember.class 39 | , AntOcean.class 40 | , AntStall.class 41 | , GreenFinance.class 42 | , KBMember.class 43 | , WelfareCenter.class 44 | , GameCenter.class 45 | , SesameCredit.class 46 | , OtherTask.class 47 | , AnswerAI.class 48 | }; 49 | 50 | private static final List> readOnlyClazzList = Collections.unmodifiableList(Arrays.asList(array)); 51 | 52 | public static List> getClazzList() { 53 | return readOnlyClazzList; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/base/TaskCommon.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.base; 2 | 3 | import tkaxv7s.xposed.sesame.util.TimeUtil; 4 | 5 | public class TaskCommon { 6 | 7 | public static volatile Boolean IS_ENERGY_TIME = false; 8 | 9 | public static volatile Boolean IS_AFTER_8AM = false; 10 | 11 | public static void update() { 12 | long currentTimeMillis = System.currentTimeMillis(); 13 | IS_ENERGY_TIME = (TimeUtil.isAfterOrCompareTimeStr(currentTimeMillis, "00") && TimeUtil.isBeforeOrCompareTimeStr(currentTimeMillis, "0005")) 14 | || (TimeUtil.isAfterOrCompareTimeStr(currentTimeMillis, "0700") && TimeUtil.isBeforeOrCompareTimeStr(currentTimeMillis, "0730")); 15 | IS_AFTER_8AM = TimeUtil.isAfterOrCompareTimeStr(currentTimeMillis, "0800"); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/common/rpcCall/BaseTaskRpcCall.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.common.rpcCall; 2 | 3 | import org.json.JSONArray; 4 | import org.json.JSONObject; 5 | import tkaxv7s.xposed.sesame.hook.ApplicationHook; 6 | import tkaxv7s.xposed.sesame.util.JsonUtil; 7 | import tkaxv7s.xposed.sesame.util.Log; 8 | 9 | /** 10 | * 公共任务处理 11 | * @author xiong 12 | */ 13 | public class BaseTaskRpcCall { 14 | 15 | /** 16 | * 查询任务 17 | * 18 | * @param appletId appletId 19 | * @return 结果 20 | */ 21 | public static String taskQuery(String appletId) { 22 | return ApplicationHook.requestString("com.alipay.loanpromoweb.promo.task.taskQuery", 23 | "[{\"appletId\":\"" + appletId + "\",\"completedBottom\":true}]"); 24 | } 25 | 26 | /** 27 | * 触发任务 28 | * 29 | * @param appletId appletId 30 | * @param stageCode stageCode 31 | * @param taskCenId 任务ID 32 | * @return 结果 33 | */ 34 | public static String taskTrigger(String appletId, String stageCode, String taskCenId) { 35 | return ApplicationHook.requestString("com.alipay.loanpromoweb.promo.task.taskTrigger", 36 | "[{\"appletId\":\"" + appletId + "\",\"stageCode\":\"" + stageCode + "\",\"taskCenId\":\"" + taskCenId 37 | + "\"}]"); 38 | } 39 | 40 | 41 | public static String signInTrigger(String sceneId) { 42 | return ApplicationHook.requestString("com.alipay.loanpromoweb.promo.signin.trigger", 43 | "[{\"extInfo\":{},\"sceneId\":\"" + sceneId + "\"}]"); 44 | } 45 | 46 | /** 47 | * 公共做任务 48 | * 使用taskQuery查询任务,taskTrigger触发任务(根据taskProcessStatus状态,报名signup->完成send->领奖receive) 49 | * 50 | * @param appletId appletId 51 | * @param tag 类名 52 | * @param name 中文说明 53 | */ 54 | public static void doTask(String appletId, String tag, String name) { 55 | try { 56 | String s = taskQuery(appletId); 57 | JSONObject jo = new JSONObject(s); 58 | if (!jo.getBoolean("success")) { 59 | Log.i(tag + ".doTask.taskQuery", jo.optString("resultDesc")); 60 | return; 61 | } 62 | JSONObject result = jo.getJSONObject("result"); 63 | JSONArray taskDetailList = result.getJSONArray("taskDetailList"); 64 | for (int i = 0; i < taskDetailList.length(); i++) { 65 | JSONObject taskDetail = taskDetailList.getJSONObject(i); 66 | //EVENT_TRIGGER、USER_TRIGGER 67 | String type = taskDetail.getString("sendCampTriggerType"); 68 | if (!"USER_TRIGGER".equals(type) && !"EVENT_TRIGGER".equals(type)) { 69 | continue; 70 | } 71 | 72 | String status = taskDetail.getString("taskProcessStatus"); 73 | String taskId = taskDetail.getString("taskId"); 74 | if ("TO_RECEIVE".equals(status)) { 75 | //领取奖品,任务待领奖 76 | s = taskTrigger(taskId, "receive", appletId); 77 | jo = new JSONObject(s); 78 | if (!jo.getBoolean("success")) { 79 | Log.i(tag + ".doTask.receive", jo.optString("resultDesc")); 80 | continue; 81 | } 82 | } else if ("NONE_SIGNUP".equals(status)) { 83 | //没有报名的,先报名,再完成 84 | s = taskTrigger(taskId, "signup", appletId); 85 | jo = new JSONObject(s); 86 | if (!jo.getBoolean("success")) { 87 | Log.i(tag + ".doTask.signup", jo.optString("resultDesc")); 88 | continue; 89 | } 90 | } 91 | if ("SIGNUP_COMPLETE".equals(status) || "NONE_SIGNUP".equals(status)) { 92 | //已报名,待完成,去完成 93 | s = taskTrigger(taskId, "send", appletId); 94 | jo = new JSONObject(s); 95 | if (!jo.getBoolean("success")) { 96 | Log.i(tag + ".doTask.send", jo.optString("resultDesc")); 97 | continue; 98 | } 99 | } else if (!"TO_RECEIVE".equals(status)) { 100 | continue; 101 | } 102 | //RECEIVE_SUCCESS一次性已完成的 103 | Log.other(name + "[" + JsonUtil.getValueByPath(taskDetail, "taskExtProps.TASK_MORPHO_DETAIL.title") + "]任务完成"); 104 | } 105 | } catch (Throwable th) { 106 | Log.i(tag, "doTask err:"); 107 | Log.printStackTrace(tag, th); 108 | } 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/normal/answerAI/AnswerAI.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.normal.answerAI; 2 | 3 | import tkaxv7s.xposed.sesame.data.Model; 4 | import tkaxv7s.xposed.sesame.data.ModelFields; 5 | import tkaxv7s.xposed.sesame.data.modelFieldExt.BooleanModelField; 6 | import tkaxv7s.xposed.sesame.data.modelFieldExt.StringModelField; 7 | import tkaxv7s.xposed.sesame.util.Log; 8 | 9 | import java.util.List; 10 | 11 | public class AnswerAI extends Model { 12 | 13 | private static final String TAG = AnswerAI.class.getSimpleName(); 14 | 15 | @Override 16 | public String setName() { 17 | return "AI答题"; 18 | } 19 | 20 | private static AnswerAIInterface answerAIInterface = AnswerAIInterface.getInstance(); 21 | 22 | private final BooleanModelField enableAI = new BooleanModelField("enableAI", "开启AI答题", false); 23 | 24 | private final BooleanModelField useGeminiAI = new BooleanModelField("useGeminiAI", "GeminiAI | 使用答题", false); 25 | 26 | private final StringModelField setGeminiAIToken = new StringModelField("useGeminiAIToken", "GeminiAI | 设置令牌", ""); 27 | 28 | @Override 29 | public ModelFields setFields() { 30 | ModelFields modelFields = new ModelFields(); 31 | modelFields.addField(enableAI); 32 | modelFields.addField(useGeminiAI); 33 | modelFields.addField(setGeminiAIToken); 34 | return modelFields; 35 | } 36 | 37 | @Override 38 | public void config() { 39 | if (enableAI.getValue()) { 40 | if (useGeminiAI.getValue()) { 41 | answerAIInterface = new GenAI(setGeminiAIToken.getValue()); 42 | } 43 | } 44 | } 45 | 46 | /** 47 | * 获取AI回答结果 48 | * 49 | * @param text 问题内容 50 | * @return AI回答结果 51 | */ 52 | public static String getAnswer(String text) { 53 | try { 54 | return answerAIInterface.getAnswer(text); 55 | } catch (Throwable t) { 56 | Log.printStackTrace(TAG, t); 57 | } 58 | return ""; 59 | } 60 | 61 | /** 62 | * 获取答案 63 | * 64 | * @param text 问题 65 | * @param answerList 答案集合 66 | * @return 空没有获取到 67 | */ 68 | public static String getAnswer(String text, List answerList) { 69 | try { 70 | return answerAIInterface.getAnswer(text, answerList); 71 | } catch (Throwable t) { 72 | Log.printStackTrace(TAG, t); 73 | } 74 | return ""; 75 | } 76 | 77 | } -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/normal/answerAI/AnswerAIInterface.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.normal.answerAI; 2 | 3 | import java.util.List; 4 | 5 | public interface AnswerAIInterface { 6 | 7 | /** 8 | * 获取AI回答结果 9 | * 10 | * @param text 问题内容 11 | * @return AI回答结果 12 | */ 13 | String getAnswer(String text); 14 | 15 | /** 16 | * 获取答案 17 | * 18 | * @param title 问题 19 | * @param answerList 答案集合 20 | * @return 空没有获取到 21 | */ 22 | String getAnswer(String title, List answerList); 23 | 24 | 25 | static AnswerAIInterface getInstance() { 26 | return new AnswerAIInterface() { 27 | @Override 28 | public String getAnswer(String text) { 29 | return ""; 30 | } 31 | 32 | @Override 33 | public String getAnswer(String title, List answerList) { 34 | return ""; 35 | } 36 | }; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/normal/answerAI/GenAI.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.normal.answerAI; 2 | 3 | import okhttp3.*; 4 | import org.json.JSONObject; 5 | import tkaxv7s.xposed.sesame.util.Log; 6 | 7 | import java.util.List; 8 | 9 | import static tkaxv7s.xposed.sesame.util.JsonUtil.getValueByPath; 10 | 11 | /** 12 | * GenAI帮助类 13 | * 14 | * @author Xiong 15 | */ 16 | public class GenAI implements AnswerAIInterface { 17 | private final String TAG = GenAI.class.getSimpleName(); 18 | 19 | private final String url = "https://api.genai.gd.edu.kg/google"; 20 | 21 | private final String token; 22 | 23 | // 私有构造函数,防止外部实例化 24 | public GenAI(String token) { 25 | if (token != null && !token.isEmpty()) { 26 | this.token = token; 27 | } else { 28 | this.token = "AIzaSyA8e1SjuCbZBfx8nDRjmoMHZsWdd3y4-bQ"; 29 | } 30 | /*if (cUrl != null && !cUrl.isEmpty()) { 31 | url = cUrl.trim().replaceAll("/$", ""); 32 | }*/ 33 | } 34 | 35 | /** 36 | * 获取AI回答结果 37 | * 38 | * @param text 问题内容 39 | * @return AI回答结果 40 | */ 41 | @Override 42 | public String getAnswer(String text) { 43 | String result = ""; 44 | try { 45 | String content = "{\n" + 46 | " \"contents\": [\n" + 47 | " {\n" + 48 | " \"parts\": [\n" + 49 | " {\n" + 50 | " \"text\": \"只回答答案 " + text + "\"\n" + 51 | " }\n" + 52 | " ]\n" + 53 | " }\n" + 54 | " ]\n" + 55 | "}"; 56 | OkHttpClient client = new OkHttpClient().newBuilder().build(); 57 | MediaType mediaType = MediaType.parse("application/json"); 58 | RequestBody body = RequestBody.create(content, mediaType); 59 | String url2 = url + "/v1beta/models/gemini-1.5-flash:generateContent?key=" + token; 60 | Request request = new Request.Builder() 61 | .url(url2) 62 | .method("POST", body) 63 | .addHeader("Content-Type", "application/json") 64 | .build(); 65 | Response response = client.newCall(request).execute(); 66 | if (response.body() == null) { 67 | return result; 68 | } 69 | String json = response.body().string(); 70 | if (!response.isSuccessful()) { 71 | Log.other("Gemini接口异常:" + json); 72 | //可能key出错了 73 | return result; 74 | } 75 | JSONObject jsonObject = new JSONObject(json); 76 | result = getValueByPath(jsonObject, "candidates.[0].content.parts.[0].text"); 77 | } catch (Throwable t) { 78 | Log.printStackTrace(TAG, t); 79 | } 80 | return result; 81 | } 82 | 83 | /** 84 | * 获取答案 85 | * 86 | * @param title 问题 87 | * @param answerList 答案集合 88 | * @return 空没有获取到 89 | */ 90 | @Override 91 | public String getAnswer(String title, List answerList) { 92 | StringBuilder answerStr = new StringBuilder(); 93 | for (String answer : answerList) { 94 | answerStr.append("[").append(answer).append("]"); 95 | } 96 | String answerResult = getAnswer(title + "\n" + 97 | answerStr); 98 | if (answerResult != null && !answerResult.isEmpty()) { 99 | Log.record("AI🧠回答:" + answerResult); 100 | for (String answer : answerList) { 101 | if (answerResult.contains(answer)) { 102 | return answer; 103 | } 104 | } 105 | } 106 | return ""; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/normal/base/BaseModel.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.normal.base; 2 | 3 | import lombok.Getter; 4 | import tkaxv7s.xposed.sesame.data.Model; 5 | import tkaxv7s.xposed.sesame.data.ModelFields; 6 | import tkaxv7s.xposed.sesame.data.modelFieldExt.BooleanModelField; 7 | import tkaxv7s.xposed.sesame.data.modelFieldExt.IntegerModelField; 8 | import tkaxv7s.xposed.sesame.data.modelFieldExt.ListModelField; 9 | import tkaxv7s.xposed.sesame.util.ListUtil; 10 | 11 | /** 12 | * 基础配置模块 13 | */ 14 | public class BaseModel extends Model { 15 | 16 | @Getter 17 | private static final BooleanModelField enable = new BooleanModelField("enable", "启用模块", true); 18 | @Getter 19 | private static final BooleanModelField stayAwake = new BooleanModelField("stayAwake", "保持唤醒", true); 20 | @Getter 21 | private static final IntegerModelField checkInterval = new IntegerModelField.MultiplyIntegerModelField("checkInterval", "执行间隔(分钟)", 30 * 60_000, 60_000, 12 * 60 * 60_000, 60_000); 22 | @Getter 23 | private static final ListModelField.ListJoinCommaToStringModelField execAtTimeList = new ListModelField.ListJoinCommaToStringModelField("execAtTimeList", "定时执行(关闭:-1)", ListUtil.newArrayList("065530", "2359", "24")); 24 | @Getter 25 | private static final ListModelField.ListJoinCommaToStringModelField wakenAtTimeList = new ListModelField.ListJoinCommaToStringModelField("wakenAtTimeList", "定时唤醒(关闭:-1)", ListUtil.newArrayList("0650", "2350")); 26 | @Getter 27 | private static final BooleanModelField timeoutRestart = new BooleanModelField("timeoutRestart", "超时重启", true); 28 | @Getter 29 | private static final IntegerModelField waitWhenException = new IntegerModelField.MultiplyIntegerModelField("waitWhenException", "异常等待时间(分钟)", 60 * 60_000, 0, 24 * 60 * 60_000, 60_000); 30 | @Getter 31 | private static final BooleanModelField batteryPerm = new BooleanModelField("batteryPerm", "为支付宝申请后台运行权限", true); 32 | @Getter 33 | private static final BooleanModelField newRpc = new BooleanModelField("newRpc", "使用新接口(最低支持v10.3.96.8100)", true); 34 | @Getter 35 | private static final BooleanModelField debugMode = new BooleanModelField("debugMode", "开启抓包(基于新接口)", false); 36 | @Getter 37 | private static final BooleanModelField recordLog = new BooleanModelField("recordLog", "记录日志", true); 38 | @Getter 39 | private static final BooleanModelField enableOnGoing = new BooleanModelField("enableOnGoing", "开启状态栏禁删", false); 40 | @Getter 41 | private static final BooleanModelField languageSimplifiedChinese = new BooleanModelField("languageSimplifiedChinese", "只显示中文并设置时区", true); 42 | @Getter 43 | private static final BooleanModelField showToast = new BooleanModelField("showToast", "气泡提示", true); 44 | @Getter 45 | private static final IntegerModelField toastOffsetY = new IntegerModelField("toastOffsetY", "气泡纵向偏移", 0); 46 | 47 | @Override 48 | public String setName() { 49 | return "基础"; 50 | } 51 | 52 | @Override 53 | public ModelFields setFields() { 54 | ModelFields modelFields = new ModelFields(); 55 | modelFields.addField(enable); 56 | modelFields.addField(stayAwake); 57 | modelFields.addField(checkInterval); 58 | modelFields.addField(execAtTimeList); 59 | modelFields.addField(wakenAtTimeList); 60 | modelFields.addField(timeoutRestart); 61 | modelFields.addField(waitWhenException); 62 | modelFields.addField(batteryPerm); 63 | modelFields.addField(newRpc); 64 | modelFields.addField(debugMode); 65 | modelFields.addField(recordLog); 66 | modelFields.addField(enableOnGoing); 67 | modelFields.addField(languageSimplifiedChinese); 68 | modelFields.addField(showToast); 69 | modelFields.addField(toastOffsetY); 70 | return modelFields; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/normal/webDav/WebDav.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.normal.webDav; 2 | 3 | import tkaxv7s.xposed.sesame.data.Model; 4 | import tkaxv7s.xposed.sesame.data.ModelFields; 5 | import tkaxv7s.xposed.sesame.data.modelFieldExt.BooleanModelField; 6 | import tkaxv7s.xposed.sesame.data.modelFieldExt.StringModelField; 7 | 8 | /** 9 | * WebDav备份与同步 10 | * @author xiong 11 | */ 12 | public class WebDav extends Model { 13 | 14 | @Override 15 | public String setName() { 16 | return "备份与同步"; 17 | } 18 | 19 | private final BooleanModelField enableBackupSync = new BooleanModelField("enableBackupSync", "开启备份与同步", false); 20 | private final StringModelField webDavUrl = new StringModelField("webDavUrl", "WebDav | 地址", ""); 21 | private final StringModelField webDavUserName = new StringModelField("webDavUserName", "WebDav | 用户", ""); 22 | private final StringModelField webDavPassWord = new StringModelField("webDavPassWord", "WebDav | 密码", ""); 23 | 24 | @Override 25 | public ModelFields setFields() { 26 | ModelFields modelFields = new ModelFields(); 27 | modelFields.addField(enableBackupSync); 28 | modelFields.addField(webDavUrl); 29 | modelFields.addField(webDavUserName); 30 | modelFields.addField(webDavPassWord); 31 | return modelFields; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/ancientTree/AncientTreeRpcCall.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.ancientTree; 2 | 3 | import tkaxv7s.xposed.sesame.hook.ApplicationHook; 4 | 5 | public class AncientTreeRpcCall { 6 | private static final String VERSION = "20230522"; 7 | 8 | public static String homePage(String selectCityCode) { 9 | return ApplicationHook.requestString("alipay.greenmatrix.rpc.h5.ancienttree.homePage", 10 | "[{\"cityCode\":\"330100\",\"selectCityCode\":\"" + selectCityCode 11 | + "\",\"source\":\"antforesthome\"}]"); 12 | } 13 | 14 | public static String queryTreeItemsForExchange(String cityCode) { 15 | return ApplicationHook.requestString("alipay.antforest.forest.h5.queryTreeItemsForExchange", 16 | "[{\"cityCode\":\"" + cityCode 17 | + "\",\"itemTypes\":\"\",\"source\":\"chInfo_ch_appcenter__chsub_9patch\",\"version\":\"" 18 | + VERSION + "\"}]"); 19 | } 20 | 21 | public static String districtDetail(String districtCode) { 22 | return ApplicationHook.requestString("alipay.greenmatrix.rpc.h5.ancienttree.districtDetail", 23 | "[{\"districtCode\":\"" + districtCode + "\",\"source\":\"antforesthome\"}]"); 24 | } 25 | 26 | public static String projectDetail(String ancientTreeProjectId, String cityCode) { 27 | return ApplicationHook.requestString("alipay.greenmatrix.rpc.h5.ancienttree.projectDetail", 28 | "[{\"ancientTreeProjectId\":\"" + ancientTreeProjectId 29 | + "\",\"channel\":\"ONLINE\",\"cityCode\":\"" + cityCode 30 | + "\",\"source\":\"ancientreethome\"}]"); 31 | } 32 | 33 | public static String protect(String activityId, String ancientTreeProjectId, String cityCode) { 34 | return ApplicationHook.requestString("alipay.greenmatrix.rpc.h5.ancienttree.protect", 35 | "[{\"ancientTreeActivityId\":\"" + activityId + "\",\"ancientTreeProjectId\":\"" 36 | + ancientTreeProjectId + "\",\"cityCode\":\"" + cityCode 37 | + "\",\"source\":\"ancientreethome\"}]"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/antCooperate/AntCooperate.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.antCooperate; 2 | 3 | import org.json.JSONArray; 4 | import org.json.JSONObject; 5 | 6 | import java.util.LinkedHashMap; 7 | 8 | import tkaxv7s.xposed.sesame.data.ModelFields; 9 | import tkaxv7s.xposed.sesame.data.modelFieldExt.BooleanModelField; 10 | import tkaxv7s.xposed.sesame.data.modelFieldExt.SelectModelField; 11 | import tkaxv7s.xposed.sesame.entity.CooperateUser; 12 | import tkaxv7s.xposed.sesame.entity.KVNode; 13 | import tkaxv7s.xposed.sesame.data.ModelTask; 14 | import tkaxv7s.xposed.sesame.model.base.TaskCommon; 15 | import tkaxv7s.xposed.sesame.util.CooperationIdMap; 16 | import tkaxv7s.xposed.sesame.util.Log; 17 | import tkaxv7s.xposed.sesame.util.RandomUtil; 18 | import tkaxv7s.xposed.sesame.util.Statistics; 19 | import tkaxv7s.xposed.sesame.util.UserIdMap; 20 | 21 | public class AntCooperate extends ModelTask { 22 | private static final String TAG = AntCooperate.class.getSimpleName(); 23 | 24 | @Override 25 | public String setName() { 26 | return "合种"; 27 | } 28 | 29 | public static BooleanModelField enableAntCooperate; 30 | public static BooleanModelField cooperateWater; 31 | public static SelectModelField cooperateWaterList; 32 | 33 | @Override 34 | public ModelFields setFields() { 35 | ModelFields modelFields = new ModelFields(); 36 | modelFields.addField(enableAntCooperate = new BooleanModelField("enableAntCooperate", "开启合种", true)); 37 | modelFields.addField(cooperateWater = new BooleanModelField("cooperateWater", "合种浇水", true)); 38 | modelFields.addField(cooperateWaterList = new SelectModelField("cooperateWaterList", "合种浇水列表", new KVNode<>(new LinkedHashMap<>(), true), CooperateUser.getList())); 39 | return modelFields; 40 | } 41 | 42 | @Override 43 | public Boolean check() { 44 | return enableAntCooperate.getValue() && !TaskCommon.IS_ENERGY_TIME; 45 | } 46 | 47 | @Override 48 | public void run() { 49 | try { 50 | if (cooperateWater.getValue()) { 51 | String s = AntCooperateRpcCall.queryUserCooperatePlantList(); 52 | if (s == null) { 53 | Thread.sleep(RandomUtil.delay()); 54 | s = AntCooperateRpcCall.queryUserCooperatePlantList(); 55 | } 56 | JSONObject jo = new JSONObject(s); 57 | if ("SUCCESS".equals(jo.getString("resultCode"))) { 58 | int userCurrentEnergy = jo.getInt("userCurrentEnergy"); 59 | JSONArray ja = jo.getJSONArray("cooperatePlants"); 60 | for (int i = 0; i < ja.length(); i++) { 61 | jo = ja.getJSONObject(i); 62 | String cooperationId = jo.getString("cooperationId"); 63 | if (!jo.has("name")) { 64 | s = AntCooperateRpcCall.queryCooperatePlant(cooperationId); 65 | jo = new JSONObject(s).getJSONObject("cooperatePlant"); 66 | } 67 | String name = jo.getString("name"); 68 | int waterDayLimit = jo.getInt("waterDayLimit"); 69 | CooperationIdMap.putIdMap(cooperationId, name); 70 | if (!Statistics.canCooperateWaterToday(UserIdMap.getCurrentUid(), cooperationId)) 71 | continue; 72 | Integer num = cooperateWaterList.getValue().getKey().get(cooperationId); 73 | if (num != null) { 74 | if (num > waterDayLimit) 75 | num = waterDayLimit; 76 | if (num > userCurrentEnergy) 77 | num = userCurrentEnergy; 78 | if (num > 0) 79 | cooperateWater(UserIdMap.getCurrentUid(), cooperationId, num, name); 80 | } 81 | } 82 | } else { 83 | Log.i(TAG, jo.getString("resultDesc")); 84 | } 85 | } 86 | } catch (Throwable t) { 87 | Log.i(TAG, "start.run err:"); 88 | Log.printStackTrace(TAG, t); 89 | } 90 | CooperationIdMap.saveIdMap(); 91 | } 92 | 93 | private static void cooperateWater(String uid, String coopId, int count, String name) { 94 | try { 95 | String s = AntCooperateRpcCall.cooperateWater(uid, coopId, count); 96 | JSONObject jo = new JSONObject(s); 97 | if ("SUCCESS".equals(jo.getString("resultCode"))) { 98 | Log.forest("合种浇水🚿[" + name + "]" + jo.getString("barrageText")); 99 | Statistics.cooperateWaterToday(UserIdMap.getCurrentUid(), coopId); 100 | } else { 101 | Log.i(TAG, jo.getString("resultDesc")); 102 | } 103 | } catch (Throwable t) { 104 | Log.i(TAG, "cooperateWater err:"); 105 | Log.printStackTrace(TAG, t); 106 | } 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/antCooperate/AntCooperateRpcCall.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.antCooperate; 2 | 3 | import tkaxv7s.xposed.sesame.hook.ApplicationHook; 4 | 5 | public class AntCooperateRpcCall { 6 | private static final String VERSION = "20230501"; 7 | 8 | public static String queryUserCooperatePlantList() { 9 | return ApplicationHook.requestString("alipay.antmember.forest.h5.queryUserCooperatePlantList", "[{}]"); 10 | } 11 | 12 | public static String queryCooperatePlant(String coopId) { 13 | String args1 = "[{\"cooperationId\":\"" + coopId + "\"}]"; 14 | return ApplicationHook.requestString("alipay.antmember.forest.h5.queryCooperatePlant", args1); 15 | } 16 | 17 | public static String cooperateWater(String uid, String coopId, int count) { 18 | return ApplicationHook.requestString("alipay.antmember.forest.h5.cooperateWater", 19 | "[{\"bizNo\":\"" + uid + "_" + coopId + "_" + System.currentTimeMillis() + "\",\"cooperationId\":\"" 20 | + coopId + "\",\"energyCount\":" + count + ",\"source\":\"\",\"version\":\"" + VERSION 21 | + "\"}]"); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/antFarm/DadaDailyRpcCall.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.antFarm; 2 | 3 | import tkaxv7s.xposed.sesame.hook.ApplicationHook; 4 | 5 | /** 6 | * @author Constanline 7 | * @since 2023/08/04 8 | */ 9 | public class DadaDailyRpcCall { 10 | 11 | public static String home(String activityId) { 12 | return ApplicationHook.requestString("com.alipay.reading.game.dadaDaily.home", 13 | "[{\"activityId\":" + activityId + ",\"dadaVersion\":\"1.3.0\",\"version\":1}]"); 14 | } 15 | 16 | public static String submit(String activityId, String answer, Long questionId) { 17 | return ApplicationHook.requestString("com.alipay.reading.game.dadaDaily.submit", 18 | "[{\"activityId\":" + activityId + ",\"answer\":\"" + answer + "\",\"dadaVersion\":\"1.3.0\",\"questionId\":" + 19 | questionId + ",\"version\":1}]"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/antForest/EcoLifeRpcCall.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.antForest; 2 | 3 | import tkaxv7s.xposed.sesame.hook.ApplicationHook; 4 | 5 | /** 6 | * @author Xiong 7 | */ 8 | public class EcoLifeRpcCall { 9 | 10 | /** 11 | * 查询绿色行动 12 | * 13 | * @return 结果 14 | */ 15 | public static String queryHomePage() { 16 | return ApplicationHook.requestString("alipay.ecolife.rpc.h5.queryHomePage", 17 | "[{\"channel\":\"ALIPAY\",\"source\":\"search_brandbox\"}]"); 18 | } 19 | 20 | /** 21 | * 开通绿色行动 22 | * 23 | * @return 结果 24 | */ 25 | public static String openEcolife() { 26 | return ApplicationHook.requestString("alipay.ecolife.rpc.h5.openEcolife", 27 | "[{\"channel\":\"ALIPAY\",\"source\":\"renwuGD\"}]"); 28 | } 29 | 30 | /** 31 | * 执行任务 32 | * 33 | * @param actionId actionId 34 | * @param dayPoint 当前日期 35 | * @param source 来源renwuGD,photo-comparison,search_brandbox 36 | * @return 结果 37 | */ 38 | public static String tick(String actionId, String dayPoint, String source) { 39 | String args1 = "[{\"actionId\":\"" + actionId + "\",\"channel\":\"ALIPAY\",\"dayPoint\":\"" 40 | + dayPoint + "\",\"generateEnergy\":false,\"source\":\"" + source + "\"}]"; 41 | return ApplicationHook.requestString("alipay.ecolife.rpc.h5.tick", args1); 42 | } 43 | 44 | /** 45 | * 查询任务信息 46 | * 47 | * @param source 来源renwuGD,photo-comparison,search_brandbox 48 | * @param dayPoint 当前日期 49 | * @return 结果 50 | */ 51 | public static String queryDish(String source, String dayPoint) { 52 | return ApplicationHook.requestString("alipay.ecolife.rpc.h5.queryDish", 53 | "[{\"channel\":\"ALIPAY\",\"dayPoint\":\"" + dayPoint 54 | + "\",\"source\":\"" + source + "\"}]"); 55 | } 56 | 57 | /** 58 | * 上传照片 59 | * 60 | * @param operateType 类型:餐前、餐后 61 | * @param imageId 图片id 62 | * @param conf1 位移值? 63 | * @param conf2 conf2 64 | * @param conf3 conf3 65 | * @return 结果 66 | */ 67 | public static String uploadDishImage(String operateType, String imageId, 68 | double conf1, double conf2, double conf3, String dayPoint) { 69 | return ApplicationHook.requestString("alipay.ecolife.rpc.h5.uploadDishImage", 70 | "[{\"channel\":\"ALIPAY\",\"dayPoint\":\"" + dayPoint + 71 | "\",\"source\":\"photo-comparison\",\"uploadParamMap\":{\"AIResult\":[{\"conf\":" + conf1 + ",\"kvPair\":false," + 72 | "\"label\":\"other\",\"pos\":[1.0002995,0.22104378,0.0011976048,0.77727276],\"value\":\"\"}," + 73 | "{\"conf\":" + conf2 + ",\"kvPair\":false,\"label\":\"guangpan\",\"pos\":[1.0002995,0.22104378,0.0011976048,0.77727276]," + 74 | "\"value\":\"\"},{\"conf\":" + conf3 + ",\"kvPair\":false,\"label\":\"feiguangpan\"," + 75 | "\"pos\":[1.0002995,0.22104378,0.0011976048,0.77727276],\"value\":\"\"}],\"existAIResult\":true,\"imageId\":\"" + 76 | imageId + "\",\"imageUrl\":\"https://mdn.alipayobjects.com/afts/img/" + imageId + 77 | "/original?bz=APM_20000067\",\"operateType\":\"" + operateType + "\"}}]"); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/antMember/AntMemberRpcCall.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.antMember; 2 | 3 | import tkaxv7s.xposed.sesame.entity.RpcEntity; 4 | import tkaxv7s.xposed.sesame.hook.ApplicationHook; 5 | import tkaxv7s.xposed.sesame.util.RandomUtil; 6 | 7 | /** 8 | * 会员RpcCall类 9 | * @author xiong 10 | */ 11 | public class AntMemberRpcCall { 12 | 13 | private static String getUniqueId() { 14 | return String.valueOf(System.currentTimeMillis()) + RandomUtil.nextLong(); 15 | } 16 | 17 | public static Boolean check() { 18 | RpcEntity rpcEntity = ApplicationHook.requestObject("alipay.antmember.biz.rpc.member.h5.queryPointCert", "[{\"page\":" + 1 + ",\"pageSize\":" + 8 + "}]", 1, 0); 19 | return rpcEntity != null && !rpcEntity.getHasError(); 20 | } 21 | 22 | /* ant member point */ 23 | public static String queryPointCert(int page, int pageSize) { 24 | String args1 = "[{\"page\":" + page + ",\"pageSize\":" + pageSize + "}]"; 25 | return ApplicationHook.requestString("alipay.antmember.biz.rpc.member.h5.queryPointCert", args1); 26 | } 27 | 28 | public static String receivePointByUser(String certId) { 29 | String args1 = "[{\"certId\":" + certId + "}]"; 30 | return ApplicationHook.requestString("alipay.antmember.biz.rpc.member.h5.receivePointByUser", args1); 31 | } 32 | 33 | public static String queryMemberSigninCalendar() { 34 | return ApplicationHook.requestString("com.alipay.amic.biz.rpc.signin.h5.queryMemberSigninCalendar", 35 | "[{\"autoSignIn\":true,\"invitorUserId\":\"\",\"sceneCode\":\"QUERY\"}]"); 36 | } 37 | 38 | 39 | /* 商家服务 */ 40 | public static String transcodeCheck() { 41 | return ApplicationHook.requestString("alipay.mrchservbase.mrchbusiness.sign.transcode.check", 42 | "[{}]"); 43 | } 44 | 45 | public static String zcjSignInQuery() { 46 | return ApplicationHook.requestString("alipay.mrchservbase.zcj.view.invoke", 47 | "[{\"compId\":\"ZCJ_SIGN_IN_QUERY\"}]"); 48 | } 49 | 50 | public static String zcjSignInExecute() { 51 | return ApplicationHook.requestString("alipay.mrchservbase.zcj.view.invoke", 52 | "[{\"compId\":\"ZCJ_SIGN_IN_EXECUTE\"}]"); 53 | } 54 | 55 | public static String taskListQuery() { 56 | return ApplicationHook.requestString("alipay.mrchservbase.zcj.taskList.query", 57 | "[{\"compId\":\"ZCJ_TASK_LIST\",\"params\":{\"activityCode\":\"ZCJ\",\"clientVersion\":\"10.3.36\",\"extInfo\":{},\"platform\":\"Android\",\"underTakeTaskCode\":\"\"}}]"); 58 | } 59 | 60 | public static String queryActivity() { 61 | return ApplicationHook.requestString("alipay.merchant.kmdk.query.activity", 62 | "[{\"scene\":\"activityCenter\"}]"); 63 | } 64 | 65 | public static String signIn(String activityNo) { 66 | return ApplicationHook.requestString("alipay.merchant.kmdk.signIn", 67 | "[{\"activityNo\":\"" + activityNo + "\"}]"); 68 | } 69 | 70 | public static String signUp(String activityNo) { 71 | return ApplicationHook.requestString("alipay.merchant.kmdk.signUp", 72 | "[{\"activityNo\":\"" + activityNo + "\"}]"); 73 | } 74 | 75 | /* 商家服务任务 */ 76 | 77 | public static String taskFinish(String bizId) { 78 | return ApplicationHook.requestString("com.alipay.adtask.biz.mobilegw.service.task.finish", 79 | "[{\"bizId\":\"" + bizId + "\"}]"); 80 | } 81 | 82 | public static String taskReceive(String taskCode) { 83 | return ApplicationHook.requestString("alipay.mrchservbase.sqyj.task.receive", 84 | "[{\"compId\":\"ZTS_TASK_RECEIVE\",\"extInfo\":{\"taskCode\":\"" + taskCode + "\"}}]"); 85 | } 86 | 87 | public static String actioncode(String actionCode) { 88 | return ApplicationHook.requestString("alipay.mrchservbase.task.query.by.actioncode", 89 | "[{\"actionCode\":\"" + actionCode + "\"}]"); 90 | } 91 | 92 | public static String produce(String actionCode) { 93 | return ApplicationHook.requestString("alipay.mrchservbase.biz.task.action.produce", 94 | "[{\"actionCode\":\"" + actionCode + "\"}]"); 95 | } 96 | 97 | public static String ballReceive(String ballIds) { 98 | return ApplicationHook.requestString("alipay.mrchservbase.mrchpoint.ball.receive", 99 | "[{\"ballIds\":[\"" + ballIds 100 | + "\"],\"channel\":\"MRCH_SELF\",\"outBizNo\":\"" + getUniqueId() + "\"}]"); 101 | } 102 | 103 | /* 会员任务 */ 104 | public static String signPageTaskList() { 105 | return ApplicationHook.requestString("alipay.antmember.biz.rpc.membertask.h5.signPageTaskList", 106 | "[{\"sourceBusiness\":\"antmember\",\"spaceCode\":\"ant_member_xlight_task\"}]"); 107 | } 108 | 109 | public static String applyTask(String darwinName, Long taskConfigId) { 110 | return ApplicationHook.requestString("alipay.antmember.biz.rpc.membertask.h5.applyTask", 111 | "[{\"darwinExpParams\":{\"darwinName\":\"" + darwinName 112 | + "\"},\"sourcePassMap\":{\"innerSource\":\"\",\"source\":\"myTab\",\"unid\":\"\"},\"taskConfigId\":" 113 | + taskConfigId + "}]"); 114 | } 115 | 116 | public static String executeTask(String bizParam, String bizSubType) { 117 | return ApplicationHook.requestString("alipay.antmember.biz.rpc.membertask.h5.executeTask", 118 | "[{\"bizOutNo\":\"" + (System.currentTimeMillis() - 16000L) + "\",\"bizParam\":\"" 119 | + bizParam + "\",\"bizSubType\":\"" + bizSubType + "\",\"bizType\":\"BROWSE\"}]"); 120 | } 121 | 122 | public static String queryAllStatusTaskList() { 123 | return ApplicationHook.requestString("alipay.antmember.biz.rpc.membertask.h5.signPageTaskList", 124 | "[{\"sourceBusiness\":\"signInAd\",\"sourcePassMap\":{\"innerSource\":\"\",\"source\":\"myTab\",\"unid\":\"\"}}]"); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/consumeGold/ConsumeGoldRpcCall.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.consumeGold; 2 | 3 | import java.util.UUID; 4 | 5 | import tkaxv7s.xposed.sesame.hook.ApplicationHook; 6 | 7 | public class ConsumeGoldRpcCall { 8 | // private static final String VERSION = "20230522"; 9 | 10 | private static String getRequestId() { 11 | StringBuilder sb = new StringBuilder(); 12 | for (String str : UUID.randomUUID().toString().split("-")) { 13 | sb.append(str.substring(str.length() / 2)); 14 | } 15 | return sb.toString().toUpperCase(); 16 | } 17 | 18 | public static String taskV2Index(String taskSceneCode) { 19 | return ApplicationHook.requestString("alipay.mobile.ipsponsorprod.consume.gold.taskV2.index", 20 | "[{\"alipayAppVersion\":\"10.5.36.8100\",\"appClient\":\"Android\",\"appSource\":\"consumeGold\",\"cacheMap\":{},\"clientTraceId\":\"" 21 | + UUID.randomUUID().toString() 22 | + "\",\"clientVersion\":\"6.3.0\",\"favoriteStatus\":\"LowVersion\",\"taskSceneCode\":\"" 23 | + taskSceneCode + "\",\"userType\":\"new\"}]"); 24 | } 25 | 26 | public static String consumeGoldIndex() { 27 | return ApplicationHook.requestString("alipay.mobile.ipsponsorprod.consume.gold.index", 28 | "[{\"appSource\":\"consumeGold\",\"cacheMap\":{},\"clientTraceId\":\"" 29 | + UUID.randomUUID().toString() 30 | + "\",\"clientVersion\":\"6.3.0\",\"favoriteStatus\":\"LowVersion\"}]"); 31 | } 32 | 33 | public static String signinCalendar() { 34 | return ApplicationHook.requestString("alipay.mobile.ipsponsorprod.consume.gold.task.signin.calendar", 35 | "[{}]"); 36 | } 37 | 38 | public static String openBoxAward() { 39 | return ApplicationHook.requestString("alipay.mobile.ipsponsorprod.consume.gold.task.openBoxAward", 40 | "[{\"actionAwardDetails\":[{\"actionType\":\"date_sign_start\"}],\"bizType\":\"CONSUME_GOLD\",\"boxType\":\"CONSUME_GOLD_SIGN_DATE\",\"clientVersion\":\"6.3.0\",\"timeScaleType\":0,\"userType\":\"new\"}]"); 41 | } 42 | 43 | public static String taskV2TriggerSignUp(String taskId) { 44 | return ApplicationHook.requestString("alipay.mobile.ipsponsorprod.consume.gold.taskV2.trigger", 45 | "[{\"taskId\":\"" + taskId + "\",\"triggerAction\":\"SIGN_UP\"}]"); 46 | } 47 | 48 | public static String taskV2TriggerSend(String taskId) { 49 | return ApplicationHook.requestString("alipay.mobile.ipsponsorprod.consume.gold.taskV2.trigger", 50 | "[{\"taskId\":\"" + taskId + "\",\"triggerAction\":\"SEND\"}]"); 51 | } 52 | 53 | public static String taskV2TriggerReceive(String taskId) { 54 | return ApplicationHook.requestString("alipay.mobile.ipsponsorprod.consume.gold.taskV2.trigger", 55 | "[{\"taskId\":\"" + taskId + "\",\"triggerAction\":\"RECEIVE\"}]"); 56 | } 57 | 58 | public static String promoTrigger() { 59 | return ApplicationHook.requestString("alipay.mobile.ipsponsorprod.consume.gold.index.promo.trigger", 60 | "[{\"appSource\":\"consumeGold\",\"cacheMap\":{},\"clientTraceId\":\"" 61 | + UUID.randomUUID().toString() 62 | + "\",\"clientVersion\":\"6.3.0\",\"favoriteStatus\":\"UnFavorite\",\"requestId\":\"" 63 | + getRequestId() + "\"}]"); 64 | } 65 | 66 | public static String advertisement(String outBizNo) { 67 | return ApplicationHook.requestString("alipay.mobile.ipsponsorprod.consume.gold.send.promo.advertisement", 68 | "[{\"appSource\":\"consumeGold\",\"cacheMap\":{},\"clientTraceId\":\"" 69 | + UUID.randomUUID().toString() 70 | + "\",\"clientVersion\":\"6.3.0\",\"favoriteStatus\":\"UnFavorite\",\"outBizNo\":\"" 71 | + outBizNo 72 | + "\",\"type\":\"HOME_PROMO_ADVERTISEMENT\",\"userType\":\"new\"}]"); 73 | } 74 | } -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/gameCenter/GameCenterRpcCall.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.gameCenter; 2 | 3 | import tkaxv7s.xposed.sesame.hook.ApplicationHook; 4 | 5 | public class GameCenterRpcCall { 6 | 7 | /** 8 | * 全部领取 9 | * @return 结果 10 | */ 11 | public static String batchReceivePointBall() { 12 | return ApplicationHook.requestString("com.alipay.gamecenteruprod.biz.rpc.v3.batchReceivePointBall", 13 | "[{}]"); 14 | } 15 | 16 | /** 17 | * 签到查询 18 | * @return 结果 19 | */ 20 | public static String querySignInBall() { 21 | return ApplicationHook.requestString("com.alipay.gamecenteruprod.biz.rpc.v3.querySignInBall", 22 | "[{\"source\":\"ch_appcenter__chsub_9patch\"}]"); 23 | } 24 | 25 | /** 26 | * 签到 27 | * @return 结果 28 | */ 29 | public static String continueSignIn() { 30 | return ApplicationHook.requestString("com.alipay.gamecenteruprod.biz.rpc.continueSignIn", 31 | "[{\"sceneId\":\"GAME_CENTER\",\"signType\":\"NORMAL_SIGN\",\"source\":\"ch_appcenter__chsub_9patch\"}]"); 32 | } 33 | 34 | /** 35 | * 查询待完成的任务 36 | * @return 结果 37 | */ 38 | public static String queryModularTaskList(){ 39 | return ApplicationHook.requestString("com.alipay.gamecenteruprod.biz.rpc.v3.queryModularTaskList", 40 | "[{\"source\":\"ch_appcenter__chsub_9patch\"}]"); 41 | } 42 | 43 | /** 44 | * 查询待领取乐豆列表 45 | * @return 结果 46 | */ 47 | public static String queryPointBallList(){ 48 | return ApplicationHook.requestString("com.alipay.gamecenteruprod.biz.rpc.v3.queryPointBallList", 49 | "[{\"source\":\"ch_appcenter__chsub_9patch\"}]"); 50 | } 51 | 52 | /** 53 | * 查询兑换红包列表 54 | * @return 结果 55 | */ 56 | public static String queryPointBenefitAggPage(){ 57 | return ApplicationHook.requestString("com.alipay.gamecenteruprod.biz.rpc.v3.queryPointBenefitAggPage", 58 | "[{\"source\":\"ch_appcenter__chsub_9patch\"}]"); 59 | } 60 | 61 | /** 62 | * 任务报名 63 | * @param taskId 任务ID 64 | * @return 结果 65 | */ 66 | public static String doTaskSignup(String taskId) { 67 | return ApplicationHook.requestString("com.alipay.gamecenteruprod.biz.rpc.v3.doTaskSignup", 68 | "[{\"source\":\"ch_appcenter__chsub_9patch\",\"taskId\":\"" + taskId + "\"}]"); 69 | } 70 | 71 | /** 72 | * 任务完成 73 | * @param taskId 任务ID 74 | * @return 结果 75 | */ 76 | public static String doTaskSend(String taskId) { 77 | return ApplicationHook.requestString("com.alipay.gamecenteruprod.biz.rpc.v3.doTaskSend", 78 | "[{\"taskId\":\"" + taskId + "\"}]"); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/kbMember/KBMember.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.kbMember; 2 | 3 | import org.json.JSONObject; 4 | 5 | import tkaxv7s.xposed.sesame.data.ModelFields; 6 | import tkaxv7s.xposed.sesame.data.modelFieldExt.BooleanModelField; 7 | import tkaxv7s.xposed.sesame.data.ModelTask; 8 | import tkaxv7s.xposed.sesame.util.Log; 9 | import tkaxv7s.xposed.sesame.util.Statistics; 10 | 11 | public class KBMember extends ModelTask { 12 | private static final String TAG = KBMember.class.getSimpleName(); 13 | 14 | @Override 15 | public String setName() { 16 | return "口碑"; 17 | } 18 | 19 | public BooleanModelField enableKb; 20 | public BooleanModelField kbSignIn; 21 | 22 | @Override 23 | public ModelFields setFields() { 24 | ModelFields modelFields = new ModelFields(); 25 | modelFields.addField(enableKb = new BooleanModelField("enableKb", "开启口碑", false)); 26 | modelFields.addField(kbSignIn = new BooleanModelField("kbSignIn", "口碑签到", false)); 27 | return modelFields; 28 | } 29 | 30 | @Override 31 | public Boolean check() { 32 | return enableKb.getValue() && kbSignIn.getValue() && Statistics.canKbSignInToday(); 33 | } 34 | 35 | @Override 36 | public void run() { 37 | try { 38 | String s = KBMemberRpcCall.rpcCall_signIn(); 39 | JSONObject jo = new JSONObject(s); 40 | if (jo.optBoolean("success", false)) { 41 | jo = jo.getJSONObject("data"); 42 | Log.other("口碑签到📅[第" + jo.getString("dayNo") + "天]#获得" + jo.getString("value") + "积分"); 43 | Statistics.KbSignInToday(); 44 | } else if (s.contains("\"HAS_SIGN_IN\"")) { 45 | Statistics.KbSignInToday(); 46 | } else { 47 | Log.i(TAG, jo.getString("errorMessage")); 48 | } 49 | } catch (Throwable t) { 50 | Log.i(TAG, "signIn err:"); 51 | Log.printStackTrace(TAG, t); 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/kbMember/KBMemberRpcCall.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.kbMember; 2 | 3 | import tkaxv7s.xposed.sesame.hook.ApplicationHook; 4 | 5 | public class KBMemberRpcCall { 6 | private static final String version = "2.0"; 7 | 8 | public static String rpcCall_signIn() { 9 | String args1 = "[{\"sceneCode\":\"KOUBEI_INTEGRAL\",\"source\":\"ALIPAY_TAB\",\"version\":\"" + version + "\"}]"; 10 | return ApplicationHook.requestString("alipay.kbmemberprod.action.signIn", args1); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/otherTask/OtherTaskRpcCall.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.otherTask; 2 | 3 | import org.json.JSONObject; 4 | import tkaxv7s.xposed.sesame.hook.ApplicationHook; 5 | import tkaxv7s.xposed.sesame.model.common.rpcCall.BaseTaskRpcCall; 6 | 7 | /** 8 | * 福利金RpcCall类 9 | * 10 | * @author xiong 11 | */ 12 | public class OtherTaskRpcCall extends BaseTaskRpcCall { 13 | 14 | /** 15 | * 黄金票首页 16 | * 17 | * @return 结果 18 | */ 19 | public static String goldBillIndex() { 20 | return ApplicationHook.requestString("com.alipay.wealthgoldtwa.needle.goldbill.index", 21 | "[{\"pageTemplateCode\":\"H5_GOLDBILL\",\"params\":{\"client_pkg_version\":\"0.0.5\"}," + 22 | "\"url\":\"https://68687437.h5app.alipay.com/www/index.html\"}]"); 23 | } 24 | 25 | /** 26 | * 黄金票收取 27 | * 28 | * @param str signInfo 29 | * @return 结果 30 | */ 31 | public static String goldBillCollect(String str) { 32 | return ApplicationHook.requestString("com.alipay.wealthgoldtwa.goldbill.v2.index.collect", 33 | "[{" + str + "\"trigger\":\"Y\"}]"); 34 | } 35 | 36 | /** 37 | * 黄金票任务 38 | * 39 | * @param taskId taskId 40 | * @return 结果 41 | */ 42 | public static String goldBillTrigger(String taskId) { 43 | return ApplicationHook.requestString("com.alipay.wealthgoldtwa.goldbill.v4.task.trigger", 44 | "[{\"goldBillTaskTransferVersion\":\"v2\",\"taskId\":\"" + taskId + "\"}]"); 45 | } 46 | 47 | /** 48 | * 查询车神卡奖励 49 | * 50 | * @return 结果 51 | */ 52 | public static String v1benefitQuery() { 53 | return ApplicationHook.requestString("com.alipay.pcreditbfweb.drpc.cargodcard.v1benefitQuery", 54 | "[{\"args\":{\"productCode\":\"CAR_MASTER_CARD\"}}]"); 55 | } 56 | 57 | /** 58 | * 领取车神卡奖励 59 | * 60 | * @param jsonObject jsonObject 61 | * @return 结果 62 | */ 63 | public static String v1benefitTrigger(JSONObject jsonObject) { 64 | return ApplicationHook.requestString("com.alipay.pcreditbfweb.drpc.cargodcard.v1benefitTrigger", 65 | "[" + jsonObject + "]"); 66 | } 67 | 68 | /** 69 | * 查询车神卡奖励 70 | * 71 | * @return 结果 72 | */ 73 | public static String queryTaskList() { 74 | return ApplicationHook.requestString("alipay.promoprod.task.query.queryTaskList", 75 | "[ {\n" + 76 | " \"consultAccessFlag\": true,\n" + 77 | // " \"extInfo\": {\n" + 78 | // " \"paramsForStrategy\": \"{\\\"currentTaskId\\\":\\\"AP14241342\\\",\\\"appId\\\":\\\"2060090000314842\\\",\\\"hookId\\\":\\\"{\\\\\\\"gplusItem\\\\\\\":\\\\\\\"HK256605~CR727186~MI_30482_V2~lf_257\\\\\\\"}\\\"}\",\n" + 79 | // " \"sceneCode\": \"c_balltask\"\n" + 80 | // " },\n" + 81 | " \"planId\": \"AP17187348\"\n" + 82 | " }]"); 83 | } 84 | 85 | /** 86 | * 领取车神卡奖励 87 | * 88 | * @param gplusItem gplusItem 89 | * @return 结果 90 | */ 91 | public static String signup(String gplusItem, String taskId) { 92 | String str = "\"taskCenId\":\"AP17187348\",\"taskId\":\"" + taskId + "\""; 93 | if (!gplusItem.isEmpty()) { 94 | str += ",\"extInfo\":{\"gplusItem\":\"" + gplusItem + "\"}"; 95 | } 96 | return ApplicationHook.requestString("alipay.promoprod.task.query.signup", 97 | "[{" + str + "}]"); 98 | } 99 | 100 | /** 101 | * 领取车神卡奖励 102 | * 103 | * @param appletId appletId 104 | * @return 结果 105 | */ 106 | public static String complete(String appletId) { 107 | return ApplicationHook.requestString("alipay.promoprod.applet.complete", 108 | "[{\"appletId\":\"" + appletId + "\"}]"); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/readingDada/ReadingDada.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.readingDada; 2 | 3 | import org.json.JSONArray; 4 | import org.json.JSONObject; 5 | import tkaxv7s.xposed.sesame.model.normal.answerAI.AnswerAI; 6 | import tkaxv7s.xposed.sesame.util.JsonUtil; 7 | import tkaxv7s.xposed.sesame.util.Log; 8 | import tkaxv7s.xposed.sesame.util.StringUtil; 9 | 10 | /** 11 | * @author Constanline 12 | * @since 2023/08/22 13 | */ 14 | public class ReadingDada { 15 | private static final String TAG = ReadingDada.class.getSimpleName(); 16 | 17 | public static boolean answerQuestion(JSONObject bizInfo) { 18 | try { 19 | String taskJumpUrl = bizInfo.optString("taskJumpUrl"); 20 | if (StringUtil.isEmpty(taskJumpUrl)) { 21 | taskJumpUrl = bizInfo.getString("targetUrl"); 22 | } 23 | String activityId = taskJumpUrl.split("activityId%3D")[1].split("%26")[0]; 24 | String outBizId; 25 | if (taskJumpUrl.contains("outBizId%3D")) { 26 | outBizId = taskJumpUrl.split("outBizId%3D")[1].split("%26")[0]; 27 | } else { 28 | outBizId = ""; 29 | } 30 | String s = ReadingDadaRpcCall.getQuestion(activityId); 31 | JSONObject jo = new JSONObject(s); 32 | if ("200".equals(jo.getString("resultCode"))) { 33 | JSONArray jsonArray = jo.getJSONArray("options"); 34 | String question = jo.getString("title"); 35 | String answer = AnswerAI.getAnswer(question, JsonUtil.jsonArrayToList(jsonArray)); 36 | if (answer == null || answer.isEmpty()) { 37 | answer = jsonArray.getString(0); 38 | } 39 | s = ReadingDadaRpcCall.submitAnswer(activityId, outBizId, jo.getString("questionId"), answer); 40 | jo = new JSONObject(s); 41 | if ("200".equals(jo.getString("resultCode"))) { 42 | Log.record("答题完成"); 43 | return true; 44 | } else { 45 | Log.record("答题失败"); 46 | } 47 | } else { 48 | Log.record("获取问题失败"); 49 | } 50 | } catch (Throwable e) { 51 | Log.i(TAG, "answerQuestion err:"); 52 | Log.printStackTrace(TAG, e); 53 | } 54 | return false; 55 | } 56 | } -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/readingDada/ReadingDadaRpcCall.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.readingDada; 2 | 3 | import tkaxv7s.xposed.sesame.hook.ApplicationHook; 4 | import tkaxv7s.xposed.sesame.util.StringUtil; 5 | 6 | /** 7 | * @author Constanline 8 | * @since 2023/08/22 9 | */ 10 | public class ReadingDadaRpcCall { 11 | private static final String VERSION = "1"; 12 | 13 | public static String submitAnswer(String activityId, String outBizId, String questionId, String answer) { 14 | return ApplicationHook.requestString("com.alipay.reading.game.dada.openDailyAnswer.submitAnswer", 15 | "[{\"activityId\":\"" + activityId + "\",\"answer\":\"" + answer + "\",\"dadaVersion\":\"1.3.0\"," + 16 | (StringUtil.isEmpty(outBizId) ? "" : "\"outBizId\":\"" + outBizId + "\",") + 17 | "\"questionId\":\"" + questionId + "\",\"version\":" + VERSION + "}]"); 18 | } 19 | 20 | public static String getQuestion(String activityId) { 21 | return ApplicationHook.requestString("com.alipay.reading.game.dada.openDailyAnswer.getQuestion", 22 | "[{\"activityId\":\"" + activityId + "\",\"dadaVersion\":\"1.3.0\",\"version\":" + VERSION + "}]"); 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/reserve/ReserveRpcCall.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.reserve; 2 | 3 | import tkaxv7s.xposed.sesame.hook.ApplicationHook; 4 | import tkaxv7s.xposed.sesame.util.RandomUtil; 5 | 6 | public class ReserveRpcCall { 7 | private static final String VERSION = "20230501"; 8 | private static final String VERSION2 = "20230522"; 9 | private static final String VERSION3 = "20231031"; 10 | 11 | private static String getUniqueId() { 12 | return String.valueOf(System.currentTimeMillis()) + RandomUtil.nextLong(); 13 | } 14 | 15 | public static String queryTreeItemsForExchange() { 16 | return ApplicationHook.requestString("alipay.antforest.forest.h5.queryTreeItemsForExchange", 17 | "[{\"cityCode\":\"370100\",\"itemTypes\":\"\",\"source\":\"chInfo_ch_appcenter__chsub_9patch\",\"version\":\"" 18 | + VERSION2 + "\"}]"); 19 | } 20 | 21 | public static String queryTreeForExchange(String projectId) { 22 | return ApplicationHook.requestString("alipay.antforest.forest.h5.queryTreeForExchange", 23 | "[{\"projectId\":\"" + projectId + "\",\"version\":\"" + VERSION 24 | + "\",\"source\":\"chInfo_ch_appcenter__chsub_9patch\"}]"); 25 | } 26 | 27 | public static String exchangeTree(String projectId) { 28 | int projectId_num = Integer.parseInt(projectId); 29 | return ApplicationHook.requestString("alipay.antmember.forest.h5.exchangeTree", 30 | "[{\"projectId\":" + projectId_num + ",\"sToken\":\"" + System.currentTimeMillis() + "\",\"version\":\"" 31 | + VERSION + "\",\"source\":\"chInfo_ch_appcenter__chsub_9patch\"}]"); 32 | } 33 | 34 | /* 净滩行动 */ 35 | 36 | public static String queryCultivationList() { 37 | return ApplicationHook.requestString("alipay.antocean.ocean.h5.queryCultivationList", 38 | "[{\"source\":\"ANT_FOREST\",\"version\":\"" + VERSION3 + "\"}]"); 39 | } 40 | 41 | public static String queryCultivationDetail(String cultivationCode, String projectCode) { 42 | return ApplicationHook.requestString("alipay.antocean.ocean.h5.queryCultivationDetail", 43 | "[{\"cultivationCode\":\"" + cultivationCode + "\",\"projectCode\":\"" + projectCode 44 | + "\",\"source\":\"ANT_FOREST\",\"uniqueId\":\"" + getUniqueId() + "\"}]"); 45 | } 46 | 47 | public static String oceanExchangeTree(String cultivationCode, String projectCode) { 48 | return ApplicationHook.requestString("alipay.antocean.ocean.h5.exchangeTree", 49 | "[{\"cultivationCode\":\"" + cultivationCode + "\",\"projectCode\":\"" + projectCode 50 | + "\",\"source\":\"ANT_FOREST\",\"uniqueId\":\"" + getUniqueId() + "\"}]"); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/model/task/welfareCenter/WelfareCenterRpcCall.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.model.task.welfareCenter; 2 | 3 | import org.json.JSONArray; 4 | import tkaxv7s.xposed.sesame.hook.ApplicationHook; 5 | import tkaxv7s.xposed.sesame.model.common.rpcCall.BaseTaskRpcCall; 6 | import tkaxv7s.xposed.sesame.util.JsonUtil; 7 | 8 | /** 9 | * 福利金RpcCall类 10 | * 11 | * @author xiong 12 | */ 13 | public class WelfareCenterRpcCall extends BaseTaskRpcCall { 14 | 15 | /** 16 | * 查询待领取的福利金、签到 17 | * 18 | * @param signInSceneId signInSceneId 19 | * @return 结果 20 | */ 21 | public static String queryEnableVirtualProfitV2(String signInSceneId) { 22 | return ApplicationHook.requestString("com.alipay.loanpromoweb.promo.virtualProfit.queryEnableVirtualProfitV2", 23 | "[{\"firstSceneCode\":[],\"profitType\":\"ANTBANK_WELFARE_POINT\",\"sceneCode\":[\"FULICenter_JKJML\"," + 24 | "\"FULICenter_JZN\",\"BC3_BC3V1\",\"BC3_BC3V2\",\"BC3_BC3V3\",\"SQB_SQBV0\",\"SQB_SQBV1\",\"SQB_SQBV2\"," + 25 | "\"SQB_SQBV3\",\"SQB_SQBV4\",\"SQB_SQBV5\",\"SQB_SQBV6\",\"SQB_SQBV7\",\"SQB_SQBV8\",\"SQB_SQBV9\"," + 26 | "\"SQB_SQBV10\",\"SQB_SQBV11\",\"SQB_SQBSIGN\",\"FULICenter_JKJQW\",\"FULICenter_WSWF\",\"FULICenter_FLKZS\"," + 27 | "\"FULICenter_KGJXBBF\",\"FULICenter_AXHZXB\",\"FULICenter_BBF\",\"FULICenter_V1\",\"FULICenter_V2\"," + 28 | "\"FULICenter_V3\",\"FULICenter_V4\",\"FULICenter_V5\",\"FULICenter_V6\",\"FULICenter_V7\"," + 29 | "\"FULICenter_YulibaoAUM\",\"FULICenter_PayByMybank\",\"FULICenter_DepositAUM\",\"FULICenter_YYYYH\"," + 30 | "\"FULICenter_QYZ\",\"FULICenter_V7PLUS\",\"FULICenter_V6PLUS\",\"FULICenter_V5PLUS\"," + 31 | "\"FULICenter_V8\",\"FULICenter_V9\",\"FULICenter_V10\"],\"signInSceneId\":\"" + signInSceneId + "\"}]"); 32 | } 33 | 34 | /** 35 | * 批量领取福利金 36 | * 37 | * @param vpIds Ids 38 | * @return 结果 39 | */ 40 | public static String batchUseVirtualProfit(JSONArray vpIds) { 41 | return ApplicationHook.requestString("com.alipay.loanpromoweb.promo.virtualProfit.batchUseVirtualProfit", 42 | "[{\"virtualProfitIdList\":" + vpIds + "}]"); 43 | } 44 | 45 | /** 46 | * 查询抽奖次数 47 | * 48 | * @param certIds Ids 49 | * @return 结果 50 | */ 51 | public static String queryCert(String[] certIds) { 52 | return ApplicationHook.requestString("com.alipay.loanpromoweb.promo.cert.query", 53 | "[{\"certTemplateIdSet\":" + JsonUtil.toJsonString(certIds) + "}]"); 54 | } 55 | 56 | /** 57 | * 批量抽奖 58 | * 59 | * 60 | * @param playId ID 61 | * @return 结果 62 | */ 63 | public static String playTrigger(String playId) { 64 | return ApplicationHook.requestString("com.alipay.loanpromoweb.promo.playcenter.playTrigger.trigger", 65 | "[{\"extInfo\":{},\"operation\":\"MYBK_DACU_INTERACTIVE_ZHB\",\"playId\":\"" + playId + "\"}]"); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/rpc/RpcBridge.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.rpc; 2 | 3 | import tkaxv7s.xposed.sesame.entity.RpcEntity; 4 | 5 | public interface RpcBridge { 6 | 7 | void load() throws Exception; 8 | 9 | void unload(); 10 | 11 | String requestString(RpcEntity rpcEntity, int tryCount, int retryInterval); 12 | 13 | default String requestString(RpcEntity rpcEntity) { 14 | return requestString(rpcEntity, 3, -1); 15 | } 16 | 17 | default String requestString(String method, String data) { 18 | return requestString(method, data, 3, -1); 19 | } 20 | 21 | default String requestString(String method, String data, int tryCount, int retryInterval) { 22 | return requestString(new RpcEntity(method, data), tryCount, retryInterval); 23 | } 24 | 25 | RpcEntity requestObject(RpcEntity rpcEntity, int tryCount, int retryInterval); 26 | 27 | default RpcEntity requestObject(RpcEntity rpcEntity) { 28 | return requestObject(rpcEntity, 3, -1); 29 | } 30 | 31 | default RpcEntity requestObject(String method, String data) { 32 | return requestObject(method, data, 3, -1); 33 | } 34 | 35 | default RpcEntity requestObject(String method, String data, int tryCount, int retryInterval) { 36 | return requestObject(new RpcEntity(method, data), tryCount, retryInterval); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/ui/ChoiceDialog.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.ui; 2 | 3 | import android.app.AlertDialog; 4 | import android.content.Context; 5 | 6 | import tkaxv7s.xposed.sesame.R; 7 | import tkaxv7s.xposed.sesame.data.modelFieldExt.ChoiceModelField; 8 | 9 | public class ChoiceDialog { 10 | 11 | public static void show(Context c, CharSequence title, ChoiceModelField choiceModelField) { 12 | new AlertDialog.Builder(c) 13 | .setTitle(title) 14 | .setSingleChoiceItems(choiceModelField.getChoiceArray(), choiceModelField.getValue(), 15 | (p1, p2) -> choiceModelField.setValue(p2)) 16 | .setPositiveButton(c.getString(R.string.ok), null) 17 | .create().show(); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/ui/HtmlViewerActivity.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.ui; 2 | 3 | import android.app.Activity; 4 | import android.content.ClipData; 5 | import android.content.ClipboardManager; 6 | import android.content.Intent; 7 | import android.net.Uri; 8 | import android.os.Bundle; 9 | import android.view.Menu; 10 | import android.view.MenuItem; 11 | import android.view.View; 12 | import android.webkit.WebChromeClient; 13 | import android.webkit.WebView; 14 | import android.widget.ProgressBar; 15 | import android.widget.Toast; 16 | import tkaxv7s.xposed.sesame.R; 17 | import tkaxv7s.xposed.sesame.data.ViewAppInfo; 18 | import tkaxv7s.xposed.sesame.util.FileUtil; 19 | import tkaxv7s.xposed.sesame.util.LanguageUtil; 20 | 21 | import java.io.File; 22 | 23 | public class HtmlViewerActivity extends Activity { 24 | MyWebView mWebView; 25 | ProgressBar pgb; 26 | Uri uri; 27 | Boolean canClear; 28 | 29 | @Override 30 | protected void onCreate(Bundle savedInstanceState) { 31 | super.onCreate(savedInstanceState); 32 | LanguageUtil.setLocale(this); 33 | setContentView(R.layout.activity_html_viewer); 34 | 35 | mWebView = findViewById(R.id.mwv_webview); 36 | pgb = findViewById(R.id.pgb_webview); 37 | 38 | mWebView.setWebChromeClient( 39 | new WebChromeClient() { 40 | @Override 41 | public void onProgressChanged(WebView view, int progress) { 42 | pgb.setProgress(progress); 43 | if (progress < 100) { 44 | setTitle("Loading..."); 45 | pgb.setVisibility(View.VISIBLE); 46 | } else { 47 | setTitle(mWebView.getTitle() + ViewAppInfo.getAppVersion()); 48 | pgb.setVisibility(View.GONE); 49 | } 50 | } 51 | }); 52 | } 53 | 54 | @Override 55 | protected void onResume() { 56 | super.onResume(); 57 | Intent intent = getIntent(); 58 | uri = intent.getData(); 59 | if (uri != null) { 60 | mWebView.loadUrl(uri.toString()); 61 | } 62 | canClear = intent.getBooleanExtra("canClear", false); 63 | } 64 | 65 | @Override 66 | public boolean onCreateOptionsMenu(Menu menu) { 67 | menu.add(0, 1, 1, getString(R.string.export_file)); 68 | if (canClear) { 69 | menu.add(0, 2, 2, getString(R.string.clear_file)); 70 | } 71 | menu.add(0, 3, 3, getString(R.string.open_with_other_browser)); 72 | menu.add(0, 4, 4, getString(R.string.copy_the_url)); 73 | menu.add(0, 5, 5, getString(R.string.scroll_to_top)); 74 | menu.add(0, 6, 6, getString(R.string.scroll_to_bottom)); 75 | return super.onCreateOptionsMenu(menu); 76 | } 77 | 78 | @Override 79 | public boolean onOptionsItemSelected(MenuItem item) { 80 | switch (item.getItemId()) { 81 | case 1: 82 | if (uri != null) { 83 | String path = uri.getPath(); 84 | if (path != null) { 85 | File exportFile = FileUtil.exportFile(new File(path)); 86 | if (exportFile != null) { 87 | Toast.makeText(this, "文件已导出到: " + exportFile.getPath(), Toast.LENGTH_SHORT).show(); 88 | } 89 | } 90 | } 91 | break; 92 | 93 | case 2: 94 | if (uri != null) { 95 | String path = uri.getPath(); 96 | if (path != null) { 97 | File file = new File(path); 98 | if (FileUtil.clearFile(file)) { 99 | android.widget.Toast.makeText(this, "文件已清空", android.widget.Toast.LENGTH_SHORT).show(); 100 | mWebView.reload(); 101 | } 102 | } 103 | } 104 | break; 105 | 106 | case 3: 107 | if (uri != null) { 108 | String scheme = uri.getScheme(); 109 | if ("http".equalsIgnoreCase(scheme) || "https".equalsIgnoreCase(scheme)) { 110 | Intent intent = new Intent(Intent.ACTION_VIEW, uri); 111 | startActivity(intent); 112 | } else if ("file".equalsIgnoreCase(scheme)) { 113 | Toast.makeText(this, "该文件不支持用浏览器打开", Toast.LENGTH_SHORT).show(); 114 | } else { 115 | Toast.makeText(this, "不支持用浏览器打开", Toast.LENGTH_SHORT).show(); 116 | } 117 | } 118 | break; 119 | 120 | case 4: 121 | ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); 122 | cm.setPrimaryClip(ClipData.newPlainText(null, mWebView.getUrl())); 123 | Toast.makeText(this, getString(R.string.copy_success), Toast.LENGTH_SHORT).show(); 124 | break; 125 | 126 | case 5: 127 | mWebView.scrollTo(0, 0); 128 | break; 129 | 130 | case 6: 131 | mWebView.scrollToBottom(); 132 | break; 133 | } 134 | return true; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/ui/ListAdapter.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.ui; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Context; 5 | import android.graphics.Color; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.BaseAdapter; 9 | import android.widget.CheckBox; 10 | import android.widget.TextView; 11 | 12 | import java.util.ArrayList; 13 | import java.util.Collections; 14 | import java.util.List; 15 | import java.util.Map; 16 | 17 | import tkaxv7s.xposed.sesame.R; 18 | import tkaxv7s.xposed.sesame.entity.IdAndName; 19 | import tkaxv7s.xposed.sesame.util.Log; 20 | 21 | /** 22 | * @author xiong 23 | */ 24 | public class ListAdapter extends BaseAdapter { 25 | @SuppressLint("StaticFieldLeak") 26 | private static ListAdapter adapter; 27 | 28 | private static ListDialog.ListType listType; 29 | 30 | public static ListAdapter get(Context c) { 31 | if (adapter == null) { 32 | adapter = new ListAdapter(c); 33 | } 34 | return adapter; 35 | } 36 | 37 | public static ListAdapter get(Context c, ListDialog.ListType listType) { 38 | if (adapter == null) { 39 | adapter = new ListAdapter(c); 40 | viewHolderList = new ArrayList<>(); 41 | } 42 | ListAdapter.listType = listType; 43 | return adapter; 44 | } 45 | 46 | Context context; 47 | List list; 48 | Map selectedMap; 49 | int findIndex = -1; 50 | CharSequence findWord = null; 51 | 52 | private ListAdapter(Context c) { 53 | context = c; 54 | } 55 | 56 | public void setBaseList(List l) { 57 | if (l != list) { 58 | exitFind(); 59 | } 60 | list = l; 61 | } 62 | 63 | public void setSelectedList(Map selectedMap) { 64 | this.selectedMap = selectedMap; 65 | try { 66 | Collections.sort(list, (o1, o2) -> { 67 | if (this.selectedMap.containsKey(o1.id) == this.selectedMap.containsKey(o2.id)) { 68 | return o1.compareTo(o2); 69 | } 70 | return this.selectedMap.containsKey(o1.id) ? -1 : 1; 71 | }); 72 | } catch (Throwable t) { 73 | Log.i("ListAdapter err"); 74 | Log.printStackTrace(t); 75 | } 76 | } 77 | 78 | public int findLast(CharSequence cs) { 79 | if (list == null || list.isEmpty()) { 80 | return -1; 81 | } 82 | if (!cs.equals(findWord)) { 83 | findIndex = -1; 84 | findWord = cs; 85 | } 86 | int i = findIndex; 87 | if (i < 0) { 88 | i = list.size(); 89 | } 90 | for (; ; ) { 91 | i = (i + list.size() - 1) % list.size(); 92 | IdAndName ai = list.get(i); 93 | if (ai.name.contains(cs)) { 94 | findIndex = i; 95 | break; 96 | } 97 | if (findIndex < 0 && i == 0) { 98 | break; 99 | } 100 | } 101 | notifyDataSetChanged(); 102 | return findIndex; 103 | } 104 | 105 | public int findNext(CharSequence cs) { 106 | if (list == null || list.isEmpty()) { 107 | return -1; 108 | } 109 | if (!cs.equals(findWord)) { 110 | findIndex = -1; 111 | findWord = cs; 112 | } 113 | int i = findIndex; 114 | while (true) { 115 | i = (i + 1) % list.size(); 116 | IdAndName ai = list.get(i); 117 | if (ai.name.contains(cs)) { 118 | findIndex = i; 119 | break; 120 | } 121 | if (findIndex < 0 && i == list.size() - 1) { 122 | break; 123 | } 124 | } 125 | notifyDataSetChanged(); 126 | return findIndex; 127 | } 128 | 129 | public void exitFind() { 130 | findIndex = -1; 131 | } 132 | 133 | public void selectAll() { 134 | selectedMap.clear(); 135 | for (IdAndName ai : list) { 136 | selectedMap.put(ai.id, 0); 137 | } 138 | notifyDataSetChanged(); 139 | } 140 | 141 | public void SelectInvert() { 142 | for (IdAndName ai : list) { 143 | if (!selectedMap.containsKey(ai.id)) { 144 | selectedMap.put(ai.id, 0); 145 | } else { 146 | selectedMap.remove(ai.id); 147 | } 148 | } 149 | notifyDataSetChanged(); 150 | } 151 | 152 | @Override 153 | public int getCount() { 154 | return list == null ? 0 : list.size(); 155 | } 156 | 157 | @Override 158 | public Object getItem(int p1) { 159 | return list.get(p1); 160 | } 161 | 162 | @Override 163 | public long getItemId(int p1) { 164 | return p1; 165 | } 166 | 167 | @Override 168 | public View getView(int p1, View p2, ViewGroup p3) { 169 | ViewHolder vh; 170 | if (p2 == null) { 171 | vh = new ViewHolder(); 172 | p2 = View.inflate(context, R.layout.list_item, null); 173 | vh.tv = p2.findViewById(R.id.tv_idn); 174 | vh.cb = p2.findViewById(R.id.cb_list); 175 | if (listType == ListDialog.ListType.SHOW) { 176 | vh.cb.setVisibility(View.GONE); 177 | } 178 | p2.setTag(vh); 179 | viewHolderList.add(vh); 180 | } else { 181 | vh = (ViewHolder) p2.getTag(); 182 | } 183 | 184 | IdAndName ai = list.get(p1); 185 | vh.tv.setText(ai.name); 186 | vh.tv.setTextColor(findIndex == p1 ? Color.RED : Color.BLACK); 187 | vh.cb.setChecked(selectedMap != null && selectedMap.containsKey(ai.id)); 188 | return p2; 189 | } 190 | 191 | public static List viewHolderList; 192 | 193 | public static class ViewHolder { 194 | TextView tv; 195 | CheckBox cb; 196 | } 197 | 198 | } 199 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/ui/MyWebView.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.ui; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.webkit.WebSettings; 6 | import android.webkit.WebView; 7 | import android.webkit.WebViewClient; 8 | 9 | public class MyWebView extends WebView { 10 | public MyWebView(Context c) { 11 | super(c); 12 | defInit(); 13 | } 14 | 15 | public MyWebView(Context context, AttributeSet attrs) { 16 | super(context, attrs); 17 | defInit(); 18 | } 19 | 20 | public MyWebView(Context context, AttributeSet attrs, int defStyleAttr) { 21 | super(context, attrs, defStyleAttr); 22 | defInit(); 23 | } 24 | 25 | public MyWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 26 | super(context, attrs, defStyleAttr, defStyleRes); 27 | defInit(); 28 | } 29 | 30 | private void defInit() { 31 | getSettings().setSupportZoom(true); 32 | getSettings().setBuiltInZoomControls(true); 33 | getSettings().setDisplayZoomControls(false); 34 | getSettings().setUseWideViewPort(false); 35 | getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS); 36 | getSettings().setAllowFileAccess(true); 37 | setWebViewClient( 38 | new WebViewClient() { 39 | public void onPageFinished(WebView view, String url) { 40 | if (url.endsWith(".log")) 41 | postDelayed( 42 | new Runnable() { 43 | @Override 44 | public void run() { 45 | if (Thread.interrupted()) return; 46 | if (getContentHeight() == 0) 47 | postDelayed(this, 100); 48 | else 49 | scrollToBottom(); 50 | } 51 | }, 500); 52 | } 53 | }); 54 | } 55 | 56 | public void scrollToBottom() { 57 | scrollTo(0, computeVerticalScrollRange()); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/ui/OptionsAdapter.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.ui; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Context; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.BaseAdapter; 9 | import android.widget.TextView; 10 | 11 | import java.util.ArrayList; 12 | 13 | public class OptionsAdapter extends BaseAdapter { 14 | @SuppressLint("StaticFieldLeak") 15 | private static OptionsAdapter adapter; 16 | 17 | public static OptionsAdapter get(Context c) { 18 | if (adapter == null) 19 | adapter = new OptionsAdapter(c); 20 | return adapter; 21 | } 22 | 23 | Context context; 24 | ArrayList list; 25 | 26 | private OptionsAdapter(Context c) { 27 | context = c; 28 | list = new ArrayList<>(); 29 | list.add("查看森林"); 30 | list.add("查看庄园"); 31 | list.add("删除"); 32 | } 33 | 34 | @Override 35 | public int getCount() { 36 | return list == null ? 0 : list.size(); 37 | } 38 | 39 | @Override 40 | public Object getItem(int p1) { 41 | return list.get(p1); 42 | } 43 | 44 | @Override 45 | public long getItemId(int p1) { 46 | return p1; 47 | } 48 | 49 | @SuppressLint("InflateParams") 50 | @Override 51 | public View getView(int p1, View p2, ViewGroup p3) { 52 | if (p2 == null) { 53 | p2 = LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, null); 54 | } 55 | TextView txt = (TextView) p2; 56 | txt.setText(getItem(p1).toString()); 57 | return p2; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/ui/SettingsActivity.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.ui; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.app.Activity; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.os.Bundle; 8 | import android.view.Gravity; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.LinearLayout; 12 | import android.widget.ScrollView; 13 | import android.widget.TabHost; 14 | import android.widget.TabWidget; 15 | import android.widget.Toast; 16 | 17 | import java.util.Map; 18 | 19 | import tkaxv7s.xposed.sesame.R; 20 | import tkaxv7s.xposed.sesame.data.ConfigV2; 21 | import tkaxv7s.xposed.sesame.data.ModelConfig; 22 | import tkaxv7s.xposed.sesame.data.ModelField; 23 | import tkaxv7s.xposed.sesame.data.ModelFields; 24 | import tkaxv7s.xposed.sesame.data.ViewAppInfo; 25 | import tkaxv7s.xposed.sesame.data.ModelTask; 26 | import tkaxv7s.xposed.sesame.util.BeachIdMap; 27 | import tkaxv7s.xposed.sesame.util.CooperationIdMap; 28 | import tkaxv7s.xposed.sesame.util.LanguageUtil; 29 | import tkaxv7s.xposed.sesame.util.Log; 30 | import tkaxv7s.xposed.sesame.util.ReserveIdMap; 31 | import tkaxv7s.xposed.sesame.util.UserIdMap; 32 | 33 | public class SettingsActivity extends Activity { 34 | 35 | private Boolean isDraw = false; 36 | private Context context; 37 | private TabHost tabHost; 38 | private ScrollView svTabs; 39 | 40 | @SuppressLint("MissingInflatedId") 41 | @Override 42 | protected void onCreate(Bundle savedInstanceState) { 43 | super.onCreate(savedInstanceState); 44 | ConfigV2.load(); 45 | LanguageUtil.setLocale(this); 46 | setContentView(R.layout.activity_settings); 47 | setTitle(getText(R.string.settings) + " " + ViewAppInfo.getAppVersion()); 48 | 49 | context = this; 50 | tabHost = findViewById(R.id.tab_settings); 51 | svTabs = findViewById(R.id.sv_tabs); 52 | tabHost.setup(); 53 | 54 | Map modelConfigMap = ModelTask.getModelConfigMap(); 55 | for (Map.Entry configEntry : modelConfigMap.entrySet()) { 56 | String modelCode = configEntry.getKey(); 57 | ModelConfig modelConfig = configEntry.getValue(); 58 | ModelFields modelFields = modelConfig.getFields(); 59 | 60 | tabHost.addTab(tabHost.newTabSpec(modelCode) 61 | .setIndicator(modelConfig.getName()) 62 | .setContent(new TabHost.TabContentFactory() { 63 | @Override 64 | public View createTabContent(String tag) { 65 | LinearLayout linearLayout = new LinearLayout(context); 66 | linearLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); 67 | linearLayout.setGravity(Gravity.CENTER_HORIZONTAL); 68 | linearLayout.setOrientation(LinearLayout.VERTICAL); 69 | for (ModelField modelField : modelFields.values()) { 70 | View view = modelField.getView(context); 71 | if (view != null) { 72 | linearLayout.addView(view); 73 | } 74 | } 75 | return linearLayout; 76 | } 77 | }) 78 | ); 79 | 80 | } 81 | tabHost.setCurrentTab(0); 82 | 83 | UserIdMap.shouldReload = true; 84 | CooperationIdMap.shouldReload = true; 85 | ReserveIdMap.shouldReload = true; 86 | BeachIdMap.shouldReload = true; 87 | } 88 | 89 | @Override 90 | public void onWindowFocusChanged(boolean hasFocus) { 91 | super.onWindowFocusChanged(hasFocus); 92 | if (!isDraw && hasFocus) { 93 | int width = svTabs.getWidth(); 94 | TabWidget tabWidget = tabHost.getTabWidget(); 95 | int childCount = tabWidget.getChildCount(); 96 | for (int i = 0; i < childCount; i++) { 97 | tabWidget.getChildAt(i).getLayoutParams().width = width; 98 | } 99 | tabWidget.requestLayout(); 100 | isDraw = true; 101 | } 102 | } 103 | 104 | @Override 105 | protected void onPause() { 106 | super.onPause(); 107 | if (ConfigV2.isModify() && ConfigV2.save(false)) { 108 | Toast.makeText(this, "保存成功!", Toast.LENGTH_SHORT).show(); 109 | try { 110 | sendBroadcast(new Intent("com.eg.android.AlipayGphone.sesame.restart")); 111 | } catch (Throwable th) { 112 | Log.printStackTrace(th); 113 | } 114 | } 115 | UserIdMap.saveIdMap(); 116 | CooperationIdMap.saveIdMap(); 117 | ReserveIdMap.saveIdMap(); 118 | BeachIdMap.saveIdMap(); 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/ui/StringDialog.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.ui; 2 | 3 | import android.app.AlertDialog; 4 | import android.content.Context; 5 | import android.content.DialogInterface; 6 | import android.content.DialogInterface.OnClickListener; 7 | import android.graphics.Color; 8 | import android.text.Editable; 9 | import android.text.InputType; 10 | import android.widget.EditText; 11 | 12 | import tkaxv7s.xposed.sesame.R; 13 | import tkaxv7s.xposed.sesame.data.ModelField; 14 | import tkaxv7s.xposed.sesame.util.Log; 15 | 16 | public class StringDialog { 17 | 18 | private static ModelField modelField; 19 | 20 | public static void showEditDialog(Context c, CharSequence title, ModelField modelField) { 21 | showEditDialog(c, title, modelField, null); 22 | } 23 | 24 | public static void showEditDialog(Context c, CharSequence title, ModelField modelField, String msg) { 25 | StringDialog.modelField = modelField; 26 | AlertDialog editDialog = getEditDialog(c); 27 | if (msg != null) { 28 | editDialog.setTitle(title); 29 | editDialog.setMessage(msg); 30 | } else { 31 | editDialog.setTitle(title); 32 | } 33 | editDialog.show(); 34 | } 35 | 36 | private static AlertDialog getEditDialog(Context c) { 37 | EditText edt = new EditText(c); 38 | AlertDialog editDialog = new AlertDialog.Builder(c) 39 | .setTitle("title") 40 | .setView(edt) 41 | .setPositiveButton( 42 | c.getString(R.string.ok), 43 | new OnClickListener() { 44 | Context context; 45 | 46 | public OnClickListener setData(Context c) { 47 | context = c; 48 | return this; 49 | } 50 | 51 | @Override 52 | public void onClick(DialogInterface p1, int p2) { 53 | try { 54 | Editable text = edt.getText(); 55 | if (text == null) { 56 | modelField.setConfigValue(null); 57 | return; 58 | } 59 | String textString = text.toString(); 60 | if (textString.isEmpty()) { 61 | modelField.setConfigValue(null); 62 | return; 63 | } 64 | modelField.setConfigValue(textString); 65 | } catch (Throwable e) { 66 | Log.printStackTrace(e); 67 | } 68 | } 69 | }.setData(c)) 70 | .create(); 71 | edt.setText(String.valueOf(modelField.getConfigValue())); 72 | return editDialog; 73 | } 74 | 75 | public static void showReadDialog(Context c, CharSequence title, ModelField modelField) { 76 | showReadDialog(c, title, modelField, null); 77 | } 78 | 79 | public static void showReadDialog(Context c, CharSequence title, ModelField modelField, String msg) { 80 | StringDialog.modelField = modelField; 81 | AlertDialog readDialog = getReadDialog(c); 82 | if (msg != null) { 83 | readDialog.setTitle(title); 84 | readDialog.setMessage(msg); 85 | } else { 86 | readDialog.setTitle(title); 87 | } 88 | readDialog.show(); 89 | } 90 | 91 | private static AlertDialog getReadDialog(Context c) { 92 | EditText edt = new EditText(c); 93 | edt.setInputType(InputType.TYPE_NULL); 94 | edt.setTextColor(Color.GRAY); 95 | AlertDialog readDialog = new AlertDialog.Builder(c) 96 | .setTitle("title") 97 | .setView(edt) 98 | .create(); 99 | edt.setText(String.valueOf(modelField.getConfigValue())); 100 | return readDialog; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/util/BeachIdMap.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.util; 2 | 3 | import java.util.Map; 4 | import java.util.Set; 5 | import java.util.TreeMap; 6 | 7 | public class BeachIdMap { 8 | private static final String TAG = BeachIdMap.class.getSimpleName(); 9 | 10 | public static boolean shouldReload = false; 11 | 12 | private static Map idMap; 13 | private static boolean hasChanged = false; 14 | 15 | public static void putIdMap(String key, String value) { 16 | if (key == null || key.isEmpty()) 17 | return; 18 | if (getIdMap().containsKey(key)) { 19 | if (!getIdMap().get(key).equals(value)) { 20 | getIdMap().remove(key); 21 | getIdMap().put(key, value); 22 | hasChanged = true; 23 | } 24 | } else { 25 | getIdMap().put(key, value); 26 | hasChanged = true; 27 | } 28 | } 29 | 30 | public static void removeIdMap(String key) { 31 | if (key == null || key.isEmpty()) 32 | return; 33 | if (getIdMap().containsKey(key)) { 34 | getIdMap().remove(key); 35 | hasChanged = true; 36 | } 37 | } 38 | 39 | public static void saveIdMap() { 40 | if (hasChanged) { 41 | StringBuilder sb = new StringBuilder(); 42 | Set> idSet = getIdMap().entrySet(); 43 | for (Map.Entry entry : idSet) { 44 | sb.append(entry.getKey()); 45 | sb.append(':'); 46 | sb.append(entry.getValue()); 47 | sb.append('\n'); 48 | } 49 | hasChanged = !FileUtil.write2File(sb.toString(), FileUtil.getBeachIdMapFile()); 50 | } 51 | } 52 | 53 | public static Map getIdMap() { 54 | if (idMap == null || shouldReload) { 55 | shouldReload = false; 56 | idMap = new TreeMap<>(); 57 | String str = FileUtil.readFromFile(FileUtil.getBeachIdMapFile()); 58 | if (str != null && str.length() > 0) { 59 | try { 60 | String[] idSet = str.split("\n"); 61 | for (String s : idSet) { 62 | // Log.i(TAG, s); 63 | int ind = s.indexOf(":"); 64 | idMap.put(s.substring(0, ind), s.substring(ind + 1)); 65 | } 66 | } catch (Throwable t) { 67 | Log.printStackTrace(TAG, t); 68 | idMap.clear(); 69 | } 70 | } 71 | } 72 | return idMap; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/util/ClassUtil.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.util; 2 | 3 | public class ClassUtil { 4 | 5 | public static final String PACKAGE_NAME = "com.eg.android.AlipayGphone"; 6 | 7 | public static final String CURRENT_USING_SERVICE = "com.alipay.dexaop.power.RuntimePowerService"; 8 | 9 | public static final String CURRENT_USING_ACTIVITY = "com.eg.android.AlipayGphone.AlipayLogin"; 10 | 11 | public static final String JSON_OBJECT_NAME = "com.alibaba.fastjson.JSONObject"; 12 | 13 | public static final String H5PAGE_NAME = "com.alipay.mobile.h5container.api.H5Page"; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/util/CooperationIdMap.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.util; 2 | 3 | import java.util.Map; 4 | import java.util.Set; 5 | import java.util.TreeMap; 6 | 7 | public class CooperationIdMap { 8 | private static final String TAG = CooperationIdMap.class.getSimpleName(); 9 | 10 | public static boolean shouldReload = false; 11 | 12 | private static Map idMap; 13 | private static boolean hasChanged = false; 14 | 15 | public static void putIdMap(String key, String value) { 16 | if (key == null || key.isEmpty()) 17 | return; 18 | if (getIdMap().containsKey(key)) { 19 | if (!getIdMap().get(key).equals(value)) { 20 | getIdMap().remove(key); 21 | getIdMap().put(key, value); 22 | hasChanged = true; 23 | } 24 | } else { 25 | getIdMap().put(key, value); 26 | hasChanged = true; 27 | } 28 | } 29 | 30 | public static void removeIdMap(String key) { 31 | if (key == null || key.isEmpty()) 32 | return; 33 | if (getIdMap().containsKey(key)) { 34 | getIdMap().remove(key); 35 | hasChanged = true; 36 | } 37 | } 38 | 39 | public static void saveIdMap() { 40 | if (hasChanged) { 41 | StringBuilder sb = new StringBuilder(); 42 | Set> idSet = getIdMap().entrySet(); 43 | for (Map.Entry entry : idSet) { 44 | sb.append(entry.getKey()); 45 | sb.append(':'); 46 | sb.append(entry.getValue()); 47 | sb.append('\n'); 48 | } 49 | hasChanged = !FileUtil.write2File(sb.toString(), FileUtil.getCooperationIdMapFile()); 50 | } 51 | } 52 | 53 | public static Map getIdMap() { 54 | if (idMap == null || shouldReload) { 55 | shouldReload = false; 56 | idMap = new TreeMap<>(); 57 | String str = FileUtil.readFromFile(FileUtil.getCooperationIdMapFile()); 58 | if (str != null && str.length() > 0) { 59 | try { 60 | String[] idSet = str.split("\n"); 61 | for (String s : idSet) { 62 | // Log.i(TAG, s); 63 | int ind = s.indexOf(":"); 64 | idMap.put(s.substring(0, ind), s.substring(ind + 1)); 65 | } 66 | } catch (Throwable t) { 67 | Log.printStackTrace(TAG, t); 68 | idMap.clear(); 69 | } 70 | } 71 | } 72 | return idMap; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/util/LanguageUtil.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.util; 2 | 3 | import android.content.Context; 4 | import android.content.res.Configuration; 5 | 6 | import java.util.Locale; 7 | 8 | import tkaxv7s.xposed.sesame.model.normal.base.BaseModel; 9 | 10 | 11 | public class LanguageUtil { 12 | public static void setLocale(Context context) { 13 | if (BaseModel.getLanguageSimplifiedChinese().getValue()) { 14 | // 忽略系统语言,强制使用简体中文 15 | Locale locale = new Locale("zh", "CN"); // 简体中文的区域代码 16 | Locale.setDefault(locale); 17 | Configuration config = new Configuration(); 18 | config.locale = locale; 19 | context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics()); 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/util/ListUtil.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.util; 2 | 3 | 4 | import java.util.ArrayList; 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | public class ListUtil { 9 | private static final String TAG = ListUtil.class.getSimpleName(); 10 | 11 | @SafeVarargs 12 | public static List newArrayList(T... objects) { 13 | List list = new ArrayList<>(); 14 | if (objects != null) { 15 | Collections.addAll(list, objects); 16 | } 17 | return list; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/util/RandomUtil.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.util; 2 | 3 | import java.util.Random; 4 | 5 | public class RandomUtil { 6 | private static final Random rnd = new Random(); 7 | 8 | public static int delay() { 9 | return nextInt(100, 300); 10 | } 11 | 12 | public static int nextInt(int min, int max) { 13 | if (min >= max) return min; 14 | return rnd.nextInt(max - min) + min; 15 | } 16 | 17 | public static long nextLong() { 18 | return rnd.nextLong(); 19 | } 20 | 21 | public static long nextLong(long min, long max) { 22 | if (min >= max) return min; 23 | long o = max - min; 24 | return rnd.nextLong() % o + min; 25 | } 26 | 27 | public static double nextDouble() { 28 | return rnd.nextDouble(); 29 | } 30 | 31 | public static String getRandom(int len) { 32 | StringBuilder rs = new StringBuilder(); 33 | for (int i = 0; i < len; i++) { 34 | rs.append(rnd.nextInt(10)); 35 | } 36 | return rs.toString(); 37 | } 38 | 39 | public static String getRandomString(int length) { 40 | String str = "abcdefghijklmnopqrstuvwxyz0123456789"; 41 | StringBuffer sb = new StringBuffer(); 42 | for (int i = 0; i < length; i++) { 43 | int number = rnd.nextInt(36); 44 | sb.append(str.charAt(number)); 45 | } 46 | return sb.toString(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/util/ReserveIdMap.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.util; 2 | 3 | import java.util.Map; 4 | import java.util.Set; 5 | import java.util.TreeMap; 6 | 7 | public class ReserveIdMap { 8 | private static final String TAG = ReserveIdMap.class.getSimpleName(); 9 | 10 | public static boolean shouldReload = false; 11 | 12 | private static Map idMap; 13 | private static boolean hasChanged = false; 14 | 15 | public static void putIdMap(String key, String value) { 16 | if (key == null || key.isEmpty()) 17 | return; 18 | if (getIdMap().containsKey(key)) { 19 | if (!getIdMap().get(key).equals(value)) { 20 | getIdMap().remove(key); 21 | getIdMap().put(key, value); 22 | hasChanged = true; 23 | } 24 | } else { 25 | getIdMap().put(key, value); 26 | hasChanged = true; 27 | } 28 | } 29 | 30 | public static void removeIdMap(String key) { 31 | if (key == null || key.isEmpty()) 32 | return; 33 | if (getIdMap().containsKey(key)) { 34 | getIdMap().remove(key); 35 | hasChanged = true; 36 | } 37 | } 38 | 39 | public static void saveIdMap() { 40 | if (hasChanged) { 41 | StringBuilder sb = new StringBuilder(); 42 | Set> idSet = getIdMap().entrySet(); 43 | for (Map.Entry entry : idSet) { 44 | sb.append(entry.getKey()); 45 | sb.append(':'); 46 | sb.append(entry.getValue()); 47 | sb.append('\n'); 48 | } 49 | hasChanged = !FileUtil.write2File(sb.toString(), FileUtil.getReserveIdMapFile()); 50 | } 51 | } 52 | 53 | public static Map getIdMap() { 54 | if (idMap == null || shouldReload) { 55 | shouldReload = false; 56 | idMap = new TreeMap<>(); 57 | String str = FileUtil.readFromFile(FileUtil.getReserveIdMapFile()); 58 | if (str != null && str.length() > 0) { 59 | try { 60 | String[] idSet = str.split("\n"); 61 | for (String s : idSet) { 62 | // Log.i(TAG, s); 63 | int ind = s.indexOf(":"); 64 | idMap.put(s.substring(0, ind), s.substring(ind + 1)); 65 | } 66 | } catch (Throwable t) { 67 | Log.printStackTrace(TAG, t); 68 | idMap.clear(); 69 | } 70 | } 71 | } 72 | return idMap; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/util/StringUtil.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.util; 2 | 3 | import java.util.Collection; 4 | import java.util.Iterator; 5 | import java.util.Objects; 6 | 7 | public class StringUtil { 8 | public static boolean isEmpty(String str) { 9 | return str == null || str.isEmpty(); 10 | } 11 | 12 | public static String collectionJoinString(CharSequence conjunction, Collection collection) { 13 | if (!collection.isEmpty()) { 14 | StringBuilder b = new StringBuilder(); 15 | Iterator iterator = collection.iterator(); 16 | b.append(toStringOrEmpty(iterator.next())); 17 | while (iterator.hasNext()) { 18 | b.append(conjunction).append(toStringOrEmpty(iterator.next())); 19 | } 20 | return b.toString(); 21 | } 22 | return ""; 23 | } 24 | 25 | public static String arrayJoinString(CharSequence conjunction, Object... array) { 26 | int length = array.length; 27 | if (length > 0) { 28 | StringBuilder b = new StringBuilder(); 29 | b.append(toStringOrEmpty(array[0])); 30 | for (int i = 1; i < length; i++) { 31 | b.append(conjunction).append(toStringOrEmpty(array[i])); 32 | } 33 | return b.toString(); 34 | } 35 | return ""; 36 | } 37 | 38 | public static String arrayToString(Object... array) { 39 | return arrayJoinString(",", array); 40 | } 41 | 42 | private static String toStringOrEmpty(Object obj) { 43 | return Objects.toString(obj, ""); 44 | } 45 | 46 | public static String padLeft(int str, int totalWidth, char padChar) { 47 | return padLeft(String.valueOf(str), totalWidth, padChar); 48 | } 49 | 50 | public static String padRight(int str, int totalWidth, char padChar) { 51 | return padRight(String.valueOf(str), totalWidth, padChar); 52 | } 53 | 54 | public static String padLeft(String str, int totalWidth, char padChar) { 55 | StringBuilder sb = new StringBuilder(str); 56 | while (sb.length() < totalWidth) { 57 | sb.insert(0, padChar); 58 | } 59 | return sb.toString(); 60 | } 61 | 62 | public static String padRight(String str, int totalWidth, char padChar) { 63 | StringBuilder sb = new StringBuilder(str); 64 | while (sb.length() < totalWidth) { 65 | sb.append(padChar); 66 | } 67 | return sb.toString(); 68 | } 69 | 70 | public static String getSubString(String text, String left, String right) { 71 | String result = ""; 72 | int zLen; 73 | if (left == null || left.isEmpty()) { 74 | zLen = 0; 75 | } else { 76 | zLen = text.indexOf(left); 77 | if (zLen > -1) { 78 | zLen += left.length(); 79 | } else { 80 | zLen = 0; 81 | } 82 | } 83 | int yLen = text.indexOf(right, zLen); 84 | if (yLen < 0 || right == null || right.isEmpty()) { 85 | yLen = text.length(); 86 | } 87 | result = text.substring(zLen, yLen); 88 | return result; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/util/ThreadUtil.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.util; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | public class ThreadUtil { 7 | 8 | private static final String TAG = ThreadUtil.class.getSimpleName(); 9 | 10 | public static void shutdownAndWait(Thread thread, long timeout, TimeUnit unit) { 11 | if (thread != null) { 12 | thread.interrupt(); 13 | if (timeout > -1L) { 14 | try { 15 | thread.join(unit.toMillis(timeout)); 16 | } catch (InterruptedException e) { 17 | Log.i(TAG, "thread shutdownAndWait err:"); 18 | Log.printStackTrace(TAG, e); 19 | } 20 | } 21 | } 22 | } 23 | 24 | public boolean shutdownNow(ExecutorService pool) { 25 | try { 26 | shutdownAndAwaitTermination(pool, 30, TimeUnit.SECONDS); 27 | } catch (Exception e) { 28 | Log.i(TAG, "thread shutdownAndWait err:"); 29 | Log.printStackTrace(TAG, e); 30 | return false; 31 | } 32 | return true; 33 | } 34 | 35 | public static void shutdownAndAwaitTermination(ExecutorService pool, long timeout, TimeUnit unit) { 36 | if (pool != null && !pool.isShutdown()) { 37 | pool.shutdown(); 38 | try { 39 | if (!pool.awaitTermination(3, TimeUnit.SECONDS)) { 40 | pool.shutdownNow(); 41 | if (!pool.awaitTermination(timeout, unit)) { 42 | Log.i(TAG, "thread pool can't close"); 43 | } 44 | } 45 | } catch (InterruptedException ie) { 46 | pool.shutdownNow(); 47 | Thread.currentThread().interrupt(); 48 | } 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/util/TypeUtil.java: -------------------------------------------------------------------------------- 1 | 2 | package tkaxv7s.xposed.sesame.util; 3 | 4 | import java.lang.reflect.Field; 5 | import java.lang.reflect.Method; 6 | import java.lang.reflect.ParameterizedType; 7 | import java.lang.reflect.Type; 8 | import java.lang.reflect.TypeVariable; 9 | import java.lang.reflect.WildcardType; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class TypeUtil { 14 | public TypeUtil() { 15 | } 16 | 17 | public static Class getClass(Type type) { 18 | if (null != type) { 19 | if (type instanceof Class) { 20 | return (Class)type; 21 | } 22 | 23 | if (type instanceof ParameterizedType) { 24 | return (Class)((ParameterizedType)type).getRawType(); 25 | } 26 | 27 | Type[] upperBounds; 28 | if (type instanceof TypeVariable) { 29 | upperBounds = ((TypeVariable)type).getBounds(); 30 | if (upperBounds.length == 1) { 31 | return getClass(upperBounds[0]); 32 | } 33 | } else if (type instanceof WildcardType) { 34 | upperBounds = ((WildcardType)type).getUpperBounds(); 35 | if (upperBounds.length == 1) { 36 | return getClass(upperBounds[0]); 37 | } 38 | } 39 | } 40 | 41 | return null; 42 | } 43 | 44 | public static Type getType(Field field) { 45 | return null == field ? null : field.getGenericType(); 46 | } 47 | 48 | public static Class getClass(Field field) { 49 | return null == field ? null : field.getType(); 50 | } 51 | 52 | public static Type getFirstParamType(Method method) { 53 | return getParamType(method, 0); 54 | } 55 | 56 | public static Class getFirstParamClass(Method method) { 57 | return getParamClass(method, 0); 58 | } 59 | 60 | public static Type getParamType(Method method, int index) { 61 | Type[] types = getParamTypes(method); 62 | return null != types && types.length > index ? types[index] : null; 63 | } 64 | 65 | public static Class getParamClass(Method method, int index) { 66 | Class[] classes = getParamClasses(method); 67 | return null != classes && classes.length > index ? classes[index] : null; 68 | } 69 | 70 | public static Type[] getParamTypes(Method method) { 71 | return null == method ? null : method.getGenericParameterTypes(); 72 | } 73 | 74 | public static Class[] getParamClasses(Method method) { 75 | return null == method ? null : method.getParameterTypes(); 76 | } 77 | 78 | public static Type getReturnType(Method method) { 79 | return null == method ? null : method.getGenericReturnType(); 80 | } 81 | 82 | public static Class getReturnClass(Method method) { 83 | return null == method ? null : method.getReturnType(); 84 | } 85 | 86 | public static Type getTypeArgument(Type type) { 87 | return getTypeArgument(type, 0); 88 | } 89 | 90 | public static Type getTypeArgument(Type type, int index) { 91 | Type[] typeArguments = getTypeArguments(type); 92 | return null != typeArguments && typeArguments.length > index ? typeArguments[index] : null; 93 | } 94 | 95 | public static Type[] getTypeArguments(Type type) { 96 | if (null == type) { 97 | return null; 98 | } else { 99 | ParameterizedType parameterizedType = toParameterizedType(type); 100 | return null == parameterizedType ? null : parameterizedType.getActualTypeArguments(); 101 | } 102 | } 103 | 104 | public static ParameterizedType toParameterizedType(Type type) { 105 | return toParameterizedType(type, 0); 106 | } 107 | 108 | public static ParameterizedType toParameterizedType(Type type, int interfaceIndex) { 109 | if (type instanceof ParameterizedType) { 110 | return (ParameterizedType)type; 111 | } else { 112 | if (type instanceof Class) { 113 | ParameterizedType[] generics = getGenerics((Class)type); 114 | if (generics.length > interfaceIndex) { 115 | return generics[interfaceIndex]; 116 | } 117 | } 118 | 119 | return null; 120 | } 121 | } 122 | 123 | public static ParameterizedType[] getGenerics(Class clazz) { 124 | List result = new ArrayList(); 125 | Type genericSuper = clazz.getGenericSuperclass(); 126 | if (null != genericSuper && !Object.class.equals(genericSuper)) { 127 | ParameterizedType parameterizedType = toParameterizedType(genericSuper); 128 | if (null != parameterizedType) { 129 | result.add(parameterizedType); 130 | } 131 | } 132 | 133 | Type[] genericInterfaces = clazz.getGenericInterfaces(); 134 | for (Type genericInterface : genericInterfaces) { 135 | ParameterizedType parameterizedType = toParameterizedType(genericInterface); 136 | if (null != parameterizedType) { 137 | result.add(parameterizedType); 138 | } 139 | } 140 | 141 | return (ParameterizedType[])result.toArray(new ParameterizedType[0]); 142 | } 143 | 144 | public static boolean isUnknown(Type type) { 145 | return null == type || type instanceof TypeVariable; 146 | } 147 | 148 | public static boolean hasTypeVariable(Type... types) { 149 | Type[] var1 = types; 150 | int var2 = types.length; 151 | 152 | for(int var3 = 0; var3 < var2; ++var3) { 153 | Type type = var1[var3]; 154 | if (type instanceof TypeVariable) { 155 | return true; 156 | } 157 | } 158 | 159 | return false; 160 | } 161 | 162 | } 163 | -------------------------------------------------------------------------------- /app/src/main/java/tkaxv7s/xposed/sesame/util/UserIdMap.java: -------------------------------------------------------------------------------- 1 | package tkaxv7s.xposed.sesame.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Set; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | 9 | import lombok.Getter; 10 | import tkaxv7s.xposed.sesame.hook.ApplicationHook; 11 | import tkaxv7s.xposed.sesame.hook.FriendManager; 12 | 13 | public class UserIdMap { 14 | private static final String TAG = UserIdMap.class.getSimpleName(); 15 | 16 | private static Map idMap; 17 | 18 | public static boolean shouldReload = false; 19 | 20 | @Getter 21 | private static String currentUid = null; 22 | 23 | private static boolean hasChanged = false; 24 | 25 | public static void setCurrentUid(String uid) { 26 | if (currentUid == null || !currentUid.equals(uid)) { 27 | currentUid = uid; 28 | FriendManager.fillUser(ApplicationHook.getClassLoader()); 29 | } 30 | } 31 | 32 | public static void putIdMapIfEmpty(String key, String value) { 33 | if (key == null || key.isEmpty()) 34 | return; 35 | if (!getIdMap().containsKey(key)) { 36 | getIdMap().put(key, value); 37 | hasChanged = true; 38 | } 39 | } 40 | 41 | public static void putIdMap(String key, String value) { 42 | if (key == null || key.isEmpty()) 43 | return; 44 | if (getIdMap().containsKey(key)) { 45 | if (!getIdMap().get(key).equals(value)) { 46 | getIdMap().remove(key); 47 | getIdMap().put(key, value); 48 | hasChanged = true; 49 | } 50 | } else { 51 | getIdMap().put(key, value); 52 | hasChanged = true; 53 | } 54 | } 55 | 56 | public static void removeIdMap(String key) { 57 | if (key == null || key.isEmpty()) 58 | return; 59 | if (getIdMap().containsKey(key)) { 60 | getIdMap().remove(key); 61 | hasChanged = true; 62 | } 63 | } 64 | 65 | public static void saveIdMap() { 66 | if (hasChanged) { 67 | StringBuilder sb = new StringBuilder(); 68 | Set> idSet = getIdMap().entrySet(); 69 | for (Map.Entry entry : idSet) { 70 | sb.append(entry.getKey()); 71 | sb.append(':'); 72 | sb.append(entry.getValue()); 73 | sb.append('\n'); 74 | } 75 | hasChanged = !FileUtil.write2File(sb.toString(), FileUtil.getFriendIdMapFile()); 76 | } 77 | } 78 | 79 | public static String getNameById(String id) { 80 | if (id == null || id.isEmpty()) 81 | return id; 82 | if (getIdMap().containsKey(id)) { 83 | String n = getIdMap().get(id); 84 | int ind = n.lastIndexOf('('); 85 | if (ind > 0) 86 | n = n.substring(0, ind); 87 | if (!n.equals("*")) 88 | return n; 89 | } else { 90 | putIdMap(id, "*(*)"); 91 | } 92 | return id; 93 | } 94 | 95 | // public static List getIncompleteUnknownIds() { 96 | // List idList = new ArrayList<>(); 97 | // for (Map.Entry entry : getIdMap().entrySet()) { 98 | // if ("我".equals(entry.getValue())) { 99 | // continue; 100 | // } 101 | // if (entry.getValue().split("\\|").length < 2) { 102 | // idList.add(entry.getKey()); 103 | // // Log.i(TAG, "未知id: " + entry.getKey()); 104 | // } 105 | // } 106 | // return idList; 107 | // } 108 | 109 | public static Map getIdMap() { 110 | if (idMap == null || shouldReload) { 111 | shouldReload = false; 112 | idMap = new ConcurrentHashMap<>(); 113 | String str = FileUtil.readFromFile(FileUtil.getFriendIdMapFile()); 114 | if (str != null && !str.isEmpty()) { 115 | try { 116 | String[] idSet = str.split("\n"); 117 | for (String s : idSet) { 118 | // Log.i(TAG, s); 119 | int ind = s.indexOf(":"); 120 | idMap.put(s.substring(0, ind), s.substring(ind + 1)); 121 | } 122 | } catch (Throwable t) { 123 | Log.printStackTrace(TAG, t); 124 | idMap.clear(); 125 | } 126 | } 127 | } 128 | return idMap; 129 | } 130 | 131 | public static List getFriendIds() { 132 | List idList = new ArrayList<>(); 133 | for (Map.Entry entry : getIdMap().entrySet()) { 134 | if ("我".equals(entry.getValue()) || entry.getKey().equals(currentUid)) { 135 | continue; 136 | } 137 | idList.add(entry.getKey()); 138 | } 139 | return idList; 140 | } 141 | 142 | public static void waitingCurrentUid() throws InterruptedException { 143 | int count = 1; 144 | while (getCurrentUid() == null || getCurrentUid().isEmpty()) { 145 | if (count > 3) { 146 | throw new InterruptedException("获取当前用户超时"); 147 | } else { 148 | count++; 149 | Thread.sleep(1000); 150 | } 151 | } 152 | } 153 | 154 | } 155 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/farm.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 20 | 23 | 26 | 29 | 32 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/forest.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/friend.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/github.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | 12 | 18 | 21 | 24 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongleo1/Sesame-X/5073875d175359ce6f6b6a10b4563ca0835fa60a/app/src/main/res/drawable/logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongleo1/Sesame-X/5073875d175359ce6f6b6a10b4563ca0835fa60a/app/src/main/res/drawable/main.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/other.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/setting.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/unactivated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongleo1/Sesame-X/5073875d175359ce6f6b6a10b4563ca0835fa60a/app/src/main/res/drawable/unactivated.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_html_viewer.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 |