├── EasyEdge ocr食用教程.md ├── LICENSE ├── QuestionBank.db ├── QuestionBank.json ├── README.md ├── Study.js ├── json_to_question.py ├── json_to_sql.py ├── question ├── question_old ├── 配置.json └── 食用教程.md /EasyEdge ocr食用教程.md: -------------------------------------------------------------------------------- 1 | ## EasyEdge OCR 2 | 3 | *假设你已安装vmos并安装好机器人及QG* 4 | 5 | *假设你已注册好hamibot账号* 6 | 7 | *假设你已完成脚本的创建和配置* 8 | 9 | **使用场景:** 10 | 11 | 在vmos虚拟机中使用脚本做QG,OCR速度出现严重损失 12 | 13 | ### 食用方法: 14 | 15 | 1) 在真机安装`EasyEdge OCR` (安装包在[Releases](https://github.com/wangwang-code/Study_hamibot/releases)中的`Study_hamibot.zip`中) 16 | 2) 编辑配置 `文字识别(OCR)类型选择` 选择 `EasyEdge OCR,需要安装EasyEdge ocr插件,并以下一下内容` 并且填写`EasyEdge OCR地址` 一般填 `默认` 即可 17 | 3) 启动vmos虚拟机 返回真机 打开`EasyEdge OCR` 18 | 4) 确保虚拟机中的机器人在线,在控制台启动脚本 19 | 5) 返回`EasyEdge OCR` 并使用悬浮球监视虚拟机 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /QuestionBank.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pandaver/Study_hamibot/5014ede27578fda8f1c75e7e956ed66f5960a4d2/QuestionBank.db -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 尽量整合,做最基本可用更新 2 | 3 | # 目前Study代码的冗余太多(垃圾代码),且逻辑混乱,需要重写 4 | 5 | **本修改版目的是解放双手,如非此目的,出门右转** 6 | 7 | **目前主要更新题库(感谢[https://github.com/Mondayfirst/XXQG_TiKu](https://github.com/Mondayfirst/XXQG_TiKu)提供的题库)** 8 | 9 | **使用自己编写的py转换为所需要的格式** 10 | 11 | # 教程在[食用教程](https://github.com/wangwang-code/Study_hamibot/blob/main/%E9%A3%9F%E7%94%A8%E6%95%99%E7%A8%8B.md#%E9%A3%9F%E7%94%A8%E6%95%99%E7%A8%8B) 12 | 13 | ---- 14 | 15 | **为了学习而Study** 16 | 17 | 修改来源于:[LazyStudy](https://github.com/lolisaikou/LazyStudy) 18 | 19 | [Hamibot_Study](https://hamibot.com/marketplace/1Kw2X?invite=ONTRWIBaZqdBWuDk6DNzT7rt) 20 | --- 21 | 22 | ## 免责声明 23 | 24 | **本脚本为免费使用,本脚本只供个人学习使用,不得盈利传播,不得用于违法用途,否则造成的一切后果自负!** 25 | 26 | --- 27 | 28 | - 功能:文章学习、订阅、评论分享、视频学习、每日答题、挑战答题、每周答题,专项答题、四人赛、双人对战。 29 | - 四人/双人赛:hamibot内置文字识别(OCR)、百度文字识别(OCR)、第三方本地文字识别(OCR) 30 | - **hamibot内置文字识别(OCR)与第三方本地文字识别(OCR)识别速度与设备硬件有关。一般速度快于百度/华为文字识别(OCR)** 31 | - hamibot内置文字识别(OCR):需要hamibot 1.3 以上,**部分机型识别较慢,则换其他OCR使用。** 32 | - 百度文字识别(OCR)需要配置 API Key 和 Secret Key:[教程](https://cloud.baidu.com/doc/OCR/s/dk3iqnq51) 33 | - 第三方本地文字识别(OCR)插件 [点击这里下载](https://twelve123.lanzouq.com/b017az0kj)[密码:7faj] 34 | - 32位适合hamibot 1.1版本 35 | - 旧手机和模拟器使用32位第三方OCR插件 36 | - 全功能支持ys模拟器 **安卓9** 37 | ``` 38 | 1. 模拟器配置(安卓 9) 39 | 2. hamibot v1.1.0版本 40 | 3. qg 2.33.0版本及以下 41 | 4. Study视频学习选择新百灵视频 四人模式选择百度/华为OCR或第三方OCR插件 42 | ``` 43 | - [电报交流群(十二)](https://t.me/+A4KV10N9_gJmZTE1) 44 | - [电报交流群(ww修改)](https://t.me/+yia2ylnVlPtkODE1) 45 | - **一张图片、一句话,并不能解决问题。** 46 | - **完整日志内容才能解决问题** 47 | 48 | --- 49 | 50 | ## 2022.5.28更新 51 | 52 | - 更改默认[题库地址](https://github.com/Pandaver/XXQG_TiKu_Transform) 53 | - 默认强制更新每日每周专项题库 54 | - 整合[Study_autoxjs](https://github.com/wangwang-code/Study_autoxjs)反滑块验证 55 | 56 | --- 57 | 58 | ## 2022.4.29更新 59 | 60 | **使用全新版号,脚本及其配套OCR插件将会在[Releases](https://github.com/wangwang-code/Study_hamibot/releases)中发布“Study_hamibot”** 61 | 62 | - 本地化四人双人挑战题库 63 | - 优化`EasyEdge OCR`识别速度 64 | - 竞赛检查是否有人100,并停止等待下一题 65 | 66 | --- 67 | 68 | ## 2022.4.21更新 69 | 70 | **使用全新版号,脚本及其配套OCR插件将会在[Releases](https://github.com/wangwang-code/Study_hamibot/releases)中发布“Study_hamibot”** 71 | 72 | - 添加`EasyEdge OCR` 73 | - 等待选项显示后再进行选项识别 74 | - 清理竞赛中的无用代码 75 | - 去除使用须知 76 | 77 | --- 78 | 79 | ## 2022.04.10.850 80 | 81 | - 改进四人/双人判断答案是否错误 82 | - 当题目发生POS(未找到答案时)延迟点击选项(A) 83 | - **已知问题:不断出现pos,该问题只能尝试重构** 84 | - **已知问题:选择读音类题目发生OCR(第三方OCR出现,其他未知)识别死循环,同样只能重写四人双人的逻辑** 85 | - **已知问题:本地频道无法打开** 86 | 87 | --- 88 | 89 | ## 2022.04.05.810 90 | 91 | - 改进四人/双人判断答案正确与否(Beta)(可以选择是否启用) 92 | - 四人/双人自动记录发生pos的题目 93 | - 四人/双人添加[XXQG_TiKu_题库_原始版.json](https://github.com/Mondayfirst/XXQG_TiKu/blob/main/%E9%A2%98%E5%BA%93_%E5%8E%9F%E5%A7%8B%E7%89%88.json)题目数据 94 | 95 | --- 96 | 97 | ## 2022.04.04.800 98 | 99 | - 添加自定义题库四人/双人/挑战题库地址功能 100 | - 添加自定义每日每周专项题库地址功能 101 | - 添加强制更新题库每日每周专项题库功能 102 | 103 | --- 104 | 105 | ## 2022.04.04.745 106 | 107 | - 添加错题自动保存(包括四人/双人) 108 | - 四人/双人答题正确与否判断(Beta) 109 | - 已知问题:四人/双人选择词语类题目有概率发生OCR识别循环 110 | 111 | --- 112 | 113 | ## 2022.04.04.740 114 | 115 | - 添加错题自动保存(包括四人/双人) 116 | - 四人/双人答题正确与否判断(Beta) 117 | - 已知问题:四人/双人选择词语类题目有概率发生OCR识别循环 118 | 119 | --- 120 | 121 | ## 2022.03.23.731 122 | 123 | - 优化乱序模式的选项搜索 124 | 125 | --- 126 | 127 | ## 2022.03.22.728 128 | 129 | - 优化乱序模式 130 | - 增加四人/双人单选开关 131 | 132 | --- 133 | 134 | ## 2022.03.20.711 135 | 136 | - 增加答题类型,自选按键 137 | 138 | --- 139 | 140 | ## 2022.03.19 141 | 142 | - 因qg更改题目选项顺序,使得顺序为随机出现,需要等待选项出现再进行答题 143 | 144 | --- 145 | 146 | ## 2022.03.16.670 147 | 148 | - 修复因2022.03.08.633版本的改进,导致挑战答题错误率高的BUG 149 | 150 | --- 151 | 152 | ## 2022.03.15.669 153 | 154 | - 增加:看门狗-----设置最长脚本运行时间,超时或报错则自动重新运行。 155 | 156 | --- 157 | 158 | ## 2022.03.13.648 159 | 160 | - 累计报错优化 161 | - 增加 **遇到错误则自动重启脚本** 选项开关 162 | 163 | --- 164 | 165 | ## 2022.03.08.633 166 | 167 | - 优化部分类型题的搜索 168 | 169 | --- 170 | 171 | ## 2022.03.06.623 172 | 173 | - 增加使用须知 174 | 175 | --- 176 | 177 | ## 2022.03.04.617 178 | 179 | - 加个进度条 180 | - 设置在hamibot界面预加载题库 181 | 182 | --- 183 | 184 | ## 2022.03.02.602 185 | 186 | - 去除一行可能造成搜错题的代码 187 | - 一些其他地方的改进 188 | 189 | --- 190 | 191 | ## 2022.03.01.599 192 | 193 | - 修复因识别错误导致未搜到题而造成报错 194 | - 优化点点通 195 | 196 | --- 197 | 198 | ## 2022.02.27.595 199 | 200 | - 去除随机模式选项--默认随机模式 201 | - 完善四人/双人搜题逻辑 202 | - 去除本地题库,修改为实时加载(避免部分手机存储异常) 203 | - 增加刷满点点通(测试) 204 | 205 | --- 206 | 207 | ## 2022.02.25.570 208 | 209 | - 根据近一个月大家反馈的错题错字,重写了部分四人/双人搜题逻辑 210 | 211 | --- 212 | 213 | ## 2022.02.14.539 214 | 215 | - 增加每日、每周、专项答题增强模式 - 使用云端OCR进行文字识别(本地ocr识别准确度较低,故不采用) 216 | 217 | --- 218 | 219 | ## 2022.02.11.529 220 | 221 | 1. 解决部分人挑战答题异常; 222 | 2. 优化每日答题、每周答题、专项答题的填空类型题目,将在此时调用百度OCR或华为OCR进行文字识别正确的填空答案(如果填入了百度OCR或华为OCR的配置的话) 223 | 224 | - **注意:想要提高填空题正确率--只需填百度或华为配置即可,与四人/双人的OCR选择不冲突** 225 | 226 | --- 227 | 228 | ## 2022.02.09.523 229 | 230 | 1. 四种OCR选择; 231 | 2. 增加四人/双人额外一轮乱答模式; 232 | 3. 挑战答题题库修改; 233 | 4. 四人/双人答题优化:从400ms以下依次测试---400->300->250->200->150->100->0,找到适合自己手机的延迟(既不卡住也不输); 234 | 5. 增加读音字形题错字的替换; 235 | 6. **四人/双人暂时存在的问题**:读音字形题需要等待选项出现才进行文字识别,所以该类型题答题较慢 且 一旦文字识别出现错字则难以搜题。 236 | 237 | - [电报交流群](https://t.me/+A4KV10N9_gJmZTE1) 238 | 239 | ---- 240 | 241 | ## 2022.02.03.510 242 | 243 | 1. 由于配置内容过多,将华为ocr替换为百度ocr:[教程](https://cloud.baidu.com/doc/OCR/s/dk3iqnq51) 244 | 2. 订阅问题修改 245 | 246 | ---- 247 | 248 | ## 2022.01.25.486 249 | 250 | 1. 优化部分人的订阅 251 | 2. 增加[push+(推送加)](https://pushplus.hxtrip.com/index) :有需要则填写Token 252 | 253 | --- 254 | 255 | ## 2022.01.24.472更新 256 | 257 | - 增加答题之前的检测 258 | 259 | --- 260 | 261 | ## 2022.01.22.467更新 262 | 263 | 1. 一个大胆的尝试:重写搜题算法,可能答题不再受文字识别的错字影响; 264 | 2. 测试阶段所有ocr均可不受积分限制答题; 265 | 3. 如果四人/双人赛答错,请截图日志; 266 | 4. 仔细查看Study配置内容。 267 | 268 | --- 269 | 270 | ## 2022.01.09.358更新 271 | 272 | 1. 优化代码 273 | 2. 增加熄屏点亮 274 | 275 | --- 276 | 277 | ## 2022.01.08.351更新 278 | 279 | 1. 重构四人赛双人赛答题逻辑(大概率获胜) 280 | 2. 增加 hamibot 内置 ocr (文字识别) ------需要 [hamibot 1.3.0-beta.1](https://hamibot.cn/download) 及以上的版本 281 | 3. 优化一些小细节 282 | 283 | --- 284 | 285 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/img_convert/d14b5725b7463db01c17a677bdfc06d8.png#pic_center) 286 | -------------------------------------------------------------------------------- /Study.js: -------------------------------------------------------------------------------- 1 | auto.waitFor(); 2 | importClass(android.database.sqlite.SQLiteDatabase); 3 | importClass(java.net.HttpURLConnection); 4 | importClass(java.net.URL); 5 | importClass(java.io.File); 6 | importClass(java.io.FileOutputStream); 7 | if (hamibot.env.QuestionBank_URL == undefined || hamibot.env.QuestionBank_URL == '') { 8 | var url = 'https://gh.fakev.cn/Pandaver/XXQG_TiKu_Transform/raw/main/QuestionBank.db'; 9 | console.info('每日每周专项使用默认题库地址'); 10 | } else { 11 | var url = hamibot.env.QuestionBank_URL; 12 | console.info('每日每周专项题库地址: ' + url); 13 | } 14 | 15 | // var dbd = hamibot.env.dbd; 16 | var path = '/sdcard/QuestionBank.db'; 17 | device.wakeUpIfNeeded(); //点亮屏幕 18 | // var first = true; //记录答题的第一次 19 | // var r; // 替换用; 20 | var meizhou_txt = hamibot.env.checkbox_02; 21 | var zhuanxiang_txt = hamibot.env.checkbox_01; 22 | var siren = hamibot.env.checkbox_03; 23 | var debug = hamibot.env.debug_ck; 24 | if (debug) console.info('已开启详细日志模式'); 25 | var shuangren = hamibot.env.shuangren; 26 | 27 | var articles = hamibot.env.article; 28 | var video = hamibot.env.video; 29 | var meiri = hamibot.env.meiri; 30 | var tiaozhan = hamibot.env.tiaozhan; 31 | 32 | var cic = hamibot.env.cic; 33 | 34 | if (hamibot.env.easyedge_ocr_url == "默认") { 35 | var easyedge_ocr_url = 'http://127.0.0.1:34567/'; 36 | } else { 37 | var easyedge_ocr_url = hamibot.env.easyedge_ocr_url; 38 | } 39 | 40 | var choose = hamibot.env.select_01; 41 | var whethe = hamibot.env.whether_mute; 42 | if (whethe) var volume = device.getMusicVolume(); 43 | 44 | var 专项答题下滑 = hamibot.env.select; 45 | var 每周答题下滑 = hamibot.env.selectm; 46 | 47 | var 订阅 = hamibot.env.ssub; 48 | // var 乱序 = 'a'; 49 | // var 随机 = hamibot.env.suiji; 50 | 51 | var 延迟时间 = hamibot.env.delay_s * 1; 52 | var pos_sleep = hamibot.env.pos_sleep * 1; 53 | if (!延迟时间 || 延迟时间 < 0) 延迟时间 = 0; 54 | var stronger = hamibot.env.stronger; //每日答题增强模式 55 | var { 56 | username 57 | } = hamibot.env; 58 | var { 59 | password 60 | } = hamibot.env; 61 | var { 62 | domainname 63 | } = hamibot.env; 64 | var { 65 | projectname 66 | } = hamibot.env; 67 | var { 68 | endpoint 69 | } = hamibot.env; 70 | var { 71 | projectId 72 | } = hamibot.env; 73 | let ocr; 74 | var token; 75 | var ttt; 76 | var question_list = []; 77 | var status = false;//是否暂停 78 | while (status) { console.log("主线程暂停中"); sleep(750); }; 79 | /** 80 | * 人机验证 81 | */ 82 | var thread1 = threads.start(function () { 83 | for (;;) { 84 | textContains("访问异常").waitFor(); 85 | console.log("检测到滑动验证"); 86 | status = true; 87 | var a = 1000; 88 | var b = idContains("nc_1_n1t").findOne().bounds(), 89 | c = text("向右滑动验证").findOne().bounds(), 90 | d = b.centerX(); 91 | c = c.right - (d - c.left); 92 | var e = (c - d) * random(5, 8) / 10 + d, 93 | f = (c - d) * random(2, 3) / 10, 94 | h = random(b.top, 95 | b.bottom); 96 | b = random(b.top, b.bottom); 97 | log("y_start:", h, "x_start:", d, "x_mid:", e, "x_end:", c); 98 | d = random(d - 7, d); 99 | c = random(c, c + 10); 100 | gesture(random(a, a + 50), [d, h], [e, b], [e - f, h], [c, b]); 101 | sleep(500); 102 | textContains("刷新").exists() ? click("刷新") : textContains("网络开小差").exists() ? click("确定") : (console.log("已完成滑动验证"), sleep(1E3)) 103 | if (status) status = false; 104 | } 105 | }) 106 | thread1.waitFor(); 107 | 108 | var init_true = false; 109 | var downloadDialog = null; 110 | // var init_url = "https://git.yumenaka.net/https://raw.githubusercontent.com/Twelve-blog/picture/master/question"; 111 | // var init_url = 'https://gitee.com/wangwang-code/picture-bed/raw/master/question'; 112 | if (hamibot.env.init_url == undefined || hamibot.env.init_url == '') { 113 | // var init_url = 'https://gitee.com/wangwang-code/tiku/raw/main/question'; 114 | var init_url = 115 | 'https://raw.gh.fakev.cn/Pandaver/XXQG_TiKu_Transform/main/question'; 116 | console.info('四人/双人/挑战使用默认题库地址'); 117 | } else { 118 | var init_url = hamibot.env.init_url; 119 | console.info('四人/双人/挑战题库地址: ' + init_url); 120 | } 121 | var first_com_no = hamibot.env.first_com_no; 122 | var file_tmp = false; 123 | var tikus = ''; 124 | var wht_update_tiku_end = false; 125 | var wht_update_tiku_competition_end = false; 126 | var update_tiku_competition = false; 127 | var update_tiku = false; 128 | 129 | function wht_update_tiku() { // 是否更新题库 130 | threads.start(function() { 131 | // console.info('查看使用须知,15s后自动关闭'); 132 | var d = dialogs.build({ 133 | title: "是否取消更新题库?", 134 | content: "点击取消将不更新每日每周专项题库 \n 5秒后关闭", 135 | positive: "取消", 136 | }).on("positive", () => { 137 | d.dismiss(); 138 | // setClip(text); 139 | d = null; 140 | // text = null; 141 | wht_update_tiku_end = true; 142 | }).show(); 143 | sleep(5000); 144 | if (!wht_update_tiku_end) { 145 | d.dismiss(); 146 | // setClip(text) 147 | d = null; 148 | // text = null; 149 | update_tiku = true; 150 | wht_update_tiku_end = true; 151 | } 152 | }); 153 | } 154 | 155 | function wht_update_tiku_competition() { // 是否更新题库 156 | threads.start(function() { 157 | // console.info('查看使用须知,15s后自动关闭'); 158 | var b = dialogs.build({ 159 | title: "是否取消更新竞赛和挑战答题题库?", 160 | content: "点击取消将不更新竞赛和挑战答题题库 \n 5秒后关闭", 161 | positive: "取消", 162 | }).on("positive", () => { 163 | b.dismiss(); 164 | // setClip(text); 165 | b = null; 166 | // text = null; 167 | wht_update_tiku_competition_end = true; 168 | }).show(); 169 | sleep(5000); 170 | if (!wht_update_tiku_competition_end) { 171 | b.dismiss(); 172 | // setClip(text) 173 | b = null; 174 | // text = null; 175 | update_tiku_competition = true; 176 | wht_update_tiku_competition_end = true; 177 | } 178 | }); 179 | } 180 | 181 | /** 182 | * 获取用户token 183 | */ 184 | function get_baidu_token() { // 百度ocr 185 | if (!hamibot.env.AK || !hamibot.env.SK) { 186 | console.error('百度ocr配置未填写!!!'); 187 | exit(); 188 | } 189 | var res = http.post( 190 | 'https://aip.baidubce.com/oauth/2.0/token', { 191 | grant_type: 'client_credentials', 192 | client_id: hamibot.env.AK.replace(/ /g, ''), 193 | client_secret: hamibot.env.SK.replace(/ /g, '') 194 | } 195 | ); 196 | var xad = res.body.json()['access_token']; 197 | if (xad == null) { 198 | console.error('百度文字识别(OCR)配置出错了!!!,脚本结束'); 199 | exit(); 200 | } else { 201 | console.info('百度文字识别(OCR)配置正确'); 202 | } 203 | return xad; 204 | } 205 | 206 | function check_easyedge_ocr() { 207 | if (!easyedge_ocr_url) { 208 | console.error('EasyEdge ocr地址未填写!!!'); 209 | exit(); 210 | } 211 | try { 212 | var check_url = http.get(easyedge_ocr_url); 213 | if (check_url.statusCode >= 200 && check_url.statusCode < 300) { 214 | console.info('easyedge_ocr正常'); 215 | } else if (check_url.statusCode == 404) { 216 | console.error('easyedge_ocr异常'); 217 | exit(); 218 | } else { 219 | console.error('错误: 请检查OCR'); 220 | exit(); 221 | } 222 | } catch (e) { 223 | console.error('easyedge_ocr未启动!!!'); 224 | exit(); 225 | } 226 | } 227 | 228 | function get_token() { // 华为ocr 229 | var res = http.postJson( 230 | 'https://iam.cn-north-4.myhuaweicloud.com/v3/auth/tokens', { 231 | "auth": { 232 | "identity": { 233 | "methods": [ 234 | "password" 235 | ], 236 | "password": { 237 | "user": { 238 | "name": username, //替换为实际用户名 239 | "password": password, //替换为实际的用户密码 240 | "domain": { 241 | "name": domainname //替换为实际账号名 242 | } 243 | } 244 | } 245 | }, 246 | "scope": { 247 | "project": { 248 | "name": projectname //替换为实际的project name,如cn-north-4 249 | } 250 | } 251 | } 252 | }, { 253 | headers: { 254 | 'Content-Type': 'application/json;charset=utf8' 255 | } 256 | } 257 | ); 258 | if (res.headers['X-Subject-Token'] == null) { 259 | console.error('华为文字识别(OCR)配置出错了!!!,脚本结束'); 260 | exit(); 261 | } else { 262 | console.info('华为文字识别(OCR)配置正确'); 263 | } 264 | return res.headers['X-Subject-Token']; 265 | } 266 | 267 | function getVersion(package_name) { // 得到包名的版本 268 | let pkgs = context.getPackageManager().getInstalledPackages(0).toArray(); 269 | for (let i in pkgs) { 270 | if (pkgs[i].packageName.toString() === package_name) { 271 | return pkgs[i].versionName; 272 | } 273 | } 274 | } 275 | 276 | function get_ocr() { 277 | console.info("你选择了第三方文字识别(OCR)"); 278 | try { 279 | ocr = plugins.load('com.hraps.ocr'); 280 | } catch (e) { 281 | console.error('未安装OCR插件,正在跳转浏览器下载\n密码:7faj'); 282 | app.openUrl('https://twelve123.lanzouq.com/b017az0kj'); 283 | exit(); 284 | } 285 | } 286 | 287 | function get_hamibot_ocr() { 288 | console.info("你选择了hamibot内置文字识别(OCR)"); 289 | if (app.versionName < "1.3.0-beta.1") { 290 | console.error("请去hamibot官网下载版本1.3.0以上的hamibot!!!,脚本结束"); 291 | exit(); 292 | } 293 | } 294 | 295 | var showlog = false; 296 | if (shuangren == true || siren == true || 订阅 != 'a' || stronger != 'a' || tiaozhan) { 297 | console.show(); 298 | if (siren == true || shuangren == true) { 299 | console.error('正在获取截图权限,并检查ocr配置是否正确'); 300 | if (choose == 'b') get_ocr(); 301 | else if (choose == 'a') { 302 | token = get_token(); 303 | } else if (choose == 'c') { 304 | get_hamibot_ocr(); 305 | } else if (choose == 'd') { 306 | token = get_baidu_token(); 307 | } else if (choose == 'e') check_easyedge_ocr(); 308 | } 309 | if (stronger != 'a') { 310 | console.info('正在检测增强模式配置'); 311 | if (stronger == 'c') { // 百度ocr 312 | if (siren == true && choose == 'd') { 313 | ttt = token; 314 | } else { 315 | ttt = get_baidu_token(); 316 | } 317 | } else if (stronger == 'b') { // 华为ocr 318 | if (siren == true && choose == 'a') { 319 | ttt = token; 320 | } else { 321 | ttt = get_token(); 322 | } 323 | } 324 | } 325 | console.info('正在打开Hamibot'); 326 | launchApp("Hamibot"); 327 | if (!files.exists(path)) { 328 | //toastLog('没有题库,正在下载题库,请等待!!!'); 329 | threads.start(function() { 330 | var tiku = http.get(url, { 331 | headers: { 332 | 'Content-Type': 'text/plain;charset=utf8', 333 | 'Connection': 'Keep-Alive', 334 | 'Accept-Encoding': 'gzip, deflate', 335 | 'User-Agent': 'Mozilla/5.0 (Linux; Android 11; V2048A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Mobile Safari/537.36', 336 | }, 337 | }).body.bytes(); 338 | //console.log(tiku) 339 | files.writeBytes(path, tiku); 340 | }); 341 | } else { 342 | sleep(5000); 343 | wht_update_tiku(); 344 | while (!wht_update_tiku_end) { 345 | sleep(1000); 346 | }; 347 | if (update_tiku) { 348 | toastLog('强制更新每日每周专项题库中'); 349 | var update_tiku_ok = false; 350 | threads.start(function() { 351 | console.time('更新每日每周专项题库耗时'); 352 | var tiku = http.get(url, { 353 | headers: { 354 | 'Content-Type': 'text/plain;charset=utf8', 355 | 'Connection': 'Keep-Alive', 356 | 'Accept-Encoding': 'gzip, deflate', 357 | 'User-Agent': 'Mozilla/5.0 (Linux; Android 11; V2048A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Mobile Safari/537.36', 358 | }, 359 | }).body.bytes(); 360 | //console.log(tiku) 361 | files.writeBytes(path, tiku); 362 | console.timeEnd('更新每日每周专项题库耗时'); 363 | update_tiku_ok = true; 364 | }); 365 | while (!update_tiku_ok) { 366 | sleep(1000); 367 | }; 368 | } 369 | } 370 | delay(2); 371 | // if (cic == "true") { 372 | // console.warn('警告:你启用了四人双人判断答案正确与否功能,该功能仍处于beta阶段,可能发生臆想不到的问题!!!'); 373 | // delay(3); 374 | // } 375 | if (whethe) { 376 | console.info('正在自动静音') 377 | try { 378 | device.setMusicVolume(0); 379 | } catch (e) { 380 | console.error('权限不足,请给 “允许修改系统设置” 权限'); 381 | console.warn('将尝试跳转到设置页面,赋予权限后请重启脚本'); 382 | delay(2); 383 | device.setMusicVolume(volume); 384 | } 385 | } 386 | /* delay(2); 387 | show_log(); 388 | while (!showlog) { 389 | sleep(1000); 390 | }; */ 391 | if (tiaozhan || siren || shuangren) 392 | init(); 393 | if (tiaozhan && !(siren == true || shuangren == true || 订阅 != 'a' || stronger != 'a')) {} //只开了挑战答题的话 394 | else { 395 | threads.start(function() { 396 | if (!requestScreenCapture(false)) { 397 | toastLog("请求截图失败,脚本结束"); 398 | exit(); 399 | } 400 | }); 401 | delay(1.5); 402 | if (textContains("立即开始").exists() || textContains("允许").exists()) { 403 | if (textContains("立即开始").exists()) { 404 | textContains("立即开始").className("Button").findOne().click(); 405 | } else { 406 | textContains("允许").className("Button").findOne().click(); 407 | } 408 | console.info('自动点击获取权限按键!!!'); 409 | } 410 | while (true) { 411 | try { 412 | captureScreen(); 413 | break; 414 | } catch (e) { 415 | console.log('等待截图权限中'); 416 | }; 417 | sleep(1500); 418 | } 419 | console.info('立即开始,允许截图权限已获取!!!'); 420 | 421 | if (choose == 'b') { 422 | console.time('文字识别'); 423 | console.log('\n测试第三方OCR识别中'); 424 | console.info('\n如果脚本结束,出现红字,则安装错误的OCR位数,卸载安装的OCR插件'); 425 | ocr_api(images.clip(captureScreen(), 0, Math.floor(device.height / 2), device.width, Math.floor(device 426 | .height / 2))); 427 | console.timeEnd('文字识别'); 428 | console.log(""); 429 | } else if (choose == 'c') { 430 | console.time('文字识别'); 431 | console.log('\n测试Hamibot内置OCR识别中'); 432 | hamibot_ocr_api(images.clip(captureScreen(), 0, Math.floor(device.height / 2), device.width, Math.floor( 433 | device.height / 2))); 434 | console.timeEnd('文字识别'); 435 | console.log(""); 436 | } else if (choose == 'e') { 437 | console.time('文字识别'); 438 | console.log('\n测试EasyEdge OCR识别中'); 439 | easyedge_ocr_api(images.clip(captureScreen(), 0, Math.floor(device.height / 2), device.width, Math.floor( 440 | device.height / 2))); 441 | console.timeEnd('文字识别'); 442 | console.log(""); 443 | } 444 | } 445 | 446 | } 447 | 448 | /* function show_log() { // 使用须知 449 | threads.start(function() { 450 | try { 451 | var text = http.get('https://gitee.com/wangwang-code/picture-bed/raw/master/showlogs').body 452 | .string(); 453 | if (text.length == 0) { 454 | show_log = true; 455 | return; 456 | } 457 | console.info('查看使用须知,15s后自动关闭'); 458 | var d = dialogs.build({ 459 | title: "使用须知", 460 | content: text, 461 | positive: "关闭", 462 | }).on("positive", () => { 463 | d.dismiss(); 464 | // setClip(text); 465 | d = null; 466 | text = null; 467 | showlog = true; 468 | }).show(); 469 | sleep(15000); 470 | if (!showlog) { 471 | d.dismiss(); 472 | // setClip(text) 473 | d = null; 474 | text = null; 475 | showlog = true; 476 | } 477 | } catch (e) { 478 | try { 479 | d.dismiss(); 480 | d = null; 481 | } catch (e) {} 482 | text = null; 483 | showlog = true; 484 | } 485 | }); 486 | } */ 487 | 488 | 489 | var lCount = 1; //挑战答题轮数 490 | var qCount = 5; //挑战答题每轮答题数 491 | 492 | var asub = 2; //订阅数 493 | var aCount = 6; //文章默认学习篇数 494 | var vCount = 6; //小视频默认学习个数 495 | var cCount = 1; //收藏+分享+评论次数 496 | var dayCount = 1; // 每日答题 497 | var tzCount = 1; // 挑战答题 498 | var zsyCount = 1; //争上游答题 499 | var doubleCount = 1; // 双人对战 500 | var meizhou = 1; //每周答题 501 | var zhuanxiang = 1; //专项答题 502 | 503 | var aTime = hamibot.env.time1; //有效阅读一分钟1分*6 504 | var vTime = hamibot.env.time2; //每个小视频学习-5秒 505 | var rTime = 370; //广播收听6分 * 60 = 360秒 506 | 507 | var 点点通 = { 508 | '有效视听': 0, 509 | '有效浏览': 0, 510 | '挑战答题': 0 511 | }; 512 | var myScores = {}; //分数 513 | var article_list = []; 514 | var delay_time = 1000; 515 | /** 516 | * @description: 延时函数 517 | * @param: seconds-延迟秒数s 518 | * @return: null 519 | */ 520 | function delay(seconds) { 521 | sleep(1000 * seconds + randomNum(0, 500)); //sleep函数参数单位为毫秒所以乘1000 522 | } 523 | /** 524 | * @description: 随机秒数 525 | * @param: seconds-秒数s 526 | * @return: [seconds+100,seconds+1000] 527 | */ 528 | function random_time(time) { 529 | return time + random(100, 1000); 530 | } 531 | /** 532 | * @description: 点击文本控件 533 | * @param: 文本 534 | * @return: null 535 | */ 536 | function my_click_clickable(target) { 537 | text(target).waitFor(); 538 | click(target); 539 | } 540 | /** 541 | * @description: 生成从minNum到maxNum的随机数 542 | * @param: minNum-较小的数 543 | * @param: maxNum-较大的数 544 | * @return: null 545 | */ 546 | function randomNum(minNum, maxNum) { 547 | switch (arguments.length) { 548 | case 1: 549 | return parseInt(Math.random() * minNum + 1, 10); 550 | case 2: 551 | return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10); 552 | default: 553 | return 0; 554 | } 555 | } 556 | 557 | /** 558 | * @description: 文章学习计时(弹窗)函数 559 | * @param: n-文章标号 seconds-学习秒数 560 | * @return: null 561 | */ 562 | function article_timing(n, seconds) { 563 | var seconds = seconds * 1; 564 | seconds = seconds + randomNum(1, 5); 565 | h = device.height; //屏幕高 566 | w = device.width; //屏幕宽 567 | x = (w / 3) * 2; 568 | h1 = (h / 6) * 5; 569 | h2 = (h / 6); 570 | for (var i = 0; i < seconds; i++) { 571 | while (!textContains("欢迎发表你的观点").exists()) //如果离开了文章界面则一直等待 572 | { 573 | console.error("当前已离开第" + (n + 1) + "文章界面,请重新返回文章页面..."); 574 | delay(2); 575 | } 576 | if (i % 5 == 0) //每5秒打印一次学习情况 577 | { 578 | console.info("第" + (n + 1) + "篇文章已经学习" + (i + 1) + "秒,剩余" + (seconds - i - 1) + "秒!"); 579 | } 580 | sleep(1000); 581 | if (i % 10 == 0) //每10秒滑动一次,如果android版本<7.0请将此滑动代码删除 582 | { 583 | toast("这是防息屏toast,请忽视-。-"); 584 | if (i <= seconds / 2) { 585 | swipe(x, h1, x, h2, 500); //向下滑动 586 | } else { 587 | swipe(x, h2, x, h1, 500); //向上滑动 588 | } 589 | } 590 | } 591 | } 592 | 593 | /** 594 | * @description: 视频学习计时(弹窗)函数 595 | * @param: n-视频标号 seconds-学习秒数 596 | * @return: null 597 | */ 598 | function video_timing_bailing(n, seconds) { 599 | var seconds = seconds * 1; 600 | seconds = seconds + randomNum(1, 5); 601 | delay(1); 602 | for (var i = 0; i < seconds; i++) { 603 | sleep(1000); 604 | while (!(textContains("分享").exists() || textContains("播放").exists()) || desc("工作").exists()) //如果离开了百灵小视频界面则一直等待 605 | { 606 | console.error("当前已离开第" + (n + 1) + "个视频界面,请重新返回视频"); 607 | delay(2); 608 | } 609 | console.info("第" + (n + 1) + "个视频已经观看" + (i + 1) + "秒,剩余" + (seconds - i - 1) + "秒!"); 610 | } 611 | } 612 | 613 | /** 614 | * @description: 广播学习计时(弹窗)函数 615 | * @param: r_time-已经收听的时间 seconds-学习秒数 616 | * @return: null 617 | */ 618 | function radio_timing(r_time, seconds) { 619 | var seconds = seconds * 1; 620 | for (var i = 0; i < seconds; i++) { 621 | sleep(1000); 622 | if (i % 5 == 0) //每5秒打印一次信息 623 | { 624 | console.info("广播已经收听" + (i + 1 + r_time) + "秒,剩余" + (seconds - i - 1) + "秒!"); 625 | } 626 | if (i % 15 == 0) //每15秒弹一次窗防止息屏 627 | { 628 | toast("这是防息屏弹窗,可忽略-. -"); 629 | } 630 | } 631 | } 632 | 633 | /** 634 | * @description: 已读文章判断 635 | * @param: null 636 | * @return: null 637 | */ 638 | function insertLearnedArticle(article) { 639 | article_list.push(article); 640 | } 641 | 642 | function getLearnedArticle(article) { 643 | for (var i = 0; i < article_list.length; i++) { 644 | if (article_list[i] == article) { 645 | return true; 646 | } 647 | } 648 | return false; 649 | } 650 | 651 | 652 | var commentText = ["歌颂共产党,永远跟党走。", "为中华崛起而读书!", "倡导富强、民主、文明、和谐", "自由,平等,公正,法治", "不忘初心,牢记使命", "努力奋斗,回报祖国!", 653 | "赞叹中共伟大成就 祝福中国美好未来!" 654 | ]; //评论内容,可自行修改,大于5个字便计分 655 | /** 656 | * @description: 分享评论 657 | * @param: null 658 | * @return: null 659 | */ 660 | function collectCommentShare() { 661 | while (!text("欢迎发表你的观点").exists()) { 662 | toastLog("需要在文章界面"); 663 | delay(1); 664 | } 665 | var textOrder = text("欢迎发表你的观点").findOnce().drawingOrder(); 666 | 667 | var zhuanOrder = textOrder + 3; 668 | 669 | 670 | var shareIcon = className("ImageView").filter(function(iv) { 671 | return iv.drawingOrder() == zhuanOrder; 672 | }).findOnce(); 673 | 674 | toastLog("正在进行分享评论..."); 675 | 676 | //收藏 677 | // var collectIcon = className("com.uc.webview.export.WebView").findOnce().parent().child(7);//右下角收藏按钮 678 | // var co = textOrder + 2; 679 | // var collectIcon = className("ImageView").filter(function (iv) { 680 | // return iv.drawingOrder() == co; 681 | // }).findOnce(); 682 | //collectIcon.click(); //点击收藏 683 | //delay(2); 684 | 685 | //var shareIcon = className("com.uc.webview.export.WebView").findOnce().parent().child(8);//右下角分享按钮 686 | shareIcon.click(); //点击分享 687 | while (!textContains("分享到学习强").exists()); //等待弹出分享选项界面 688 | delay(2); 689 | click("分享到学习强国"); 690 | delay(1); 691 | toastLog("分享成功!"); 692 | delay(1); 693 | back(); //返回文章界面 694 | delay(2); 695 | //评论 696 | 697 | var num = random(0, commentText.length - 1) //随机数 698 | click("欢迎发表你的观点"); 699 | delay(1); 700 | setText(commentText[num]); //输入评论内容 701 | delay(1); 702 | click("发布"); //点击右上角发布按钮 703 | //toastLog("评论成功!"); 704 | delay(2); 705 | click("删除"); //删除该评论 706 | delay(2); 707 | click("确认"); //确认删除 708 | //toastLog("评论删除成功!"); 709 | delay(2); 710 | // collectIcon.click(); //取消收藏 711 | // delay(1); 712 | toastLog("分享,评论结束"); 713 | 714 | //toastLog("收藏成功!"); 715 | //分享 716 | } 717 | 718 | 719 | /** 720 | * @description: 文章学习函数 (阅读文章+文章学习时长)---6+6=12分 721 | * @param: null 722 | * @return: null 723 | */ 724 | function articleStudy(x) { 725 | var aCatlog = '推荐' 726 | while (!desc("工作").exists()); //等待加载出主页 727 | var listView = className("ListView"); //获取文章ListView控件用于翻页 728 | if (x == 0) { 729 | desc("工作").click(); //点击主页正下方的"学习"按钮 730 | delay(2); 731 | click(aCatlog); 732 | } 733 | delay(2); 734 | var zt_flag = false; //判断进入专题界面标志 735 | var fail = 0; //点击失败次数 736 | var x = aCount; 737 | if (点点通['有效浏览']) { 738 | x = Math.max(点点通['有效浏览'] * 6 - (6 - aCount), 点点通['有效浏览'] * 6); 739 | } 740 | console.log('需要学习' + x + '篇'); 741 | for (var i = 0, t = 0; i < x;) { 742 | if (aCount <= 0) aTime = 6; 743 | try { 744 | if ((text('播报').findOnce(t).parent().parent().parent().child(0).parent().parent().click()) == true) { 745 | delay(3); 746 | // // delay(10); //等待加载出文章页面,后面判断是否进入了视频文章播放要用到 747 | //获取当前正在阅读的文章标题 748 | let n = 0; 749 | while (!textContains("欢迎发表你的观点").exists()) { //如果没有找到评论框则认为没有进入文章界面,一直等待 750 | delay(1); 751 | console.warn("正在等待加载文章界面..."); 752 | if (n > 2) { //等待超过3秒则认为进入了专题界面,退出进下一篇文章 753 | console.warn("没找到评论框!该界面非文章界面!"); 754 | zt_flag = true; 755 | break; 756 | } 757 | n++; 758 | } 759 | if (text("展开").exists()) { //如果存在“展开”则认为进入了文章栏中的视频界面需退出 760 | console.warn("进入了视频界面,退出并进入下一篇文章!"); 761 | t++; 762 | back(); 763 | listView.scrollForward(); 764 | delay(1.5); 765 | if (rTime != 0) { 766 | while (!desc("工作").exists()); 767 | console.info("因为广播被打断,重新收听广播..."); 768 | delay(0.5); 769 | listenToRadio(); //听电台广播 770 | while (!desc("工作").exists()); 771 | desc("工作").click(); 772 | } 773 | delay(2); 774 | continue; 775 | } 776 | if (zt_flag == true) { //进入专题页标志 777 | console.warn("进入了专题界面,即将退出并进下一篇文章!"); 778 | t++; 779 | back(); 780 | delay(2); 781 | zt_flag = false; 782 | continue; 783 | } 784 | var currentNewsTitle = "" 785 | if (id("xxqg-article-header").exists()) { 786 | currentNewsTitle = id("xxqg-article-header").findOne().child(0).text(); // 最终解决办法 787 | } else if (textContains("来源").exists()) { 788 | currentNewsTitle = textContains("来源").findOne().parent().children()[0].text(); 789 | } else if (textContains("作者").exists()) { 790 | currentNewsTitle = textContains("作者").findOne().parent().children()[0].text(); 791 | } else if (descContains("来源").exists()) { 792 | currentNewsTitle = descContains("来源").findOne().parent().children()[0].desc(); 793 | } else if (descContains("作者").exists()) { 794 | currentNewsTitle = descContains("作者").findOne().parent().children()[0].desc(); 795 | } else { 796 | console.log("无法定位文章标题,即将退出并阅读下一篇") 797 | t++; 798 | back(); 799 | delay(2); 800 | continue; 801 | } 802 | if (currentNewsTitle == "") { 803 | console.log("标题为空,即将退出并阅读下一篇") 804 | t++; 805 | back(); 806 | delay(2); 807 | continue; 808 | } 809 | var flag = getLearnedArticle(currentNewsTitle); 810 | if (flag) { 811 | //已经存在,表明阅读过了 812 | console.info("该文章已经阅读过,即将退出并阅读下一篇"); 813 | t++; 814 | back(); 815 | delay(2); 816 | continue; 817 | } else { 818 | //没阅读过,添加到数据库 819 | insertLearnedArticle(currentNewsTitle); 820 | } 821 | console.log("正在学习第" + (i + 1) + "篇文章,标题:", currentNewsTitle); 822 | fail = 0; //失败次数清0 823 | //开始循环进行文章学习 824 | article_timing(i, aTime); 825 | aCount--; 826 | delay(2); 827 | if (sCount != 0) { 828 | console.info("第" + (3 - sCount) + "次分享开始"); 829 | sCount--; 830 | collectCommentShare(); //评论和分享 831 | } 832 | back(); //返回主界面 833 | console.info('返回主界面'); 834 | delay(0.3); 835 | while (!desc("工作").exists()) { //等待加载出主页 836 | console.info("等待加载主页"); 837 | delay(2); 838 | } 839 | delay(2); 840 | //console.info('i++,t++') 841 | listView.scrollForward(); 842 | delay(1) 843 | i++; 844 | t++; //t为实际点击的文章控件在当前布局中的标号,和i不同,勿改动! 845 | } else { 846 | t++; 847 | } 848 | } catch (e) { 849 | listView.scrollForward(); 850 | //console.info('异常') 851 | t = 0; 852 | delay(1.5); 853 | } 854 | } 855 | aTime = hamibot.env.time1; 856 | } 857 | 858 | /** 859 | * @description:百灵小视频学习函数 860 | * @param: null 861 | * @return: null 862 | */ 863 | function videoStudy_news(tmp) { 864 | h = device.height; //屏幕高 865 | w = device.width; //屏幕宽 866 | x = (w / 3) * 2; 867 | h1 = (h / 6) * 5; 868 | h2 = (h / 6); 869 | //delay(1) 870 | if (tmp == 1) { 871 | desc("工作").click(); 872 | delay(2) 873 | click("百灵"); 874 | delay(1) 875 | } 876 | click("推荐"); 877 | delay(2); 878 | //获取listView视频列表控件用于翻页 879 | var v = className('android.widget.FrameLayout').clickable(true).depth(24).findOne().bounds(); 880 | press(v.centerX(), v.centerY(), 150); 881 | // if (text('').exists()) 882 | // text('').findOnce(0).parent().parent().parent().parent().child(0).click(); 883 | delay(1); 884 | //var listView = className("ListView"); 885 | for (var i = 0; i < vCount;) { 886 | if (textContains("分享").exists()) { 887 | console.log("即将学习第" + (i + 1) + "个视频!"); 888 | video_timing_bailing(i, vTime); //学习每个新闻联播小片段 889 | //back();//返回联播频道界面 890 | swipe(x, h1, x, h2, 500); // 下滑动 891 | delay(1); 892 | i++; 893 | } else { 894 | delay(1); 895 | console.error("等待百灵视频界面"); 896 | } 897 | } 898 | delay(2); 899 | back(); 900 | } 901 | 902 | function new_bailing_video(tmp) { 903 | h = device.height; //屏幕高 904 | w = device.width; //屏幕宽 905 | x = (w / 3) * 2; 906 | h1 = (h / 6) * 5; 907 | h2 = (h / 6); 908 | //delay(1) 909 | if (tmp == 1) { 910 | desc("工作").click(); 911 | delay(2) 912 | click("百灵"); 913 | delay(1) 914 | } 915 | for (var i = 0; i < vCount;) { 916 | if (textContains("百灵").exists()) { 917 | try { 918 | if (i % 2 == 0) { 919 | click("推荐"); 920 | delay(2); 921 | } 922 | className('android.widget.FrameLayout').clickable(true).depth(22).findOnce((i % 2)).click(); 923 | console.log("即将学习第" + (i + 1) + "个视频!"); 924 | video_timing_bailing(i, vTime); //学习每个新闻联播小片段 925 | back(); //返回联播频道界面 926 | delay(1); 927 | i++; 928 | } catch (e) { 929 | delay(1); 930 | console.error("等待百灵视频界面"); 931 | } 932 | 933 | } else { 934 | delay(1); 935 | console.error("等待百灵视频界面"); 936 | } 937 | 938 | } 939 | } 940 | 941 | function video_news_time(n, seconds) { 942 | var seconds = seconds * 1; 943 | seconds = seconds + randomNum(1, 5); 944 | for (var i = 0; i < seconds; i++) { 945 | sleep(1000); 946 | while (!desc("工作").exists()) //如果离开了看电视视频界面则一直等待 947 | { 948 | console.error("当前已离开第" + (n + 1) + "个视频界面,请重新返回视频"); 949 | delay(2); 950 | } 951 | console.info("第" + (n + 1) + "个视频已经观看" + (i + 1) + "秒,剩余" + (seconds - i - 1) + "秒!"); 952 | } 953 | } 954 | 955 | /** 956 | * @description:电视台视频学习 957 | * @param: null 958 | * @return: null 959 | */ 960 | function video_news(tmp) { 961 | h = device.height; //屏幕高 962 | w = device.width; //屏幕宽 963 | x = (w / 3) * 2; 964 | h1 = (h / 6) * 5; 965 | h2 = (h / 6); 966 | //delay(1) 967 | var t = 6; 968 | if (tmp == 1) { 969 | desc("工作").click(); 970 | delay(2); 971 | click("电视台"); 972 | delay(1) 973 | click("看电视"); 974 | delay(2); 975 | t = 0; 976 | } 977 | var s = textContains("中央广播电视总台").depth(22).findOnce().parent(); 978 | s.click(); 979 | console.info('改变提示框位置'); 980 | delay(1); 981 | console.setPosition(device.width / 4, -device.height / 4); 982 | for (var i = 0; i < vCount; i++) { 983 | if (textContains("电视台").exists()) { 984 | console.log("即将学习第" + (i + 1) + "个视频!"); 985 | var cctv = s.parent().parent().parent().parent().child(1).child(0).child(t).bounds(); 986 | press(cctv.centerX(), cctv.centerY(), 150); 987 | delay(2); 988 | video_news_time(i, vTime); //学习每个直播小片段 989 | delay(1); 990 | t++; 991 | t = t % 8; 992 | } else { 993 | delay(1); 994 | console.error("等待电视台->看电视界面"); 995 | } 996 | } 997 | console.setPosition(0, device.height / 2); 998 | delay(2); 999 | //back(); 1000 | } 1001 | 1002 | /** 1003 | * @description: 听“电台”新闻广播函数 (视听学习+视听学习时长)---6+6=12分 1004 | * @param: null 1005 | * @return: null 1006 | */ 1007 | function listenToRadio() { 1008 | click("电台"); 1009 | delay(1); 1010 | click("听广播"); 1011 | delay(2); 1012 | while (!(textContains("正在收听").exists() || textContains("最近收听").exists() || textContains("推荐收听").exists())) { 1013 | log("等待加载"); 1014 | delay(1); 1015 | } 1016 | if (click("最近收听") == 0) { 1017 | if (click("推荐收听") == 0) { 1018 | click("正在收听"); 1019 | } 1020 | } 1021 | delay(2); 1022 | if (id("btn_back").findOne().click() == 0) { 1023 | delay(2); 1024 | back(); //返回电台界面 1025 | } 1026 | delay(2); 1027 | 1028 | } 1029 | 1030 | 1031 | 1032 | /** 1033 | * @description: 启动app 1034 | * @param: null 1035 | * @return: null 1036 | */ 1037 | function start_app() { 1038 | console.setPosition(0, device.height / 2); //部分华为手机console有bug请注释本行 1039 | console.show(); //部分华为手机console有bug请注释本行 1040 | console.log("正在启动app..."); 1041 | if (!(launchApp("学习强国") || launch('cn.xuexi.android'))) //启动学习强国app 1042 | { 1043 | console.error("找不到学习强国App!,请自己尝试打开"); 1044 | // return; 1045 | } 1046 | while (!desc("工作").exists()) { 1047 | console.log("正在等待加载出主页,如果一直加载此信息,请检测是否在主界面,或者无障碍服务可能出现BUG,请停止运行hamibot重新给无障碍服务"); 1048 | if (textContains("取消").exists() && textContains("立即升级").exists()) { 1049 | //toast('1'); 1050 | text("取消").click(); 1051 | } 1052 | delay(3); 1053 | } 1054 | delay(1); 1055 | } 1056 | 1057 | 1058 | /** 1059 | * @description: 本地频道 1060 | * @param: null 1061 | * @return: null 1062 | */ 1063 | function localChannel() { 1064 | delay(1) 1065 | while (!desc("工作").exists()); //等待加载出主页 1066 | desc("工作").click(); 1067 | sleep(random_time(delay_time)); 1068 | 1069 | /* if (className("android.widget.LinearLayout").exists()) { 1070 | console.log('去本地频道'); 1071 | swipe(device.width - 200, device.height / 2, 200, device.height / 2, 300) 1072 | sleep(random_time(delay_time)); 1073 | swipe(device.width - 200, device.height / 2, 200, device.height / 2, 300); 1074 | sleep(random_time(delay_time)); 1075 | swipe(device.width - 200, device.height / 2, 200, device.height / 2, 300); 1076 | sleep(random_time(delay_time)); 1077 | console.log("点击: 本地频道"); 1078 | className("android.widget.LinearLayout").clickable(true).depth(26).findOne().click(); 1079 | sleep(random_time(delay_time)); 1080 | back(); 1081 | } else { 1082 | console.log("请手动点击本地频道!"); 1083 | } */ 1084 | console.log("点击本地频道"); 1085 | if (text("思想").exists()) { 1086 | text("思想").findOne().parent().parent().child(3).click(); 1087 | delay(3); 1088 | className("android.support.v7.widget.RecyclerView").findOne().child(2).click(); 1089 | delay(2); 1090 | console.log("返回主界面"); 1091 | back(); 1092 | launchApp("学习强国"); 1093 | delay(1); 1094 | text("思想").findOne().parent().parent().child(0).click(); 1095 | } else { 1096 | console.log("请手动点击本地频道!"); 1097 | } 1098 | 1099 | } 1100 | 1101 | /** 1102 | * @description: 获取积分 1103 | * @param: null 1104 | * @return: null 1105 | **/ 1106 | function getScores(i) { 1107 | while (!desc("工作").exists()); //等待加载出主页 1108 | console.log("正在获取积分..."); 1109 | delay(2); 1110 | while (!text("学习积分").exists()) { 1111 | if (id("comm_head_xuexi_score").exists()) { 1112 | id("comm_head_xuexi_score").findOnce().click(); 1113 | } else if (text("积分").exists()) { 1114 | text("积分").findOnce().parent().child(1).click(); 1115 | } 1116 | delay(3); 1117 | } 1118 | while (!text('登录').exists()) { 1119 | delay(0.5); 1120 | } 1121 | let err = false; 1122 | while (!err) { 1123 | try { 1124 | className("android.widget.ListView").findOnce().children().forEach(item => { 1125 | var name; 1126 | try { 1127 | name = item.child(0).child(0).text(); 1128 | } catch (e) { 1129 | name = item.child(0).text(); 1130 | } 1131 | let score = item.child(3).child(0).text(); 1132 | myScores[name] = score; 1133 | }); 1134 | err = true; 1135 | } catch (e) { 1136 | console.log(e); 1137 | } 1138 | } 1139 | if (i == 3) { 1140 | var score = textContains("今日已累积").findOne().text(); 1141 | score += '%0A四人赛:' + myScores["四人赛"] + '分'; 1142 | score += '%0A双人赛:' + myScores["双人对战"] + '分'; 1143 | score += '%0A成长总积分:' + textContains("成长总积分").findOne().parent().child(3).text() + '分%0A'; 1144 | log(score); 1145 | back(); 1146 | return score; 1147 | } 1148 | console.log(myScores); 1149 | 1150 | aCount = Math.ceil((12 - myScores["我要选读文章"]) / 2); //文章个数 1151 | if (i == 1) { 1152 | console.info("检查阅读文章是否满分!") 1153 | aCount = 12 - myScores["我要选读文章"]; 1154 | if (aCount != 0) { 1155 | console.log("还需要阅读:" + aCount.toString() + "篇!"); 1156 | } else { 1157 | console.info("已满分!"); 1158 | } 1159 | delay(1); 1160 | back(); 1161 | delay(1); 1162 | return; 1163 | } 1164 | if (i == 2) { 1165 | console.info("检查视频是否满分!") 1166 | vCount = 6 - myScores["视听学习"]; 1167 | if (vCount != 0) { 1168 | console.log("还需要观看:" + vCount.toString() + "篇!"); 1169 | } else { 1170 | console.info("已满分!"); 1171 | } 1172 | delay(1); 1173 | back(); 1174 | delay(1); 1175 | return; 1176 | } 1177 | if (aCount != 0) { 1178 | aCount = aCount; 1179 | } 1180 | vCount = 6 - myScores["视听学习"]; 1181 | rTime = (6 - myScores["视听学习时长"]) * 60; 1182 | asub = 2 - myScores["订阅"]; 1183 | sCount = 0 1184 | cCount = 1 - myScores["发表观点"] 1185 | if (myScores["每日答题"] < 5) dayCount = 1; 1186 | else dayCount = 0; 1187 | if (myScores["挑战答题"] < 6) tzCount = 1; 1188 | else tzCount = 0; 1189 | if (myScores["四人赛"] == 0) zsyCount = 1; 1190 | else zsyCount = 0; 1191 | if (myScores["双人对战"] == 0) doubleCount = 1; 1192 | else doubleCount = 0; 1193 | if (myScores["每周答题"] == 0) meizhou = 1; 1194 | else meizhou = 0; 1195 | if (myScores["专项答题"] == 0) zhuanxiang = 1; 1196 | else zhuanxiang = 0; 1197 | 1198 | console.log('评论:' + cCount.toString() + '个') 1199 | console.log('分享:' + sCount.toString() + '个') 1200 | console.log('订阅:' + asub.toString() + '个') 1201 | console.log('剩余文章:' + aCount.toString() + '篇') 1202 | // console.log('剩余每篇文章学习时长:' + aTime.toString() + '秒') 1203 | console.log('剩余视频:' + vCount.toString() + '个') 1204 | console.log('剩视听学习时长:' + rTime.toString() + '秒') 1205 | console.log('每日答题:\t' + dayCount.toString()); 1206 | console.log('挑战答题:\t' + tzCount.toString()); 1207 | console.log('四人赛:\t' + zsyCount.toString()); 1208 | console.log('双人对战:\t' + doubleCount.toString()); 1209 | if (meizhou_txt == "开启") 1210 | console.log('每周答题:\t' + meizhou.toString()); 1211 | if (zhuanxiang_txt == "开启") 1212 | console.log('专项答题:\t' + zhuanxiang.toString()); 1213 | 1214 | delay(1); 1215 | back(); 1216 | delay(1); 1217 | } 1218 | 1219 | /** 1220 | @description: 停止广播 1221 | @param: null 1222 | @return: null 1223 | */ 1224 | function stopRadio() { 1225 | console.log("停止收听广播!"); 1226 | click("电台"); 1227 | delay(1); 1228 | click("听广播"); 1229 | delay(2); 1230 | back_table(); 1231 | while (!(textContains("正在收听").exists() || textContains("最近收听").exists() || textContains("推荐收听").exists())) { 1232 | log("等待加载"); 1233 | delay(2) 1234 | } 1235 | if (click("正在收听") == 0) { 1236 | click("最近收听"); 1237 | } 1238 | delay(3); 1239 | id("v_play").findOnce(0).click(); 1240 | delay(2) 1241 | if (id("btn_back").findOne().click() == 0) { 1242 | delay(2); 1243 | back(); 1244 | } 1245 | delay(2); 1246 | try { 1247 | if (id("v_playing").exists()) 1248 | id("v_playing").findOnce(0).click(); 1249 | } catch (e) {} 1250 | 1251 | } 1252 | 1253 | /** 1254 | @description: 学习平台订阅 1255 | @param: null 1256 | @return: null 1257 | */ 1258 | function pic_click(a, b, s1) { 1259 | while (asub > 0) { 1260 | let result = findColor(captureScreen(), '#E42417', { 1261 | max: 5, 1262 | region: [s1, 100, device.width - s1, device.height - 200], //区域 1263 | threshold: 10, 1264 | }); 1265 | if (result) { 1266 | console.log("已经订阅了" + (3 - asub) + "个"); 1267 | press(result.x + a, result.y + b, 100); 1268 | asub--; 1269 | } else { 1270 | break; 1271 | } 1272 | delay(1); 1273 | } 1274 | } 1275 | 1276 | function sub() { 1277 | console.info('正在订阅'); 1278 | h = device.height; //屏幕高 1279 | w = device.width; //屏幕宽 1280 | x = (w / 3) * 2; 1281 | h1 = (h / 6) * 5; 1282 | h2 = (h / 6); 1283 | desc("工作").click(); 1284 | delay(1); 1285 | click("订阅"); 1286 | delay(1); 1287 | click("添加"); 1288 | delay(3); 1289 | if (!desc('推荐').exists()) { 1290 | console.info('没有找到,可能你的xxqg不是2.33及以下版本,不支持订阅!!!'); 1291 | back(); 1292 | delay(1); 1293 | back_table(); 1294 | return 0; 1295 | } 1296 | var len = desc('推荐').depth(15).findOne().parent(); 1297 | var s1 = className("android.view.View").depth(14).scrollable(true).findOne().child(0).child(2).bounds().left; 1298 | // 小图 = images.clip(小图1,0,0,Math.min(device.width-s1,160),64); // 切割图片 1299 | var old_names = ''; 1300 | console.log('搜索中'); 1301 | for (var i = 0; i < len.childCount() - 1 && asub != 0; i++) { 1302 | if (订阅 == 'c') i = 1; 1303 | len.child(i).click(); 1304 | delay(1); 1305 | while (true && asub != 0) { 1306 | pic_click(20, 20, s1); 1307 | // className("android.view.View").scrollable(true).depth(14).findOne().scrollForward(); 1308 | swipe(x, h1, x, h2, random(800, 1200)); // 下滑动 1309 | delay(1); 1310 | pic_click(20, 20, s1); 1311 | // className("android.view.View").scrollable(true).depth(14).findOne().scrollForward(); 1312 | swipe(x, h1, x, h2, random(800, 1200)); // 下滑动 1313 | delay(1); 1314 | try { 1315 | var list = className("android.view.View").depth(14).findOnce(1); 1316 | var names = list.child(2).child(1).desc(); //看第二个 1317 | if (names == old_names) { 1318 | break; 1319 | } else old_names = names; 1320 | } catch (e) { 1321 | if (list != null && list.childCount() < 5) break; 1322 | } 1323 | //toastLog(names); 1324 | } 1325 | if (订阅 == 'c') break; 1326 | } 1327 | if (asub == 0) { 1328 | back(); 1329 | delay(1); 1330 | back_table(); 1331 | console.info('订阅完成'); 1332 | return 0; 1333 | } 1334 | desc('地方平台\nTab 2 of 2').click(); 1335 | delay(2); 1336 | len = desc('推荐').depth(15).findOne().parent(); 1337 | list = className("android.view.View").depth(14).scrollable(true).findOne(); 1338 | old_names = ''; 1339 | for (var i = 0; i < len.childCount() - 1 && asub != 0; i++) { 1340 | if (订阅 == 'c') i = 1; 1341 | len.child(i).click(); 1342 | delay(1); 1343 | while (true && asub != 0) { 1344 | pic_click(20, 20, s1); 1345 | // className("android.view.View").scrollable(true).depth(14).findOne().scrollForward(); 1346 | swipe(x, h1, x, h2, random(800, 1200)); // 下滑动 1347 | delay(1); 1348 | pic_click(20, 20, s1); 1349 | // className("android.view.View").scrollable(true).depth(14).findOne().scrollForward(); 1350 | swipe(x, h1, x, h2, random(800, 1200)); // 下滑动 1351 | delay(1); 1352 | try { 1353 | var list = className("android.view.View").depth(14).findOnce(1); 1354 | var names = list.child(2).child(1).desc(); 1355 | if (names == old_names) { 1356 | break; 1357 | } else old_names = names; 1358 | } catch (e) { 1359 | if (list != null && list.childCount() < 5) break; 1360 | } 1361 | } 1362 | if (订阅 == 'c') break; 1363 | } 1364 | if (asub == 0) { 1365 | console.info('订阅完成'); 1366 | } else { 1367 | console.info('订阅结束,已经没有订阅的了'); 1368 | } 1369 | back(); 1370 | delay(1); 1371 | back_table(); 1372 | } 1373 | 1374 | function questionShow() { 1375 | while (!desc("工作").exists()) { 1376 | console.log("等待加载出主页"); 1377 | delay(1); 1378 | if (text("排行榜").exists()) { 1379 | return; 1380 | } 1381 | } 1382 | console.log("当前在主界面") 1383 | if (text("我的").exists()) { 1384 | text("我的").click(); 1385 | console.log("点击我的"); 1386 | } 1387 | delay(1); 1388 | while (!desc("我的信息").exists()) { 1389 | console.log("等待 我的 界面"); 1390 | delay(1); 1391 | } 1392 | console.log("点击我要答题"); 1393 | text("我要答题").findOne().parent().click(); 1394 | delay(1); 1395 | } 1396 | 1397 | function meizhouAnswer() { 1398 | h = device.height; //屏幕高 1399 | w = device.width; //屏幕宽 1400 | x = (w / 3) * 2; 1401 | h1 = (h / 6) * 5; 1402 | h2 = (h / 6); 1403 | while (!text("排行榜").exists()) { 1404 | console.info("等待我要答题界面"); 1405 | delay(1); 1406 | } 1407 | var textOrder = text("排行榜").findOnce().parent(); 1408 | while (text("排行榜").exists()) { 1409 | console.info("点击每周答题"); 1410 | textOrder.child(3).click(); 1411 | delay(1); 1412 | } 1413 | delay(3); 1414 | var t = 0; 1415 | while (true) { 1416 | if (text('未作答').exists()) { 1417 | text("未作答").findOne().parent().click(); 1418 | dailyAnswer(); 1419 | break; 1420 | } else { 1421 | if (每周答题下滑 == 'a') { 1422 | console.info("没有可答题的题目,返回"); 1423 | back(); 1424 | delay(1); 1425 | if (text("已作答").exists()) { // 防止出现网络卡顿 1426 | back(); 1427 | delay(1); 1428 | } 1429 | break; 1430 | } else { 1431 | if (textContains('您已经看到了我的底线').exists()) { 1432 | console.log("已经没有可答题的题目了,返回"); 1433 | back(); 1434 | delay(1); 1435 | break; 1436 | } 1437 | swipe(x, h1, x, h2, 100); // 下滑动 1438 | try { 1439 | textContains("月").findOnce(0).parent().parent().parent().scrollForward(); 1440 | } catch (e) {} 1441 | delay(1); 1442 | if (t % 10 == 0) 1443 | console.log("向下滑动中!!!"); 1444 | t++; 1445 | } 1446 | } 1447 | } 1448 | 1449 | } 1450 | 1451 | function zhuanxiangAnswer() { 1452 | h = device.height; //屏幕高 1453 | w = device.width; //屏幕宽 1454 | x = (w / 3) * 2; 1455 | h1 = (h / 6) * 5; 1456 | h2 = (h / 6); 1457 | while (!text("排行榜").exists()) { 1458 | console.info("等待我要答题界面"); 1459 | delay(1); 1460 | } 1461 | var textOrder = text("排行榜").findOnce().parent(); 1462 | while (text("排行榜").exists()) { 1463 | console.info("点击专项答题"); 1464 | textOrder.child(4).click(); 1465 | delay(1); 1466 | } 1467 | delay(3); 1468 | var t = 0; 1469 | 1470 | while (true) { 1471 | if (text("继续答题").exists() || text("开始答题").exists()) { 1472 | if (text("继续答题").exists()) 1473 | text("继续答题").findOne().click(); 1474 | else if (text("开始答题").exists()) 1475 | text("开始答题").findOne().click(); 1476 | delay(1); 1477 | dailyAnswer(); 1478 | break; 1479 | } else { 1480 | if (专项答题下滑 == 'a') { 1481 | console.log('没有可答题的题目,返回'); 1482 | back(); 1483 | delay(1); 1484 | if (text("已满分").exists() || text("继续答题").exists() || text("开始答题").exists()) { // 防止出现网络卡顿 1485 | back(); 1486 | delay(1); 1487 | } 1488 | break; 1489 | } else { 1490 | if (textContains('您已经看到了我的底线').exists()) { 1491 | console.log("已经没有可答题的题目了,返回"); 1492 | back(); 1493 | delay(1); 1494 | break; 1495 | } 1496 | swipe(x, h1, x, h2, 100); // 下滑动 1497 | try { 1498 | textContains("专项").findOnce(0).parent().scrollForward(); 1499 | } catch (e) {} 1500 | 1501 | //delay(1); 1502 | if (t % 10 == 0) 1503 | console.log("向下滑动中!!!"); 1504 | t++; 1505 | } 1506 | } 1507 | } 1508 | } 1509 | 1510 | 1511 | /** 1512 | * @description: 获取填空题题目数组 1513 | * @param: null 1514 | * @return: questionArray 1515 | */ 1516 | function getFitbQuestion() { 1517 | var questionCollections = className("EditText").findOnce().parent().parent(); 1518 | var questionArray = []; 1519 | var findBlank = false; 1520 | var blankCount = 0; 1521 | var blankNumStr = ""; 1522 | var i = 0; 1523 | questionCollections.children().forEach(item => { 1524 | if (item.className() != "android.widget.EditText") { 1525 | if (item.text() != "") { //题目段 1526 | if (findBlank) { 1527 | blankNumStr = "|" + blankCount.toString(); 1528 | questionArray.push(blankNumStr); 1529 | findBlank = false; 1530 | } 1531 | questionArray.push(item.text()); 1532 | } else { 1533 | findBlank = true; 1534 | blankCount = (className("EditText").findOnce(i).parent().childCount() - 1); 1535 | i++; 1536 | } 1537 | } 1538 | }); 1539 | return questionArray; 1540 | } 1541 | 1542 | 1543 | /** 1544 | * @description: 获取选择题题目数组 1545 | * @param: null 1546 | * @return: questionArray 1547 | */ 1548 | function getChoiceQuestion() { 1549 | var questionCollections = className("ListView").findOnce().parent().child(1); 1550 | var questionArray = []; 1551 | questionArray.push(questionCollections.text()); 1552 | return questionArray; 1553 | } 1554 | 1555 | 1556 | /** 1557 | * @description: 获取提示字符串 1558 | * @param: null 1559 | * @return: tipsStr 1560 | */ 1561 | function getTipsStr() { 1562 | var tipsStr = ""; 1563 | while (tipsStr == "") { 1564 | if (text("查看提示").exists()) { 1565 | var seeTips = text("查看提示").findOnce(); 1566 | seeTips.click(); 1567 | delay(1); 1568 | click(device.width * 0.5, device.height * 0.41); 1569 | delay(1); 1570 | click(device.width * 0.5, device.height * 0.35); 1571 | } else { 1572 | console.error("未找到查看提示"); 1573 | } 1574 | if (text("提示").exists()) { 1575 | var tipsLine = text("提示").findOnce().parent(); 1576 | //获取提示内容 1577 | var tipsView = tipsLine.parent().child(1).child(0); 1578 | tipsStr = tipsView.text(); 1579 | //关闭提示 1580 | tipsLine.child(1).click(); 1581 | break; 1582 | } 1583 | delay(1); 1584 | } 1585 | return tipsStr; 1586 | } 1587 | 1588 | 1589 | /** 1590 | * @description: 从提示中获取填空题答案 1591 | * @param: timu, tipsStr 1592 | * @return: ansTips 1593 | */ 1594 | function getAnswerFromTips(timu, tipsStr) { 1595 | var ansTips = ""; 1596 | for (var i = 1; i < timu.length - 1; i++) { 1597 | if (timu[i].charAt(0) == "|") { 1598 | if (timu[i].charAt(0) == "|") { 1599 | var blankLen = timu[i].substring(1); 1600 | // var indexKey = tipsStr.indexOf(timu[i + 1].substr(0,Math.min(8,timu[i + 1].length))); 1601 | // if(timu[i + 1]=='。') indexKey = tipsStr.length - 1; 1602 | // var ansFind = tipsStr.substr(indexKey - blankLen, blankLen); 1603 | // ansTips += ansFind; 1604 | var s = timu[i - 1].substr(Math.max(0, timu[i - 1].length - 12), 12); 1605 | var indexKey = tipsStr.indexOf(s) + s.length; 1606 | var ansFind = tipsStr.substr(indexKey, blankLen); 1607 | ansTips += ansFind; 1608 | } 1609 | } 1610 | } 1611 | return ansTips; 1612 | } 1613 | 1614 | /** 1615 | * @description: 根据提示点击选择题选项 1616 | * @param: tipsStr 1617 | * @return: clickStr 1618 | */ 1619 | function clickByTips(tipsStr) { 1620 | var clickStr = ""; 1621 | var isFind = false; 1622 | if (className("ListView").exists()) { 1623 | var listArray = className("ListView").findOne().children(); 1624 | listArray.forEach(item => { 1625 | var ansStr = item.child(0).child(2).text(); 1626 | if (tipsStr.indexOf(ansStr) >= 0) { 1627 | item.child(0).click(); 1628 | clickStr += item.child(0).child(1).text().charAt(0); 1629 | isFind = true; 1630 | } 1631 | }); 1632 | if (!isFind) { //没有找到 点击第一个 1633 | listArray[0].child(0).click(); 1634 | clickStr += listArray[0].child(0).child(1).text().charAt(0); 1635 | } 1636 | } 1637 | return clickStr; 1638 | } 1639 | 1640 | 1641 | /** 1642 | * @description: 根据答案点击选择题选项 1643 | * @param: answer 1644 | * @return: null 1645 | */ 1646 | function clickByAnswer(answer) { 1647 | var click_true = false; 1648 | if (className("ListView").exists()) { 1649 | var listArray = className("ListView").findOnce().children(); 1650 | listArray.forEach(item => { 1651 | var listIndexStr = item.child(0).child(1).text().charAt(0); 1652 | //单选答案为非ABCD 1653 | var listDescStr = item.child(0).child(2).text(); 1654 | if (answer.indexOf(listIndexStr) >= 0 || answer == listDescStr) { 1655 | item.child(0).click(); 1656 | click_true = true; 1657 | } 1658 | }); 1659 | } 1660 | if (!click_true) { 1661 | console.error('没有找到选项,选A跳过'); 1662 | className("ListView").findOnce().child(0).child(0).click(); 1663 | } 1664 | } 1665 | 1666 | /** 1667 | * @description: 检查答案是否正确 1668 | * @param: question, ansTiku, answer 1669 | * @return: null 1670 | */ 1671 | function checkAndUpdate(question, ansTiku, answer) { 1672 | sleep(500); 1673 | if (textContains("答案解析").exists()) { //答错了 1674 | swipe(device.width / 2, device.height - 200, 100, 100, 500); 1675 | if (text("确定").exists()) { 1676 | text("确定").click(); 1677 | } else if (textContains('下一题').exists()) { 1678 | textContains('下一题').click(); 1679 | } else if (className("Button").exists()) { 1680 | className("Button").findOnce().click(); 1681 | } else { 1682 | click(device.width * 0.85, device.height * 0.06); 1683 | } 1684 | } 1685 | } 1686 | 1687 | function daily_Answer(question, table_name) { 1688 | try { 1689 | var db = SQLiteDatabase.openOrCreateDatabase(path, null); 1690 | sql = "SELECT answer FROM " + table_name + " WHERE question LIKE '" + question + "%'" 1691 | var cursor = db.rawQuery(sql, null); 1692 | if (cursor.moveToFirst()) { 1693 | var answer = cursor.getString(0); 1694 | cursor.close(); 1695 | return answer; 1696 | } else { 1697 | cursor.close(); 1698 | return ''; 1699 | } 1700 | } catch (e) { 1701 | return ''; 1702 | } 1703 | 1704 | } 1705 | /** 1706 | * @description: 每日答题循环 1707 | * @param: null 1708 | * @return: null 1709 | */ 1710 | function dailyQuestionLoop() { 1711 | while (true) { 1712 | if (textStartsWith("填空题").exists()) { 1713 | var questionArray = getFitbQuestion(); 1714 | break; 1715 | } else if (textStartsWith("多选题").exists() || textStartsWith("单选题").exists()) { 1716 | var questionArray = getChoiceQuestion(); 1717 | break; 1718 | } 1719 | log('等待题目出现'); 1720 | delay(1); 1721 | } 1722 | 1723 | 1724 | var blankArray = []; 1725 | var question = ""; 1726 | questionArray.forEach(item => { 1727 | if (item != null && item.charAt(0) == "|") { //是空格数 1728 | blankArray.push(item.substring(1)); 1729 | } else { //是题目段 1730 | question += item; 1731 | } 1732 | }); 1733 | question = question.replace(/\s/g, ""); 1734 | console.log("题目:" + question); 1735 | 1736 | var ansTiku = daily_Answer(question, 'tiku'); 1737 | 1738 | if (ansTiku.length == 0) { //tiku表中没有则到tikuNet表中搜索答案 1739 | ansTiku = daily_Answer(question, 'tikuNet'); 1740 | } 1741 | var answer = ansTiku.replace(/(^\s*)|(\s*$)/g, ""); 1742 | // getAnswer(question); 1743 | 1744 | if (textStartsWith("填空题").exists()) { 1745 | if (answer == "") { 1746 | if (stronger == 'a') { 1747 | var tipsStr = getTipsStr(); 1748 | answer = getAnswerFromTips(questionArray, tipsStr); 1749 | console.info("提示中的答案:" + answer); 1750 | } else if (stronger == 'b') { 1751 | var seeTips = text("查看提示").findOnce(); 1752 | seeTips.click(); 1753 | delay(1); 1754 | var img = captureScreen(); 1755 | try { 1756 | var t = text('提示').findOne(3000); 1757 | t = t.parent().parent().child(1).child(0).bounds(); 1758 | img = images.clip(img, t.left, t.top, t.right - t.left, t.bottom - t.top); 1759 | } catch (e) {} 1760 | answer = huawei_ocr_api(images.inRange(img, '#FFFF0000', '#FFFF0000'), ttt); 1761 | console.info("华为OCR识别的答案:" + answer); 1762 | back(); 1763 | } else if (stronger == 'c') { 1764 | var seeTips = text("查看提示").findOnce(); 1765 | seeTips.click(); 1766 | delay(1); 1767 | var img = captureScreen(); 1768 | try { 1769 | var t = text('提示').findOne(3000); 1770 | t = t.parent().parent().child(1).child(0).bounds(); 1771 | img = images.clip(img, t.left, t.top, t.right - t.left, t.bottom - t.top); 1772 | } catch (e) {} 1773 | answer = baidu_ocr_api(images.inRange(img, '#FFFF0000', '#FFFF0000'), ttt); 1774 | console.info("百度OCR识别的答案:" + answer); 1775 | back(); 1776 | } 1777 | 1778 | if (answer == '') answer = '没有找到提示'; 1779 | setText(0, answer.substr(0, blankArray[0])); 1780 | if (blankArray.length > 1) { 1781 | for (var i = 1; i < blankArray.length; i++) { 1782 | setText(i, answer.substr(blankArray[i - 1], blankArray[i])); 1783 | } 1784 | } 1785 | } else { 1786 | console.info("答案:" + answer); 1787 | setText(0, answer.substr(0, blankArray[0])); 1788 | if (blankArray.length > 1) { 1789 | for (var i = 1; i < blankArray.length; i++) { 1790 | setText(i, answer.substr(blankArray[i - 1], blankArray[i])); 1791 | } 1792 | } 1793 | } 1794 | } else if (textStartsWith("多选题").exists() || textStartsWith("单选题").exists()) { 1795 | if (answer == "") { 1796 | if (stronger == 'a') { 1797 | var tipsStr = getTipsStr(); 1798 | answer = clickByTips(tipsStr); 1799 | console.info("提示中的答案:" + answer); 1800 | } else if (stronger == 'b') { 1801 | var seeTips = text("查看提示").findOnce(); 1802 | seeTips.click(); 1803 | delay(1); 1804 | var img = captureScreen(); 1805 | try { 1806 | var t = text('提示').findOne(3000); 1807 | t = t.parent().parent().child(1).child(0).bounds(); 1808 | img = images.clip(img, t.left, t.top, t.right - t.left, t.bottom - t.top); 1809 | } catch (e) {} 1810 | answer = huawei_ocr_api(images.inRange(img, '#FFFF0000', '#FFFF0000'), ttt); 1811 | console.info("华为OCR识别的答案:" + answer); 1812 | back(); 1813 | delay(1); 1814 | click_answer(answer); 1815 | } else if (stronger == 'c') { 1816 | var seeTips = text("查看提示").findOnce(); 1817 | seeTips.click(); 1818 | delay(1); 1819 | var img = captureScreen(); 1820 | try { 1821 | var t = text('提示').findOne(3000); 1822 | t = t.parent().parent().child(1).child(0).bounds(); 1823 | img = images.clip(img, t.left, t.top, t.right - t.left, t.bottom - t.top); 1824 | } catch (e) {} 1825 | answer = baidu_ocr_api(images.inRange(img, '#FFFF0000', '#FFFF0000'), ttt); 1826 | console.info("百度OCR识别的答案:" + answer); 1827 | back(); 1828 | delay(1); 1829 | click_answer(answer); 1830 | } 1831 | } else { 1832 | console.info("答案:" + answer); 1833 | clickByAnswer(answer); 1834 | } 1835 | } 1836 | 1837 | delay(0.5); 1838 | 1839 | if (text("确定").exists()) { 1840 | text("确定").click(); 1841 | delay(0.5); 1842 | } else if (text("下一题").exists()) { 1843 | click("下一题"); 1844 | delay(0.5); 1845 | } else if (text("完成").exists()) { 1846 | text("完成").click(); 1847 | delay(0.5); 1848 | } else { 1849 | console.warn("未找到右上角确定按钮控件,根据坐标点击(可能是模拟器)"); 1850 | click(device.width * 0.85, device.height * 0.06); //右上角确定按钮,根据自己手机实际修改 1851 | } 1852 | 1853 | checkAndUpdate(question, ansTiku, answer); 1854 | console.log("------------"); 1855 | delay(2); 1856 | } 1857 | 1858 | function click_answer(answer) { 1859 | var f = true; 1860 | if (className("ListView").exists()) { 1861 | if (textStartsWith("多选题").exists()) { 1862 | var listArray = className("ListView").findOnce().children(); 1863 | listArray.forEach(item => { 1864 | var listIndexStr = item.child(0).child(2).text(); 1865 | var num = 0; 1866 | for (var i = 0; i < listIndexStr.length; i++) { 1867 | if (answer.indexOf(listIndexStr[i]) != -1) { 1868 | num++; 1869 | } 1870 | } 1871 | if (num / listIndexStr.length > 1 / 2) { 1872 | item.child(0).click(); 1873 | f = false; 1874 | } 1875 | }); 1876 | } else { 1877 | var listArray = className("ListView").findOnce().children(); 1878 | listArray.forEach(item => { 1879 | var listIndexStr = item.child(0).child(2).text(); 1880 | if (answer.indexOf(listIndexStr) != -1) { 1881 | item.child(0).click(); 1882 | f = false; 1883 | return; 1884 | } 1885 | }); 1886 | if (f) { 1887 | var a = 0; 1888 | var num = 0; 1889 | var ch = 0; 1890 | listArray.forEach(item => { 1891 | var maxx = 0; 1892 | var listIndexStr = item.child(0).child(2).text(); 1893 | for (var i = 0; i < listIndexStr.length; i++) { 1894 | if (answer.indexOf(listIndexStr[i]) != -1) { 1895 | maxx++; 1896 | } 1897 | } 1898 | if (maxx > num) { 1899 | num = maxx; 1900 | ch = a; 1901 | } 1902 | a++; 1903 | }); 1904 | className("ListView").findOnce().child(ch).child(0).click(); 1905 | f = false; 1906 | } 1907 | 1908 | } 1909 | if (f) { 1910 | if (textContains('A').exists()) { 1911 | textContains('A').click(); 1912 | } 1913 | console.error('没有找到,选A跳过'); 1914 | } 1915 | } 1916 | } 1917 | /** 1918 | * @description: 每日答题 1919 | * @param: null 1920 | * @return: null 1921 | */ 1922 | function dailyAnswer() { 1923 | console.info("开始答题"); 1924 | console.setPosition(0, 0); 1925 | delay(1); 1926 | let dlNum = 0; //每日答题轮数 1927 | var flag = true; 1928 | if (textStartsWith("填空题").exists() || textStartsWith("多选题").exists() || textStartsWith("单选题").exists()) { 1929 | flag = false; 1930 | } 1931 | if (flag) { 1932 | var s = 1; 1933 | while (!text("排行榜").exists()) { 1934 | console.log("等待我要答题界面"); 1935 | delay(1) 1936 | if ((textStartsWith("填空题").exists() || textStartsWith("多选题").exists() || textStartsWith("单选题").exists())) { 1937 | s = 0; 1938 | break; 1939 | } 1940 | } 1941 | if (s == 1) { 1942 | var textOrder = text("排行榜").findOnce().parent(); 1943 | while (!className(textOrder.child(2).className()).exists()) { 1944 | toastLog("等待界面出现"); 1945 | } 1946 | textOrder.child(2).click(); 1947 | } 1948 | } 1949 | // var widget = text("太阳每天都是新的").findOne(); 1950 | // click(widget.bounds().centerX(), widget.bounds().centerY()); 1951 | delay(0.5); 1952 | while (true) { 1953 | delay(2); 1954 | // if (!(textStartsWith("填空题").exists() || textStartsWith("多选题").exists() || textStartsWith("单选题").exists())) { 1955 | // // toastLog("没有找到题目!请检查是否进入答题界面!"); 1956 | // console.error("没有找到题目!请检查是否进入答题界面!"); 1957 | // console.log("停止"); 1958 | // 故意报错重启脚本; 1959 | // break; 1960 | // } //冗余 1961 | dailyQuestionLoop(); 1962 | if (text("再练一次").exists()) { 1963 | delay(1.5); 1964 | while(status) {console.log("主线程暂停中");sleep(750);}; 1965 | console.log("每周答题结束!") 1966 | text("返回").click(); 1967 | delay(2); 1968 | back(); 1969 | break; 1970 | } else if (text("查看解析").exists()) { 1971 | delay(1.5); 1972 | while(status) {console.log("主线程暂停中");sleep(750);}; 1973 | console.log("专项答题结束!") 1974 | back(); 1975 | delay(0.5); 1976 | back(); 1977 | delay(0.5); 1978 | break; 1979 | } else if (text("再来一组").exists()) { 1980 | delay(2); 1981 | dlNum++; 1982 | if (!text("领取奖励已达今日上限").exists()) { 1983 | text("再来一组").click(); 1984 | console.warn("第" + (dlNum + 1).toString() + "轮答题:"); 1985 | delay(1); 1986 | } else { 1987 | delay(1.5); 1988 | while(status) {console.log("主线程暂停中");sleep(750);}; 1989 | console.log("每日答题结束!") 1990 | text("返回").click(); 1991 | delay(2); 1992 | break; 1993 | } 1994 | } 1995 | } 1996 | console.setPosition(0, device.height / 2); 1997 | } 1998 | 1999 | ////////////////////////////挑战答题模块功能//////////////////////// 2000 | /** 2001 | * @description: 从数据库中搜索答案 2002 | * @param: question 问题 2003 | * @return: answer 答案 2004 | */ 2005 | function getAnswer(question) { 2006 | var question1 = question.split('来源:')[0]; //去除来源 2007 | question1 = question1.replace(/ /g, ''); //再删除多余空格 2008 | question1 = question1.replace(/  /g, ''); 2009 | try { 2010 | var option = ''; 2011 | var similars = 0; 2012 | var pos = -1; 2013 | for (var i = 0; i < question_list.length; i++) { 2014 | var s = similarity(question_list[i][0], '', question1, 0); 2015 | if (s > similars) { 2016 | similars = s; 2017 | pos = i; 2018 | } 2019 | } 2020 | option = question_list[pos][1]; 2021 | var ans = question_list[pos][2].split(' ')[option[0].charCodeAt(0) - 65]; 2022 | if (!ans) return 'A'; 2023 | return ans; 2024 | // return option; 2025 | } catch (e) { 2026 | return "A"; 2027 | } 2028 | 2029 | } 2030 | 2031 | 2032 | function indexFromChar(str) { 2033 | return str.charCodeAt(0) - "A".charCodeAt(0); 2034 | } 2035 | 2036 | /** 2037 | * @description: 每次答题循环 2038 | * @param: conNum 连续答对的次数 2039 | * @return: null 2040 | */ 2041 | function challengeQuestionLoop(conNum) { 2042 | let ClickAnswer; //定义已点击答案 2043 | if (conNum >= qCount) //答题次数足够退出,每轮qCount=5+随机1-3次 2044 | { 2045 | let listArray = className("ListView").findOnce().children(); //题目选项列表 2046 | let i = random(0, listArray.length - 1); 2047 | console.log("本轮答题数足够,随机点击答案"); 2048 | var question = className("ListView").findOnce().parent().child(0).text(); 2049 | question = question.replace(/\s/g, ""); 2050 | var options = []; //选项列表 2051 | if (className("ListView").exists()) { 2052 | className("ListView").findOne().children().forEach(child => { 2053 | var answer_q = child.child(0).child(1).text(); 2054 | options.push(answer_q); 2055 | }); 2056 | } else { 2057 | console.error("答案获取失败!"); 2058 | return; 2059 | } //20201217添加 极低概率下,答题数足够,下一题随机点击,碰到字形题 2060 | //20220408去除 2061 | /* if (question == "选择正确的读音" || question == "选择词语的正确词形" || question == "下列词形正确的是") { 2062 | // 选择第一个 2063 | console.log((conNum + 1).toString() + ".直接选第一个!!!"); 2064 | className('android.widget.RadioButton').depth(28).findOne().click(); 2065 | return; 2066 | } */ 2067 | console.log((conNum + 1).toString() + ".随机点击题目:" + question); 2068 | delay(random(0.5, 1)); //随机延时0.5-1秒 2069 | listArray[i].child(0).click(); //随意点击一个答案 2070 | ClickAnswer = listArray[i].child(0).child(1).text();; //记录已点击答案 2071 | console.log("随机点击:" + ClickAnswer); 2072 | //如果随机点击答案正确,则更新到本地题库tiku表 2073 | delay(0.5); //等待0.5秒,是否出现X 2074 | console.log("---------------------------"); 2075 | return; 2076 | } 2077 | if (className("ListView").exists()) { 2078 | var question = className("ListView").findOnce().parent().child(0).text(); 2079 | } else { 2080 | console.error("提取题目失败!"); 2081 | let listArray = className("ListView").findOnce().children(); //题目选项列表 2082 | let i = random(0, listArray.length - 1); 2083 | console.log("随机点击"); 2084 | delay(random(0.5, 1)); //随机延时0.5-1秒 2085 | listArray[i].child(0).click(); //随意点击一个答案 2086 | return; 2087 | } 2088 | var chutiIndex = question.lastIndexOf("出题单位"); 2089 | if (chutiIndex != -1) { 2090 | question = question.substring(0, chutiIndex - 2); 2091 | } 2092 | //question = question.replace(/\s/g, ""); 2093 | var options = []; //选项列表 2094 | if (className("ListView").exists()) { 2095 | className("ListView").findOne().children().forEach(child => { 2096 | var answer_q = child.child(0).child(1).text(); 2097 | options.push(answer_q); 2098 | }); 2099 | } else { 2100 | console.error("答案获取失败!"); 2101 | return; 2102 | } 2103 | // var reg = /.*择词语的正确.*/g; 2104 | // var rea = /.*择正确的读音.*/g; 2105 | // var reb = /.*不属于二十四史的是.*/g; 2106 | // if (reg.test(question) || rea.test(question) || reb.test(question)) { // 选择第一个 2107 | // console.log((conNum + 1).toString() + ".直接选第一个!!!"); 2108 | // className('android.widget.RadioButton').depth(28).findOne().click(); 2109 | // return; 2110 | // } 2111 | console.log((conNum + 1).toString() + ".题目:" + question); 2112 | var answer = getAnswer(question); 2113 | console.info("答案:" + answer); 2114 | if (/^[a-zA-Z]{1}$/.test(answer)) { //如果为ABCD形式 2115 | var indexAnsTiku = indexFromChar(answer.toUpperCase()); 2116 | answer = options[indexAnsTiku]; 2117 | toastLog(answer); 2118 | } 2119 | let hasClicked = false; 2120 | let listArray = className("ListView").findOnce().children(); //题目选项列表 2121 | if (answer == "") //如果没找到答案 2122 | { 2123 | let i = random(0, listArray.length - 1); 2124 | console.error("没有找到答案,随机点击"); 2125 | delay(random(0.5, 1)); //随机延时0.5-1秒 2126 | listArray[i].child(0).click(); //随意点击一个答案 2127 | ClickAnswer = listArray[i].child(0).child(1).text();; //记录已点击答案 2128 | hasClicked = true; 2129 | console.log("随机点击:" + ClickAnswer); //如果随机点击答案正确,则更新到本地题库tiku表 2130 | delay(0.5); //等待0.5秒,是否出现X 2131 | console.log("---------------------------"); 2132 | } else //如果找到了答案 2133 | { 2134 | var ii = 1; 2135 | var iii = 1; 2136 | listArray.forEach(items => { 2137 | try { 2138 | console.info('选项' + ii + ':' + items.child(0).child(1).text()); 2139 | } catch (e) {} 2140 | ii++; 2141 | }); 2142 | listArray.forEach(item => { 2143 | try { 2144 | var listDescStr = item.child(0).child(1).text(); 2145 | var answer_replace = answer.replace(/\ +/g, ""); //去掉空格方法 2146 | answer_replace = answer_replace.replace(/[ ]/g, ""); //去掉空格 2147 | answer_replace = answer_replace.replace(/[\r\n]/g, ""); //去掉回车换行 2148 | answer_replace = answer_replace.replace(/-/g, ""); //去掉"-"号 2149 | var listDescStr_replace = listDescStr.replace(/\ +/g, ""); //去掉空格方法 2150 | listDescStr_replace = listDescStr.replace(/[ ]/g, ""); //去掉空格 2151 | listDescStr_replace = listDescStr.replace(/[\r\n]/g, ""); //去掉回车换行 2152 | listDescStr_replace = listDescStr.replace(/-/g, ""); //去掉"-"号 2153 | } catch (e) {} 2154 | if (listDescStr_replace == answer_replace) { 2155 | console.info('答案匹配选项:' + listDescStr_replace); 2156 | delay(random(0.5, 1)); //随机延时0.5-1秒 2157 | try { 2158 | item.child(0).click(); //点击答案 2159 | hasClicked = true; 2160 | } catch (e) {} //防止答错后因为child为空导致报错而停止脚本 2161 | delay(0.5); //等待0.5秒,是否出现X 2162 | if (!text("v5IOXn6lQWYTJeqX2eHuNcrPesmSud2JdogYyGnRNxujMT8RS7y43zxY4coWepspQkvw" + 2163 | "RDTJtCTsZ5JW+8sGvTRDzFnDeO+BcOEpP0Rte6f+HwcGxeN2dglWfgH8P0C7HkCMJOAAAAAElFTkSuQmCC") 2164 | .exists() || text("再来一局").exists()) //遇到❌号,则答错了,不再通过结束本局字样判断 2165 | { 2166 | console.log("题库答案正确……"); 2167 | } 2168 | if (text("v5IOXn6lQWYTJeqX2eHuNcrPesmSud2JdogYyGnRNxujMT8RS7y43zxY4coWepspQkvw" + 2169 | "RDTJtCTsZ5JW+8sGvTRDzFnDeO+BcOEpP0Rte6f+HwcGxeN2dglWfgH8P0C7HkCMJOAAAAAElFTkSuQmCC") 2170 | .exists() || text("再来一局").exists()) //遇到❌号,则答错了,不再通过结束本局字样判断 2171 | { 2172 | console.error("答案错误!!!"); 2173 | console.error("题目:" + question + "答案:" + answer); 2174 | var texterror = question + "答案:" + answer; 2175 | files.append('/sdcard/Wronganswer.txt', "\n" + texterror); 2176 | /*checkAndUpdate(question, answer, ClickAnswer);*/ 2177 | } 2178 | console.log("---------------------------"); 2179 | } else { 2180 | console.log('答案未能匹配选项' + iii); 2181 | } 2182 | iii++; 2183 | }); 2184 | } 2185 | if (!hasClicked) //如果没有点击成功 2186 | { //因导致不能成功点击问题较多,故该部分不更新题库,大部分问题是题库题目适配为填空题或多选题或错误选项 2187 | console.error("未能成功点击,随机点击"); 2188 | let i = random(0, listArray.length - 1); 2189 | delay(random(0.5, 1)); //随机延时0.5-1秒 2190 | listArray[i].child(0).click(); //随意点击一个答案 2191 | console.log("随机点击:" + ClickAnswer); 2192 | delay(0.5); //等待0.5秒,是否出现X 2193 | if (!text("v5IOXn6lQWYTJeqX2eHuNcrPesmSud2JdogYyGnRNxujMT8RS7y43zxY4coWepspQkvw" + 2194 | "RDTJtCTsZ5JW+8sGvTRDzFnDeO+BcOEpP0Rte6f+HwcGxeN2dglWfgH8P0C7HkCMJOAAAAAElFTkSuQmCC").exists() || text( 2195 | "再来一局").exists()) //遇到❌号,则答错了,不再通过结束本局字样判断 2196 | { 2197 | console.log("随机点击正确……"); 2198 | } 2199 | if (text("v5IOXn6lQWYTJeqX2eHuNcrPesmSud2JdogYyGnRNxujMT8RS7y43zxY4coWepspQkvw" + 2200 | "RDTJtCTsZ5JW+8sGvTRDzFnDeO+BcOEpP0Rte6f+HwcGxeN2dglWfgH8P0C7HkCMJOAAAAAElFTkSuQmCC").exists() || text( 2201 | "再来一局").exists()) //遇到❌号,则答错了,不再通过结束本局字样判断 2202 | { 2203 | console.error("随机点击错误!!!"); 2204 | /*checkAndUpdate(question, answer, ClickAnswer);*/ 2205 | } 2206 | console.log("---------------------------"); 2207 | } 2208 | } 2209 | 2210 | 2211 | /** 2212 | * @description: 挑战答题 2213 | * @param: null 2214 | * @return: null 2215 | */ 2216 | function challengeQuestion() { 2217 | // init(); 2218 | if (!className("RadioButton").exists()) { 2219 | while (!text("排行榜").exists()) { 2220 | console.info("等待我要答题界面"); 2221 | delay(1); 2222 | } 2223 | var textOrder = text("排行榜").findOnce().parent(); 2224 | while (text("排行榜").exists()) { 2225 | console.info("点击挑战答题"); 2226 | textOrder.child(10).click(); 2227 | delay(2); 2228 | } 2229 | } 2230 | let conNum = 0; //连续答对的次数 2231 | let lNum = 0; //轮数 2232 | var 复活 = true; 2233 | while (true) { 2234 | delay(2); 2235 | if (!className("RadioButton").exists()) { 2236 | if (复活 == false) { 2237 | console.log("出现错误,等5秒开始下一轮...") 2238 | delay(3); //等待3秒才能开始下一轮 2239 | text("再来一局").click(); 2240 | delay(4); 2241 | conNum = 0; 2242 | 复活 = true; 2243 | } else { 2244 | // toastLog("没有找到题目!请检查是否进入答题界面!"); 2245 | console.error("没有找到题目!请检查是否进入答题界面!"); 2246 | console.log("停止"); 2247 | break; 2248 | } 2249 | } 2250 | challengeQuestionLoop(conNum); 2251 | delay(1); 2252 | if (text('wrong@3x.9ccb997c').exists() || text('2kNFBadJuqbAAAAAElFTkSuQmCC').exists() || text( 2253 | "v5IOXn6lQWYTJeqX2eHuNcrPesmSud2JdogYyGnRNxujMT8RS7y43zxY4coWepspQkvw" + 2254 | "RDTJtCTsZ5JW+8sGvTRDzFnDeO+BcOEpP0Rte6f+HwcGxeN2dglWfgH8P0C7HkCMJOAAAAAElFTkSuQmCC") 2255 | .exists()) //遇到❌号,则答错了,不再通过结束本局字样判断 2256 | { 2257 | if (conNum >= qCount) { 2258 | lNum++; 2259 | qCount = randomNum(3, 6); 2260 | } 2261 | if (lNum >= lCount) { 2262 | delay(1.2); 2263 | while(status) {console.log("主线程暂停中");sleep(750);}; 2264 | console.log("挑战答题结束!返回我要答题界面!"); 2265 | if (复活) { 2266 | textContains('每局仅可复活一次').waitFor(); 2267 | delay(1); 2268 | back(); 2269 | } 2270 | textContains("再来一局").waitFor(); 2271 | delay(1); 2272 | back(); 2273 | delay(2); 2274 | break; 2275 | } else { 2276 | if (复活 && conNum < qCount) { 2277 | 复活 = false; 2278 | textContains('分享就能复活').findOne().click(); 2279 | delay(0.5); 2280 | back(); 2281 | delay(1); 2282 | } else { 2283 | if (复活) { 2284 | textContains('每局仅可复活一次').waitFor(); 2285 | delay(1); 2286 | back(); 2287 | } 2288 | console.log("等5秒开始下一轮...") 2289 | delay(3); //等待3秒才能开始下一轮 2290 | text("再来一局").click(); 2291 | delay(4); 2292 | conNum = 0; 2293 | 复活 = true; 2294 | } 2295 | } 2296 | } else //答对了 2297 | { 2298 | conNum++; 2299 | } 2300 | } 2301 | delay(1); 2302 | if (desc("我的信息").exists()) { 2303 | text("我要答题").findOne().parent().click(); 2304 | delay(2); 2305 | } 2306 | } 2307 | //挑战答题 2308 | ////////////////////////////////////////////////////////////////// 2309 | 2310 | // var xn = 0; 2311 | // var 音字 = false; 2312 | /* 2313 | 获取ocr识别出来的题目,depth_option对应32,question1对应question 2314 | */ 2315 | function do_contest_answer(depth_option, question1) { 2316 | // console.time('搜题'); 2317 | question1 = question1.replace(/先择词语/g, "选择词语"); 2318 | question1 = question1.replace(/'/g, ""); // 处理一些标点符号 2319 | question1 = question1.replace(/"/g, ""); 2320 | question1 = question1.replace(/“/g, ""); 2321 | question1 = question1.replace(/”/g, ""); 2322 | old_old_question = question1 2323 | old_question = JSON.parse(JSON.stringify(question1)); //处理question1的数据 2324 | question1 = question1.split('来源:')[0]; //去除来源 2325 | question1 = question1.split('来源:')[0]; //去除来源 2326 | question1 = question1.split('推荐')[0]; //去除推荐 2327 | question = question1.split('A.')[0]; 2328 | if (debug) console.info('处理后的题目:' + question); 2329 | // question = question.split('(.*)')[0]; 2330 | reg = /下列..正确的是.*/g; 2331 | reb = /选择词语的正确.*/g; 2332 | rea = /选择正确的读音.*/g; 2333 | rec = /下列不属于二十四史的是.*/g; 2334 | rex = /劳动行政部门自收到集体合同文本之日起.*/g; 2335 | var onlx; 2336 | if (reb.test(question) || rea.test(question)) { 2337 | if (debug) console.info('发现选择正确/词语类题目,直接用题库中的选项答题!'); 2338 | while (true) { 2339 | if (className('android.widget.RadioButton').depth(32).exists()) { 2340 | break; 2341 | } 2342 | if (text('继续挑战').exists()) return -1; 2343 | } 2344 | console.log('等待选项显示'); 2345 | /* do { 2346 | var xuanx = className('ListView').depth(29).findOne().bounds(); 2347 | } while (!xuanx == null); */ 2348 | className('ListView').depth(29).waitFor(); 2349 | try { 2350 | var ocr_s = true; 2351 | var img = captureScreen(); 2352 | var b = className('ListView').depth(29).findOne(3000).bounds(); 2353 | img = images.clip(img, b.left, b.top, b.right - b.left, b.bottom - b.top); 2354 | if (choose == 'a') { // 文字识别 2355 | old_question = huawei_ocr_api(img, token); 2356 | } else if (choose == 'e') { 2357 | old_question = easyedge_ocr_api(img); 2358 | } else if (choose == 'b') { 2359 | old_question = ocr_api(img); 2360 | } else if (choose == 'c') { 2361 | old_question = hamibot_ocr_api(img); 2362 | } else { 2363 | old_question = baidu_ocr_api(img, token); 2364 | } 2365 | // images.save(img, "/sdcard/选项"+xn+".png", "png", 50); 2366 | // xn++; 2367 | console.log('选项: ' + old_question); 2368 | var question = old_old_question + old_question; 2369 | if (debug) console.log('合并后:' + question); 2370 | 2371 | } catch (e) { 2372 | console.error(e); 2373 | console.info('选项获取失败'); 2374 | } 2375 | if (reb.test(old_old_question)) { 2376 | xaunxbj = old_question 2377 | xaunxbj = xaunxbj.replace(/A./g, "|"); 2378 | xaunxbj = xaunxbj.replace(/B./g, "|"); 2379 | var xaunxbjA = xaunxbj.split("|")[1]; 2380 | var xaunxbjB = xaunxbj.split("|")[2]; 2381 | if (xaunxbjA === xaunxbjB) { 2382 | console.log('AB选项一致,使用原选项'); 2383 | onlx = true; 2384 | } else { 2385 | console.log('AB选项不一致,进行乱序识别'); 2386 | onlx = false; 2387 | } 2388 | } else { 2389 | onlx = false; 2390 | } 2391 | } else { 2392 | var ocr_s = false; 2393 | } 2394 | var option = 'N'; 2395 | var answer = 'N'; 2396 | var similars = 0; 2397 | var pos = -1; 2398 | // var answers_list = ''; 2399 | /* if (rex.test(question) || rec.test(question) || reg.test(question) || rea.test(question) || reb.test(question)) { 2400 | // 音字 = true; 2401 | // first = false; 2402 | try { 2403 | old_question = old_question.replace(/4\./g, 'A.'); 2404 | var old_answers = old_question.split('A.')[1].split('C')[0]; 2405 | for (var k = 0; k < 2; k++) { 2406 | // 处理ocr的一些错别字 2407 | answers = old_answers.split('B.')[k]; 2408 | // answers = answers.match(/[\u4e00-\u9fa5]/g).join(""); //剩余汉字 2409 | answers = answers.replace(/哆峻/g, "啰唆"); 2410 | answers = answers.replace(/罗峻/g, "罗唆"); 2411 | answers = answers.replace(/暖陀/g, "蹉跎"); 2412 | answers = answers.replace(/暖跑/g, "蹉跎"); 2413 | answers = answers.replace(/跨踏/g, "踌躇"); 2414 | // answers = answers.replace(/chuo/g, "chuò"); 2415 | // answers = answers.replace(/cuotuo/g, "cuōtuó"); 2416 | // answers = answers.replace(/duo/g, "duō"); 2417 | answers = answers.replace(/蹈/g, "踌躇"); 2418 | answers = answers.replace(/调帐/g, "惆怅"); 2419 | answers = answers.replace(/任悔/g, "忏悔"); 2420 | answers = answers.replace(/仟悔/g, "忏悔"); 2421 | answers = answers.replace(/忧心../g, "忧心忡忡"); 2422 | answers = answers.replace(/美轮美./g, "美轮美奂"); 2423 | answers = answers.replace(/决穿/g, "诀窍"); 2424 | answers = answers.replace(/浙临/g, "濒临"); 2425 | answers = answers.replace(/不落../g, "不落窠臼"); 2426 | answers = answers.replace(/.目结舌/g, "膛目结舌"); 2427 | answers = answers.replace(/泉水../g, "泉水淙淙"); 2428 | answers = answers.replace(/饮.止渴/g, "饮鸠止渴"); 2429 | answers = answers.replace(/趋之若./g, "趋之若鹜"); 2430 | answers = answers.replace(/一.而就/g, "一蹴而就"); 2431 | answers = answers.replace(/刚.自用/g, "刚愎自用"); 2432 | answers = answers.replace(/风驰电./g, "风驰电掣"); 2433 | answers = answers.replace(/不.而走/g, "不胫而走"); 2434 | answers = answers.replace(/.声叹气/g, "唉声叹气"); 2435 | answers = answers.replace(/.而走险/g, "铤而走险"); 2436 | answers = answers.replace(/底护/g, "庇护"); 2437 | answers = answers.replace(/蓓./g, "蓓蕾"); 2438 | answers = answers.replace(/抵悟/g, "抵牾"); 2439 | answers = answers.replace(/情懒/g, "慵懒"); 2440 | answers = answers.replace(/差道/g, "差遣"); 2441 | answers = answers.replace(/泽炼/g, "淬炼"); 2442 | answers = answers.replace(/博奔/g, "博弈"); 2443 | answers = answers.replace(/相形见./g, "相形见绌"); 2444 | answers = answers.replace(/对.公堂/g, "对簿公堂"); 2445 | answers = answers.replace(/疼李/g, "痉挛"); 2446 | answers = answers.replace(/痉李/g, "痉挛"); 2447 | answers = answers.replace(/..人口/g, "脍炙人口"); 2448 | answers = answers.replace(/.意安为/g, "恣意妄为"); 2449 | answers = answers.replace(/凌合/g, "凑合"); 2450 | answers = answers.replace(/神抵/g, "神祗"); 2451 | answers = answers.replace(/叫苦不./g, "叫苦不迭"); 2452 | answers = answers.replace(/草.人命/g, "草菅人命"); 2453 | answers = answers.replace(/鞭./g, "鞭笞"); 2454 | answers = answers.replace(/发物/g, "发轫"); 2455 | answers = answers.replace(/..充数/g, "滥芋充数"); 2456 | answers = answers.replace(/水蒸气/g, "水蒸气 水蒸汽"); 2457 | answers = answers.replace(/..置疑/g, "毋庸置疑"); 2458 | answers = answers.replace(/..不振/g, "萎靡不振"); 2459 | answers = answers.replace(/瓜熟.落/g, "瓜熟蒂落"); 2460 | answers = answers.replace(/虎视../g, "虎视眈眈"); 2461 | answers = answers.replace(/进裂/g, "崩裂"); 2462 | answers = answers.replace(/立华/g, "立竿"); 2463 | // try{ 2464 | // answers = r.replace(answers); 2465 | // }catch(e){} 2466 | answers_list += answers; 2467 | } 2468 | } catch (e) { 2469 | while (!className('android.widget.RadioButton').depth(32).exists()) { 2470 | if (text('继续挑战').exists()) return -1; 2471 | // if (className('android.widget.Image').depth(23).waitFor()) return -1; 2472 | // 答题结束了 2473 | } 2474 | return -2; 2475 | }; 2476 | } 2477 | // console.log('answers_list:' + answers_list) 2478 | if (音字) question = answers_list; */ 2479 | // question_list:题库 2480 | // console.log('similarity_question:' + question); 2481 | // if (question == null) question = old_question 2482 | /* if (question.length < 3) { 2483 | // 如果处理过的题目长度小于未处理过的题题目的一半,则使用未被处理过的题目 2484 | if (debug) console.error('处理后的题目存在异常!!!'); 2485 | var question = old_old_question; 2486 | if (debug) console.log('使用old_old_question!\n' + old_old_question); 2487 | } */ 2488 | for (var i = 0; i < question_list.length; i++) { 2489 | // 搜题, 2490 | // question answer q flag 2491 | // 丢进去跟题库比较相似 2492 | var s = similarity(question_list[i][0], question_list[i][2], question, false); 2493 | if (s > similars) { 2494 | // 如果相似度大于0(题库中找到了) 2495 | similars = s; 2496 | pos = i; 2497 | } 2498 | if (s == 999) { 2499 | console.error('异常:s等于999'); 2500 | break; 2501 | } 2502 | } 2503 | if (pos != -1) { 2504 | // 题库中匹配到题目 2505 | option = question_list[pos][1]; 2506 | answer = question_list[pos][2]; 2507 | } else { 2508 | console.error('没搜到答案,题目异常:\n“' + old_question + '”,已保存到pos_Wronganswer.txt 长度:' + question_list.length); 2509 | if (debug) console.log('详细日志:\n' + '\n question: \n' + question + '\n ') 2510 | files.append('/sdcard/pos_Wronganswer.txt', "\n" + old_question); 2511 | console.info('此题pos = ' + pos + ',s=' + s + ' 等待' + pos_sleep + '秒再答'); 2512 | sleep(pos_sleep * 1000); 2513 | } 2514 | if (option[0] >= 'A' && option[0] <= 'D') { 2515 | var ans = answer.split(' ')[option[0].charCodeAt(0) - 65]; 2516 | console.info('答案:' + ans); 2517 | var last = option; 2518 | // if (乱序 == 'a' && !first && !音字 && !onlx) { 2519 | if (!ocr_s) { 2520 | while (true) { 2521 | if (className('android.widget.RadioButton').depth(32).exists()) { 2522 | break; 2523 | } 2524 | if (text('继续挑战').exists()) return -1; 2525 | } 2526 | console.log('等待选项显示'); 2527 | // do { 2528 | // var xuanx = className('ListView').depth(29).findOne(3000).bounds(); 2529 | // } while (!xuanx == null); 2530 | className('ListView').depth(29).waitFor(); 2531 | try { 2532 | var img = captureScreen(); 2533 | var b = className('ListView').depth(29).findOne(3000).bounds(); 2534 | img = images.clip(img, b.left, b.top, b.right - b.left, b.bottom - b.top); 2535 | if (choose == 'a') { // 文字识别 2536 | old_question = huawei_ocr_api(img, token); 2537 | } else if (choose == 'e') { 2538 | old_question = easyedge_ocr_api(img); 2539 | } else if (choose == 'b') { 2540 | old_question = ocr_api(img); 2541 | } else if (choose == 'c') { 2542 | old_question = hamibot_ocr_api(img); 2543 | } else { 2544 | old_question = baidu_ocr_api(img, token); 2545 | } 2546 | // images.save(img, "/sdcard/选项"+xn+".png", "png", 50); 2547 | // xn++; 2548 | // console.log('选项:' + old_question); 2549 | } catch (e) { 2550 | console.error(e); 2551 | console.info('选项获取失败'); 2552 | } 2553 | } 2554 | // if (乱序 == 'a' && !onlx) { 2555 | if (!onlx) { 2556 | try { 2557 | // console.log('选项:' + old_question); 2558 | option = click_by_answer(ans, old_question); 2559 | if (!option) option = last; 2560 | } catch (e) { 2561 | console.error("此题选项异常!!!") 2562 | } 2563 | console.info('点击选项:' + option + ' 原选项:' + last); 2564 | } else { 2565 | console.info('点击选项:' + option); 2566 | } 2567 | if (text('继续挑战').exists()) return -1; 2568 | while (!className("ListView").exists()) { 2569 | // className('android.widget.RadioButton').findOnce(answer[0].charCodeAt(0) - 65).click(); 2570 | if (text('继续挑战').exists()) return -1; 2571 | } 2572 | if (text('继续挑战').exists()) return -1; 2573 | // if (!first && !音字) { 2574 | // sleep(延迟时间); 2575 | // } 2576 | sleep(延迟时间); 2577 | // first = false; 2578 | onlx = false; 2579 | try { 2580 | while (!className("ListView").findOne(5000).child(option[0].charCodeAt(0) - 65).child(0).click()) { 2581 | if (text('继续挑战').exists()) return -1; 2582 | } 2583 | } catch (e) { 2584 | while (!className('android.widget.RadioButton').depth(depth_option).exists()) { 2585 | if (text('继续挑战').exists()) return -1; 2586 | } 2587 | try { 2588 | className('android.widget.RadioButton').depth(depth_option).findOnce(option[0].charCodeAt(0) - 65) 2589 | .click(); 2590 | } catch (e) { 2591 | console.error('没找到选项,选A跳过'); 2592 | className('android.widget.RadioButton').depth(depth_option).findOnce(0).click(); 2593 | } 2594 | } 2595 | return 0; 2596 | } 2597 | try { 2598 | className('android.widget.RadioButton').depth(depth_option).findOnce(0).click(); 2599 | } catch (e) { 2600 | while (!className("ListView").findOne(5000).child(0).child(0).click()) { 2601 | if (text('继续挑战').exists()) return -1; 2602 | } 2603 | } 2604 | return 0; 2605 | } 2606 | var o = ['A.', 'B.', 'C.', 'D.', 'AAAA']; 2607 | var o1 = ['A', 'B', 'C', 'D', 'AAAA']; 2608 | 2609 | function click_by_answer(ans, question) { 2610 | ans = ans.match(/[\u4e00-\u9fa5a-zA-Z0-9āáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜü]/g).join("") 2611 | question = question.replace(/ /g, ''); 2612 | question = question.replace(/4\./g, 'A.'); 2613 | question = question.replace(/:/g, ':'); 2614 | // try { 2615 | // question = r.replace(question); 2616 | // } catch (e) {} 2617 | // question = question.split('A.'); 2618 | question = question.replace(/c\./g, "C."); 2619 | question = question.replace(/,/g, "."); 2620 | console.log('选项:' + old_question); 2621 | var sum = 0; 2622 | for (var i = 0; i < question.length; i++) { 2623 | if (question[i] >= 'A' && question[i] <= 'D') { 2624 | sum++; 2625 | } 2626 | } 2627 | var op = []; 2628 | if (sum <= 4) { 2629 | question = question.replace(/\./g, ""); 2630 | for (var i = 0; i < 4; i++) { 2631 | try { 2632 | var tmp = question.split(o1[i])[1].split(o1[i + 1])[0].split('推荐:')[0].split('出题')[0]; 2633 | op.push(tmp.match(/[\u4e00-\u9fa5a-zA-Z0-9āáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜü]/g).join("")); 2634 | } catch (e) { 2635 | op.push('&'); 2636 | } 2637 | } 2638 | } else { 2639 | for (var i = 0; i < 4; i++) { 2640 | try { 2641 | var tmp = question.split(o[i])[1].split(o[i + 1])[0].split('推荐:')[0].split('出题')[0]; 2642 | op.push(tmp.match(/[\u4e00-\u9fa5a-zA-Z0-9āáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜü]/g).join("")); 2643 | } catch (e) { 2644 | op.push('&'); 2645 | } 2646 | } 2647 | } 2648 | // op[op.length-1] = op[op.length-1].split('推荐')[0].split('出题')[0]; 2649 | var s = 0; 2650 | var pos = -1; 2651 | for (var i = 0; i < op.length; i++) { 2652 | if (op[i] == '&') continue; 2653 | if (op[i] == ans) { 2654 | return o1[i]; 2655 | } 2656 | var tmp = similarity_answer(op[i], ans); 2657 | if (tmp > s) { 2658 | s = tmp; 2659 | pos = i; 2660 | } 2661 | } 2662 | return o1[pos]; 2663 | } 2664 | 2665 | function similarity_answer(op, ans) { 2666 | var num = 0; 2667 | for (var i = 0; i < ans.length; i++) { 2668 | if (op.indexOf(ans[i]) != -1) num++; 2669 | } 2670 | for (var i = 0; i < ans.length - 1; i++) { 2671 | if (op.indexOf(ans[i] + ans[i + 1]) != -1) num++; 2672 | } 2673 | for (var i = 0; i < ans.length - 2; i++) { 2674 | if (op.indexOf(ans[i] + ans[i + 1] + ans[i + 2]) != -1) num++; 2675 | } 2676 | return num / (2 * op.length + 2 * ans.length); 2677 | } 2678 | 2679 | // question_list[i][0], question_list[i][2], question, 音字 2680 | function similarity(question, answer, q, flag) { 2681 | var num = 0; 2682 | if (flag) { 2683 | if (q.indexOf('十五日') != -1 && question.indexOf('劳动行政部门自收到集体合同文本之日起') != -1 && answer.split('\t')[0].indexOf( 2684 | '十日') != -1) { 2685 | return 999; 2686 | } 2687 | if (q.indexOf('十五日') == -1 && q.indexOf('十日') != -1 && question.indexOf('劳动行政部门自收到集体合同文本之日起') != -1 && answer 2688 | .split('\t')[0].indexOf('五日') != -1) { 2689 | return 999; 2690 | } 2691 | if (question.indexOf('正确') == -1 && question.indexOf('下列不属于二十四史的') == -1) { 2692 | return 0; 2693 | } 2694 | for (var i = 0; i < q.length; i++) { 2695 | if (answer.indexOf(q[i]) != -1) { 2696 | num++; 2697 | } 2698 | } 2699 | return num / (answer.length + q.length); 2700 | } else { 2701 | var tmp = 1; 2702 | if (q.length > 20) tmp = 2; 2703 | if (q.length > 40) tmp = 3; 2704 | if (q.length > 50) tmp = 4; 2705 | for (var i = 0; i < q.length - tmp; i += tmp) { 2706 | if (question.indexOf(q[i] + q[i + 1]) != -1) { 2707 | num++; 2708 | } 2709 | } 2710 | return num / (question.length + q.length); 2711 | } 2712 | } 2713 | 2714 | /* function similarity_pos(question, answer, q) { 2715 | var num = 0; 2716 | for (var i = 0; i < q.length; i++) { 2717 | if (question.indexOf(q[i]) != -1) { 2718 | num++; 2719 | } 2720 | } 2721 | return num / (question.length + q.length); 2722 | 2723 | } */ 2724 | /** 2725 | * 点击对应的去答题或去看看 2726 | * @param {image} img 传入图片 2727 | */ 2728 | function baidu_ocr_api(img, tokens) { 2729 | console.log('百度ocr文字识别中'); 2730 | var answer = ""; 2731 | var res = http.post( 2732 | 'https://aip.baidubce.com/rest/2.0/ocr/v1/general', { 2733 | headers: { 2734 | 'Content-Type': 'application/x-www-form-urlencoded' 2735 | }, 2736 | access_token: tokens, 2737 | image: images.toBase64(img), 2738 | } 2739 | ); 2740 | 2741 | var res = res.body.json(); 2742 | try { 2743 | var words_list = res.words_result; 2744 | } catch (error) { 2745 | console.error('百度ocr文字识别请求错误,可能有以下情况\n1.百度ocr欠费\n2.其他的错误'); 2746 | exit(); 2747 | } 2748 | for (var i in words_list) { 2749 | answer += words_list[i].words; 2750 | } 2751 | return answer.replace(/\s*/g, ""); 2752 | } 2753 | /** 2754 | * 点击对应的去答题或去看看 2755 | * @param {image} img 传入图片,本地。 2756 | */ 2757 | function ocr_api(img) { 2758 | console.log('第三方本地ocr文字识别中'); 2759 | try { 2760 | var answer = ""; 2761 | var results = ocr.detect(img.getBitmap(), 1); 2762 | for (var i = 0; i < results.size(); i++) { 2763 | var s = results.get(i).text; 2764 | answer += s; 2765 | // 提取图片中的文字 2766 | } 2767 | // console.info(answer.replace(/\s*/g, "")); 2768 | return answer.replace(/\s*/g, ""); 2769 | } catch (e) { 2770 | console.error(e); 2771 | console.info("第三方OCR插件安装错了位数,分为64位和32位\n卸载之前的插件,换一个位数安装"); 2772 | exit(); 2773 | } 2774 | } 2775 | 2776 | function hamibot_ocr_api() { 2777 | console.log('hamibot文字识别中'); 2778 | let list = ocr.recognize(arguments[0])['results']; // 识别文字,并得到results 2779 | let eps = 30; // 坐标误差 2780 | if (arguments.length >= 2) eps = arguments[1]; 2781 | for ( 2782 | var i = 0; i < list.length; i++ // 选择排序对上下排序,复杂度O(N²)但一般list的长度较短只需几十次运算 2783 | ) { 2784 | for (var j = i + 1; j < list.length; j++) { 2785 | if (list[i]['bounds']['bottom'] > list[j]['bounds']['bottom']) { 2786 | var tmp = list[i]; 2787 | list[i] = list[j]; 2788 | list[j] = tmp; 2789 | } 2790 | } 2791 | } 2792 | 2793 | for ( 2794 | var i = 0; i < list.length; i++ // 在上下排序完成后,进行左右排序 2795 | ) { 2796 | for (var j = i + 1; j < list.length; j++) { 2797 | // 由于上下坐标并不绝对,采用误差eps 2798 | if ( 2799 | Math.abs(list[i]['bounds']['bottom'] - list[j]['bounds']['bottom']) < 2800 | eps && 2801 | list[i]['bounds']['left'] > list[j]['bounds']['left'] 2802 | ) { 2803 | var tmp = list[i]; 2804 | list[i] = list[j]; 2805 | list[j] = tmp; 2806 | } 2807 | } 2808 | } 2809 | let res = ''; 2810 | for (var i = 0; i < list.length; i++) { 2811 | res += list[i]['text']; 2812 | } 2813 | list = null; 2814 | return res; 2815 | } 2816 | // 百度easyedge 2817 | function easyedge_ocr_api(img) { 2818 | console.log('EasyEdge OCR文字识别中'); 2819 | var img_scale = images.scale(img, 0.25, 0.25); // 将图片缩放为原来的一半 2820 | var Base64_img = images.toBase64(img_scale, 'jpeg', 50); 2821 | // var easyedge_ocr_url = hamibot.env.easyedge_ocr_url; 2822 | r = http.postJson(easyedge_ocr_url, { 2823 | action: 'ocr', 2824 | imgPath: Base64_img, 2825 | } 2826 | /* , { 2827 | headers: { 2828 | 'Content-Type': 'text/plain;charset=utf8', 2829 | 'Connection': 'Keep-Alive', 2830 | 'Accept-Encoding': 'gzip, deflate' 2831 | }, 2832 | } */ 2833 | ); 2834 | /* r = http.postJson(easyedge_ocr_url, { 2835 | action: 'ocr', 2836 | imgPath: text, 2837 | }); */ 2838 | let obj = r.body.json(); 2839 | /* 2840 | threads.start(function() { 2841 | img_scale.recycle(); 2842 | var r = null, Base64_img = null; 2843 | });*/ 2844 | return obj.result; 2845 | } 2846 | 2847 | function huawei_ocr_api(img, tokens) { 2848 | console.log('华为ocr文字识别中'); 2849 | var answer = ""; 2850 | var res = http.postJson( 2851 | 'https://' + endpoint + '/v2/' + projectId + '/ocr/web-image', { 2852 | "image": images.toBase64(img) 2853 | }, { 2854 | headers: { 2855 | "User-Agent": "API Explorer", 2856 | "X-Auth-Token": tokens, 2857 | "Content-Type": "application/json;charset=UTF-8" 2858 | } 2859 | } 2860 | ); 2861 | var res = res.body.json(); 2862 | try { 2863 | var words_list = res.result.words_block_list; 2864 | } catch (error) { 2865 | // console.info('华为ocr文字识别请求错误,可能有两种情况\n1.华为ocr欠费\n2.配置时除账号密码外,其他的出错') 2866 | toastLog(error); 2867 | exit(); 2868 | } 2869 | for (var i in words_list) { 2870 | answer += words_list[i].words; 2871 | } 2872 | // console.info(answer.replace(/\s*/g, "")); 2873 | return answer.replace(/\s*/g, ""); 2874 | } 2875 | 2876 | var download = null; 2877 | /** 2878 | * @description: 加载题库和加载替换 2879 | * @param: null 2880 | * @return: null 2881 | */ 2882 | function init() { 2883 | wht_update_tiku_competition(); 2884 | while (!wht_update_tiku_competition_end) { 2885 | sleep(1000); 2886 | }; 2887 | if (init_true) return; 2888 | 2889 | /* threads.start(function() { 2890 | try { 2891 | var x = http.get('https://gitee.com/wangwang-code/picture-bed/raw/master/replace.js').body.string(); 2892 | files.write('/sdcard/replace.js', x); 2893 | r = require('/sdcard/replace.js'); 2894 | } catch (e) {} 2895 | x = null; 2896 | }); */ 2897 | if (update_tiku_competition) { 2898 | console.info('正在加载四人/双人/挑战题库中.....'); 2899 | downloadDialog = dialogs.build({ 2900 | title: "正在加载四人/双人/挑战题库...", 2901 | progress: { 2902 | max: 100, 2903 | showMinMax: true 2904 | }, 2905 | autoDismiss: false, 2906 | cancelable: true 2907 | }).show(); 2908 | try { 2909 | startDownload(); 2910 | // delay(2); 2911 | download.join(1000 * 60); 2912 | if (!file_tmp) { 2913 | download.interrupt(); 2914 | console.error('四人/双人/挑战题库加载超时!,再次加载一次'); 2915 | startDownload(); 2916 | } 2917 | while (!file_tmp) { 2918 | toastLog('等待加载四人/双人/挑战题库!!!'); 2919 | delay(2); 2920 | } 2921 | file_tmp = null; 2922 | console.info('保存题库到手机根目录下的question.txt (路径:/sdcard/question.txt)'); 2923 | sleep(500); 2924 | tikus = tikus.split('\n'); 2925 | for (var i = 0; i < tikus.length; i++) { 2926 | var t = tikus[i].split(' '); 2927 | if (t[1] && t[0]) { 2928 | var answer = ''; 2929 | for (var j = 2; j < t.length; j++) { // 可能tiku答案有空格,但是被切割了 2930 | answer += t[j]; 2931 | } 2932 | question_list.push([t[1], t[0], answer]); 2933 | } 2934 | } 2935 | answer = null; 2936 | tikus = null; 2937 | init_true = true; 2938 | if (question_list.length < 1000) { 2939 | console.info('四人/双人/挑战题库崩了!!!,等!!!'); 2940 | exit(); 2941 | } 2942 | } catch (e) { 2943 | console.error('四人/双人/挑战题库获取失败,检查网络连接!!!'); 2944 | exit(); 2945 | } 2946 | } else if (files.exists('/sdcard/question.txt')) { 2947 | tikus = files.read('/sdcard/question.txt', encoding = "utf-8"); 2948 | tikus = tikus.split('\n'); 2949 | for (var i = 0; i < tikus.length; i++) { 2950 | var t = tikus[i].split(' '); 2951 | if (t[1] && t[0]) { 2952 | var answer = ''; 2953 | for (var j = 2; j < t.length; j++) { // 可能tiku答案有空格,但是被切割了 2954 | answer += t[j]; 2955 | } 2956 | question_list.push([t[1], t[0], answer]); 2957 | } 2958 | } 2959 | answer = null; 2960 | tikus = null; 2961 | init_true = true; 2962 | if (question_list.length < 1000) { 2963 | console.info('四人/双人/挑战题库崩了!!!,等!!!'); 2964 | exit(); 2965 | } 2966 | init_true = true; 2967 | } else if (!files.exists('/sdcard/question.txt')) { 2968 | console.error('手机根目录下未找到question.txt (路径: /sdcard/question.txt)'); 2969 | exit(); 2970 | } else { 2971 | console.error('未知错误!!!'); 2972 | exit(); 2973 | } 2974 | } 2975 | 2976 | function startDownload() { 2977 | download = threads.start(function() { 2978 | toastLog('等待加载四人/双人/挑战题库!!!'); 2979 | try { 2980 | var conn = new URL(init_url).openConnection(); 2981 | conn.connect(); 2982 | let is = conn.getInputStream(); 2983 | let count = 0; 2984 | length = 973328; 2985 | let buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024); 2986 | while (true) { 2987 | var p = Math.abs(Math.min(((count / length) * 100), 100)); 2988 | let numread = is.read(buffer); 2989 | count += numread; 2990 | if (numread < 0) { 2991 | toast("加载完成"); 2992 | console.info("加载完成"); 2993 | try { 2994 | files.write('/sdcard/question.txt', tikus, encoding = "utf-8"); 2995 | } catch (e) { 2996 | console.error('题库写入文件失败'); 2997 | sleep(3000); 2998 | } 2999 | if (!files.exists('/sdcard/question.txt')) { 3000 | console.error('题库写入未成功!'); 3001 | sleep(3000); 3002 | } 3003 | downloadDialog.dismiss(); 3004 | downloadDialog = null; 3005 | break; 3006 | } 3007 | downloadDialog.setProgress(p); 3008 | tikus += java.lang.String(buffer, "UTF-8").slice(0, numread); 3009 | } 3010 | is.close(); 3011 | file_tmp = true; 3012 | } catch (e) { 3013 | console.error(e); 3014 | console.warn('四人/双人/挑战题库加载失败'); 3015 | question_list = null; 3016 | is.close(); 3017 | tikus = null; 3018 | hamibot.exit(); 3019 | exit(); 3020 | } 3021 | }) 3022 | } 3023 | 3024 | /** 3025 | * @description: 四人赛 3026 | * @param: null 3027 | * @return: null 3028 | */ 3029 | var xxx = 1; 3030 | 3031 | function zsyAnswer() { 3032 | if (first_com_no) { 3033 | console.info('已开启首轮不答'); 3034 | sleep(random_time(delay_time)); 3035 | if (text("随机匹配").exists()) { 3036 | text("随机匹配").findOne(3000).parent().child(0).click(); 3037 | console.log("点击随机匹配"); 3038 | } else { 3039 | console.log("点击开始比赛"); 3040 | var s = text("开始比赛").findOne(5000); 3041 | if (s) { 3042 | s.click(); 3043 | } else { 3044 | console.log('没有找到开始比赛,点击随机匹配'); 3045 | text("随机匹配").findOne(3000).parent().child(0).click(); 3046 | } 3047 | } 3048 | delay(1); 3049 | if (text('知道了').exists()) { 3050 | console.warn('答题已满'); 3051 | text('知道了').findOnce().click(); 3052 | delay(2); 3053 | if (text("随机匹配").exists() || text("开始比赛").exists()) { 3054 | console.info('停止脚本'); 3055 | exit(); 3056 | } else return 0; 3057 | } 3058 | className("ListView").waitFor(); 3059 | console.info('等待比赛结束'); 3060 | while (!text('继续挑战').exists()) { 3061 | sleep(5000); 3062 | } 3063 | console.info('比赛结束'); 3064 | delay(1); 3065 | text('继续挑战').click(); 3066 | delay(3); 3067 | var j = text("开始比赛").findOne(5000); 3068 | if (j = null) { 3069 | console.error('不在竞赛页面,停止脚本'); 3070 | exit(); 3071 | } 3072 | console.info('开始正式比赛'); 3073 | } 3074 | var break100 = false; 3075 | reb = /选择词语的正确.*/g; 3076 | rea = /选择正确的读音.*/g; 3077 | var img = captureScreen(); 3078 | try { 3079 | var point = findColor(img, '#1B1F25', { 3080 | region: [0, 0, 100, 100], 3081 | threshold: 10, 3082 | }); 3083 | } catch (e) { 3084 | console.error(e); 3085 | console.info('你可能使用了模拟器并且hamibot的版本是1.3.0及以上,请使用hamibot1.1.0版本'); 3086 | exit(); 3087 | } 3088 | // init(); 3089 | if (choose == 'a') { 3090 | huawei_ocr_api(img, token); 3091 | } else if (choose == 'b') { 3092 | ocr_api(img); 3093 | } else if (choose == 'e') { 3094 | question = easyedge_ocr_api(img); 3095 | } else if (choose == 'c') { 3096 | hamibot_ocr_api(img); 3097 | } else baidu_ocr_api(img, token); 3098 | var count = 2; 3099 | console.info('改变提示框位置'); 3100 | console.setPosition(device.width / 10, -device.height / 8); 3101 | // var qn = 0 3102 | for (var i = 0; i < count; i++) { 3103 | sleep(random_time(delay_time)); 3104 | if (text("随机匹配").exists()) { 3105 | text("随机匹配").findOne(3000).parent().child(0).click(); 3106 | console.log("点击随机匹配"); 3107 | count = 1; 3108 | } else { 3109 | console.log("点击开始比赛"); 3110 | // my_click_clickable('开始比赛'); 3111 | var s = text("开始比赛").findOne(5000); 3112 | if (s) { 3113 | s.click(); 3114 | } else { 3115 | console.log('没有找到开始比赛,点击随机匹配'); 3116 | text("随机匹配").findOne(3000).parent().child(0).click(); 3117 | count = 1; 3118 | } 3119 | } 3120 | // first = true; 3121 | // 音字 = false; 3122 | delay(1); 3123 | if (text('知道了').exists()) { 3124 | console.warn('答题已满'); 3125 | text('知道了').findOnce().click(); 3126 | delay(2); 3127 | if (text("随机匹配").exists() || text("开始比赛").exists()) { 3128 | break; 3129 | } else return 0; 3130 | } 3131 | className("ListView").waitFor(); 3132 | var range = className("ListView").findOnce().parent().bounds(); 3133 | var x = range.left + 20, 3134 | dx = range.right - x - 20; 3135 | var y = range.top, 3136 | dy = device.height - 300 - y; 3137 | console.log('坐标获取完成'); 3138 | // 给颜色判断划区域 3139 | var cix = range.left + 35, 3140 | cidx = dx / 2; 3141 | var ciy = range.top, 3142 | cidy = device.height - 200 - ciy; 3143 | //if (debug) console.log(cix + "," + ciy + "," + cidx + "," + cidy); 3144 | while (!text('继续挑战').exists()) { 3145 | // if (className('android.widget.Image').depth(23).waitFor()) break; 3146 | do { 3147 | img = captureScreen(); 3148 | var point = findColor(img, '#1B1F25', { 3149 | region: [x, y, dx, dy], 3150 | threshold: 10, 3151 | }); 3152 | // console.log("等待题目显示"); 3153 | } while (!point); 3154 | console.time('答题'); 3155 | try { 3156 | range = className("ListView").findOnce().parent().bounds(); 3157 | // if (choose == 'a') img = images.inRange(img, '#000000', '#444444'); 3158 | // if (!first && !音字) 3159 | // img = images.clip(img, x, y, dx, (range.bottom - y) / 3); 3160 | // else 3161 | img = images.clip(img, x, y, dx, range.bottom - y); 3162 | } catch (e) { 3163 | img = images.clip(img, x, y, dx, dy); 3164 | } 3165 | // images.save(img, "/sdcard/题目"+xxx+".jpg", "jpg", 50); 3166 | // xxx++; 3167 | var question; 3168 | // 文字识别 3169 | if (className("android.view.View").text("100").depth(24).exists()) { 3170 | console.info('有人100了'); 3171 | break100 = true; 3172 | break; 3173 | } 3174 | if (choose == 'a') { 3175 | // if (!first && !音字) 3176 | // img = images.inRange(img, '#000000', '#444444'); 3177 | question = huawei_ocr_api(img, token); 3178 | } else if (choose == 'b') { 3179 | question = ocr_api(img); 3180 | } else if (choose == 'e') { 3181 | question = easyedge_ocr_api(img); 3182 | } else if (choose == 'c') { 3183 | // if (!first && !音字) // 第一题不变色的原因的: 3184 | // img = images.inRange(img, '#000000', '#444444'); 3185 | question = hamibot_ocr_api(img); 3186 | } else { 3187 | // if (!first && !音字) 3188 | // img = images.inRange(img, '#000000', '#444444'); 3189 | question = baidu_ocr_api(img, token); 3190 | } 3191 | question = question.slice(question.indexOf('.') + 1); 3192 | question = question.replace(/,/g, ","); 3193 | console.log('OCR识别出的题目:' + question); 3194 | if (reb.test(question) || rea.test(question) && cic) { 3195 | if (debug) console.warn('发现选择正确/词语类题目,不进行选项颜色判断'); 3196 | var stopcic = true; 3197 | } else { 3198 | var stopcic = false; 3199 | } 3200 | if (question) { 3201 | var c = do_contest_answer(32, question); 3202 | // 丢进去找答案,并且选择选项 3203 | if (c == -1) { 3204 | break; 3205 | } else if (c == -2) { 3206 | className('android.widget.RadioButton').waitFor(); 3207 | continue; 3208 | } // 如果反回-1或者-2 答题结束或者没找到选项 3209 | } else { 3210 | images.save(img, "/sdcard/截图.jpg", "jpg", 50); 3211 | console.error( 3212 | "没有识别出任何内容,为了查错已经将截图保存在根目录./截图.jpg,如果截图正常并使用的是本地ocr,那么当前你的手机可能并不适配该ocr,百度/华为ocr则检查扣费次数情况"); 3213 | console.log('截图坐标为(' + x + ',' + y + '),(' + dx + ',' + dy + ')'); 3214 | break; 3215 | } 3216 | console.timeEnd('答题'); 3217 | // 根据选项颜色判断是否答错 3218 | img.recycle(); // 回收 3219 | if (cic && !stopcic) { 3220 | do { 3221 | if (className("android.view.View").text("100").depth(24).exists()) { 3222 | console.info('有人100了'); 3223 | break100 = true; 3224 | break; 3225 | } 3226 | if (text("继续挑战").exists()) break; //如果发现答题结束就退出 3227 | if (text("我要分享").exists()) break; //如果发现答题结束就退出 3228 | var point = findColor(captureScreen(), '#555AB6', { 3229 | region: [x, y, dx, dy], 3230 | threshold: 30, 3231 | }); //防卡 3232 | if (point) break; 3233 | /* var pointok = findColor(captureScreen(), '#1ac97c', { 3234 | region: [cix, ciy, cidx, cidy], 3235 | threshold: 13, 3236 | }); 3237 | if (pointok) break; //跳出循环再进行下一步 */ 3238 | var pointokno = findColor(captureScreen(), '#f54f75', { 3239 | region: [cix, ciy, cidx, cidy], 3240 | threshold: 1, 3241 | }); 3242 | if (pointokno && !text("继续挑战").exists() && !text("我要分享").exists()) { 3243 | console.error('答案错误。坐标:(' + pointokno.x + ',' + pointokno.y + ')'); 3244 | click(pointokno.x, pointokno.y); 3245 | if (!pointokno.x == 149 && !pointokno.y == 1080) { 3246 | files.append('/sdcard/Wronganswer.txt', "\n" + question); 3247 | } 3248 | do { // 防同一题进行两次OCR和点击选项 3249 | var point = findColor(captureScreen(), '#555AB6', { 3250 | region: [x, y, dx, dy], 3251 | threshold: 10, 3252 | }); 3253 | } while (!point); 3254 | break; 3255 | } //跳出循环再进行下一步 3256 | } while (true); 3257 | } else { 3258 | do { 3259 | var point = findColor(captureScreen(), '#555AB6', { 3260 | region: [x, y, dx, dy], 3261 | threshold: 10, 3262 | }); 3263 | } while (!point); 3264 | } 3265 | /* if (pointok && cic == "true") { 3266 | console.info('答案正确'); 3267 | do { // 防同一题进行两次OCR和点击选项 3268 | var point = findColor(captureScreen(), '#555AB6', { 3269 | region: [x, y, dx, dy], 3270 | threshold: 10, 3271 | }); 3272 | } while (!point); 3273 | } */ 3274 | /* if (pointokno && cic == "true") { 3275 | console.error('答案错误'); 3276 | files.append('/sdcard/Wronganswer.txt', "\n" + question); 3277 | do { // 防同一题进行两次OCR和点击选项 3278 | var point = findColor(captureScreen(), '#555AB6', { 3279 | region: [x, y, dx, dy], 3280 | threshold: 10, 3281 | }); 3282 | } while (!point); 3283 | } */ 3284 | if (break100) { 3285 | var true100 = className("android.view.View").text("100").depth(24).findOne(500); 3286 | if (true100 == null) { 3287 | console.info('无法确定是否有人真的100!不动作'); 3288 | var break100 = false; 3289 | } else { 3290 | console.info('有人100了,不再等待下一题!'); 3291 | var break100 = false; 3292 | sleep(5000); 3293 | while (true) { 3294 | if (text("继续挑战").exists()) { 3295 | break; 3296 | } else { 3297 | sleep(500); 3298 | } 3299 | } 3300 | break; 3301 | } 3302 | } 3303 | console.log('等待下一题\n----------'); 3304 | // if (className('android.widget.Image').depth(23).waitFor()) break; 3305 | } 3306 | // 四人 3307 | if (i == 0 && count == 2) { 3308 | sleep(random_time(delay_time)); 3309 | console.log('第二轮答题开始'); 3310 | while (!click('继续挑战')); 3311 | sleep(random_time(delay_time)); 3312 | } 3313 | } 3314 | if (hamibot.env.another) 3315 | var x = hamibot.env.another * 1; 3316 | else 3317 | var x = 0; 3318 | while (x > 0) { 3319 | console.info('额外的 ' + x + ' 轮即将开始!'); 3320 | x--; 3321 | delay(2); 3322 | click('继续挑战'); 3323 | delay(3); 3324 | if (text("随机匹配").exists()) { 3325 | text("随机匹配").findOne().parent().child(0).click(); 3326 | console.log("点击随机匹配"); 3327 | } else { 3328 | console.log("点击开始比赛"); 3329 | // my_click_clickable('开始比赛'); 3330 | var s = text("开始比赛").findOne(5000); 3331 | if (s) { 3332 | s.click(); 3333 | } else { 3334 | console.log('没有找到开始比赛,点击随机匹配'); 3335 | text("随机匹配").findOne(3000).parent().child(0).click(); 3336 | } 3337 | } 3338 | delay(1); 3339 | if (text('知道了').exists()) { 3340 | console.warn('答题已满'); 3341 | text('知道了').findOnce().click(); 3342 | delay(1); 3343 | return 0; 3344 | } 3345 | while (true) { 3346 | if (text('继续挑战').exists()) break; 3347 | while (!className('android.widget.RadioButton').depth(32).exists()) { 3348 | delay(randomNum(3, 5)); 3349 | if (text('继续挑战').exists()) break; 3350 | } 3351 | delay(2); 3352 | console.warn('随机点击'); 3353 | try { 3354 | var t = className("ListView").findOne(5000).childCount(); 3355 | t = randomNum(0, t - 1); 3356 | className('android.widget.RadioButton').depth(32).findOnce(t).click(); 3357 | } catch (e) {} 3358 | if (text('继续挑战').exists()) break; 3359 | sleep(200); 3360 | } 3361 | // console.warn('额外一轮结束!'); 3362 | } 3363 | console.info('答题结束'); // 竞赛结束 3364 | while(status) {console.log("主线程暂停中");sleep(750);}; 3365 | delay(2); 3366 | back(); 3367 | delay(3); 3368 | back(); 3369 | delay(3); 3370 | if (count == 1) { 3371 | // if (text('退出').exists()) { 3372 | if (className("android.view.View").text("确定离开擂台吗?").exists()) { 3373 | delay(2); 3374 | className("android.widget.Button").text("退出").findOne().click(); 3375 | } else { 3376 | console.warn('没有找到退出,按坐标点击(可能失败)\n如果没返回,手动退出双人赛即可继续运行'); 3377 | delay(2); 3378 | // console.setPosition(device.width * 0.2, device.height * 0.5); 3379 | click(device.width * 0.2, device.height * 0.53); 3380 | } 3381 | sleep(random_time(delay_time)); 3382 | } 3383 | } 3384 | 3385 | 3386 | //运行主函数 3387 | // if (随机) { 3388 | 3389 | // } else { 3390 | // main(); 3391 | // } 3392 | 3393 | var ta = hamibot.env.alltime * 1; 3394 | if (!ta || ta <= 0) ta = 1500; 3395 | var thread = null; 3396 | 3397 | function rt() { 3398 | var num = 0; 3399 | while (true) { 3400 | num++; 3401 | console.log('设置脚本运行最长时间为:' + ta + 's'); 3402 | device.keepScreenOn(ta * 1000 + 60000); 3403 | thread = threads.start(function() { 3404 | rand_mode(); 3405 | }) 3406 | thread.join(ta * 1000); 3407 | thread.interrupt(); 3408 | console.error('脚本超时或者出错!!!,重启脚本'); 3409 | if (!(launchApp("学习强国") || launch('cn.xuexi.android'))) //启动学习强国app 3410 | {} 3411 | console.info('等待10s后继续开始'); 3412 | toast('等待10s后继续开始'); 3413 | delay(10); 3414 | back_table(); 3415 | toast(' '); 3416 | delay(1); 3417 | if (num > 3) break; 3418 | } 3419 | console.error('已经重新运行了3轮,停止脚本'); 3420 | question_list = null; 3421 | console.error('无障碍服务可能出了问题'); 3422 | exit(); 3423 | } 3424 | rt(); 3425 | 3426 | function push_score() { 3427 | console.warn('正在获取今日积分'); 3428 | var score = getScores(3); 3429 | score += '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'; 3430 | try { 3431 | url = 'https://pushplus.hxtrip.com/send?token=' + hamibot.env.Token.replace(/ /g, '') + 3432 | '&title=Study&content=' + score + '&template=html'; 3433 | http.get(url); 3434 | } catch (e) {} 3435 | try { 3436 | url = 'http://www.pushplus.plus/send?token=' + hamibot.env.Token.replace(/ /g, '') + '&title=Study&content=' + 3437 | score + '&template=html'; 3438 | http.get(url); 3439 | } catch (e) {} 3440 | } 3441 | 3442 | function re_store() { 3443 | try { 3444 | if (hamibot.env.xianzhi == true) { 3445 | console.warn('四人双人答题无限制开启'); 3446 | zsyCount = 1; 3447 | doubleCount = 1; 3448 | } 3449 | } catch (e) {}; 3450 | } 3451 | 3452 | function back_table() { 3453 | delay(1); 3454 | var num = 0; 3455 | while (!desc("工作").exists()) { //等待加载出主页 3456 | console.info("当前没有在主页,正在返回主页"); 3457 | back(); 3458 | delay(1); 3459 | num++; 3460 | if (className('Button').textContains('退出').exists()) { 3461 | var c = className('Button').textContains('退出').findOne(3000); 3462 | if (c) c.click(); 3463 | delay(1); 3464 | } 3465 | if (num > 10) { 3466 | console.error('返回超过10次,可能当前不在xxqg,正在启动app...'); 3467 | if (!(launchApp("学习强国") || launch('cn.xuexi.android'))) //启动学习强国app 3468 | {} 3469 | console.info('等待10s继续进行'); 3470 | delay(10); 3471 | num = 0; 3472 | } 3473 | } 3474 | // console.info('当前在主页,回到桌面!'); 3475 | // home(); //回到桌面 3476 | } 3477 | 3478 | function rand_mode() { 3479 | start_app(); //启动app 3480 | // 四人(); 3481 | var start = new Date().getTime(); //程序开始时间 3482 | // console.info('随机模式开始'); 3483 | getScores(0); //获取积分 3484 | re_store(); 3485 | diandian(); 3486 | var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];; 3487 | var t; 3488 | for (var i = 0; i < arr.length; i++) { 3489 | var rand = parseInt(Math.random() * arr.length); 3490 | t = arr[rand]; 3491 | arr[rand] = arr[i]; 3492 | arr[i] = t; 3493 | } 3494 | for (var i = 0; i < arr.length; i++) { 3495 | if (arr[i] == 0) { 3496 | 专项(); 3497 | } else if (arr[i] == 1) { 3498 | 每周(); 3499 | } else if (arr[i] == 2) { 3500 | 视频学习(); 3501 | } else if (arr[i] == 3) { 3502 | 订(); 3503 | } else if (arr[i] == 4) { 3504 | //} else if (true) { 3505 | 挑战(); 3506 | } else if (arr[i] == 5) { 3507 | 文章和广播(); 3508 | } else if (arr[i] == 6) { 3509 | 双人(); 3510 | } else if (arr[i] == 7) { 3511 | 每日(); 3512 | } else if (arr[i] == 8) { 3513 | 本地(); 3514 | } else if (arr[i] == 9) { 3515 | 四人(); 3516 | } 3517 | } 3518 | question_list = null; 3519 | article_list = null; 3520 | back_table(); 3521 | if (hamibot.env.Token != null && hamibot.env.Token.length > 6) { 3522 | delay(1); 3523 | push_score(); 3524 | } 3525 | end = new Date().getTime(); 3526 | console.log("运行结束,共耗时" + (parseInt(end - start)) / 1000 + "秒"); 3527 | if (whethe) { 3528 | delay(2); 3529 | device.setMusicVolume(volume); 3530 | console.info('已解除静音') 3531 | } 3532 | console.log("3s后自动关闭悬浮窗,查看日志请到hamibot内查看"); 3533 | desc("工作").click(); 3534 | delay(3); 3535 | console.hide(); 3536 | device.cancelKeepingAwake(); 3537 | hamibot.exit(); 3538 | exit(); 3539 | } 3540 | 3541 | function 专项() { 3542 | if (zhuanxiang_txt == true && zhuanxiang != 0) { 3543 | console.info('开始专项答题'); 3544 | delay(1); 3545 | if (!text("排行榜").exists()) { 3546 | console.info("进入我要答题"); 3547 | questionShow(); // 进入我要答题 3548 | delay(1); 3549 | } 3550 | zhuanxiangAnswer(); 3551 | delay(0.5); 3552 | } 3553 | } 3554 | 3555 | function 每周() { 3556 | if (meizhou_txt == true && meizhou != 0) { 3557 | console.info('开始每周答题'); 3558 | delay(1); 3559 | if (!text("排行榜").exists()) { 3560 | console.info("进入我要答题"); 3561 | questionShow(); // 进入我要答题 3562 | delay(1); 3563 | } 3564 | meizhouAnswer(); 3565 | delay(0.5); 3566 | } 3567 | } 3568 | 3569 | function 双人() { 3570 | if (doubleCount != 0 && shuangren == true) { 3571 | console.info('开始双人答题'); 3572 | delay(2); 3573 | if (!text("排行榜").exists()) { 3574 | console.info("进入我要答题"); 3575 | questionShow(); // 进入我要答题 3576 | delay(1); 3577 | } 3578 | while (!text("排行榜").exists()) { 3579 | console.info("等待我要答题界面"); 3580 | delay(1); 3581 | } 3582 | var textOrder = text("排行榜").findOnce().parent(); 3583 | while (text("排行榜").exists()) { 3584 | console.info("点击双人答题,悬浮窗位置改变"); 3585 | textOrder.child(9).click(); 3586 | delay(1); 3587 | } 3588 | zsyAnswer(); 3589 | delay(1); 3590 | console.info("双人答题结束,悬浮窗位置改变"); 3591 | console.setPosition(0, device.height / 2); 3592 | } 3593 | } 3594 | 3595 | function 四人() { 3596 | if (zsyCount != 0 && siren == true) { 3597 | // delay(2); 3598 | console.info('开始四人答题'); 3599 | delay(2); 3600 | if (!text("排行榜").exists()) { 3601 | console.info("进入我要答题"); 3602 | questionShow(); // 进入我要答题 3603 | delay(1); 3604 | } 3605 | while (!text("排行榜").exists()) { 3606 | console.info("等待我要答题界面"); 3607 | delay(1); 3608 | } 3609 | var textOrder = text("排行榜").findOnce().parent(); 3610 | while (text("排行榜").exists()) { 3611 | console.info("点击四人赛答题,悬浮窗位置改变"); 3612 | textOrder.child(8).click(); 3613 | delay(1); 3614 | } 3615 | zsyAnswer(); 3616 | delay(0.5); 3617 | console.info("四人赛答题结束,悬浮窗位置改变"); 3618 | console.setPosition(0, device.height / 2); 3619 | //delay(1); 3620 | // back(); 3621 | } 3622 | } 3623 | 3624 | function 挑战() { 3625 | //tzCount = 1; 3626 | if ((tzCount != 0 || 点点通['挑战答题']) && tiaozhan == true) { 3627 | news = false; 3628 | console.info('开始挑战答题'); 3629 | if (!text("排行榜").exists()) { 3630 | console.info("进入我要答题"); 3631 | questionShow(); // 进入我要答题 3632 | delay(1); 3633 | } 3634 | delay(1); 3635 | challengeQuestion(); //挑战答题 3636 | delay(0.5); 3637 | } 3638 | } 3639 | 3640 | function 每日() { 3641 | // dayCount = 1; 3642 | if (dayCount != 0 && meiri == true) { 3643 | console.info('开始每日答题'); 3644 | if (!text("排行榜").exists()) { 3645 | console.info("进入我要答题"); 3646 | questionShow(); // 进入我要答题 3647 | delay(1); 3648 | } 3649 | delay(1); 3650 | dailyAnswer(); // 每天答题 3651 | delay(0.5); 3652 | } 3653 | } 3654 | 3655 | function 视频学习() { 3656 | var x = 1; 3657 | if (text("排行榜").exists()) { 3658 | delay(0.5); 3659 | back(); 3660 | delay(0.5); 3661 | back(); 3662 | delay(0.5); 3663 | } 3664 | while (!desc("工作").exists()) { //等待加载出主页 3665 | console.info("等待加载主页"); 3666 | if (text("排行榜").exists()) { 3667 | delay(0.5); 3668 | back(); 3669 | delay(0.5); 3670 | back(); 3671 | delay(0.5); 3672 | } 3673 | delay(2); 3674 | } 3675 | while ((vCount != 0 || 点点通['有效视听']) && video != 'a') { 3676 | if (点点通['有效视听']) 3677 | vCount = Math.max(点点通['有效视听'] * 6 - (6 - vCount), 点点通['有效视听'] * 6); 3678 | console.error('当前第' + x + '次看视频'); 3679 | if (video == 'b') 3680 | videoStudy_news(x); //看视频 3681 | else if (video == 'a') 3682 | video_news(x); //电视台 3683 | else new_bailing_video(x); // 新百灵 3684 | console.info("等待3秒,然后确认视频是否已满分。"); 3685 | delay(3); 3686 | getScores(2); 3687 | diandian(); 3688 | x++; 3689 | if (x > 2) { //尝试三次 3690 | console.info("尝试2次,跳过。"); 3691 | break; 3692 | } 3693 | } 3694 | } 3695 | 3696 | function 本地() { 3697 | if (myScores['本地频道'] != 1) { 3698 | // if (true) { 3699 | console.info('开始本地频道'); 3700 | if (text("排行榜").exists()) { 3701 | delay(0.5); 3702 | back(); 3703 | delay(0.5); 3704 | back(); 3705 | delay(0.5); 3706 | } 3707 | while (!desc("工作").exists()) { //等待加载出主页 3708 | console.info("等待加载主页"); 3709 | if (text("排行榜").exists()) { 3710 | delay(0.5); 3711 | back(); 3712 | delay(0.5); 3713 | back(); 3714 | delay(0.5); 3715 | } 3716 | delay(2); 3717 | } 3718 | localChannel(); //本地频道 3719 | } 3720 | } 3721 | 3722 | function 订() { 3723 | if (订阅 != 'a' && asub != 0) { 3724 | if (text("排行榜").exists()) { 3725 | delay(0.5); 3726 | back(); 3727 | delay(0.5); 3728 | back(); 3729 | delay(0.5); 3730 | } 3731 | while (!desc("工作").exists()) { //等待加载出主页 3732 | console.info("等待加载主页"); 3733 | if (text("排行榜").exists()) { 3734 | delay(0.5); 3735 | back(); 3736 | delay(0.5); 3737 | back(); 3738 | delay(0.5); 3739 | } 3740 | delay(2); 3741 | } 3742 | sub(); //订阅 3743 | } 3744 | } 3745 | 3746 | 3747 | function 文章和广播() { 3748 | if (text("排行榜").exists()) { 3749 | delay(0.5); 3750 | back(); 3751 | delay(0.5); 3752 | back(); 3753 | delay(0.5); 3754 | } 3755 | while (!desc("工作").exists()) { //等待加载出主页 3756 | console.info("等待加载主页"); 3757 | if (text("排行榜").exists()) { 3758 | delay(0.5); 3759 | back(); 3760 | delay(0.5); 3761 | back(); 3762 | delay(0.5); 3763 | } 3764 | delay(2); 3765 | } 3766 | if (rTime != 0 && articles == true) { 3767 | listenToRadio(); //听电台广播 3768 | h = device.height; //屏幕高 3769 | w = device.width; //屏幕宽 3770 | x = (w / 3) * 2; 3771 | h1 = (h / 6) * 5; 3772 | h2 = (h / 6); 3773 | delay(1); 3774 | swipe(x, h1, x, h2, 100); 3775 | } 3776 | var r_start = new Date().getTime(); //广播开始时间 3777 | var x = 0; 3778 | while ((aCount != 0 || 点点通['有效浏览']) && articles == true) { 3779 | aTime = hamibot.env.time1; 3780 | articleStudy(x); //学习文章,包含点赞、分享和评论 3781 | console.info("等待3秒,然后确认文章是否已满分。"); 3782 | delay(3); 3783 | getScores(1); 3784 | diandian(); 3785 | x++; 3786 | if (x > 2) { //尝试三次 3787 | console.info("尝试3次未满分,暂时跳过。"); 3788 | break; 3789 | } 3790 | } 3791 | if (articles == true) { 3792 | var end = new Date().getTime(); //广播结束时间 3793 | var radio_time = (parseInt((end - r_start) / 1000)); //广播已经收听的时间 3794 | radio_timing(parseInt((end - r_start) / 1000), rTime - radio_time); //广播剩余需收听时间 3795 | if (rTime != 0) { 3796 | stopRadio(); 3797 | } 3798 | } 3799 | 3800 | } 3801 | 3802 | function diandian() { 3803 | if (hamibot.env.diandian == null || hamibot.env.diandian == false) return; 3804 | while (!desc("工作").exists()) { //等待加载出主页 3805 | console.info("等待加载主页"); 3806 | delay(1); 3807 | } 3808 | text("我的").click(); 3809 | console.log('正在查看点点通分数'); 3810 | delay(1); 3811 | text("强国城").findOne().parent().click(); 3812 | delay(2); 3813 | text("点点通明细").findOne().parent().click(); 3814 | delay(2); 3815 | 点点通['挑战答题'] = 0; 3816 | 点点通['有效视听'] = 0; 3817 | 点点通['有效浏览'] = 0; 3818 | try { 3819 | textContains('+').findOne(5000).parent().parent().children().forEach(item => { 3820 | try { 3821 | let name = item.child(2).text(); 3822 | let score = item.child(3).text().match(/[0-9][0-9]*/g); 3823 | log(name + ' ' + score); 3824 | 点点通[name] *= 1; 3825 | 点点通[name] += 1; 3826 | } catch (e) {} 3827 | }); 3828 | } catch (e) {}; 3829 | 点点通['挑战答题'] *= 3; 3830 | 点点通['有效视听'] *= 6; 3831 | 点点通['有效浏览'] *= 6; 3832 | log(点点通); 3833 | 点点通['挑战答题'] = Math.max(0, 3 - Math.floor((点点通['挑战答题'] * 1) / 3)); 3834 | 点点通['有效视听'] = Math.max(0, 2 - Math.floor((1 * 点点通['有效视听']) / 6)); 3835 | 点点通['有效浏览'] = Math.max(0, 2 - Math.floor((1 * 点点通['有效浏览']) / 6)); 3836 | console.info('挑战答题:' + 点点通['挑战答题'] + '轮'); 3837 | console.info('视频学习:' + 点点通['有效视听'] + '轮'); 3838 | console.info('文章学习:' + 点点通['有效浏览'] + '轮'); 3839 | lCount = 点点通['挑战答题']; 3840 | if (lCount == 3) 3841 | lCount = 4; 3842 | back_table(); 3843 | } 3844 | -------------------------------------------------------------------------------- /json_to_question.py: -------------------------------------------------------------------------------- 1 | #-*- coding: UTF-8 -*- 2 | import json 3 | import re 4 | import time 5 | 6 | i = 0 7 | with open('.\QuestionBank.json','r',encoding='utf8')as fp: 8 | json_data = json.load(fp) 9 | for key, value in json_data.items(): 10 | cy = key.replace(" 。|","") 11 | cy_bc = cy.replace(" 。","") 12 | cy_k = cy_bc.replace(" ","") 13 | cy2 = cy_k.replace("|",",") 14 | pie = re.split(r"[\|]", key) 15 | # print(pie) 16 | if value == pie[1] : 17 | options = 'A' 18 | elif value == pie[2] : 19 | options = 'B' 20 | elif value == pie[3] : 21 | options = 'C' 22 | elif value == pie[4] : 23 | options = 'D' 24 | else: 25 | options = 'NULL' 26 | opt = list(pie[0]) 27 | topic = pie[0].replace(" ","") 28 | if "".join(opt[0]+opt[1]+opt[2]+opt[3]) == '选择词语': 29 | if len(pie) == 3: 30 | strt = options + " " + cy2 + "。" + " " + pie[1] + " " + pie[2] 31 | elif len(pie) == 4: 32 | strt = options + " " + cy2 + "。" + " " + pie[1] + " " + pie[2] + " " + pie[3] 33 | elif len(pie) == 5: 34 | strt = options + " " + cy2 + "。" + " " + pie[1] + " " + pie[2] + " " + pie[3] + " " + pie[4] 35 | print("发现选择词语类题目,选项添加到题目中!") 36 | elif "".join(opt[0]+opt[1]+opt[2]+opt[3]) == '选择正确': 37 | if len(pie) == 3: 38 | strt = options + " " + cy2 + "。" + " " + pie[1] + " " + pie[2] 39 | elif len(pie) == 4: 40 | strt = options + " " + cy2 + "。" + " " + pie[1] + " " + pie[2] + " " + pie[3] 41 | elif len(pie) == 5: 42 | strt = options + " " + cy2 + "。" + " " + pie[1] + " " + pie[2] + " " + pie[3] + " " + pie[4] 43 | print("发现选择词语类题目,选项添加到题目中!") 44 | else: 45 | if len(pie) == 3: 46 | strt = options + " " + topic + " " + pie[1] + " " + pie[2] 47 | elif len(pie) == 4: 48 | strt = options + " " + topic + " " + pie[1] + " " + pie[2] + " " + pie[3] 49 | elif len(pie) == 5: 50 | strt = options + " " + topic + " " + pie[1] + " " + pie[2] + " " + pie[3] + " " + pie[4] 51 | # strt = 'INSERT INTO "tiku" VALUES (' + "'" + pie[0]+pie[1]+'、'+pie[2] + "'" + ',' + "'" + value + "'" + ", NULL, '" + options + "', '" + time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) +"');" 52 | # if (pie[4] == ) 53 | # strt = options + " " + pie[0] + " " + pie[1] + " " 54 | f = open('.\question','a',encoding='utf8') 55 | f.write(strt + "\n") 56 | f.close() 57 | i = i + 1 58 | stri=str(i) 59 | print("已处理" +stri + "条数据") 60 | # 睿智 61 | -------------------------------------------------------------------------------- /json_to_sql.py: -------------------------------------------------------------------------------- 1 | #-*- coding: UTF-8 -*- 2 | import json 3 | import re 4 | import time 5 | 6 | with open('H:\Study_hamibot\QuestionBank.json','r',encoding='utf8')as fp: 7 | json_data = json.load(fp) 8 | for key, value in json_data.items(): 9 | pie = re.split(r"[\|]", key) 10 | # sort = {'1': } 11 | if value == pie[1] : 12 | options = 'A' 13 | elif value == pie[2] : 14 | options = 'B' 15 | elif value == pie[3] : 16 | options = 'C' 17 | elif value == pie[4] : 18 | options = 'D' 19 | else: 20 | options = 'NULL' 21 | str = 'INSERT INTO "tiku" VALUES (' + "'" + key + "'" + ',' + "'" + value + "'" + ", NULL, '" + options + "', '" + time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) +"');" 22 | # 睿智 23 | # print(str) 24 | f = open('H:\Study_hamibot\QuestionBank.sql','a',encoding='utf8') 25 | f.write('\n' + str) 26 | f.close() 27 | -------------------------------------------------------------------------------- /配置.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "name": "whether_mute", 3 | "type": "checkbox", 4 | "label": "自动静音", 5 | "help": "是否在脚本执行期间静音?(需要修改系统设置权限)" 6 | }, 7 | { 8 | "name": "QuestionBank_URL", 9 | "type": "text", 10 | "label": "自定义每日每周专项题库地址", 11 | "placeholder": "https://gh.fakev.cn/Pandaver/XXQG_TiKu_Transform/raw/main/QuestionBank.db", 12 | "help": "一定要是直链!!,留空使用默认地址" 13 | }, 14 | { 15 | "name": "init_url", 16 | "type": "text", 17 | "label": "自定义题库四人/双人/挑战", 18 | "placeholder": "https://raw.gh.fakev.cn/Pandaver/XXQG_TiKu_Transform/main/question", 19 | "help": "一定要是直链!!,留空使用默认地址" 20 | }, 21 | { 22 | "label": "订阅", 23 | "type": "select", 24 | "name": "ssub", 25 | "options": { 26 | "a": "关闭订阅", 27 | "b": "翻遍全部,直到订阅完成", 28 | "c": "只查看上新" 29 | } 30 | }, 31 | { 32 | "name": "article", 33 | "type": "checkbox", 34 | "label": "文章学习和广播收听", 35 | "help": " " 36 | }, 37 | { 38 | "label": "视频学习", 39 | "type": "select", 40 | "name": "video", 41 | "options": { 42 | "a": "不进行学习", 43 | "b": "百灵视频学习", 44 | "c": "看电视视频学习", 45 | "d": "新百灵视频学习" 46 | } 47 | }, 48 | { 49 | "name": "meiri", 50 | "type": "checkbox", 51 | "label": "每日答题", 52 | "help": " " 53 | }, 54 | { 55 | "name": "tiaozhan", 56 | "type": "checkbox", 57 | "label": "挑战答题", 58 | "help": " " 59 | }, 60 | { 61 | "name": "checkbox_01", 62 | "type": "checkbox", 63 | "label": "专项答题(建议手动答题)", 64 | "help": "不保证全部正确" 65 | }, 66 | { 67 | "name": "select", 68 | "type": "select", 69 | "label": "专项答题模式选择", 70 | "options": { 71 | "a": "不向下滑动,只答当天的题目,没有则返回", 72 | "b": "向下滑动,直到找到可答题的题目" 73 | }, 74 | "validation": "required", 75 | "help": "" 76 | }, 77 | { 78 | "name": "checkbox_02", 79 | "type": "checkbox", 80 | "label": "每周答题(建议手动答题)", 81 | "help": "不保证全部正确" 82 | }, 83 | { 84 | "name": "selectm", 85 | "type": "select", 86 | "label": "每周答题模式选择", 87 | "options": { 88 | "a": "不向下滑动,只答当天的题目,没有则返回", 89 | "b": "向下滑动,直到找到可答题的题目" 90 | }, 91 | "validation": "required", 92 | "help": "" 93 | }, 94 | { 95 | "name": "checkbox_03", 96 | "type": "checkbox", 97 | "label": "四人答题", 98 | "help": "勾选之前,需要配置以下信息" 99 | }, 100 | { 101 | "name": "shuangren", 102 | "type": "checkbox", 103 | "label": "双人答题", 104 | "help": "勾选之前,需要配置以下信息" 105 | }, 106 | { 107 | "name": "first_com_no", 108 | "type": "checkbox", 109 | "label": "首轮不答", 110 | "help": "四人/双人第一次比赛不答(第一轮容易匹配到科技)" 111 | }, 112 | { 113 | "name": "cic", 114 | "type": "select", 115 | "label": "四人/双人判断答案是否正确(beta)", 116 | "options": { 117 | "false": "不进行判断", 118 | "true": "进行判断" 119 | }, 120 | "help": "说明:判断选项颜色来确定是否正确,时间卡的很准,手机性能不行的切勿进行判断" 121 | }, 122 | { 123 | "name": "delay_s", 124 | "type": "number", 125 | "label": "四人/双人点击的延迟时间ms毫秒", 126 | "validation": "required", 127 | "help": "说明:0ms最快,越大越慢--(文字识别速度影响最大)" 128 | }, 129 | { 130 | "name": "pos_sleep", 131 | "type": "number", 132 | "label": "四人/双人发生POS延迟点击(防卡黄)", 133 | "validation": "required", 134 | "help": "说明:单位:秒,POS:题库中没搜到答案" 135 | }, 136 | { 137 | "name": "select_01", 138 | "type": "select", 139 | "label": "文字识别(OCR)类型选择", 140 | "options": { 141 | "b": "第三方OCR插件,需要安装第三方插件->推荐", 142 | "e": "EasyEdge OCR,需要安装EasyEdge ocr插件,并以下一下内容", 143 | "c": "hamibot内置OCR", 144 | "a": "华为OCR接口,需要填入以下关于华为的内容", 145 | "d": "百度OCR接口,需要填入以下关于百度的内容" 146 | }, 147 | "validation": "required", 148 | "help": "帮助:选择适合自己手机的文字识别,建议都试一遍" 149 | }, 150 | { 151 | "name": "easyedge_ocr_url", 152 | "type": "text", 153 | "label": "EasyEdge OCR地址", 154 | "placeholder": "http://127.0.0.1:34567/", 155 | "help": "需要安装EasyEdge OCR并启动,填“默认”使用默认地址" 156 | }, 157 | { 158 | "name": "AK", 159 | "type": "text", 160 | "label": "百度OCR的API Key", 161 | "help": " " 162 | }, 163 | { 164 | "name": "SK", 165 | "type": "text", 166 | "label": "百度OCR的Secret Key", 167 | "help": " " 168 | }, 169 | { 170 | "name": "endpoint", 171 | "type": "text", 172 | "label": "华为OCR的Endpoint", 173 | "help": " " 174 | }, 175 | { 176 | "name": "username", 177 | "type": "text", 178 | "label": "华为OCR刚刚新建的用户名-username", 179 | "help": " " 180 | }, 181 | { 182 | "name": "password", 183 | "type": "text", 184 | "label": "华为OCR刚刚新建的用户名密码-password", 185 | "help": " " 186 | }, 187 | { 188 | "name": "domainname", 189 | "type": "text", 190 | "label": "华为OCR的账号名-domainname", 191 | "help": " " 192 | }, 193 | { 194 | "name": "projectname", 195 | "type": "text", 196 | "label": "华为OCR的项目名-projectname", 197 | "help": " " 198 | }, 199 | { 200 | "name": "project_Id", 201 | "type": "text", 202 | "label": "华为OCR的projectId", 203 | "help": " " 204 | }, 205 | { 206 | "name": "xxxxxxx", 207 | "type": "link", 208 | "label": "------------------------------------------------------------------------------------------", 209 | "help": "" 210 | }, 211 | { 212 | "name": "diandian", 213 | "type": "checkbox", 214 | "label": "点点通刷满", 215 | "help": "" 216 | }, 217 | { 218 | "name": "alltime", 219 | "type": "number", 220 | "label": "看门狗-脚本运行的最长时间,超时或错误则自动重启脚本-时间s秒", 221 | "validation": "required", 222 | "placeholder": "2000", 223 | "help": "部分手机可能出现不可控错误,一般重启脚本解决,故设置看门狗" 224 | }, 225 | { 226 | "name": "time1", 227 | "type": "number", 228 | "label": "文章学习时间自定义---每篇文章的秒数", 229 | "validation": "required", 230 | "placeholder": "61", 231 | "help": " " 232 | }, 233 | { 234 | "name": "time2", 235 | "type": "number", 236 | "label": "视频学习时间自定义---每个视频的秒数", 237 | "validation": "required", 238 | "placeholder": "6", 239 | "help": " " 240 | }, 241 | { 242 | "name": "xianzhi", 243 | "type": "checkbox", 244 | "label": "四人/双人不受积分限制开关", 245 | "help": "说明:勾选后再一次运行脚本,四人/双人会再答题一次" 246 | }, 247 | { 248 | "name": "another", 249 | "type": "number", 250 | "label": "四人/双人额外的随机答题次数(乱答)", 251 | "help": "" 252 | }, 253 | { 254 | "name": "stronger", 255 | "type": "select", 256 | "label": "每日、每周、专项答题增强模式", 257 | "options": { 258 | "a": "关闭", 259 | "b": "使用华为OCR识别答案", 260 | "c": "使用百度OCR识别答案" 261 | }, 262 | "validation": "required", 263 | "help": "" 264 | }, 265 | { 266 | "name": "Token", 267 | "type": "text", 268 | "label": "push+ 消息推送", 269 | "help": "注:有需要的自行填写push+的Token,否则留空即可" 270 | }, 271 | { 272 | "name": "debug_ck", 273 | "type": "checkbox", 274 | "label": "详细日志", 275 | "help": "会输出更多的日志(四人双人)" 276 | } 277 | ] 278 | -------------------------------------------------------------------------------- /食用教程.md: -------------------------------------------------------------------------------- 1 | ## 食用教程 2 | 3 | **假设你已注册hamibot** 4 | 5 | ### 第一步下载[Study.js](https://github.com/wangwang-code/Study_hamibot/raw/main/Study.js)并保存到你能找到的地方 6 | 7 | ### 第二步打开[配置.json](https://raw.githubusercontent.com/wangwang-code/Study_hamibot/main/%E9%85%8D%E7%BD%AE.json) Ctrl+A全选复制 8 | 9 | ### 第三步打开[脚本控制台](https://hamibot.com/dashboard/scripts/console) 10 | 11 | ### 第四步创建脚本 12 | ![1649161407725](https://user-images.githubusercontent.com/64469117/161752755-372d07f4-3b95-4987-9f09-b03241b37360.png) 13 | 名字随意 14 | 15 | 然后创建 16 | ![image](https://user-images.githubusercontent.com/64469117/161752948-0e5c3d9c-3e29-441c-b6e9-d78e42672cc4.png) 17 | ### 第五部步点击![image](https://user-images.githubusercontent.com/64469117/161753157-d3c92687-efee-4837-afac-51076b6288cb.png) 18 | 切换到配置模式![image](https://user-images.githubusercontent.com/64469117/161753255-44c199e3-e6a0-4d92-a0e8-e31ed17ddf7c.png) 19 | 20 | 删除[],粘贴刚复制的配置.json中的内容 21 | 保存并返回 22 | 23 | ### 第五步上传脚本 24 | ![image](https://user-images.githubusercontent.com/64469117/161753558-e5d34c93-43ab-4084-8222-c96337921a71.png) 25 | ### 第六步配置脚本 26 | 27 | 按需即可 28 | 29 | 自定义每日每周专项题库地址:https://cdn.jsdelivr.net/gh/wangwang-code/1@main/QuestionBank.db 30 | 31 | 自定义题库四人/双人/挑战:https://cdn.jsdelivr.net/gh/wangwang-code/Study_hamibot@main/question 32 | --------------------------------------------------------------------------------