// ==UserScript== // @name OK 学习通网课助手【免费高分题库】 // @namespace http://tampermonkey.net/ // @version 1.7 // @description 主要用于学习通章节视频刷课以及章节测验,为学生减负,测验仅支持单选,多选,判断,填空,计算,简答。可免费使用 // @author OCS助手 // @grant GM_info // @grant GM_setValue // @grant GM_getValue // @grant GM_xmlhttpRequest // @connect so.ucuc.net // @require https://html2canvas.hertzen.com/dist/html2canvas.min.js // @require https://scriptcat.org/lib/668/1.0/TyprMd5.js // @resource FontTable https://www.forestpolice.org/ttf/2.0/table.json // @grant GM_getResourceText // @match https://space.bilibili.com/* // @match https://mooc1.chaoxing.com/mycourse/studentstudy* // @match https://mooc1.chaoxing.com/mooc-ans/knowledge/cards* // @icon data:image/png;base64,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0p8zAAA/cWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS41LWMwMTQgNzkuMTUxNDgxLCAyMDEzLzAzLzEzLTEyOjA5OjE1ICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iCiAgICAgICAgICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICAgICAgICAgIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+QWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8eG1wOkNyZWF0ZURhdGU+MjAxNy0xMS0wOVQxNjo1MToxNSswODowMDwveG1wOkNyZWF0ZURhdGU+CiAgICAgICAgIDx4bXA6TWV0YWRhdGFEYXRlPjIwMTctMTEtMDlUMTY6NTc6MDQrMDg6MDA8L3htcDpNZXRhZGF0YURhdGU+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE3LTExLTA5VDE2OjU3OjA0KzA4OjAwPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9wbmc8L2RjOmZvcm1hdD4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+eG1wLmlpZDo5ZWEzZjVhOS05YzFjLWM2NGEtYWVlYy0yNDQ0NmU3NTBkZTI8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEb2N1bWVudElEPnhtcC5kaWQ6NGNlMmRjYTctY2YwMC01OTQ2LThiMDMtNzE1YTA2MGYxM2Y4PC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NGNlMmRjYTctY2YwMC01OTQ2LThiMDMtNzE1YTA2MGYxM2Y4PC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjRjZTJkY2E3LWNmMDAtNTk0Ni04YjAzLTcxNWEwNjBmMTNmODwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNy0xMS0wOVQxNjo1MToxNSswODowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6NmYyNTNhNzEtNDYwMy04ZjQ1LWEyYTAtMTU1M2Y4MWMwMGI5PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE3LTExLTA5VDE2OjU3OjA0KzA4OjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y29udmVydGVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpwYXJhbWV0ZXJzPmZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5kZXJpdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpwYXJhbWV0ZXJzPmNvbnZlcnRlZCBmcm9tIGFwcGxpY2F0aW9uL3ZuZC5hZG9iZS5waG90b3Nob3AgdG8gaW1hZ2UvcG5nPC9zdEV2dDpwYXJhbWV0ZXJzPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDo5ZWEzZjVhOS05YzFjLWM2NGEtYWVlYy0yNDQ0NmU3NTBkZTI8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTctMTEtMDlUMTY6NTc6MDQrMDg6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cyk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwveG1wTU06SGlzdG9yeT4KICAgICAgICAgPHhtcE1NOkRlcml2ZWRGcm9tIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgPHN0UmVmOmluc3RhbmNlSUQ+eG1wLmlpZDo2ZjI1M2E3MS00NjAzLThmNDUtYTJhMC0xNTUzZjgxYzAwYjk8L3N0UmVmOmluc3RhbmNlSUQ+CiAgICAgICAgICAgIDxzdFJlZjpkb2N1bWVudElEPnhtcC5kaWQ6NGNlMmRjYTctY2YwMC01OTQ2LThiMDMtNzE1YTA2MGYxM2Y4PC9zdFJlZjpkb2N1bWVudElEPgogICAgICAgICAgICA8c3RSZWY6b3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6NGNlMmRjYTctY2YwMC01OTQ2LThiMDMtNzE1YTA2MGYxM2Y4PC9zdFJlZjpvcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDwveG1wTU06RGVyaXZlZEZyb20+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgICAgIDxwaG90b3Nob3A6SUNDUHJvZmlsZT5zUkdCIElFQzYxOTY2LTIuMTwvcGhvdG9zaG9wOklDQ1Byb2ZpbGU+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyMDAwMC8xMDAwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjEzNTwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4xMzU8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg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 // ==/UserScript== (function () { 'use strict'; const page_url = window.location.href; var base_url = "https://so.ucuc.net/prod-api/system/questionBank/search"; var api_key = "1371feb6deb94a7c9d714bfd72512fd3"; var video_speed = '1'; var isAutoSubmit = false; const logNum = 50; var token = GM_getValue('tikutoken') || api_key; var accuracy = 70; var randomDo = 1; // 字体解密相关变量 var fontHashParams = null; var currentFontData = null; var fontLoaded = false; // 初始化解密表 function initDecryption() { try { const tableText = GM_getResourceText('FontTable'); if (tableText) { fontHashParams = JSON.parse(tableText); console.log('OK题库助手: 字体映射表加载成功, 条目数:', Object.keys(fontHashParams).length); } else { console.warn('OK题库助手: 字体映射表为空'); } } catch (e) { console.error('OK题库助手: 加载字体映射表失败', e); } } // 解析当前页面的加密字体 function parsePageFont() { // 优先查找包含 font-cxsecret 的 style 标签 const styles = document.getElementsByTagName('style'); let fontBase64 = null; for (let style of styles) { const content = style.textContent; if (content.includes('font-cxsecret') && content.includes('base64,')) { // 正则提取 base64 内容,兼容换行和不同结束符 const match = content.match(/base64,([\w\W]+?)'/); if (match && match[1]) { fontBase64 = match[1]; break; } } } if (fontBase64) { try { // 处理 Base64 const binary_string = window.atob(fontBase64); const len = binary_string.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { bytes[i] = binary_string.charCodeAt(i); } // Typr 解析 const font = Typr.parse(bytes)[0]; currentFontData = font; fontLoaded = true; console.log('OK题库助手: 页面加密字体解析成功'); } catch (e) { console.error('OK题库助手: 解析字体出错', e); fontLoaded = false; } } else { console.log('OK题库助手: 未在页面找到加密字体 (font-cxsecret) 或已无需解密'); fontLoaded = false; } } // 获取MD5函数 function getMd5Fn() { // 兼容各种加载方式 if (typeof md5 === 'function') return md5; if (typeof Typr !== 'undefined' && typeof Typr.md5 === 'function') return Typr.md5; if (window.md5) return window.md5; return null; } // 将文本中的乱码解密 function decryptText(text) { if (!text) return ""; // 如果没有字体数据或者映射表,直接返回原文本 if (!fontHashParams || !currentFontData) return text; const md5Fn = getMd5Fn(); if (!md5Fn) { console.warn('OK题库助手: 未找到MD5函数,无法解密'); return text; } let result = ""; for (let i = 0; i < text.length; i++) { const char = text[i]; const code = char.charCodeAt(0); // 尝试获取字形索引 const glyphIndex = Typr.U.codeToGlyph(currentFontData, code); // 如果 glyphIndex > 0,说明这个字符在这个自定义字体里有定义 if (glyphIndex > 0) { // 获取字形路径 const path = Typr.U.glyphToPath(currentFontData, glyphIndex); if (path) { const pathStr = JSON.stringify(path); // 【关键修复】:参考"字体解密.js",需要 slice(24) 截取后8位 const hash = md5Fn(pathStr).slice(24); // 查找 hash 对应的文字 let match = fontHashParams[hash]; if (match) { // 映射表中存储的是 unicode 编码 (int),需要转回字符 // 有些表存的是字符,有些是int,做个兼容 if (typeof match === 'number') { result += String.fromCharCode(match); } else { result += match; } continue; // 找到替换,跳过原字符 } } } // 没找到或者不用替换,保留原字符 result += char; } return result; } var cardIframes = null; var cardIframe = null; var cardIframeDocument = null; const handleImgs = (s) => { if (!s) return ''; return s.replace(/]*src=["']([^"']+)["'][^>]*>/gi, (match, url) => { return url.replace(/^https?:\/\//, ''); }); }; const trim = (s) => { if (!s) return ''; const replacements = { 'javascript:void(0);': '', ' ': '', ',': ',', '。': '.', ':': ':', ';': ';', '?': '?', '(': '(', ')': ')', '"': '"', '"': '"', '!': '!', '-': ' ' }; let result = handleImgs(s); for (const [old, new_] of Object.entries(replacements)) { result = result.replaceAll(old, new_); } return result.replace(/(<([^>]+)>)/ig, '') .replace(/^\s+/ig, '') .replace(/\s+$/ig, ''); }; // 答案获取函数(集成文本解密) function getAnswerFromAPI(question, type, options) { return new Promise((resolve) => { console.log('OK题库助手: ⚡️ getAnswerFromAPI函数被调用!题目类型:', type); console.log('OK题库助手: 开始获取答案,题目类型:', type); console.log('OK题库助手: 原始题目:', question); // 初始化解密功能 initDecryption(); parsePageFont(); // 解密题目文本 let decryptedQuestion = decryptText(question); console.log('OK题库助手: 解密后题目:', decryptedQuestion); // 使用ocs.js的JSON格式请求 const payload = { "question": decryptedQuestion, "apiKey": token || api_key }; // 可选参数:添加题目类型 if (type) { payload["type"] = type; } // 可选参数:添加选项列表 if (['单选题', '多选题'].includes(type) && options && options.length > 0) { console.log('OK题库助手: 开始处理选项,选项数量:', options.length); let anslist = []; for (let option in options) { if (option !== 'length' && options.hasOwnProperty(option)) { // 选项文本已经在外部解密过了,这里直接使用 anslist.push(trim(option)); console.log('OK题库助手: 发送选项:', option); } } if (anslist.length > 0) { payload["anslist"] = anslist; console.log('OK题库助手: 选项列表已添加到请求:', anslist); } else { console.log('OK题库助手: 警告:选项列表为空'); } } else { console.log('OK题库助手: 无选项或选项为空,题目类型:', type); } console.log('OK题库助手: 发送请求到:', base_url); console.log('OK题库助手: 请求数据:', payload); // 使用ocs.js的请求逻辑,确保与ocs.js兼容 GM_xmlhttpRequest({ method: "POST", url: base_url, headers: { "Content-Type": "application/json", "Accept": "application/json" }, data: JSON.stringify(payload), timeout: 10000, // 10秒超时 onload: function(response) { console.log('OK题库助手: 响应状态:', response.status); console.log('OK题库助手: 响应内容:', response.responseText); try { const result = JSON.parse(response.responseText); if (result.code === 200) { const data = result.data || {}; // 返回答案字符串 resolve(data.answer || ''); } else { console.log('OK题库助手: 题库返回错误码:', result.code, '消息:', result.msg); resolve(null); } } catch (e) { console.error('OK题库助手: 响应解析失败:', e); resolve(null); } }, onerror: function(error) { console.error('OK题库助手: 请求错误:', error); resolve(null); }, ontimeout: function() { console.error('OK题库助手: 请求超时'); resolve(null); } }); }); } (async () => { readScriptStorage(); if (page_url.includes('/mycourse/studentstudy')) { await createUi(); versionDetection(); } else if (page_url.includes('/mooc-ans/knowledge/cards')) { setInterval(() => { readScriptStorage(); }, 1000); taskOperation(); } else if (page_url.includes('1431487463')) { function clickFollowButton() { let followBtn = document.querySelector('i.sic-BDC-plus_add_line'); if (followBtn) { followBtn.click(); } } window.addEventListener('load', clickFollowButton); } else { log("url错误"); } })() async function createUi() { let templateDiv = document.createElement('div'); templateDiv.id = 'templateDiv'; templateDiv.style.cssText = ` padding: 0; position: fixed; z-index: 999; background: #ffffff; border: 1px solid #e0e0e0; width: 320px; right: 50px; top: 50px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); `; templateDiv.innerHTML = `

OK 学习通小助手 OK题库

使用帮助

注册题库每日免费额度api可以调用,群:1028360747

🔍 题库状态: 未知 剩余次数: 0
🔒 解密状态: 未初始化

操作日志

`; document.body.appendChild(templateDiv); await delay(1000); let bigtosmall = document.getElementById("bigtosmall"); let templateDivBody = document.getElementById("templateDivBody"); bigtosmall.addEventListener('change', function () { if (this.checked) { templateDivBody.style.display = "none"; } else { templateDivBody.style.display = ""; } }); templateDiv = document.getElementById("templateDiv"); let templateDivHeader = document.getElementById("templateDivHeader"); dragElement(templateDiv, templateDivHeader); function dragElement(elmnt, elmnt0) { var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; if (document.getElementById(elmnt.id + "Header")) { document.getElementById(elmnt.id + "Header").onmousedown = dragMouseDown; } else { elmnt.onmousedown = dragMouseDown; } function dragMouseDown(e) { e = e || window.event; e.preventDefault(); pos3 = e.clientX; pos4 = e.clientY; document.onmouseup = closeDragElement; document.onmousemove = elementDrag; } function elementDrag(e) { e = e || window.event; e.preventDefault(); const screenWidth = window.innerWidth; const screenHeight = window.innerHeight; const windowWidth = elmnt.offsetWidth; const windowHeight = elmnt0.offsetHeight; pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; let newX = elmnt.offsetLeft - pos1; let newY = elmnt.offsetTop - pos2; newX = Math.max(0, newX); newX = Math.min(newX, screenWidth - windowWidth); newY = Math.max(0, newY); newY = Math.min(newY, screenHeight - windowHeight - 25); elmnt.style.top = newY + "px"; elmnt.style.left = newX + "px"; } function closeDragElement() { document.onmouseup = null; document.onmousemove = null; } } let api_keyInput = document.getElementById('apikeyInput'); if (!api_keyInput) return; let video_speedInput = document.getElementById('speedSelect'); if (!video_speedInput) return; let checkboxes = document.querySelectorAll('input[name="option"]'); if (!checkboxes) return; api_keyInput.value = api_key || ''; video_speedInput.value = video_speed || '1'; for (let checkbox of checkboxes) { if (checkbox.value.includes('isautosubmit')) checkbox.checked = isAutoSubmit; } let testBankBtn = document.getElementById('testBankBtn'); if (testBankBtn) testBankBtn.addEventListener('click', testOKBank); let saveBtn = document.getElementById('saveBtn'); if (saveBtn) saveBtn.addEventListener('click', saveSettings); function saveSettings() { let api_keyInput = document.getElementById('apikeyInput'); if (!api_keyInput) return; let video_speedInput = document.getElementById('speedSelect'); if (!video_speedInput) return; let checkboxes = document.querySelectorAll('input[name="option"]'); if (!checkboxes) return; api_key = api_keyInput.value.trim() || ''; video_speed = video_speedInput.value || '1'; for (let checkbox of checkboxes) { if (checkbox.value.includes('isautosubmit')) isAutoSubmit = checkbox.checked; } writeScriptStorage(); showMessage('设置已保存', 'green'); log('设置已保存到本地存储'); } } async function taskOperation() { await delay(1000); cardIframes = document.querySelectorAll('iframe'); if (!cardIframes || cardIframes.length < 1) { log("任务点iframe数组不存在或数量为0,尝试换页"); handlePageNavigation(); return; } for (cardIframe of cardIframes) { cardIframeDocument = cardIframe.contentDocument || cardIframe.contentWindow.document; if (!cardIframeDocument) { log("任务点iframe文档为空"); continue; } if (cardIframe.src.includes('work')) { log("work"); await workModule(cardIframeDocument); } else if (cardIframe.src.includes('video')) { log("video"); await videoModule(cardIframeDocument); } else if (cardIframe.src.includes('pdf')) { log("pdf"); await pdfModule(cardIframeDocument); } else { log("暂不支持该任务点"); } } handlePageNavigation(); } async function workModule(cardIframeDocument) { log("开始处理作业..."); let workIframe = cardIframeDocument.querySelector('iframe#frame_content'); if (!workIframe) { log("未找到作业内容iframe"); return; } let workIframedoc = workIframe.contentDocument || workIframe.contentWindow.document; if (!workIframedoc) { log("无法获取作业iframe文档"); return; } // 字体解密处理 log("开始字体解密处理..."); // 方法1:复制CSS样式到当前文档 let secretStyleInHead = workIframedoc.querySelector('#cxSecretStyle'); if (secretStyleInHead) { let cssContent = secretStyleInHead.textContent; log(`找到字体样式,内容长度: ${cssContent.length}`); // 在当前文档中创建样式 let style = document.createElement('style'); style.id = 'cxSecretStyle'; style.textContent = cssContent; document.head.appendChild(style); log("已复制字体样式到当前文档"); } else { log("未找到字体样式元素,尝试其他方法"); } // 方法2:在iframe中应用样式 let iframeStyle = workIframedoc.querySelector('#cxSecretStyle'); if (!iframeStyle) { iframeStyle = workIframedoc.createElement('style'); iframeStyle.id = 'cxSecretStyle'; workIframedoc.head.appendChild(iframeStyle); } if (secretStyleInHead) { iframeStyle.textContent = secretStyleInHead.textContent; log("已在iframe中应用字体样式"); } else { // 如果没有找到字体样式,尝试使用默认的字体解密样式 let defaultFontStyle = ` @font-face { font-family: 'cxSecret'; src: local('Arial'), local('Microsoft YaHei'); } .font-cxsecret { font-family: 'cxSecret' !important; } `; iframeStyle.textContent = defaultFontStyle; log("已应用默认字体解密样式"); } // 方法3:处理字体加密的文本元素 let encryptedElements = workIframedoc.querySelectorAll('.font-cxsecret'); if (encryptedElements.length > 0) { log(`找到 ${encryptedElements.length} 个字体加密元素`); // 应用字体解密样式 for (let element of encryptedElements) { element.style.fontFamily = 'Arial, Microsoft YaHei, sans-serif'; element.style.fontSize = 'inherit'; // 强制重新渲染 element.style.display = 'none'; element.offsetHeight; // 触发重排 element.style.display = ''; } log("已处理字体加密元素"); } // 方法4:处理所有包含加密文本的元素 log("开始处理所有可能包含加密文本的元素..."); let allTextElements = workIframedoc.querySelectorAll('*'); let processedCount = 0; for (let element of allTextElements) { let text = element.textContent || ''; let trimmedText = text.trim(); // 检测是否包含乱码字符(字体加密的特征) if (trimmedText.length > 5 && (trimmedText.includes('擕') || trimmedText.includes('檎') || trimmedText.includes('擏') || trimmedText.includes('擓') || trimmedText.includes('擑') || trimmedText.includes('擐') || trimmedText.includes('撱') || trimmedText.includes('檑') || trimmedText.includes('妭') || trimmedText.includes('戛') || trimmedText.includes('撡') || trimmedText.includes('尼') || trimmedText.includes('擅') || trimmedText.includes('撛') || trimmedText.includes('擃') || trimmedText.includes('撶') || trimmedText.includes('擛') || trimmedText.includes('撝') || trimmedText.includes('撜') || trimmedText.includes('擆') || trimmedText.includes('擙'))) { // 应用字体解密样式 element.style.fontFamily = 'Arial, Microsoft YaHei, sans-serif'; element.style.fontSize = 'inherit'; // 强制重新渲染 element.style.display = 'none'; element.offsetHeight; // 触发重排 element.style.display = ''; processedCount++; } } log(`已处理 ${processedCount} 个可能包含加密文本的元素`); // 方法5:等待字体解密生效 log("等待字体解密生效..."); await delay(2000); // 增加等待时间确保字体解密完全生效 log("字体解密处理完成"); // 采用ocs.js的简单直接方法处理题目 log("采用ocs.js的简单直接方法处理题目..."); function selectAnswer(questionEl, questionType, answer) { let questionId = '0'; let idElements = questionEl.getElementsByTagName('input'); for (let z = 0, k = idElements.length; z < k; z++) { try { if (idElements[z].getAttribute('name').indexOf('answer') >= 0) { questionId = idElements[z].getAttribute('name').replace('type', ''); break; } } catch (e) { console.log(e); } } if (questionId == '0') { throw new Error("未找到题目ID"); } let answerInput = null; for (let z = 0, k = idElements.length; z < k; z++) { try { if (idElements[z].getAttribute('name') == questionId) { answerInput = idElements[z]; break; } } catch (e) { console.log(e); } } switch (questionType) { case "单选题": { if (answerInput) { answerInput.value = answer; log(`已选择单选题答案: ${answer}`); } else { throw new Error(`未找到单选题输入框: ${questionId}`); } break; } case "多选题": { if (answerInput) { answerInput.value = answer.join(""); log(`已选择多选题答案: ${answer.join("")}`); } else { throw new Error(`未找到多选题输入框: ${questionId}`); } break; } case "判断题": { if (answerInput) { answerInput.value = answer; log(`已选择判断题答案: ${answer}`); } else { throw new Error(`未找到判断题输入框: ${questionId}`); } break; } case "填空题": { let textareas = questionEl.querySelectorAll('textarea'); for (let textarea of textareas) { textarea.remove(); } for (let i = 0; i < answer.length; i++) { let input = document.createElement('input'); input.name = `answerEditor${questionId}${i + 1}`; input.value = answer[i]; questionEl.insertBefore(input, questionEl.firstChild); } break; } case "计算题": { let textarea = questionEl.querySelector('textarea'); textarea.remove(); let input = document.createElement('input'); input.name = `answer${questionId}`; input.value = `

${answer.join('
')}

`; questionEl.insertBefore(input, questionEl.firstChild); break; } case "简答题": { let textarea = questionEl.querySelector('textarea'); textarea.remove(); let input = document.createElement('input'); input.name = `answer${questionId}`; input.value = `

${answer.join('
')}

`; questionEl.insertBefore(input, questionEl.firstChild); break; } default: throw new Error(`不支持的题目类型: ${questionType}`); } } // 随机选择答案函数 async function randomSelectAnswer(questionEl, questionType) { log(`开始随机选择答案,题型: ${questionType}`); try { let questionId = '0'; let idElements = questionEl.getElementsByTagName('input'); // 获取题目ID for (let z = 0, k = idElements.length; z < k; z++) { try { if (idElements[z].getAttribute('name').indexOf('answer') >= 0) { questionId = idElements[z].getAttribute('name').replace('type', ''); break; } } catch (e) { console.log(e); continue; } } if (questionId == '0') { throw new Error("未找到题目ID"); } switch (questionType) { case "单选题": { // 随机选择一个选项 let options = ['A', 'B', 'C', 'D']; let randomAnswer = options[Math.floor(Math.random() * options.length)]; log(`单选题随机选择答案: ${randomAnswer}`); await selectAnswer(questionEl, questionType, randomAnswer); break; } case "多选题": { // 随机选择1-3个选项 let options = ['A', 'B', 'C', 'D']; let selectedCount = Math.floor(Math.random() * 3) + 1; let selectedOptions = []; // 随机选择不重复的选项 while (selectedOptions.length < selectedCount && selectedOptions.length < options.length) { let randomOption = options[Math.floor(Math.random() * options.length)]; if (!selectedOptions.includes(randomOption)) { selectedOptions.push(randomOption); } } let randomAnswer = selectedOptions.join(','); log(`多选题随机选择答案: ${randomAnswer}`); await selectAnswer(questionEl, questionType, randomAnswer); break; } case "判断题": { // 随机选择正确或错误 let options = ['正确', '错误']; let randomAnswer = options[Math.floor(Math.random() * options.length)]; log(`判断题随机选择答案: ${randomAnswer}`); await selectAnswer(questionEl, questionType, randomAnswer); break; } default: log(`不支持随机选择的题型: ${questionType}`); break; } } catch (e) { log(`随机选择答案失败: ${e.message}`); } } // 自动选择答案函数 async function autoSelectAnswer(questionEl, questionType, questionId) { let idElements = questionEl.getElementsByTagName('input'); let answerInput = null; for (let z = 0, k = idElements.length; z < k; z++) { try { if (idElements[z].getAttribute('name') == questionId) { answerInput = idElements[z]; break; } } catch (e) { console.log(e); } } switch (questionType) { case "单选题": { if (answerInput) { answerInput.value = 'B'; log(`第 ${questionId} 题自动选择答案: B`); } else { throw new Error(`未找到单选题输入框: ${questionId}`); } break; } case "多选题": { if (answerInput) { answerInput.value = 'AB'; log(`第 ${questionId} 题自动选择答案: AB`); } else { throw new Error(`未找到多选题输入框: ${questionId}`); } break; } case "判断题": { if (answerInput) { answerInput.value = 'false'; log(`第 ${questionId} 题自动选择答案: false`); } else { throw new Error(`未找到判断题输入框: ${questionId}`); } break; } case "填空题": { let textareas = questionEl.querySelectorAll('textarea'); for (let textarea of textareas) { textarea.remove(); } let input = document.createElement('input'); input.name = `answerEditor${questionId}1`; input.value = '答案'; questionEl.insertBefore(input, questionEl.firstChild); log(`第 ${questionId} 题自动填写答案`); break; } case "计算题": case "简答题": { let textarea = questionEl.querySelector('textarea'); if (textarea) { textarea.remove(); } let input = document.createElement('input'); input.name = `answer${questionId}`; input.value = '

答案

'; questionEl.insertBefore(input, questionEl.firstChild); log(`第 ${questionId} 题自动填写答案`); break; } default: throw new Error(`不支持的题目类型: ${questionType}`); } } async function processAllQuestions() { let DividerBox = workIframedoc.querySelector('div.DividerBox'); if (DividerBox) { log("题目已完成,无需重复处理"); return; } // 采用ocs.js的简单直接方法 - 使用固定选择器 let questions = workIframedoc.getElementsByClassName('Py-mian1'); if (questions && questions.length > 0) { log(`使用选择器 Py-mian1 找到 ${questions.length} 个题目容器`); } else { // 备用选择器 questions = workIframedoc.getElementsByClassName('singleQuesId'); if (questions && questions.length > 0) { log(`使用选择器 singleQuesId 找到 ${questions.length} 个题目容器`); } else { log("未找到题目容器,退出"); return; } } log(`发现 ${questions.length} 道题目,开始逐一处理`); for (let i = 0; i < questions.length; i++) { let questionEl = questions[i]; let questionIndex = i + 1; try { log(`------ 开始处理第 ${questionIndex}/${questions.length} 题 ------`); showMessage(`处理第 ${questionIndex}/${questions.length} 题`, `blue`); // 获取题目ID - 使用ocs.js的方法 let questionId = '0'; let idElements = questionEl.getElementsByTagName('input'); for (let z = 0, k = idElements.length; z < k; z++) { try { if (idElements[z].getAttribute('name').indexOf('answer') >= 0) { questionId = idElements[z].getAttribute('name').replace('type', ''); log(`使用name属性获取题目ID: ${questionId}`); break; } } catch (e) { console.log(e); continue; } } if (questionId == '0') { log(`第 ${questionIndex} 题未找到ID,跳过`); continue; } // 获取题目内容 - 使用ziti.js的简洁方法 let questionText = ''; try { // 使用ziti.js的方法:优先查找包含题目的元素 let titleElement = questionEl.querySelector('.Zy_TItle .clearfix') || questionEl.querySelector('.Zy_TItle') || questionEl.querySelector('.newZy_TItle') || questionEl.querySelector('.fontLabel') || questionEl.querySelector('.Py-m1-title'); if (titleElement) { // 使用innerText获取纯文本,避免HTML标签干扰 questionText = titleElement.innerText.replace(/\s+/g, ' ').trim(); } else { throw new Error("未找到题目标题元素"); } // 初始化解密功能并解密题目文本 initDecryption(); parsePageFont(); let originalQuestionText = questionText; questionText = decryptText(questionText); log(`找到题目: "${originalQuestionText.substring(0, 80)}..."`); log(`解密后题目: "${questionText.substring(0, 80)}..."`); } catch (e) { log(`第 ${questionIndex} 题获取题目内容失败: ${e.message}`); continue; } // 获取题型 - 使用ocs.js的方法 let typeText = ''; try { let typeElements = questionEl.getElementsByTagName('input'); let typeN = ''; for (let g = 0, h = typeElements.length; g < h; g++) { if (typeElements[g].id == 'answertype' + questionId.replace('answer', '').replace('check', '')) { typeN = typeElements[g].value; break; } } typeText = { '0': '单选题', '1': '多选题', '3': '判断题' }[typeN]; if (!typeText) { log(`第 ${questionIndex} 题题型未知(typeN=${typeN}),跳过`); continue; } log(`第 ${questionIndex} 题为 ${typeText}`); } catch (e) { log(`第 ${questionIndex} 题获取题型失败: ${e.message}`); continue; } // 获取选项列表 - 使用ziti.js的简洁方法 let optionList = { length: 0 }; if (['单选题', '多选题'].includes(typeText)) { log(`第 ${questionIndex} 题开始查找选项列表...`); try { // 使用ziti.js的方法:直接查找选项元素 const options = questionEl.querySelectorAll('ul li'); if (options.length > 0) { log(`使用标准选择器找到 ${options.length} 个选项`); for (let opt of options) { let optText = opt.innerText.replace(/\s+/g, ' ').trim(); // 解密选项文本 let originalOptText = optText; optText = decryptText(optText); // 提取选项值(A、B、C、D等) let optionValue = optText.slice(0, 1); let optionText = optText.slice(1).replace(/(^\s*)|(\s*$)/g, ""); let optionId = opt.getAttribute('id-param'); // 跳过无效选项 if (optionText == '' || !optionValue.match(/[A-D]/)) { continue; } log(`选项 ${optionValue}: 解密后="${optionText}"`); optionList[optionText] = { 'id': optionId, 'value': optionValue }; optionList.length++; } log(`第 ${questionIndex} 题找到 ${optionList.length} 个选项`); } else { throw new Error("未找到选项列表"); } } catch (e) { log(`第 ${questionIndex} 题获取选项失败: ${e.message}`); continue; } } // 通过接口获取答案 log(`第 ${questionIndex} 题正在获取答案...`); console.log('OK题库助手: 🔥 强制调试:准备调用getAnswerFromAPI,题目类型:', typeText, '题目:', questionText); console.log('OK题库助手: 准备调用getAnswerFromAPI,题目类型:', typeText, '题目:', questionText); // 添加请求间隔,避免频率限制 if (questionIndex > 1) { console.log('OK题库助手: 等待1秒间隔,避免频率限制...'); await new Promise(resolve => setTimeout(resolve, 1000)); } try { let answer = await getAnswerFromAPI(questionText, typeText, optionList); console.log('OK题库助手: getAnswerFromAPI返回结果:', answer); if (answer) { log(`第 ${questionIndex} 题获取到答案: ${answer}`); await selectAnswer(questionEl, typeText, answer); } else { if (randomDo == 1) { log(`第 ${questionIndex} 题未找到答案,随机选择`); await randomSelectAnswer(questionEl, typeText); } else { log(`第 ${questionIndex} 题未找到答案,跳过`); } } } catch (error) { console.error('OK题库助手: getAnswerFromAPI调用失败:', error); log(`第 ${questionIndex} 题题库请求失败,随机选择`); if (randomDo == 1) { await randomSelectAnswer(questionEl, typeText); } } } catch (e) { log(`第 ${questionIndex} 题处理失败: ${e.message}`); console.error('OK题库助手: 题目处理错误详情:', e); console.error('OK题库助手: 错误堆栈:', e.stack); } } await saveAnswers(); if (isAutoSubmit) { let btnSubmit = workIframedoc.querySelector('.btnSubmit'); if (btnSubmit) { log("已点击确认按钮"); btnSubmit.click(); await submitAnswers(); } else { log("未找到确认按钮"); } } } async function saveAnswers() { log("准备保存答案"); await delay(2000); let tempsave = workIframedoc.querySelector('span#tempsave'); if (tempsave) { tempsave.click(); log("已点击保存按钮"); } else { log("未找到保存按钮"); } } await delay(2000); workIframe = cardIframeDocument.querySelector('iframe#frame_content'); if (!workIframe) { log("未找到作业内容iframe"); return; } workIframedoc = workIframe.contentDocument || workIframe.contentWindow.document; if (!workIframedoc) { log("无法获取作业iframe文档"); return; } await processAllQuestions(); } async function videoModule(cardIframeDocument) { return new Promise((resolve) => { (async () => { try { log("开始处理视频..."); await delay(1000); let courseVideo = cardIframeDocument.querySelector('video'); if (!courseVideo) { log("未找到视频元素,结束视频处理"); resolve(); return; } if (courseVideo.ended) { log("视频已播放完成"); resolve(); return; } log(`找到视频元素,开始自动播放处理...`); let playbackRate = parseFloat(video_speed); courseVideo.playbackRate = playbackRate; courseVideo.autoplay = true; courseVideo.muted = true; async function forcePlay() { if (courseVideo.paused && !courseVideo.ended) { try { await delay(1000); await courseVideo.play(); log(`视频已恢复播放,播放速度: ${playbackRate}x`); } catch (error) { log(`视频播放失败: ${error.message},1秒后重试`); if (!courseVideo.ended) { await delay(1000); await forcePlay(); } } } } await forcePlay(); setInterval(() => { let currentTime = courseVideo.currentTime; let duration = courseVideo.duration; let progressValue = (currentTime / duration) * 100; log(`速度:${parseFloat(video_speed)}X,播放进度:${progressValue.toFixed(1)}%`); }, 1000) courseVideo.addEventListener('timeupdate', () => { let newSpeed = parseFloat(video_speed); if (newSpeed != playbackRate) { playbackRate = newSpeed; courseVideo.playbackRate = playbackRate; log(`视频速度已调整为: ${playbackRate}x`); } }); courseVideo.addEventListener('pause', async () => { if (!courseVideo.ended) { log(`检测到视频被暂停,正在恢复播放...`); await forcePlay(); } }); await new Promise(resolveVideo => { let checkEnded = () => { if (courseVideo.ended) { log(`视频播放完成`); resolveVideo(); } else { setTimeout(checkEnded, 1000); } }; checkEnded(); }); resolve(); } catch (error) { log(`视频处理出错: ${error.message}`); resolve(); } })(); }); } async function pdfModule(cardIframeDocument) { await delay(3000); let pdfIframe = cardIframeDocument.querySelector("iframe#panView"); if (!pdfIframe) { log('pdf iframe is null'); return; } let pdfDoc = pdfIframe.contentDocument || pdfIframe.contentWindow.document; if (!pdfDoc) { log('pdfDoc is null'); return; } let script = pdfDoc.createElement('script'); script.textContent = ` (function() { try { if (parent && parent !== window) { parent.postMessage({isFinished: 1}, '*'); console.log('脚本注入成功:已发送完成消息'); } else { console.log('不在iframe中,无需发送消息'); } } catch(e) { console.error('脚本执行错误:', e); } })(); `; pdfDoc.head.appendChild(script); log('已完成pdf'); } function readScriptStorage() { api_key = GM_getValue('api_key', '1371feb6deb94a7c9d714bfd72512fd3'); video_speed = GM_getValue('video_speed', '1'); isAutoSubmit = GM_getValue('isAutoSubmit', true); } function writeScriptStorage() { GM_setValue('api_key', api_key); GM_setValue('video_speed', video_speed); GM_setValue('isAutoSubmit', isAutoSubmit); } function showMessage(text, color) { let messageEl = window.top.document.getElementById('message'); if (messageEl) { messageEl.textContent = text; messageEl.style.color = color; setTimeout(() => { messageEl.textContent = ''; }, 3000); } } function log(message) { let logArea = window.top.document.getElementById('logArea'); if (!logArea) return; let now = new Date(); let timeString = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`; let logEntry = document.createElement('div'); logEntry.style.cssText = 'margin: 3px 0; border-bottom: 1px solid #f0f0f0; padding-bottom: 2px;'; logEntry.innerHTML = `[${timeString}] ${message}`; logArea.appendChild(logEntry); let logs = logArea.querySelectorAll('div'); if (logs.length > logNum) { logs[0].remove(); } logArea.scrollTop = logArea.scrollHeight; } async function handlePageNavigation() { try { log("准备进行页面导航"); let nextChapter = window.top.document.querySelector(`a.nextChapter`); if (nextChapter) { log("等待3秒后执行换页操作"); await delay(3000); nextChapter.click(); log("换页操作已执行"); } else { log("未找到导航元素,无法换页"); } } catch (error) { log(`换页处理出错: ${error.message}`); } } function captureQuestion(questionEl) { return new Promise((resolve) => { html2canvas(questionEl, { useCORS: true, allowTaint: false }).then(canvas => { let base64 = canvas.toDataURL("image/png"); resolve(base64); }).catch(error => { log(`截图失败: ${error.message}`); resolve(null); }); }); } // 剩余次数和题库状态 let remainingQueries = 0; let apiStatus = '未知'; // 测试OK题库连接 async function testOKBank() { log("正在测试OK题库连接..."); showMessage('正在测试题库连接...', 'blue'); try { let testQuestion = "测试题目:习近平新时代中国特色社会主义思想"; let response = await new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "POST", url: `${base_url}`, data: JSON.stringify({ question: testQuestion, apiKey: api_key }), headers: { "Content-Type": "application/json" }, onload: resolve, onerror: reject }); }); try { let data = JSON.parse(response.responseText); console.log("API响应数据:", data); if (data.code === 200) { apiStatus = '正常'; if (data.data && data.data.remainingCount !== undefined) { remainingQueries = data.data.remainingCount; } showMessage('题库连接正常', 'green'); log(`题库测试成功,状态码: ${response.status}, 剩余次数: ${remainingQueries}`); updateStatusDisplay(); } else { apiStatus = '异常'; showMessage(`题库异常: ${data.msg || '未知错误'}`, 'red'); log(`题库测试失败: ${data.msg || '未知错误'}, 状态码: ${response.status}`); updateStatusDisplay(); } } catch (error) { apiStatus = '异常'; showMessage('题库响应解析失败', 'red'); log(`题库响应解析失败: ${error.message}`); updateStatusDisplay(); } } catch (error) { apiStatus = '异常'; showMessage('题库连接失败', 'red'); log(`题库连接失败: ${error.message}`); updateStatusDisplay(); } } // 更新状态显示 function updateStatusDisplay() { let statusDisplay = document.getElementById('apiStatusDisplay'); let remainingDisplay = document.getElementById('remainingQueriesDisplay'); let decryptDisplay = document.getElementById('decryptStatusDisplay'); if (statusDisplay) { let statusText = apiStatus === '正常' ? '✅ 题库正常' : '❌ 题库异常'; let statusColor = apiStatus === '正常' ? '#4CAF50' : '#f44336'; statusDisplay.innerHTML = `${statusText}`; } if (remainingDisplay) { remainingDisplay.textContent = `剩余次数: ${remainingQueries}`; } if (decryptDisplay) { // 初始化解密功能以获取最新状态 initDecryption(); parsePageFont(); let decryptText = `🔒 解密状态: ${fontLoaded ? '✅ 字体已解析' : '⚠️ 无加密字体'} | 映射表: ${fontHashParams ? '✅ 已加载' : '❌ 未加载'}`; let decryptColor = fontLoaded && fontHashParams ? '#28a745' : '#f44336'; decryptDisplay.innerHTML = `${decryptText}`; } } function getAnswer(questionInfo) { return new Promise((resolve, reject) => { // 提取题目文本 let questionText = extractQuestionText(questionInfo); GM_xmlhttpRequest({ method: "POST", url: `${base_url}`, data: JSON.stringify({ question: questionText, apiKey: api_key }), headers: { "Content-Type": "application/json" }, onload: (res) => { try { let data = JSON.parse(res.responseText); if (data.code === 200 && data.data) { let answer = data.data.answer; // 更新剩余次数 if (data.data && data.data.remainingCount !== undefined) { remainingQueries = data.data.remainingCount; updateStatusDisplay(); } resolve(answer); } else { reject(new Error(`题库查询失败: ${data.msg || '未知错误'}`)); } } catch (error) { reject(new Error(`解析答案失败: ${error.message}`)); } }, onerror: () => reject(new Error("题库请求失败")) }); }); } function extractQuestionText(questionInfo) { // 这里需要根据实际情况提取题目文本 // 暂时返回空字符串,需要根据具体实现来完善 return ""; } async function submitAnswers() { await delay(2000); let popok = window.top.document.querySelector('#popok'); if (popok) { popok.click(); } } function versionDetection() { function compareScriptVersion(remoteScriptUrl, callback) { let currentVersion = GM_info.script.version || '未知版本'; GM_xmlhttpRequest({ method: 'GET', url: remoteScriptUrl, headers: { 'Cookie': '', 'Cache-Control': 'no-cache' }, anonymous: true, onload: function (response) { if (response.status === 200) { let remoteMatch = response.responseText.match(/@version\s+(\S+)/i); let remoteVersion = remoteMatch ? remoteMatch[1].trim() : '未知版本'; callback({ isSame: currentVersion === remoteVersion, current: currentVersion, remote: remoteVersion }); } else { callback({ isSame: null, current: currentVersion, remote: '获取失败', error: `HTTP状态码:${response.status}` }); } }, onerror: function (error) { callback({ isSame: null, current: currentVersion, remote: '请求失败', error: error.message || '网络错误' }); } }); } // 远程更新功能 function checkForUpdates() { // 使用脚本猫平台的脚本页面URL let targetUrl = 'https://scriptcat.org/scripts/code/5529/%E5%AD%A6%E4%B9%A0%E9%80%9A%E7%BD%91%E8%AF%BE%E5%8A%A9%E6%89%8B%E3%80%90%E5%AD%A6%E4%B9%A0%E9%80%9A%E9%A2%98%E5%BA%93%E5%A4%A7%E5%85%A8%E3%80%91%E3%80%90%E5%85%8D%E8%B4%B9%E9%AB%98%E5%88%86%E9%A2%98%E5%BA%93%E3%80%91%E3%80%90%E6%90%9C%E9%A2%98%E3%80%91%E3%80%90%E5%AE%8C%E5%85%A8%E5%85%8D%E8%B4%B9%E3%80%91.user.js'; log("开始检查版本更新..."); compareScriptVersion(targetUrl, (result) => { if (result.error) { console.error('版本对比出错:', result.error); log(`版本对比失败:${result.error}`); // 如果是网络错误,延迟后重试一次 if (result.error.includes('网络错误') || result.error.includes('请求失败')) { log("网络连接失败,5秒后重试版本检查..."); setTimeout(() => { checkForUpdates(); }, 5000); } return; } console.log(`当前版本:${result.current},远程版本:${result.remote}`); log(`版本检测完成:当前版本 ${result.current},远程版本 ${result.remote}`); if (result.isSame) { console.log(`版本一致\n:${result.current}\n:${result.remote}`); log(`版本一致,无需更新`); } else if (result.isSame === null) { console.log(`版本检测失败:${result.remote}`); log(`版本检测失败:${result.remote}`); } else { console.log(`版本不一致\n:${result.current}\n:${result.remote}`); log(`发现新版本:${result.remote},当前版本:${result.current}`); // 显示更新提示 showUpdateNotification(result.current, result.remote); } }); } // 显示更新通知 function showUpdateNotification(currentVersion, remoteVersion) { let notification = document.createElement('div'); notification.style.cssText = ` position: fixed; top: 20px; left: 50%; transform: translateX(-50%); background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 10px; z-index: 10000; box-shadow: 0 8px 25px rgba(0,0,0,0.3); font-family: Arial, sans-serif; font-size: 14px; max-width: 450px; text-align: center; border: 2px solid rgba(255,255,255,0.2); `; notification.innerHTML = `
🚀 发现新版本可用!
当前版本: ${currentVersion}
最新版本: ${remoteVersion}
💡 建议及时更新以获得最佳体验和最新功能
🔧 需要脚本猫扩展支持?点击安装
`; document.body.appendChild(notification); // 立即更新按钮事件 document.getElementById('updateNow').addEventListener('click', function() { this.style.background = '#1e7e34'; window.open('https://scriptcat.org/script-show-page/5529', '_blank'); setTimeout(() => { notification.remove(); log('用户选择立即更新,已打开脚本页面'); }, 300); }); // 稍后提醒按钮事件 document.getElementById('updateLater').addEventListener('click', function() { this.style.background = 'rgba(255,255,255,0.3)'; setTimeout(() => { notification.remove(); log('用户选择稍后更新'); }, 300); }); // 按钮悬停效果 let buttons = notification.querySelectorAll('button'); buttons.forEach(btn => { btn.addEventListener('mouseenter', function() { this.style.transform = 'translateY(-2px)'; this.style.boxShadow = '0 4px 8px rgba(0,0,0,0.3)'; }); btn.addEventListener('mouseleave', function() { this.style.transform = 'translateY(0)'; this.style.boxShadow = 'none'; }); }); // 10秒后自动关闭 setTimeout(() => { if (document.body.contains(notification)) { notification.style.opacity = '0'; notification.style.transform = 'translateX(-50%) translateY(-20px)'; setTimeout(() => { if (document.body.contains(notification)) { notification.remove(); log('更新通知已自动关闭'); } }, 500); } }, 10000); } // 执行版本检查 checkForUpdates(); } function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } })();