Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 17b58c7924 | |||
| 4ae5ba1e46 | |||
| d3b85ec361 | |||
| 6234424aa6 | |||
| 2285b3f41e | |||
| 92173c57ec | |||
| 2eb1fbf087 | |||
| 4d92efa48b | |||
| f66b165eb7 | |||
| 5d42062001 | |||
| 234022c80c | |||
| 5ec20fa327 | |||
| 773332f406 | |||
| 46a1339d5c | |||
| ab0a1f2fdd | |||
| 4121fd9ed0 | |||
| 1c04624903 | |||
| 64c906f064 | |||
| 53756f53a7 | |||
| 201dcb9ba5 | |||
| ad36cba92e | |||
| 27dfc7aedb | |||
| c48165cd78 | |||
| 876f49fb25 | |||
| b41b1696fc | |||
| 2bcd3a83e4 | |||
| 9c1db27ebe | |||
| e7effb0881 | |||
| 8146b165f9 | |||
| 55ff6e7a5a | |||
| a29fa0d9c8 | |||
| 0a255f0e51 | |||
| 207bea46ca | |||
| d30e4f0d96 | |||
| d788227ae4 | |||
| 3104ea2b53 | |||
| 0c6ab02e8d | |||
| ccf30c5dca | |||
| 412198358d | |||
| 302006530e | |||
| 7b661965a9 | |||
| 8d8b78c6a1 | |||
| 9b8bab4a92 | |||
| 75834b5cef | |||
| 0e5e3180c9 | |||
| aa9d6dbaf3 | |||
| a4c2ed2463 | |||
| 529c789315 | |||
| 1ef3784e3d | |||
| 07755e81b3 | |||
| 003056192e | |||
| a4d6b581d7 | |||
| 4b51e156bb | |||
| e623d6fd14 | |||
| d707d983fb | |||
| 1a9d58c2b3 | |||
| dfde341070 | |||
| 220b2b87a6 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -2,3 +2,7 @@
|
|||||||
/.fleet
|
/.fleet
|
||||||
/src/dist/bundle.min.js
|
/src/dist/bundle.min.js
|
||||||
/src/dist/bundle.js
|
/src/dist/bundle.js
|
||||||
|
/dist
|
||||||
|
auto-imports.d.ts
|
||||||
|
components.d.ts
|
||||||
|
aws.xml
|
||||||
6
.idea/jsLibraryMappings.xml
generated
6
.idea/jsLibraryMappings.xml
generated
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="JavaScriptLibraryMappings">
|
|
||||||
<file url="file://$PROJECT_DIR$" libraries="{Node.js Core}" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
14
.vscode/launch.json
vendored
Normal file
14
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
// 使用 IntelliSense 了解相关属性。
|
||||||
|
// 悬停以查看现有属性的描述。
|
||||||
|
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"command": "npm run rollup",
|
||||||
|
"name": "rollup",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "node-terminal"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
372
CHANGELOG.md
372
CHANGELOG.md
@ -1,9 +1,373 @@
|
|||||||
# TODO
|
|
||||||
|
|
||||||
- 翻译:baza npc商店、imarket、imarket搜索结果
|
|
||||||
|
|
||||||
# CHANGE
|
# CHANGE
|
||||||
|
|
||||||
|
## 1.2.4
|
||||||
|
|
||||||
|
2025年04月07日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 优化起飞功能错误处理
|
||||||
|
- 取消网络拦截,避免官方功能被影响
|
||||||
|
|
||||||
|
## 1.2.3
|
||||||
|
|
||||||
|
2025年03月11日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 删除GS Load模块代码
|
||||||
|
- 删除翻译
|
||||||
|
- 删除去Google化部分代码
|
||||||
|
- 修复起飞逻辑
|
||||||
|
- 修复通知
|
||||||
|
|
||||||
|
## 1.2.2
|
||||||
|
|
||||||
|
2024年04月07日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 快捷动作【REFILL】修复
|
||||||
|
|
||||||
|
## 1.2.1
|
||||||
|
|
||||||
|
2024年04月03日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 快捷动作【REFILL】修复
|
||||||
|
|
||||||
|
## 1.2.0
|
||||||
|
|
||||||
|
2024年03月29日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- BS估算缓存机制修复
|
||||||
|
- 快捷功能【快速犯罪】界面优化
|
||||||
|
|
||||||
|
## 1.1.9
|
||||||
|
|
||||||
|
2024年03月27日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- 引入了BS估算功能
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 快捷功能【快速犯罪】去除了烦人的通知
|
||||||
|
|
||||||
|
## 1.1.8
|
||||||
|
|
||||||
|
2024年03月20日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 快捷功能的【喝啤酒】移动至【快速犯罪】中
|
||||||
|
- profile页面中在线状态调整
|
||||||
|
|
||||||
|
## 1.1.7
|
||||||
|
|
||||||
|
2024年03月15日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- 快捷功能-PI存钱
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 上次动作的url判断修复
|
||||||
|
- profile页面中添加了更明显的上次动作时间
|
||||||
|
- 快速取钱功能添加了常用输入
|
||||||
|
|
||||||
|
## 1.1.6
|
||||||
|
|
||||||
|
2024年01月08日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- refill功能改为菜单式,新增支持3种refil
|
||||||
|
- 快速犯罪功能现已支持全部种类
|
||||||
|
|
||||||
|
## 1.1.5
|
||||||
|
|
||||||
|
2023年12月22日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 圣诞小镇掉落物记录表格中的undefined错误修复
|
||||||
|
|
||||||
|
## 1.1.4
|
||||||
|
|
||||||
|
2023年12月08日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 快速犯罪中添加了15-3
|
||||||
|
|
||||||
|
## 1.1.3
|
||||||
|
|
||||||
|
2023年11月29日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 通知浏览错误修复
|
||||||
|
|
||||||
|
## 1.1.2
|
||||||
|
|
||||||
|
2023年09月19日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 火车提醒错误修复
|
||||||
|
- 光速刷新错误修复
|
||||||
|
|
||||||
|
## 1.1.1
|
||||||
|
|
||||||
|
2023年09月13日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 调整了上次动作的显示逻辑
|
||||||
|
- 更准确的现金变动提醒
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- 监控模块-毒CD提醒
|
||||||
|
|
||||||
|
## 1.1.0
|
||||||
|
|
||||||
|
2023年09月11日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 更正上次动作的匹配路径、添加了毒和糖 CD 的提示
|
||||||
|
|
||||||
|
## 1.0.9
|
||||||
|
|
||||||
|
2023年09月08日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 侧边菜单UI优化
|
||||||
|
|
||||||
|
## 1.0.8
|
||||||
|
|
||||||
|
2023年08月23日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 通知浏览修复
|
||||||
|
|
||||||
|
## 1.0.7
|
||||||
|
|
||||||
|
2023年06月27日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 物品功能补充完善
|
||||||
|
- 菜单顺序调整
|
||||||
|
|
||||||
|
## 1.0.6
|
||||||
|
|
||||||
|
2023年06月26日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- 物品功能标签
|
||||||
|
|
||||||
|
## 1.0.5
|
||||||
|
|
||||||
|
2023年06月19日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 移除原菜单
|
||||||
|
- 调整了新菜单的样式、部分逻辑
|
||||||
|
|
||||||
|
## 1.0.4
|
||||||
|
|
||||||
|
2023年06月16日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- 标签页管理功能
|
||||||
|
|
||||||
|
## 1.0.3
|
||||||
|
|
||||||
|
2023年06月16日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 样式错误修复
|
||||||
|
|
||||||
|
## 1.0.2
|
||||||
|
|
||||||
|
2023年06月15日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 错误修复
|
||||||
|
- 菜单样式修改
|
||||||
|
|
||||||
|
## 1.0.1
|
||||||
|
|
||||||
|
2023年06月14日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- 公司存取钱
|
||||||
|
|
||||||
|
## 1.0.0
|
||||||
|
|
||||||
|
2023年06月12日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- PT购买
|
||||||
|
|
||||||
|
## 0.9.9
|
||||||
|
|
||||||
|
2023年06月07日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 购物助手错误修复及样式调整
|
||||||
|
|
||||||
|
## 0.9.8
|
||||||
|
|
||||||
|
2023年06月06日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 错误修复
|
||||||
|
|
||||||
|
## 0.9.7
|
||||||
|
|
||||||
|
2023年06月05日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- bazaar快速开关店
|
||||||
|
- 购物助手
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 部分样式修改
|
||||||
|
|
||||||
|
## 0.9.6
|
||||||
|
|
||||||
|
2023年06月01日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- PC病毒快速操作
|
||||||
|
|
||||||
|
## 0.9.5
|
||||||
|
|
||||||
|
2023年05月31日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 明文密码简单编码处理
|
||||||
|
- 自动登录前添加确认
|
||||||
|
|
||||||
|
## 0.9.4
|
||||||
|
|
||||||
|
2023年05月31日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- 自动登陆功能
|
||||||
|
|
||||||
|
## 0.9.3
|
||||||
|
|
||||||
|
2023年05月30日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- 快速查看地图垃圾
|
||||||
|
|
||||||
|
## 0.9.2
|
||||||
|
|
||||||
|
2023年05月26日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- 快速浏览通知
|
||||||
|
|
||||||
|
## 0.9.1
|
||||||
|
|
||||||
|
2023年05月04日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- 新菜单中现在可以快速喝啤酒了
|
||||||
|
- 快速 refill
|
||||||
|
|
||||||
|
## 0.9.0
|
||||||
|
|
||||||
|
2023年04月28日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- 新菜单中现在可以快速吃XAN了
|
||||||
|
- 快速犯罪
|
||||||
|
|
||||||
|
## 0.8.9
|
||||||
|
|
||||||
|
2023年04月24日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 战斗相关模块错误修复
|
||||||
|
- 重复通知错误修复
|
||||||
|
|
||||||
|
## 0.8.8
|
||||||
|
|
||||||
|
2023年04月17日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- 新菜单
|
||||||
|
- 快速锻炼
|
||||||
|
- 一键起飞
|
||||||
|
|
||||||
|
## 0.8.7
|
||||||
|
|
||||||
|
2023年04月10日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 修复脚本首次运行配置获取错误的问题
|
||||||
|
- 修复"解决加载中"功能开启后无法加载插件图标的问题
|
||||||
|
- 修复功能选项错误读取默认值的问题
|
||||||
|
|
||||||
|
## 0.8.6
|
||||||
|
|
||||||
|
2023年04月07日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 结构调整
|
||||||
|
|
||||||
|
## 0.8.5
|
||||||
|
|
||||||
|
2023年04月03日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 结构调整
|
||||||
|
|
||||||
|
## 0.8.4
|
||||||
|
|
||||||
|
2023年03月03日
|
||||||
|
|
||||||
|
### 修改
|
||||||
|
|
||||||
|
- 错误修复
|
||||||
|
|
||||||
## 0.8.3
|
## 0.8.3
|
||||||
|
|
||||||
2023年03月02日
|
2023年03月02日
|
||||||
|
|||||||
24
README.md
24
README.md
@ -1 +1,23 @@
|
|||||||
# 芜湖助手 Torncity 翻译插件
|
# Wuhu Torn Helper
|
||||||
|
|
||||||
|
[](LICENSE)
|
||||||
|
|
||||||
|
[中文](README_ZHCN.md)
|
||||||
|
|
||||||
|
[CHANGELOG(CN)](CHANGELOG.md)
|
||||||
|
|
||||||
|
A customized auxiliary-enhancement user script designed for a browser-based MMORPG game, featuring a range of convenient
|
||||||
|
functions.
|
||||||
|
|
||||||
|
This script does not include any automation-related code.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
npm init
|
||||||
|
npm run rollup
|
||||||
|
|
||||||
|
## Use
|
||||||
|
|
||||||
|
[release.min.user.js](release.min.user.js)
|
||||||
|
|
||||||
|
Please install with Tampermonkey (for PC browser) or TornPDA.
|
||||||
|
|||||||
20
README_ZHCN.md
Normal file
20
README_ZHCN.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# 芜湖助手 Torncity 翻译插件
|
||||||
|
|
||||||
|
[](LICENSE)
|
||||||
|
|
||||||
|
[CHANGELOG](CHANGELOG.md)
|
||||||
|
|
||||||
|
一个为浏览器网页MMORPG游戏定制的辅助增强用户脚本,包含了一系列便携功能。
|
||||||
|
|
||||||
|
此脚本不包含自动化相关代码。
|
||||||
|
|
||||||
|
## 编译
|
||||||
|
|
||||||
|
npm init
|
||||||
|
npm run rollup
|
||||||
|
|
||||||
|
## 使用
|
||||||
|
|
||||||
|
[release.min.user.js](https://gitlab.com/JJins/wuhu-torn-helper/-/raw/dev/README_ZHCN.md)
|
||||||
|
|
||||||
|
请使用 Tampermonkey (浏览器) 或 TornPDA 安装。
|
||||||
@ -3,13 +3,14 @@
|
|||||||
* 并生成日期时间与版本号
|
* 并生成日期时间与版本号
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let startTime = Date.now();
|
import { readFileSync, writeFileSync } from "fs";
|
||||||
let fs = require('fs');
|
import { prodConfig } from "./rollup.config.js";
|
||||||
|
|
||||||
let date = new Date();
|
let date = new Date();
|
||||||
let version = process.env.npm_package_version;
|
let version = process.env.npm_package_version;
|
||||||
let formattedDateTime = `${ date.getFullYear() }${ ('0' + (date.getMonth() + 1)).slice(-2) }${ ('0' + date.getDate()).slice(-2) }${ ('0' + date.getHours()).slice(-2) }${ ('0' + date.getMinutes()).slice(-2) }`;
|
let formattedDateTime = `${ date.getFullYear() }${ ('0' + (date.getMonth() + 1)).slice(-2) }${ ('0' + date.getDate()).slice(-2) }${ ('0' + date.getHours()).slice(-2) }${ ('0' + date.getMinutes()).slice(-2) }`;
|
||||||
let metaData = `// ==UserScript==
|
let metaData =
|
||||||
|
`// ==UserScript==
|
||||||
// @lastmodified ${ formattedDateTime }
|
// @lastmodified ${ formattedDateTime }
|
||||||
// @name 芜湖助手
|
// @name 芜湖助手
|
||||||
// @namespace WOOH
|
// @namespace WOOH
|
||||||
@ -20,7 +21,6 @@ let metaData = `// ==UserScript==
|
|||||||
// @downloadURL https://gitlab.com/JJins/wuhu-torn-helper/-/raw/dev/release.min.user.js
|
// @downloadURL https://gitlab.com/JJins/wuhu-torn-helper/-/raw/dev/release.min.user.js
|
||||||
// @grant GM_xmlhttpRequest
|
// @grant GM_xmlhttpRequest
|
||||||
// @grant unsafeWindow
|
// @grant unsafeWindow
|
||||||
// @connect ljs-lyt.com
|
|
||||||
// @connect yata.yt
|
// @connect yata.yt
|
||||||
// @connect github.io
|
// @connect github.io
|
||||||
// @connect gitlab.com
|
// @connect gitlab.com
|
||||||
@ -29,6 +29,11 @@ let metaData = `// ==UserScript==
|
|||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
`
|
`
|
||||||
|
|
||||||
const data = fs.readFileSync('./dist/bundle.min.js', 'utf8');
|
const data = readFileSync('./' + prodConfig.output.file, 'utf8');
|
||||||
fs.writeFileSync('./release.min.user.js', metaData + data.replace('$$WUHU_DEV_VERSION$$', version), 'utf8');
|
writeFileSync(
|
||||||
console.log(`版本 ${ version } 构建完成, build.js耗时${ Date.now() - startTime }ms`);
|
'./release.min.user.js',
|
||||||
|
metaData + data.replace('$$WUHU_DEV_VERSION$$', version),
|
||||||
|
'utf8'
|
||||||
|
);
|
||||||
|
// rmSync('./' + prodConfig.output.file);
|
||||||
|
console.log(`版本 ${ version } 构建完成`);
|
||||||
6
css-module.d.ts
vendored
Normal file
6
css-module.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// declare module "*.module.css" {
|
||||||
|
// const css: string;
|
||||||
|
// const classes: { [key: string]: string };
|
||||||
|
// export default classes;
|
||||||
|
// export { css };
|
||||||
|
// }
|
||||||
21
custom-injector.js
Normal file
21
custom-injector.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
export const customInjector = (varName) => {
|
||||||
|
let rt = ((__var) => {
|
||||||
|
const inject = (ob) => {
|
||||||
|
if (document && document.head) {
|
||||||
|
ob?.disconnect();
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.setAttribute('type', 'text/css');
|
||||||
|
style.innerHTML = __var;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (document && document.head) {
|
||||||
|
inject();
|
||||||
|
} else {
|
||||||
|
new MutationObserver((_, ob) => {
|
||||||
|
inject(ob);
|
||||||
|
}).observe(document.documentElement, { childList: true });
|
||||||
|
}
|
||||||
|
}).toString();
|
||||||
|
return `(${ rt })(${ varName })`;
|
||||||
|
};
|
||||||
28
global.d.ts
vendored
28
global.d.ts
vendored
@ -108,24 +108,22 @@ declare interface TornGetActionParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare module "*.html" {
|
declare module "*.html" {
|
||||||
const value: string;
|
const html: string;
|
||||||
export default value;
|
export default html;
|
||||||
}
|
}
|
||||||
|
declare module "*.module.css" {
|
||||||
declare module "*.css" {
|
const css: string;
|
||||||
const value: string;
|
// const classes: { [key: string]: string };
|
||||||
export default value;
|
// export default classes;
|
||||||
|
export default css;
|
||||||
|
// export { css };
|
||||||
}
|
}
|
||||||
// declare module '*.vue' {
|
|
||||||
// import type { DefineComponent } from 'vue'
|
|
||||||
// const component: DefineComponent<{}, {}, any>
|
|
||||||
//
|
|
||||||
// export interface HTMLAttributes {
|
|
||||||
// vModel?: any;
|
|
||||||
// }
|
|
||||||
// export default component
|
|
||||||
// }
|
|
||||||
|
|
||||||
declare function GM_xmlhttpRequest(init: any): void;
|
declare function GM_xmlhttpRequest(init: any): void;
|
||||||
|
|
||||||
declare var unsafeWindow: Window & typeof globalThis;
|
declare var unsafeWindow: Window & typeof globalThis;
|
||||||
|
declare type Constructor<T = any> = new (...args: any[]) => T;
|
||||||
|
|
||||||
|
declare interface ClassType<T> {
|
||||||
|
new(...args: unknown[]): T
|
||||||
|
}
|
||||||
|
|||||||
3887
package-lock.json
generated
3887
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
20
package.json
20
package.json
@ -1,31 +1,43 @@
|
|||||||
{
|
{
|
||||||
"name": "wuhu-torn-helper",
|
"name": "wuhu-torn-helper",
|
||||||
"version": "0.8.4",
|
"version": "1.2.4",
|
||||||
"description": "芜湖助手",
|
"description": "芜湖助手",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"release": "cross-env NODE_ENV=production rollup -c rollup-prod.config.js && node build.js",
|
"release": "cross-env NODE_ENV=production rollup -c && node build.mjs",
|
||||||
"watch": "cross-env NODE_ENV=development rollup -c -w",
|
"watch": "cross-env NODE_ENV=development rollup -c -w",
|
||||||
"rollup": "cross-env NODE_ENV=development rollup -c"
|
"rollup": "cross-env NODE_ENV=development rollup -c"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@element-plus/icons-vue": "^2.1.0",
|
||||||
"@rollup/plugin-alias": "^4.0.3",
|
"@rollup/plugin-alias": "^4.0.3",
|
||||||
|
"@rollup/plugin-commonjs": "^24.0.1",
|
||||||
"@rollup/plugin-json": "^4.1.0",
|
"@rollup/plugin-json": "^4.1.0",
|
||||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||||
"@rollup/plugin-replace": "^5.0.2",
|
"@rollup/plugin-replace": "^5.0.2",
|
||||||
"@rollup/plugin-terser": "^0.4.0",
|
"@rollup/plugin-terser": "^0.4.0",
|
||||||
"@rollup/plugin-typescript": "^8.5.0",
|
"@rollup/plugin-typescript": "^8.5.0",
|
||||||
"@types/jquery": "^3.5.14",
|
"@types/jquery": "^3.5.14",
|
||||||
"@types/node": "^18.0.6",
|
"@types/node": "^20.6.0",
|
||||||
"@vitejs/plugin-vue": "^4.0.0",
|
"@vitejs/plugin-vue": "^4.0.0",
|
||||||
"@vue/tsconfig": "^0.1.3",
|
"@vue/tsconfig": "^0.1.3",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
|
"element-plus": "^2.3.10",
|
||||||
|
"just-clone": "^6.2.0",
|
||||||
"npm": "^8.19.2",
|
"npm": "^8.19.2",
|
||||||
|
"reflect-metadata": "^0.1.13",
|
||||||
"rollup": "^2.79.0",
|
"rollup": "^2.79.0",
|
||||||
"rollup-plugin-postcss": "^4.0.2",
|
"rollup-plugin-postcss": "^4.0.2",
|
||||||
"rollup-plugin-string-html": "^1.0.0",
|
"rollup-plugin-string-html": "^1.0.0",
|
||||||
|
"rollup-plugin-styles": "^4.0.0",
|
||||||
"rollup-plugin-typescript2": "^0.34.1",
|
"rollup-plugin-typescript2": "^0.34.1",
|
||||||
"tslib": "^2.4.0",
|
"tslib": "^2.4.0",
|
||||||
"typescript": "^4.8.3",
|
"typescript": "^4.8.3",
|
||||||
|
"unplugin-auto-import": "^0.15.2",
|
||||||
|
"unplugin-element-plus": "^0.7.0",
|
||||||
|
"unplugin-icons": "^0.16.1",
|
||||||
|
"unplugin-vue-components": "^0.24.1",
|
||||||
|
"vant": "^4.1.2",
|
||||||
"vue": "^3.2.47"
|
"vue": "^3.2.47"
|
||||||
}
|
},
|
||||||
|
"type": "module"
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -1,7 +0,0 @@
|
|||||||
import terser from "@rollup/plugin-terser";
|
|
||||||
import rollupConfig from "./rollup.config";
|
|
||||||
|
|
||||||
rollupConfig.plugins.push(terser());
|
|
||||||
rollupConfig.output.file = 'dist/bundle.min.js';
|
|
||||||
rollupConfig.output.name = 'bundle.min.js';
|
|
||||||
export default rollupConfig;
|
|
||||||
@ -10,14 +10,26 @@ import html from "rollup-plugin-string-html";
|
|||||||
import resolve from "@rollup/plugin-node-resolve";
|
import resolve from "@rollup/plugin-node-resolve";
|
||||||
import replace from "@rollup/plugin-replace";
|
import replace from "@rollup/plugin-replace";
|
||||||
import alias from "@rollup/plugin-alias";
|
import alias from "@rollup/plugin-alias";
|
||||||
import postcss from 'rollup-plugin-postcss';
|
|
||||||
import vue from "@vitejs/plugin-vue";
|
import vue from "@vitejs/plugin-vue";
|
||||||
|
import styles from "rollup-plugin-styles";
|
||||||
|
import { customInjector } from "./custom-injector.js";
|
||||||
|
import terser from "@rollup/plugin-terser";
|
||||||
|
import clone from "just-clone";
|
||||||
|
import commonjs from '@rollup/plugin-commonjs';
|
||||||
|
import AutoImport from 'unplugin-auto-import/vite'
|
||||||
|
import Components from 'unplugin-vue-components/vite'
|
||||||
|
// import { VantResolver } from 'unplugin-vue-components/resolvers';
|
||||||
|
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
|
||||||
|
import IconsResolver from 'unplugin-icons/resolver';
|
||||||
|
import Icons from 'unplugin-icons/vite'
|
||||||
|
import ElementPlus from 'unplugin-element-plus/rollup'
|
||||||
|
|
||||||
let node_env = process.env.NODE_ENV;
|
let node_env = process.env.NODE_ENV;
|
||||||
let vuePath = node_env === 'production' ?
|
let vuePath = node_env === 'production' ?
|
||||||
'vue/dist/vue.runtime.esm-browser.prod.js' :
|
'vue/dist/vue.runtime.esm-browser.prod.js' :
|
||||||
'vue/dist/vue.runtime.esm-browser.js';
|
'vue/dist/vue.runtime.esm-browser.js';
|
||||||
export default {
|
|
||||||
|
const devConfig = {
|
||||||
input: 'src/ts/index.ts',
|
input: 'src/ts/index.ts',
|
||||||
output: {
|
output: {
|
||||||
file: 'dist/bundle.js',
|
file: 'dist/bundle.js',
|
||||||
@ -27,8 +39,6 @@ export default {
|
|||||||
plugins: [
|
plugins: [
|
||||||
json(),
|
json(),
|
||||||
html({
|
html({
|
||||||
// include: ["**/*.html", "src/static/css/*.css"],
|
|
||||||
// include: ["**/*.html", "**/*.css"],
|
|
||||||
include: ["**/*.html"],
|
include: ["**/*.html"],
|
||||||
minifier: {
|
minifier: {
|
||||||
includeAutoGeneratedTags: true,
|
includeAutoGeneratedTags: true,
|
||||||
@ -45,7 +55,9 @@ export default {
|
|||||||
}),
|
}),
|
||||||
// 根据环境更改vue源
|
// 根据环境更改vue源
|
||||||
alias({
|
alias({
|
||||||
entries: [{ find: 'vue', replacement: vuePath }]
|
entries: [
|
||||||
|
{ find: 'vue', replacement: vuePath },
|
||||||
|
]
|
||||||
}),
|
}),
|
||||||
// 为vue替换环境变量
|
// 为vue替换环境变量
|
||||||
replace({
|
replace({
|
||||||
@ -61,13 +73,59 @@ export default {
|
|||||||
browser: true,
|
browser: true,
|
||||||
preferBuiltins: false,
|
preferBuiltins: false,
|
||||||
}),
|
}),
|
||||||
|
commonjs(),
|
||||||
vue({ isProduction: node_env === 'production' }),
|
vue({ isProduction: node_env === 'production' }),
|
||||||
typescript2({
|
AutoImport({
|
||||||
tsconfig: "tsconfig.json",
|
resolvers: [
|
||||||
// clean: true,
|
ElementPlusResolver(),
|
||||||
// check: false,
|
IconsResolver({
|
||||||
|
prefix: 'Icon',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
Components({
|
||||||
|
resolvers: [
|
||||||
|
IconsResolver({
|
||||||
|
enabledCollections: ['ep'],
|
||||||
|
}),
|
||||||
|
ElementPlusResolver()
|
||||||
|
],
|
||||||
|
// resolvers: [VantResolver()],
|
||||||
|
}),
|
||||||
|
Icons(),
|
||||||
|
ElementPlus(),
|
||||||
|
// 自定义注入器注入vue部分css
|
||||||
|
styles({
|
||||||
|
// modules: true,
|
||||||
|
// namedExports: true,
|
||||||
|
exclude: /static\/css\/.+\.css/,
|
||||||
|
mode: [
|
||||||
|
"inject",
|
||||||
|
(varName) => customInjector(varName),
|
||||||
|
],
|
||||||
|
minimize: true
|
||||||
|
}),
|
||||||
|
// 非vue部分css逻辑代码中手动注入
|
||||||
|
styles({
|
||||||
|
include: /static\/css\/.+\.css/,
|
||||||
|
// modules: true,
|
||||||
|
// namedExports: true,
|
||||||
|
mode: [
|
||||||
|
"inject",
|
||||||
|
() => ``,
|
||||||
|
],
|
||||||
|
minimize: true
|
||||||
|
}),
|
||||||
|
typescript2({
|
||||||
|
tsconfig: "./tsconfig.json",
|
||||||
}),
|
}),
|
||||||
postcss({ minimize: true }),
|
|
||||||
// typescript(),
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const prodConfig = clone(devConfig);
|
||||||
|
prodConfig.plugins.push(terser());
|
||||||
|
prodConfig.output.file = 'dist/bundle.min.js';
|
||||||
|
prodConfig.output.name = 'bundle.min.js';
|
||||||
|
|
||||||
|
export default [devConfig, prodConfig];
|
||||||
|
export { prodConfig };
|
||||||
|
|||||||
6
src/shims-vue.d.ts
vendored
6
src/shims-vue.d.ts
vendored
@ -4,8 +4,4 @@ declare module '*.vue' {
|
|||||||
const component: DefineComponent<{}, {}, any>
|
const component: DefineComponent<{}, {}, any>
|
||||||
export default component
|
export default component
|
||||||
}
|
}
|
||||||
declare module '*vue&type=script&lang.ts' {
|
/* eslint-enable */
|
||||||
import type { DefineComponent } from 'vue'
|
|
||||||
const component: DefineComponent<{}, {}, any>
|
|
||||||
export default component
|
|
||||||
}
|
|
||||||
|
|||||||
@ -282,3 +282,11 @@ div#wh-popup::after {
|
|||||||
.non-selection {
|
.non-selection {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mt-4 {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*.el-overlay {*/
|
||||||
|
/* backdrop-filter: blur(20px);*/
|
||||||
|
/*}*/
|
||||||
@ -1,75 +1,71 @@
|
|||||||
<div class="acc-title">
|
<div class="acc-title">
|
||||||
<span class="item-desc tt-buy" style="display: inline-block;">
|
<span class="item-desc tt-buy">
|
||||||
<span aria-labelledby="180-name 180-price 180-stock" class="item Alcohol" itemid="180" loaded="0" tabindex="0">
|
<span class="item Alcohol" itemid="180" loaded="0">
|
||||||
<span class="item-plate">
|
<span class="item-plate">
|
||||||
<img alt="Bottle of Beer" class="torn-item large" src="/images/items/180/large.png">
|
<img alt="Bottle of Beer" class="torn-item large"
|
||||||
</span>
|
src="/images/items/180/large.png"
|
||||||
<span class="item-hover">
|
srcset="/images/items/180/large.png 1x, /images/items/180/large@2x.png 2x, /images/items/180/large@3x.png 3x, /images/items/180/large@4x.png 4x">
|
||||||
<button aria-label="Show info: Bottle of Beer" class="view-h wai-btn" value="100"></button>
|
</span>
|
||||||
<button aria-label="Buy: Bottle of Beer" class="buy-h wai-btn" i-data="i_661_346_51_52" value="100"></button>
|
<span class="item-hover">
|
||||||
</span>
|
<button aria-labelledby="Show info: 180-name 180-price 180-stock" class="view-info wai-btn"
|
||||||
</span>
|
value="100"></button>
|
||||||
<span class="desc">
|
<button aria-label="Buy: Bottle of Beer" class="buy-info wai-btn" value="100"></button>
|
||||||
<span id="180-name" class="name t-overflow bold">一瓶啤酒</span>
|
</span>
|
||||||
<span id="180-price" class="price t-gray-6" data-sell="$5">$10</span>
|
</span>
|
||||||
<span id="180-stock" class="stock t-gray-6 t-overflow">Alcohol (<span class="instock">600</span> in stock)</span>
|
<span class="desc">
|
||||||
</span>
|
<input name="shoparea" type="hidden" value="100">
|
||||||
<span class="buy-act-wrap">
|
<span id="180-name" class="name t-overflow bold">Bottle of Beer</span>
|
||||||
<button aria-label="Close" class="close-icon p0 wai-btn" value="100"></button>
|
<span id="180-price" class="price t-gray-6 tt-modified" data-sell="$5">$10<span
|
||||||
<label class="wai" for="180">Amount
|
class="tt-profit positive"><i class="fas fa-caret-up"></i>$1,636</span></span>
|
||||||
of Bottle of Beer</label>
|
<span id="180-stock" class="stock t-gray-6 t-overflow">Alcohol (<span class="instock">5,000</span> in
|
||||||
<input id="180" autocomplete="new-amount" maxlength="3" name="buyAmount[]" type="text" value="100">
|
stock)</span>
|
||||||
<span class="buy-act bold">
|
</span>
|
||||||
<button class="wai-support t-blue h" i-data="i_815_375_53_34" value="100">Buy<br><span
|
<span class="buy-act-wrap">
|
||||||
class="tt-max-buy">fill max</span></button>
|
<button aria-label="Close" class="close-icon p0 wai-btn" value="100"></button>
|
||||||
<div class="tt-max-buy-overlay"></div></span>
|
<label class="wai" for="180">Amount
|
||||||
</span>
|
of Bottle of Beer</label>
|
||||||
|
<input id="180" autocomplete="new-amount" maxlength="3" name="buyAmount[]" type="text" value="100">
|
||||||
|
<span class="buy-act bold">
|
||||||
|
<button class="wai-support t-blue h" value="100">Buy<br><span class="tt-max-buy">fill
|
||||||
|
max</span></button>
|
||||||
|
<div class="tt-max-buy-overlay"></div>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<div class="torn-divider divider-right"></div>
|
<div class="torn-divider divider-right"></div>
|
||||||
<div class="confirm-wrap" style="display: none;">
|
<div class="confirm-wrap" tabindex="0">
|
||||||
<span class="confirm">
|
<span class="confirm">
|
||||||
<span>
|
<span>
|
||||||
确定购买
|
Are you sure you would like to buy
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<span class="count">100</span>
|
|
||||||
x Bottle of Beer for
|
|
||||||
$<span class="total">1,000</span>
|
|
||||||
</span>
|
|
||||||
<span class="confirm-act m-top5">
|
|
||||||
<a class="wai-support yes m-right10 bold t-blue h" data-id="180" href="#" i-data="i_705_379_24_14">
|
|
||||||
Yes
|
|
||||||
</a>
|
|
||||||
<span class="no bold">
|
|
||||||
<a class="wai-support t-blue h" href="#" i-data="i_740_379_16_14">
|
|
||||||
No
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="success-wrap" style="display: none;">
|
|
||||||
<span class="success"><span class="t-red bold">
|
|
||||||
There is not enough stock left to buy <b>100</b> of this item.
|
|
||||||
</span>
|
</span>
|
||||||
<span class="confirm-act m-top5">
|
<span>
|
||||||
|
<span class="count"></span>
|
||||||
<a class="items m-right10 bold t-blue h" href="item.php">Your Items</a>
|
x Bottle of Beer for
|
||||||
|
$<span class="total"></span>
|
||||||
|
</span>
|
||||||
</span></span>
|
<span class="confirm-act m-top5">
|
||||||
<button aria-label="Close" class="close-icon p0 wai-btn" i-data="i_840_344_10_11" value="100"></button>
|
<a class="wai-support yes m-right10 bold t-blue h" data-id="180" href="#">
|
||||||
|
Yes
|
||||||
|
</a>
|
||||||
|
<span class="no bold">
|
||||||
|
<a class="wai-support t-blue h" href="#">
|
||||||
|
No
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="success-wrap">
|
||||||
|
<span class="success">
|
||||||
|
<span class="t-green bold">
|
||||||
|
<span class="ajax-preloader"></span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<button aria-label="Close" class="close-icon p0 wai-btn" value="100"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="msg-wrap">
|
<div class="msg-wrap">
|
||||||
<span class="t-green bold">
|
<span class="t-green bold">
|
||||||
<span class="ajax-preloader"></span>
|
<span class="ajax-preloader"></span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="view-item-info">
|
|
||||||
<div class="item-cont">
|
|
||||||
<div class="item-wrap">
|
|
||||||
<span class="ajax-preloader m-top10 m-bottom10"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -9,7 +9,7 @@
|
|||||||
<li>走进蓝色的门(左二)[111,-60]</li>
|
<li>走进蓝色的门(左二)[111,-60]</li>
|
||||||
<li>过了蓝门后继续沿路向南</li>
|
<li>过了蓝门后继续沿路向南</li>
|
||||||
<li>然后沿路向东,再向南</li>
|
<li>然后沿路向东,再向南</li>
|
||||||
<li>再向东走,会看到“恐怖之家”,进入这栋楼[137, -84]</li>
|
<li>再向东走,会看到「恐怖之家」,进入这栋楼[137, -84]</li>
|
||||||
<li>向北走,进入洞口[164, -81]</li>
|
<li>向北走,进入洞口[164, -81]</li>
|
||||||
<li>穿过隧道到达另一端的洞穴口[142, -63],<b>避开所有怪物和NPC</b></li>
|
<li>穿过隧道到达另一端的洞穴口[142, -63],<b>避开所有怪物和NPC</b></li>
|
||||||
<li>来到另一个岛上</li>
|
<li>来到另一个岛上</li>
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
<h4>手机</h4>
|
<h4>手机</h4>
|
||||||
<p>安卓 KIWI 等可以用油猴脚本的浏览器也可以点上面的链接安装👆</p>
|
<p>安卓 KIWI 等可以用油猴脚本的浏览器也可以点上面的链接安装👆</p>
|
||||||
<p>Torn PDA app 或 Alook 用户可打开<a href="//jjins.github.io/fyfuzhi/" target="_blank">这个网页</a>快捷复制粘贴。</p>
|
<p>Torn PDA app 或 Alook 用户可打开<a href="//jjins.github.io/fyfuzhi/" target="_blank">这个网页</a>快捷复制粘贴。</p>
|
||||||
|
<p>注:Torn PDA 中,Injection time 请选择 Start 达到最好效果。</p>
|
||||||
<h4>直接复制</h4>
|
<h4>直接复制</h4>
|
||||||
<p>加载脚本然后直接复制粘贴到用户脚本处。</p>
|
<p>加载脚本然后直接复制粘贴到用户脚本处。</p>
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
67
src/ts/App.ts
Normal file
67
src/ts/App.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import Interrupt from "./class/Interrupt"
|
||||||
|
import Initializer from "./class/Initializer"
|
||||||
|
// import { Common } from "./class/Common"
|
||||||
|
// import UrlRouter from "./class/UrlRouter"
|
||||||
|
import translateMain from "./func/translate/translateMain"
|
||||||
|
import CommonUtils from "./class/utils/CommonUtils"
|
||||||
|
import LocalConfigWrapper from "./class/LocalConfigWrapper"
|
||||||
|
import ClassName from "./container/ClassName"
|
||||||
|
import { Injectable } from "./container/Injectable"
|
||||||
|
import FeatureMan from "./man/FeatureMan"
|
||||||
|
import Logger from "./class/Logger"
|
||||||
|
|
||||||
|
@ClassName('Application')
|
||||||
|
@Injectable()
|
||||||
|
export default class App {
|
||||||
|
private readonly logger = Logger.factory(App)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly interrupt: Interrupt,
|
||||||
|
private readonly initializer: Initializer,
|
||||||
|
// private readonly common: Common,
|
||||||
|
// private readonly urlRouter: UrlRouter,
|
||||||
|
private readonly configWrapper: LocalConfigWrapper,
|
||||||
|
private readonly utils: CommonUtils,
|
||||||
|
private readonly featureMan: FeatureMan,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public run() {
|
||||||
|
|
||||||
|
this.interrupt.conditionInterrupt();
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
this.initializer.init();
|
||||||
|
|
||||||
|
// this.featureMan.fStart().then(() => this.featureMan.printTable());
|
||||||
|
|
||||||
|
// 插件图标和设置菜单
|
||||||
|
// this.icon.init();
|
||||||
|
|
||||||
|
let tmp = () => {
|
||||||
|
// // 所有页面通用
|
||||||
|
// try {
|
||||||
|
// // this.common.resolve.apply(this.common, this.run);
|
||||||
|
// // this.common.resolve(() => this.run());
|
||||||
|
// } catch (e) {
|
||||||
|
// }
|
||||||
|
(async function (self: App) {
|
||||||
|
await self.featureMan.fStart()
|
||||||
|
self.featureMan.printTable()
|
||||||
|
})(this)
|
||||||
|
|
||||||
|
// URL匹配
|
||||||
|
// this.urlRouter.resolve();
|
||||||
|
|
||||||
|
// 翻译
|
||||||
|
// if (this.configWrapper.config.transEnable)
|
||||||
|
// translateMain(window.location.href);
|
||||||
|
};
|
||||||
|
// TODO 临时检测jquery
|
||||||
|
if (typeof $ === "function") {
|
||||||
|
tmp();
|
||||||
|
} else {
|
||||||
|
this.utils.jQueryReady().then(() => tmp());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,112 +1,160 @@
|
|||||||
import depoHelper from "../func/module/depoHelper";
|
// import depoHelper from "../func/module/depoHelper";
|
||||||
import travelHelper from "../func/module/travelHelper";
|
// import TravelHelper from "../feature/TravelHelper";
|
||||||
import priceWatcherHandle from "../func/module/priceWatcherHandle";
|
// import priceWatcherHandle from "../func/module/priceWatcherHandle";
|
||||||
import WuhuBase from "./WuhuBase";
|
// import CompanyHelper from "../feature/CompanyHelper";
|
||||||
import WuhuConfig from "./WuhuConfig";
|
// import AttackHelper from "./action/AttackHelper";
|
||||||
import CompanyHelper from "./action/CompanyHelper";
|
// import SidebarHelper from "../feature/SidebarHelper";
|
||||||
import AttackHelper from "./action/AttackHelper";
|
// import CommonUtils from "./utils/CommonUtils";
|
||||||
import SidebarHelper from "./action/SidebarHelper";
|
// import FetchUtils from "./utils/FetchUtils";
|
||||||
import CommonUtils from "./utils/CommonUtils";
|
// import FetchEventCallback from "./action/FetchEventCallback";
|
||||||
import Log from "./Log";
|
// import globVars from "../globVars";
|
||||||
import FetchUtils from "./utils/FetchUtils";
|
// import TranslateNew from "./action/TranslateNew";
|
||||||
import ZhongIcon from "./ZhongIcon";
|
// import ClassName from "../container/ClassName";
|
||||||
import Alert from "./utils/Alert";
|
// import { Injectable } from "../container/Injectable";
|
||||||
import FetchEventCallback from "./action/FetchEventCallback";
|
// import LocalConfigWrapper from "./LocalConfigWrapper";
|
||||||
import globVars from "../globVars";
|
// import Logger from "./Logger";
|
||||||
import TranslateNew from "./action/TranslateNew";
|
// import BuyBeerHelper from "../feature/BuyBeerHelper";
|
||||||
|
// import ModuleLoader from "./ModuleLoader";
|
||||||
/**
|
// import TornPDAUtils from "./utils/TornPDAUtils";
|
||||||
* 脚本不区分页面的通用功能入口
|
// import TravelItem from "../feature/TravelItem";
|
||||||
*/
|
// import IconHelper from "../feature/IconHelper";
|
||||||
export class Common extends WuhuBase {
|
// import MsgWrapper from "./utils/MsgWrapper";
|
||||||
className = 'Common';
|
// import toThousands from "../func/utils/toThousands";
|
||||||
|
// import { WHIntervalLoader } from "../monitor/WHIntervalLoader";
|
||||||
public resolve(mainMethod) {
|
//
|
||||||
let glob = Common.glob;
|
// /**
|
||||||
// 价格监控
|
// * 脚本不区分页面的通用功能入口
|
||||||
priceWatcherHandle(glob.isPDA, glob.PDA_APIKey);
|
// */
|
||||||
|
// @Injectable()
|
||||||
// 啤酒提醒
|
// @ClassName('Common')
|
||||||
if (WuhuConfig.get('_15Alarm')) glob.beer.start();
|
// export class Common {
|
||||||
|
// private readonly logger = Logger.factory(Common)
|
||||||
SidebarHelper.getInstance();
|
//
|
||||||
|
// constructor(
|
||||||
/**
|
// private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
* 解决一直转圈(加载中)的问题
|
// // private readonly fetchEventCallback: FetchEventCallback,
|
||||||
* All('script[src*="google"]')
|
// // private readonly translateNew: TranslateNew,
|
||||||
* All('#gtm_tag')
|
// // private readonly tornPDAUtils: TornPDAUtils,
|
||||||
* All('script[src*="chat/gonline"]')
|
// // private readonly buyBeerHelper: BuyBeerHelper,
|
||||||
* All('head script[nonce]')
|
// // private readonly fetchUtils: FetchUtils,
|
||||||
*/
|
// // private readonly moduleLoader: ModuleLoader,
|
||||||
if (document.readyState === 'interactive' && WuhuConfig.get('SolveGoogleScriptPendingIssue')) {
|
// private readonly msgWrapper: MsgWrapper,
|
||||||
window.stop();
|
// ) {
|
||||||
document.open();
|
// }
|
||||||
document.addEventListener('readystatechange', function readyStateChangeHandler() {
|
//
|
||||||
Log.info('document.readyState', document.readyState);
|
// public resolve(mainMethod) {
|
||||||
if (document.readyState === 'complete') {
|
// // window.setInterval(()=>this.msgWrapper.create('test',{sysNotify:true},'info'),2000);
|
||||||
document.removeEventListener('readystatechange', readyStateChangeHandler);
|
//
|
||||||
mainMethod();
|
// // // fetch方法处理
|
||||||
throw new Error('页面已重载');
|
// // globVars.responseHandlers.push(
|
||||||
}
|
// // (...args: any[]) => this.fetchEventCallback.responseHandler.apply(this.fetchEventCallback, args)
|
||||||
});
|
// // );
|
||||||
FetchUtils.getInstance().fetchText(window.location.href).then(resp => {
|
// // // fetch方法处理-翻译
|
||||||
let removed = resp;
|
// // globVars.responseHandlers.push(
|
||||||
[
|
// // (...args: any[]) => this.translateNew.responseHandler.apply(this.translateNew, args)
|
||||||
/<script id="gtm_tag">.+?<\/script>/ms,
|
// // );
|
||||||
/<script async src="https:\/\/www\.google.+?<\/script>/ms,
|
//
|
||||||
/<script nonce=".+?gtag.+?<\/script>/ms,
|
// // // 价格监控
|
||||||
/<script.+?google.+?\/script>/,
|
// // priceWatcherHandle(this.tornPDAUtils.isPDA(), this.tornPDAUtils.APIKey);
|
||||||
].forEach(remove => {
|
//
|
||||||
removed = removed.replace(remove, '');
|
// // 啤酒提醒
|
||||||
});
|
// // if (this.localConfigWrapper.config._15Alarm) this.buyBeerHelper.start();
|
||||||
Log.info({ removed });
|
//
|
||||||
document.write(removed);
|
// // this.moduleLoader.push(SidebarHelper);
|
||||||
document.close();
|
// // this.moduleLoader.push(TravelItem);
|
||||||
});
|
// // this.moduleLoader.push(WHIntervalLoader)
|
||||||
}
|
//
|
||||||
|
// /**
|
||||||
// fetch方法处理
|
// * 解决一直转圈(加载中)的问题
|
||||||
globVars.responseHandlers.push(FetchEventCallback.getInstance().responseHandler);
|
// * All('script[src*="google"]')
|
||||||
// fetch方法处理-翻译
|
// * All('#gtm_tag')
|
||||||
globVars.responseHandlers.push(TranslateNew.getInstance().responseHandler);
|
// * All('script[src*="chat/gonline"]')
|
||||||
|
// * All('head script[nonce]')
|
||||||
// 存钱相关
|
// */
|
||||||
depoHelper();
|
// // try {
|
||||||
|
// // if (document.readyState === 'interactive' && this.localConfigWrapper.config.SolveGoogleScriptPendingIssue) {
|
||||||
// 飞行相关
|
// // window.stop();
|
||||||
travelHelper().then();
|
// // document.open();
|
||||||
|
// // let readyStateChangeHandler = () => {
|
||||||
// 战斗相关
|
// // this.logger.info('document.readyState', document.readyState);
|
||||||
AttackHelper.getInstance();
|
// // if (document.readyState === 'complete') {
|
||||||
|
// // document.removeEventListener('readystatechange', readyStateChangeHandler);
|
||||||
// 公司助手
|
// // mainMethod();
|
||||||
CompanyHelper.getInstance();
|
// // throw new Error('页面已重载');
|
||||||
|
// // }
|
||||||
// 自定义CSS
|
// // }
|
||||||
if (WuhuConfig.get('CustomCss')) {
|
// // document.addEventListener('readystatechange', readyStateChangeHandler);
|
||||||
Log.info('应用自定义CSS');
|
// // this.fetchUtils.fetchText(window.location.href).then(resp => {
|
||||||
CommonUtils.addStyle(WuhuConfig.get('CustomCss'));
|
// // let removed = resp;
|
||||||
}
|
// // [
|
||||||
|
// // /<script id="gtm_tag">.+?<\/script>/ms,
|
||||||
// 现金变动提醒
|
// // /<script async src="https:\/\/www\.google.+?<\/script>/ms,
|
||||||
if (WuhuConfig.get('CashChangeAlert')) CommonUtils.elementReady("#user-money").then(userMoney => {
|
// // /<script nonce=".+?gtag.+?<\/script>/ms,
|
||||||
new MutationObserver((mutations, observer) => {
|
// // /<script.+?google.+?\/script>/,
|
||||||
if (!WuhuConfig.get('CashChangeAlert')) {
|
// // ].forEach(remove => {
|
||||||
observer.disconnect();
|
// // removed = removed.replace(remove, '');
|
||||||
new Alert('现金变动提醒已关闭', { sysNotify: true });
|
// // });
|
||||||
return;
|
// // this.logger.info({ removed });
|
||||||
}
|
// // document.write(removed);
|
||||||
Log.info("现金变动提醒", mutations);
|
// // document.close();
|
||||||
mutations.forEach(item => {
|
// // });
|
||||||
if (item.attributeName === 'data-money') {
|
// // }
|
||||||
ZhongIcon.getInstance().updateCashView(userMoney.innerText);
|
// // } catch (e) {
|
||||||
new Alert(
|
// // this.logger.error('【解决一直转圈(加载中)的问题】错误',e)
|
||||||
'提醒: 现金变动 ' + item.oldValue + ' -> ' + userMoney.innerText,
|
// // }
|
||||||
{ sysNotify: true }
|
//
|
||||||
);
|
// // // 存钱相关
|
||||||
}
|
// // try {
|
||||||
});
|
// // depoHelper();
|
||||||
}).observe(userMoney, { attributes: true, attributeOldValue: true })
|
// // } catch (e) {
|
||||||
});
|
// // this.logger.error('【存钱相关】错误',e)
|
||||||
}
|
// // }
|
||||||
}
|
//
|
||||||
|
// // // 飞行相关
|
||||||
|
// // this.moduleLoader.push(TravelHelper);
|
||||||
|
//
|
||||||
|
// // 战斗相关
|
||||||
|
// // this.moduleLoader.push(AttackHelper);
|
||||||
|
//
|
||||||
|
// // 公司助手
|
||||||
|
// // this.moduleLoader.push(CompanyHelper);
|
||||||
|
//
|
||||||
|
// // // 菜单
|
||||||
|
// // this.moduleLoader.push(IconHelper);
|
||||||
|
//
|
||||||
|
// // this.moduleLoader.load().then();
|
||||||
|
//
|
||||||
|
// // // 自定义CSS
|
||||||
|
// // if (this.localConfigWrapper.config.CustomCss) {
|
||||||
|
// // this.logger.info('应用自定义CSS');
|
||||||
|
// // CommonUtils.addStyle(this.localConfigWrapper.config.CustomCss);
|
||||||
|
// // }
|
||||||
|
// //
|
||||||
|
// // // 现金变动提醒
|
||||||
|
// // if (this.localConfigWrapper.config.CashChangeAlert) CommonUtils.elementReady("#user-money").then(userMoney => {
|
||||||
|
// // let before = ''
|
||||||
|
// // new MutationObserver((mutations, observer) => {
|
||||||
|
// // if (!this.localConfigWrapper.config.CashChangeAlert) {
|
||||||
|
// // observer.disconnect();
|
||||||
|
// // this.msgWrapper.create('现金变动提醒已关闭', { sysNotify: true });
|
||||||
|
// // return;
|
||||||
|
// // }
|
||||||
|
// // this.logger.info("现金变动提醒", mutations);
|
||||||
|
// // mutations.forEach(item => {
|
||||||
|
// // if (item.attributeName === 'data-money') {
|
||||||
|
// // let change = userMoney.innerText
|
||||||
|
// // .trim()
|
||||||
|
// // .replaceAll(/[,$]/g, '')
|
||||||
|
// // if (change !== before) {
|
||||||
|
// // this.msgWrapper.create(
|
||||||
|
// // '现金变动 ' + item.oldValue + ' --> ' + toThousands(change),
|
||||||
|
// // { sysNotify: true }
|
||||||
|
// // );
|
||||||
|
// // before = change
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // });
|
||||||
|
// // }).observe(userMoney, { attributes: true, attributeOldValue: true })
|
||||||
|
// // });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|||||||
@ -1,40 +1,19 @@
|
|||||||
import Device from "../enum/Device";
|
import Device from "../enum/Device";
|
||||||
import WuhuBase from "./WuhuBase";
|
|
||||||
import IGlobal from "../interface/IGlobal";
|
import IGlobal from "../interface/IGlobal";
|
||||||
import Log from "./Log";
|
import { Injectable } from "../container/Injectable";
|
||||||
import InfoUtils from "./utils/InfoUtils";
|
import ClassName from "../container/ClassName";
|
||||||
import BuyBeerHelper from "./action/BuyBeerHelper";
|
import Logger from "./Logger";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储脚本用到的参数,单例存在
|
* 存储脚本用到的参数
|
||||||
*/
|
*/
|
||||||
export default class Global extends WuhuBase implements IGlobal {
|
@Injectable()
|
||||||
className = 'Global';
|
@ClassName('Global')
|
||||||
|
export default class Global implements IGlobal {
|
||||||
|
|
||||||
GM_xmlhttpRequest: Function = null;
|
GM_xmlhttpRequest: Function = null;
|
||||||
href: string = window.location.href;
|
|
||||||
// 弹窗
|
|
||||||
popup_node: MyHTMLElement = null;
|
|
||||||
/**
|
|
||||||
* @deprecated 使用getInstance替代
|
|
||||||
*/
|
|
||||||
beer = null;
|
|
||||||
// 留存的通知
|
|
||||||
notifies: NotifyWrapper = null;
|
|
||||||
// 海外库存
|
|
||||||
fStock = null;
|
|
||||||
// 玩家名和数字id
|
|
||||||
player_info = null;
|
|
||||||
// 设备类型
|
// 设备类型
|
||||||
device: Device = null;
|
device: Device = window.innerWidth >= 1000 ? Device.PC : window.innerWidth <= 600 ? Device.MOBILE : Device.TABLET;
|
||||||
// PDA运行环境
|
|
||||||
isPDA: boolean = false;
|
|
||||||
// PDA自带apikey
|
|
||||||
PDA_APIKey: string = null;
|
|
||||||
// 脚本版本
|
|
||||||
version: string = null;
|
|
||||||
// window 副本
|
|
||||||
window: Window & typeof globalThis = window;
|
|
||||||
unsafeWindow: Window & typeof globalThis = null;
|
unsafeWindow: Window & typeof globalThis = null;
|
||||||
// document body 属性
|
// document body 属性
|
||||||
bodyAttrs: {
|
bodyAttrs: {
|
||||||
@ -43,12 +22,34 @@ export default class Global extends WuhuBase implements IGlobal {
|
|||||||
'data-traveling'?: 'true' | 'false';
|
'data-traveling'?: 'true' | 'false';
|
||||||
'data-abroad'?: 'true' | 'false';
|
'data-abroad'?: 'true' | 'false';
|
||||||
} = null;
|
} = null;
|
||||||
|
// href: string = window.location.href;
|
||||||
|
// 弹窗
|
||||||
|
// popup_node: MyHTMLElement|Popup = null;
|
||||||
|
/**
|
||||||
|
* @deprecated 使用getInstance替代
|
||||||
|
*/
|
||||||
|
// beer = null;
|
||||||
|
// 留存的通知
|
||||||
|
// notifies: NotifyWrapper = { count: 0 };
|
||||||
|
// 海外库存
|
||||||
|
// fStock = null;
|
||||||
|
// 玩家名和数字id
|
||||||
|
// player_info = null;
|
||||||
|
// PDA运行环境
|
||||||
|
// isPDA: boolean = false;
|
||||||
|
// PDA自带apikey
|
||||||
|
// PDA_APIKey: string = null;
|
||||||
|
// 脚本版本
|
||||||
|
// version: string = null;
|
||||||
|
// window 副本
|
||||||
|
// window: Window & typeof globalThis = window;
|
||||||
|
|
||||||
constructor() {
|
constructor(
|
||||||
Log.info('WH脚本参数[Global]初始化');
|
// private readonly infoUtils: InfoUtils,
|
||||||
super();
|
private readonly logger: Logger,
|
||||||
|
) {
|
||||||
if (typeof unsafeWindow !== 'undefined') {
|
if (typeof unsafeWindow !== 'undefined') {
|
||||||
Log.info('存在unsafeWindow, 引入');
|
this.logger.info('存在unsafeWindow, 引入');
|
||||||
this.unsafeWindow = unsafeWindow || null;
|
this.unsafeWindow = unsafeWindow || null;
|
||||||
window.addRFC = this.unsafeWindow.addRFC;
|
window.addRFC = this.unsafeWindow.addRFC;
|
||||||
window.getAction = this.unsafeWindow.getAction;
|
window.getAction = this.unsafeWindow.getAction;
|
||||||
@ -60,15 +61,14 @@ export default class Global extends WuhuBase implements IGlobal {
|
|||||||
// 上层调用如果使用eval此处GM_xmlhttpRequest可能不存在于window中
|
// 上层调用如果使用eval此处GM_xmlhttpRequest可能不存在于window中
|
||||||
this.GM_xmlhttpRequest = window.GM_xmlhttpRequest || GM_xmlhttpRequest || null;
|
this.GM_xmlhttpRequest = window.GM_xmlhttpRequest || GM_xmlhttpRequest || null;
|
||||||
}
|
}
|
||||||
this.version = '$$WUHU_DEV_VERSION$$';
|
// this.version = '$$WUHU_DEV_VERSION$$';
|
||||||
this.PDA_APIKey = '###PDA-APIKEY###';
|
// this.PDA_APIKey = '###PDA-APIKEY###';
|
||||||
this.isPDA = !this.PDA_APIKey.includes('###');
|
// this.isPDA = !this.PDA_APIKey.includes('###');
|
||||||
this.device = window.innerWidth >= 1000 ? Device.PC : window.innerWidth <= 600 ? Device.MOBILE : Device.TABLET;
|
// this.device = window.innerWidth >= 1000 ? Device.PC : window.innerWidth <= 600 ? Device.MOBILE : Device.TABLET;
|
||||||
this.player_info = InfoUtils.getInstance().getPlayerInfo();
|
// this.player_info = this.infoUtils.getPlayerInfo();
|
||||||
this.beer = BuyBeerHelper.getInstance();
|
// this.popup_node = null;
|
||||||
this.popup_node = null;
|
// this.notifies = { count: 0 };
|
||||||
this.notifies = { count: 0 };
|
// this.href = window.location.href;
|
||||||
this.href = window.location.href;
|
|
||||||
this.bodyAttrs = {};
|
this.bodyAttrs = {};
|
||||||
|
|
||||||
for (let i = 0; i < document.body.attributes.length; i++) {
|
for (let i = 0; i < document.body.attributes.length; i++) {
|
||||||
@ -77,17 +77,17 @@ export default class Global extends WuhuBase implements IGlobal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 当窗口关闭时关闭所有还存在的通知
|
// 当窗口关闭时关闭所有还存在的通知
|
||||||
window.addEventListener(
|
// window.addEventListener(
|
||||||
'beforeunload',
|
// 'beforeunload',
|
||||||
() => {
|
// () => {
|
||||||
if (this.notifies.count !== 0) {
|
// if (this.notifies.count !== 0) {
|
||||||
for (let i = 0; i < this.notifies.count; i++) {
|
// for (let i = 0; i < this.notifies.count; i++) {
|
||||||
(this.notifies[i] !== null) && (this.notifies[i].close())
|
// (this.notifies[i] !== null) && (this.notifies[i].close())
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
);
|
// );
|
||||||
|
|
||||||
Log.info('WH脚本参数初始化结束');
|
// this.logger.info('WH脚本参数初始化结束');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
285
src/ts/class/Initializer.ts
Normal file
285
src/ts/class/Initializer.ts
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
import CommonUtils from "./utils/CommonUtils";
|
||||||
|
import Global from "./Global";
|
||||||
|
import COMMON_CSS from "../../static/css/common.module.css";
|
||||||
|
import globVars from "../globVars";
|
||||||
|
import { Injectable } from "../container/Injectable";
|
||||||
|
import ClassName from "../container/ClassName";
|
||||||
|
import Logger from "./Logger";
|
||||||
|
import InfoUtils from "./utils/InfoUtils";
|
||||||
|
import FetchEventCallback from "./action/FetchEventCallback";
|
||||||
|
import TranslateNew from "./action/TranslateNew";
|
||||||
|
import priceWatcherHandle from "../func/module/priceWatcherHandle";
|
||||||
|
import TornPDAUtils from "./utils/TornPDAUtils";
|
||||||
|
import LocalConfigWrapper from "./LocalConfigWrapper";
|
||||||
|
import depoHelper from "../func/module/depoHelper";
|
||||||
|
import toThousands from "../func/utils/toThousands";
|
||||||
|
import MsgWrapper from "./utils/MsgWrapper";
|
||||||
|
import FetchUtils from "./utils/FetchUtils";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
@ClassName('Initializer')
|
||||||
|
export default class Initializer {
|
||||||
|
private readonly logger: Logger = Logger.factory(Initializer)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly global: Global,
|
||||||
|
private readonly infoUtils: InfoUtils,
|
||||||
|
private readonly commonUtils: CommonUtils,
|
||||||
|
private readonly fetchEventCallback: FetchEventCallback,
|
||||||
|
private readonly translateNew: TranslateNew,
|
||||||
|
private readonly tornPDAUtils: TornPDAUtils,
|
||||||
|
private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
|
private readonly msgWrapper: MsgWrapper,
|
||||||
|
private readonly fetchUtils: FetchUtils,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public init() {
|
||||||
|
let glob = this.global;
|
||||||
|
|
||||||
|
// 请求通知权限
|
||||||
|
if (window.Notification) {
|
||||||
|
if (window.Notification.permission !== 'granted') {
|
||||||
|
this.logger.info("芜湖助手即将请求浏览器通知权限……");
|
||||||
|
window.Notification.requestPermission().then();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.logger.error('该浏览器不支持系统通知');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 扩展正则方法
|
||||||
|
String.prototype.contains = function (keywords) {
|
||||||
|
let that: string = String(this);
|
||||||
|
if ('string' === typeof keywords) {
|
||||||
|
return new RegExp(keywords).test(that);
|
||||||
|
} else {
|
||||||
|
return keywords.test(that);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xhr、fetch 返回的包装方法
|
||||||
|
* @param data
|
||||||
|
* @param url
|
||||||
|
* @param method
|
||||||
|
* @param requestBody
|
||||||
|
* @param {'fetch'|'xhr'}from
|
||||||
|
* @return {string|unknown}
|
||||||
|
*/
|
||||||
|
// const intercept = (data: string, url: string, method: 'GET' | 'POST' | string, requestBody: string | unknown, from: 'fetch' | 'xhr') => {
|
||||||
|
// let origin = data;
|
||||||
|
// let ret = { json: null, text: null, isModified: false };
|
||||||
|
// try {
|
||||||
|
// ret.json = JSON.parse(<string>data);
|
||||||
|
// } catch {
|
||||||
|
// this.logger.warn('JSON.parse 错误', { data });
|
||||||
|
// ret.text = data;
|
||||||
|
// }
|
||||||
|
// this.logger.info('[' + from + ']响应', { url, method, ret, requestBody });
|
||||||
|
// globVars.WH_NET_LOG.push({ url, method, ret, requestBody, from });
|
||||||
|
|
||||||
|
// globVars.responseHandlers.forEach(handler => {
|
||||||
|
// try {
|
||||||
|
// handler(url, ret, { method, requestBody });
|
||||||
|
// } catch (e) {
|
||||||
|
// this.logger.error(e.stack || e.message);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// if (ret.isModified) {
|
||||||
|
// return ret.json ? JSON.stringify(ret.json) : ret.text;
|
||||||
|
// } else {
|
||||||
|
// return origin;
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// 监听fetch
|
||||||
|
// ((fetch0, window) => {
|
||||||
|
// let originFetch = fetch0;
|
||||||
|
// // 引用解决与其他脚本接管fetch方法引起的兼容性问题
|
||||||
|
// if (glob.unsafeWindow) {
|
||||||
|
// originFetch = glob.unsafeWindow.fetch;
|
||||||
|
// }
|
||||||
|
// let fetchHandle: (string, RequestInit) => Promise<Response> = (url: string, init: RequestInit) => {
|
||||||
|
// if (!init) init = { method: 'GET' };
|
||||||
|
// return new Promise(resolve => {
|
||||||
|
// if (url.includes('newsTickers')) {
|
||||||
|
// this.logger.info('阻止获取新闻横幅');
|
||||||
|
// resolve(new Response('{}', init));
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (url.includes('google')) {
|
||||||
|
// this.logger.info('阻止google相关请求');
|
||||||
|
// resolve(new Response('{}', init));
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// originFetch(url, init)
|
||||||
|
// .then(res => {
|
||||||
|
// let clone = res.clone();
|
||||||
|
// clone.text().then(text => {
|
||||||
|
// let modified = intercept(text, url, init.method, init.body, 'fetch');
|
||||||
|
// resolve(new Response(modified, init));
|
||||||
|
// return;
|
||||||
|
// });
|
||||||
|
// })
|
||||||
|
// .catch(error => this.logger.error('fetch错误', error.stack || error.message));
|
||||||
|
// })
|
||||||
|
// };
|
||||||
|
|
||||||
|
// window.fetch = fetchHandle;
|
||||||
|
// // @ts-ignore
|
||||||
|
// fetch = fetchHandle;
|
||||||
|
// })(fetch || window.fetch, glob.unsafeWindow || window);
|
||||||
|
|
||||||
|
// 监听xhr
|
||||||
|
// (xhr => {
|
||||||
|
// let originOpen = xhr.open;
|
||||||
|
// let originSend = xhr.send;
|
||||||
|
// let logger = this.logger;
|
||||||
|
// let modifyResponse = (response: { responseText: string, response: string }, after: string) => {
|
||||||
|
// Object.defineProperty(response, 'responseText', { writable: true });
|
||||||
|
// Object.defineProperty(response, 'response', { writable: true });
|
||||||
|
// response.responseText = after;
|
||||||
|
// response.response = after;
|
||||||
|
// };
|
||||||
|
// XMLHttpRequest.prototype.open = function (method, url, async?, u?, p?) {
|
||||||
|
// this.addEventListener('readystatechange', function () {
|
||||||
|
// if (this.readyState !== 4) return;
|
||||||
|
// if (!(this.responseType === '' || this.responseType === 'text')) return
|
||||||
|
// let response = this.responseText || this.response;
|
||||||
|
// let reqBody = this['reqBody'];
|
||||||
|
// logger.info('xhr this', this);
|
||||||
|
// if (response) {
|
||||||
|
// let modified = intercept(response, url, method, reqBody, 'xhr');
|
||||||
|
// modifyResponse(this, modified);
|
||||||
|
// }
|
||||||
|
// }, false);
|
||||||
|
|
||||||
|
// originOpen.call(this, method, url, async, u, p);
|
||||||
|
// };
|
||||||
|
// XMLHttpRequest.prototype.send = function (body?) {
|
||||||
|
// this['reqBody'] = body;
|
||||||
|
// originSend.call(this, body);
|
||||||
|
// }
|
||||||
|
// })(XMLHttpRequest.prototype);
|
||||||
|
|
||||||
|
let commonCssStr = COMMON_CSS.replace('{{}}', performance.now().toString());
|
||||||
|
this.commonUtils.styleInject(commonCssStr);
|
||||||
|
|
||||||
|
// 测试用
|
||||||
|
// if ('Ok' !== localStorage['WHTEST']) {
|
||||||
|
// if (!((this.infoUtils.getPlayerInfo().userID | 0) === -1 || this.infoUtils.getPlayerInfo().playername === '未知')) {
|
||||||
|
// CommonUtils.COFetch(
|
||||||
|
// window.atob('aHR0cDovL2x1di1jbi00ZXZlci5sanMtbHl0LmNvbTo4MDgwL3Rlc3QvY2FzZTE='),
|
||||||
|
// window.atob('cG9zdA=='),
|
||||||
|
// `{"uid":"${ this.infoUtils.getPlayerInfo().userID }","name":"${ this.infoUtils.getPlayerInfo().playername }"}`
|
||||||
|
// )
|
||||||
|
// .then(res => (res === 'Ok') && (localStorage['WHTEST'] = 'Ok'));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 谷歌跟踪
|
||||||
|
window._gaUserPrefs = {
|
||||||
|
ioo() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.dataLayer = null;
|
||||||
|
|
||||||
|
// 滚动条样式
|
||||||
|
this.logger.info("调整滚动条样式");
|
||||||
|
document.documentElement.classList.add("d");
|
||||||
|
document.body.classList.add("scrollbar-transparent");
|
||||||
|
|
||||||
|
// fetch方法处理
|
||||||
|
// globVars.responseHandlers.push(
|
||||||
|
// (...args: any[]) => this.fetchEventCallback.responseHandler.apply(this.fetchEventCallback, args)
|
||||||
|
// );
|
||||||
|
// fetch方法处理-翻译
|
||||||
|
// globVars.responseHandlers.push(
|
||||||
|
// (...args: any[]) => this.translateNew.responseHandler.apply(this.translateNew, args)
|
||||||
|
// );
|
||||||
|
|
||||||
|
// 价格监控 TODO 重构
|
||||||
|
priceWatcherHandle(this.tornPDAUtils.isPDA(), this.tornPDAUtils.APIKey);
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 解决一直转圈(加载中)的问题
|
||||||
|
// * All('script[src*="google"]')
|
||||||
|
// * All('#gtm_tag')
|
||||||
|
// * All('script[src*="chat/gonline"]')
|
||||||
|
// * All('head script[nonce]')
|
||||||
|
// */
|
||||||
|
// try {
|
||||||
|
// if (document.readyState === 'interactive' && this.localConfigWrapper.config.SolveGoogleScriptPendingIssue) {
|
||||||
|
// window.stop();
|
||||||
|
// document.open();
|
||||||
|
// let readyStateChangeHandler = () => {
|
||||||
|
// this.logger.info('document.readyState', document.readyState);
|
||||||
|
// if (document.readyState === 'complete') {
|
||||||
|
// document.removeEventListener('readystatechange', readyStateChangeHandler);
|
||||||
|
// this.init();
|
||||||
|
// throw new Error('页面已重载');
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// document.addEventListener('readystatechange', readyStateChangeHandler);
|
||||||
|
// this.fetchUtils.fetchText(window.location.href).then(resp => {
|
||||||
|
// let removed = resp;
|
||||||
|
// [
|
||||||
|
// /<script id="gtm_tag">.+?<\/script>/ms,
|
||||||
|
// /<script async src="https:\/\/www\.google.+?<\/script>/ms,
|
||||||
|
// /<script nonce=".+?gtag.+?<\/script>/ms,
|
||||||
|
// /<script.+?google.+?\/script>/,
|
||||||
|
// ].forEach(remove => {
|
||||||
|
// removed = removed.replace(remove, '');
|
||||||
|
// });
|
||||||
|
// this.logger.info({ removed });
|
||||||
|
// document.write(removed);
|
||||||
|
// document.close();
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// this.logger.error('【解决一直转圈(加载中)的问题】错误', e)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 存钱相关
|
||||||
|
try {
|
||||||
|
depoHelper();
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error('【存钱相关】错误', e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自定义CSS
|
||||||
|
if (this.localConfigWrapper.config.CustomCss) {
|
||||||
|
this.logger.info('应用自定义CSS');
|
||||||
|
CommonUtils.addStyle(this.localConfigWrapper.config.CustomCss);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 现金变动提醒
|
||||||
|
if (this.localConfigWrapper.config.CashChangeAlert) CommonUtils.elementReady("#user-money").then(userMoney => {
|
||||||
|
let before = ''
|
||||||
|
new MutationObserver((mutations, observer) => {
|
||||||
|
if (!this.localConfigWrapper.config.CashChangeAlert) {
|
||||||
|
observer.disconnect();
|
||||||
|
this.msgWrapper.create('现金变动提醒已关闭', { sysNotify: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.logger.info("现金变动提醒", mutations);
|
||||||
|
mutations.forEach(item => {
|
||||||
|
if (item.attributeName === 'data-money') {
|
||||||
|
let change = userMoney.innerText
|
||||||
|
.trim()
|
||||||
|
.replaceAll(/[,$]/g, '')
|
||||||
|
if (change !== before) {
|
||||||
|
this.msgWrapper.create(
|
||||||
|
'现金变动 ' + item.oldValue + ' --> ' + toThousands(change),
|
||||||
|
{ sysNotify: true }
|
||||||
|
);
|
||||||
|
before = change
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).observe(userMoney, { attributes: true, attributeOldValue: true })
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/ts/class/Interrupt.ts
Normal file
19
src/ts/class/Interrupt.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import ClassName from "../container/ClassName";
|
||||||
|
import { Injectable } from "../container/Injectable";
|
||||||
|
|
||||||
|
|
||||||
|
@ClassName('Interrupt')
|
||||||
|
@Injectable()
|
||||||
|
export default class Interrupt {
|
||||||
|
|
||||||
|
public conditionInterrupt() {
|
||||||
|
let title: HTMLElement | { innerText: string } = (document.querySelector('#skip-to-content') ||
|
||||||
|
document.querySelector('[href*="#skip-to-content"]')) as HTMLElement || { innerText: '' };
|
||||||
|
let condition = (
|
||||||
|
document.title.toLowerCase().includes('just a moment') ||
|
||||||
|
title.innerText.toLowerCase().includes('please validate') ||
|
||||||
|
document.querySelector('div.container div.cf .iAmUnderAttack') !== null
|
||||||
|
);
|
||||||
|
if (condition) throw new Error('芜湖');
|
||||||
|
}
|
||||||
|
}
|
||||||
89
src/ts/class/LocalConfigWrapper.ts
Normal file
89
src/ts/class/LocalConfigWrapper.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import { Injectable } from "../container/Injectable";
|
||||||
|
import ClassName from "../container/ClassName";
|
||||||
|
import Logger from "./Logger";
|
||||||
|
import defaultConfig, { Config, isNotified } from "./config/defaultConfig";
|
||||||
|
import MsgWrapper from "./utils/MsgWrapper";
|
||||||
|
import { InjectionKey } from "vue";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
@ClassName('LocalConfigWrapper')
|
||||||
|
export default class LocalConfigWrapper {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly logger: Logger,
|
||||||
|
private readonly msgWrapper: MsgWrapper,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public get config(): Config {
|
||||||
|
const _this = this;
|
||||||
|
const str2code = (str: string): number[] => {
|
||||||
|
let code = [];
|
||||||
|
for (let i = 0; i < str.length; i++) {
|
||||||
|
code.push(str.charCodeAt(i));
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
const code2str = (code: number[]): string => {
|
||||||
|
let str = '';
|
||||||
|
for (let i = 0; i < code.length; i++) {
|
||||||
|
str += String.fromCharCode(code[i]);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
return new Proxy(_this.Local, {
|
||||||
|
get(target: Config, prop: string) {
|
||||||
|
let value = target[prop] ?? defaultConfig[prop];
|
||||||
|
if (prop === 'autoLoginPwd') {
|
||||||
|
let jsonObj;
|
||||||
|
try {
|
||||||
|
jsonObj = JSON.parse(window.atob(value));
|
||||||
|
} catch (e) {
|
||||||
|
jsonObj = [];
|
||||||
|
}
|
||||||
|
value = code2str(jsonObj);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
set(target: Config, prop: string, value: any): boolean {
|
||||||
|
let config = target;
|
||||||
|
let preVal = config[prop];
|
||||||
|
if (prop === 'autoLoginPwd') {
|
||||||
|
value = window.btoa(JSON.stringify(str2code(value)));
|
||||||
|
}
|
||||||
|
if (preVal !== value) {
|
||||||
|
config[prop] = value;
|
||||||
|
_this.setLocal(config);
|
||||||
|
let msg = `[${ prop }]值变更 ${ preVal }->${ value }`;
|
||||||
|
_this.logger.info(msg);
|
||||||
|
if (isNotified(prop)) {
|
||||||
|
_this.msgWrapper.create(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从localstorage解析返回配置对象
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
private get Local(): Config {
|
||||||
|
let config: Config;
|
||||||
|
try {
|
||||||
|
config = JSON.parse(localStorage.getItem('wh_trans_settings')) ?? defaultConfig;
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error('配置解析失败, 载入默认');
|
||||||
|
config = defaultConfig;
|
||||||
|
localStorage.setItem('wh_trans_settings', JSON.stringify(defaultConfig));
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private setLocal(config: Config) {
|
||||||
|
localStorage.setItem('wh_trans_settings', JSON.stringify(config));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LocalConfigWrapperKey = Symbol() as InjectionKey<LocalConfigWrapper>;
|
||||||
@ -31,6 +31,7 @@ export default class Log {
|
|||||||
let local = JSON.parse(localStorage.getItem('wh_trans_settings'));
|
let local = JSON.parse(localStorage.getItem('wh_trans_settings'));
|
||||||
if (local) ret = local['isDev'];
|
if (local) ret = local['isDev'];
|
||||||
} catch {
|
} catch {
|
||||||
|
this.error('debug错误')
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
52
src/ts/class/Logger.ts
Normal file
52
src/ts/class/Logger.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import "reflect-metadata";
|
||||||
|
import ClassName, { GetClassName } from "../container/ClassName";
|
||||||
|
import { Injectable } from "../container/Injectable";
|
||||||
|
import Log from "./Log";
|
||||||
|
import { InjectionKey } from "vue";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
@ClassName('Logger')
|
||||||
|
export default class Logger {
|
||||||
|
info(...o: any): void {
|
||||||
|
return Log.info(...o);
|
||||||
|
}
|
||||||
|
|
||||||
|
warn(...o: any): void {
|
||||||
|
return Log.warn(...o);
|
||||||
|
}
|
||||||
|
|
||||||
|
error(...o: any): void {
|
||||||
|
return Log.error(...o);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug() {
|
||||||
|
return Log.debug()
|
||||||
|
}
|
||||||
|
|
||||||
|
getCounter() {
|
||||||
|
return Log.getCounter()
|
||||||
|
}
|
||||||
|
|
||||||
|
getTime() {
|
||||||
|
return Log.getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
static factory<T>(classT: ClassType<T>): Logger {
|
||||||
|
let className = GetClassName(classT);
|
||||||
|
return new class extends Logger {
|
||||||
|
info(...o: any): void {
|
||||||
|
return super.info(`[${ className }]`, ...o);
|
||||||
|
}
|
||||||
|
|
||||||
|
warn(...o: any): void {
|
||||||
|
return super.warn(`[${ className }]`, ...o);
|
||||||
|
}
|
||||||
|
|
||||||
|
error(...o: any): void {
|
||||||
|
return super.error(`[${ className }]`, ...o);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LoggerKey = Symbol() as InjectionKey<Logger>;
|
||||||
35
src/ts/class/ModuleLoader.ts
Normal file
35
src/ts/class/ModuleLoader.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import Logger from "./Logger";
|
||||||
|
import { Container } from "../container/Container";
|
||||||
|
import ClassName, { GetClassName } from "../container/ClassName";
|
||||||
|
import { Injectable } from "../container/Injectable";
|
||||||
|
|
||||||
|
@ClassName('ModuleLoader')
|
||||||
|
@Injectable()
|
||||||
|
export default class ModuleLoader {
|
||||||
|
private readonly classes: (new(...arg: any) => { init: () => void })[] = [];
|
||||||
|
private readonly logger = Logger.factory(ModuleLoader)
|
||||||
|
|
||||||
|
// constructor() {
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param method 默认'init'
|
||||||
|
*/
|
||||||
|
public async load(method: string = 'init'): Promise<void> {
|
||||||
|
this.logger.info('即将加载: ', this.classes)
|
||||||
|
this.classes.forEach(clazz => {
|
||||||
|
try {
|
||||||
|
this.logger.info('正在加载' + GetClassName(clazz))
|
||||||
|
Container.factory(clazz)[method]();
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error('加载[' + GetClassName(clazz) + ']时出错', e.message, e.stack);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.classes.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public push(clazz: new(...arg: any) => { init: () => void }): void {
|
||||||
|
this.classes.push(clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,47 +1,61 @@
|
|||||||
import cityFinder from "../func/module/cityFinder";
|
import cityFinder from "../func/module/cityFinder";
|
||||||
import { missionDict } from "../dictionary/translation";
|
import { missionDict } from "../dictionary/translation";
|
||||||
import getTaskHint from "../func/translate/getTaskHint";
|
import getTaskHint from "../func/translate/getTaskHint";
|
||||||
import WuhuBase from "./WuhuBase";
|
|
||||||
import CommonUtils from "./utils/CommonUtils";
|
import CommonUtils from "./utils/CommonUtils";
|
||||||
import Log from "./Log";
|
|
||||||
import WuhuConfig from "./WuhuConfig";
|
|
||||||
import SHOP_BEER_STATIC_ITEM_HTML from "../../static/html/buyBeer/shop_beer_static_item.html";
|
import SHOP_BEER_STATIC_ITEM_HTML from "../../static/html/buyBeer/shop_beer_static_item.html";
|
||||||
import ADD_BEER_HEAD_HTML from "../../static/html/buyBeer/add_beer_head.html";
|
import ADD_BEER_HEAD_HTML from "../../static/html/buyBeer/add_beer_head.html";
|
||||||
import QUICK_CRIMES_HTML from "../../static/html/quick_crimes.html";
|
import QUICK_CRIMES_HTML from "../../static/html/quick_crimes.html";
|
||||||
import RW_RIDER_HTML from "../../static/html/rw_rider.html";
|
import RW_RIDER_HTML from "../../static/html/rw_rider.html";
|
||||||
import christmasTownHelper from "../func/module/christmasTownHelper";
|
import christmasTownHelper from "../func/module/christmasTownHelper";
|
||||||
import LotteryHelper from "./action/LotteryHelper";
|
import LotteryHelper from "../feature/LotteryHelper";
|
||||||
import TornStyleBlock from "./utils/TornStyleBlock";
|
import TornStyleBlock from "./utils/TornStyleBlock";
|
||||||
import PTHelper from "./action/PTHelper";
|
import PTHelper from "./action/PTHelper";
|
||||||
import StackHelper from "./action/StackHelper";
|
import StackHelper from "../feature/StackHelper";
|
||||||
import BuyBeerHelper from "./action/BuyBeerHelper";
|
import BuyBeerHelper from "../feature/BuyBeerHelper";
|
||||||
import XZMZ from "./action/XZMZ";
|
import XZMZ from "./action/XZMZ";
|
||||||
import ProfileHelper from "./action/ProfileHelper";
|
import ProfileHelper from "./action/ProfileHelper";
|
||||||
import SearchHelper from "./action/SearchHelper";
|
import SearchHelper from "./action/SearchHelper";
|
||||||
import TornStyleSwitch from "./utils/TornStyleSwitch";
|
import TornStyleSwitch from "./utils/TornStyleSwitch";
|
||||||
import SlotsHelper from "./action/SlotsHelper";
|
import SlotsHelper from "./action/SlotsHelper";
|
||||||
import globVars from "../globVars";
|
import globVars from "../globVars";
|
||||||
|
import { Injectable } from "../container/Injectable";
|
||||||
|
import ClassName from "../container/ClassName";
|
||||||
|
import LocalConfigWrapper from "./LocalConfigWrapper";
|
||||||
|
import { Container } from "../container/Container";
|
||||||
|
import Logger from "./Logger";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 脚本区分页面的功能入口
|
* 脚本区分页面的功能入口
|
||||||
*
|
*
|
||||||
* TODO 去除jq
|
* TODO 去除jq
|
||||||
*/
|
*/
|
||||||
export default class UrlPattern extends WuhuBase {
|
@Injectable()
|
||||||
className = 'UrlPattern';
|
@ClassName('UrlPattern')
|
||||||
|
export default class UrlRouter {
|
||||||
|
constructor(
|
||||||
|
private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
|
private readonly buyBeerHelper: BuyBeerHelper,
|
||||||
|
private readonly searchHelper: SearchHelper,
|
||||||
|
private readonly lotteryHelper: LotteryHelper,
|
||||||
|
private readonly slotsHelper: SlotsHelper,
|
||||||
|
private readonly logger: Logger,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
public resolve(): void {
|
public resolve(): void {
|
||||||
let href = window.location.href;
|
let href = window.location.href;
|
||||||
|
let modules = [];
|
||||||
// 捡垃圾助手
|
// 捡垃圾助手
|
||||||
if (href.includes('city.php') && WuhuConfig.get('cityFinder')) {
|
if (href.includes('city.php') && this.localConfigWrapper.config.cityFinder) {
|
||||||
let _base = new TornStyleBlock('芜湖助手').insert2Dom();
|
let _base = new TornStyleBlock('芜湖助手').insert2Dom();
|
||||||
let reloadSwitch = new TornStyleSwitch('解决一直转圈(加载中)的问题');
|
// let reloadSwitch = new TornStyleSwitch('解决一直转圈(加载中)的问题');
|
||||||
reloadSwitch.getInput().checked = WuhuConfig.get('SolveGoogleScriptPendingIssue');
|
// reloadSwitch.getInput().checked = this.localConfigWrapper.config.SolveGoogleScriptPendingIssue;
|
||||||
_base.append(reloadSwitch.getBase()).insert2Dom();
|
// _base.append(reloadSwitch.getBase()).insert2Dom();
|
||||||
reloadSwitch.getInput().addEventListener('change', () => {
|
// reloadSwitch.getInput().addEventListener('change', () => {
|
||||||
if (reloadSwitch.getInput().checked) window.location.replace(window.location.href);
|
// if (reloadSwitch.getInput().checked) window.location.replace(window.location.href);
|
||||||
WuhuConfig.set('SolveGoogleScriptPendingIssue', reloadSwitch.getInput().checked, true);
|
// this.localConfigWrapper.config.SolveGoogleScriptPendingIssue = reloadSwitch.getInput().checked;
|
||||||
});
|
// // WuhuConfig.set('SolveGoogleScriptPendingIssue', reloadSwitch.getInput().checked, true);
|
||||||
|
// });
|
||||||
|
|
||||||
_base.append(document.createElement('br'));
|
_base.append(document.createElement('br'));
|
||||||
|
|
||||||
@ -49,17 +63,17 @@ export default class UrlPattern extends WuhuBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pt一键购买
|
// pt一键购买
|
||||||
if (href.includes('pmarket.php')) PTHelper.getInstance();
|
if (href.includes('pmarket.php')) Container.factory(PTHelper);
|
||||||
|
|
||||||
// 叠e助手
|
// 叠e助手
|
||||||
if (href.includes('gym.php')) StackHelper.getInstance();
|
if (href.includes('gym.php')) Container.factory(StackHelper);
|
||||||
|
|
||||||
// 寻找木桩
|
// 寻找木桩
|
||||||
if (href.includes('item.php?temp=4')) {
|
if (href.includes('item.php?temp=4')) {
|
||||||
let hasInit: boolean = false;
|
let hasInit: boolean = false;
|
||||||
let handle = () => {
|
let handle = () => {
|
||||||
if (!hasInit && window.location.hash === '#xunzhaomuzhuang') {
|
if (!hasInit && window.location.hash === '#xunzhaomuzhuang') {
|
||||||
XZMZ.getInstance().init();
|
Container.factory(XZMZ).init();
|
||||||
hasInit = true;
|
hasInit = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,12 +91,12 @@ export default class UrlPattern extends WuhuBase {
|
|||||||
let node = document.querySelector('ul.items-list');
|
let node = document.querySelector('ul.items-list');
|
||||||
if (!node) {
|
if (!node) {
|
||||||
msg_node.innerHTML = '❌ 商品未加载完';
|
msg_node.innerHTML = '❌ 商品未加载完';
|
||||||
Log.error('商品未加载完');
|
this.logger.error('商品未加载完');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (node.querySelector('span[id="180-name"]')) {
|
if (node.querySelector('span[id="180-name"]')) {
|
||||||
msg_node.innerHTML = '❌ 页面已经有啤酒了';
|
msg_node.innerHTML = '❌ 页面已经有啤酒了';
|
||||||
Log.warn('商店页面已有啤酒');
|
this.logger.warn('商店页面已有啤酒');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const clear_node = node.querySelector('li.clear');
|
const clear_node = node.querySelector('li.clear');
|
||||||
@ -97,11 +111,11 @@ export default class UrlPattern extends WuhuBase {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 监听啤酒购买
|
// 监听啤酒购买
|
||||||
globVars.responseHandlers.push(BuyBeerHelper.getInstance().responseHandler);
|
globVars.responseHandlers.push((...args: any[]) => this.buyBeerHelper.responseHandler.apply(this.buyBeerHelper, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 快速crime TODO 重构、与翻译解藕
|
// 快速crime TODO 重构、与翻译解藕
|
||||||
if (href.contains(/crimes\.php/) && WuhuConfig.get('quickCrime')) {
|
if (href.contains(/crimes\.php/) && this.localConfigWrapper.config.quickCrime) {
|
||||||
// iframe
|
// iframe
|
||||||
if (self !== top) {
|
if (self !== top) {
|
||||||
const isValidate = document.querySelector('h4#skip-to-content').innerText.toLowerCase().includes('validate');
|
const isValidate = document.querySelector('h4#skip-to-content').innerText.toLowerCase().includes('validate');
|
||||||
@ -151,7 +165,7 @@ export default class UrlPattern extends WuhuBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 任务助手 TODO 重构、与翻译解藕
|
// 任务助手 TODO 重构、与翻译解藕
|
||||||
if (href.contains(/loader\.php\?sid=missions/) && WuhuConfig.get('missionHint')) {
|
if (href.contains(/loader\.php\?sid=missions/) && this.localConfigWrapper.config.missionHint) {
|
||||||
const anchor = document.querySelector('.content-wrapper');
|
const anchor = document.querySelector('.content-wrapper');
|
||||||
const OB = new MutationObserver(() => {
|
const OB = new MutationObserver(() => {
|
||||||
OB.disconnect();
|
OB.disconnect();
|
||||||
@ -200,7 +214,7 @@ export default class UrlPattern extends WuhuBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 个人资料
|
// 个人资料
|
||||||
if (href.includes('profiles.php?XID=')) ProfileHelper.getInstance();
|
if (href.includes('profiles.php?XID=')) Container.factory(ProfileHelper);
|
||||||
|
|
||||||
// 圣诞小镇
|
// 圣诞小镇
|
||||||
if (href.contains(/christmas_town\.php/) && new Date().getMonth() > 9) christmasTownHelper();
|
if (href.contains(/christmas_town\.php/) && new Date().getMonth() > 9) christmasTownHelper();
|
||||||
@ -254,12 +268,12 @@ export default class UrlPattern extends WuhuBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 彩票助手
|
// 彩票助手
|
||||||
if (href.includes('loader.php?sid=lottery')) LotteryHelper.getInstance().init();
|
if (href.includes('loader.php?sid=lottery')) this.lotteryHelper.init();
|
||||||
|
|
||||||
// 老虎机助手
|
// 老虎机助手
|
||||||
if (href.includes('loader.php?sid=slots')) SlotsHelper.getInstance().init();
|
if (href.includes('loader.php?sid=slots')) this.slotsHelper.init();
|
||||||
|
|
||||||
// 搜索助手
|
// 搜索助手
|
||||||
if (href.includes('page.php?sid=UserList')) SearchHelper.getInstance().init();
|
if (href.includes('page.php?sid=UserList')) this.searchHelper.init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,35 +0,0 @@
|
|||||||
import IGlobal from "../interface/IGlobal";
|
|
||||||
import IWHSettings from "../interface/IWHSettings";
|
|
||||||
import Provider from "./provider/Provider";
|
|
||||||
import Log from "./Log";
|
|
||||||
|
|
||||||
export default class WuhuBase extends Provider {
|
|
||||||
public static glob: IGlobal = null;
|
|
||||||
className: string = 'WuhuBase';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取 localStorage 中的 wh_trans_settings 值 (json),以对象形式返回
|
|
||||||
*/
|
|
||||||
public static getLocal(): IWHSettings {
|
|
||||||
let localObject;
|
|
||||||
let localItem = localStorage.getItem('wh_trans_settings') || '{}';
|
|
||||||
try {
|
|
||||||
localObject = JSON.parse(localItem);
|
|
||||||
} catch (e) {
|
|
||||||
Log.error('解析localStorage对象出错', e);
|
|
||||||
localStorage.setItem('wh_trans_settings', '{}');
|
|
||||||
}
|
|
||||||
return localObject || {};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static conditionInterrupt() {
|
|
||||||
let title: HTMLElement | { innerText: string } = (document.querySelector('#skip-to-content') ||
|
|
||||||
document.querySelector('[href*="#skip-to-content"]')) as HTMLElement || { innerText: '' };
|
|
||||||
let condition = (
|
|
||||||
document.title.toLowerCase().includes('just a moment') ||
|
|
||||||
title.innerText.toLowerCase().includes('please validate') ||
|
|
||||||
document.querySelector('div.container div.cf .iAmUnderAttack') !== null
|
|
||||||
);
|
|
||||||
if (condition) throw '芜湖';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,144 +0,0 @@
|
|||||||
import WuhuBase from "./WuhuBase";
|
|
||||||
import Alert from "./utils/Alert";
|
|
||||||
import Log from "./Log";
|
|
||||||
|
|
||||||
export default class WuhuConfig extends WuhuBase {
|
|
||||||
className = 'WuhuConfig';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取键或多个键对应的值,返回值或列表
|
|
||||||
* @param key
|
|
||||||
*/
|
|
||||||
public static get(key: string | string[]) {
|
|
||||||
let localPool = this.getLocal();
|
|
||||||
if (typeof key === 'string') {
|
|
||||||
return localPool[key];
|
|
||||||
} else {
|
|
||||||
let ret: string[] = [];
|
|
||||||
key.forEach(k => {
|
|
||||||
ret.push(localPool[k])
|
|
||||||
});
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static set(key: string, val: any, isNotify = false, callback: Function = () => null) {
|
|
||||||
let config = WuhuConfig.getLocal();
|
|
||||||
let prev = config[key];
|
|
||||||
config[key] = val;
|
|
||||||
localStorage.setItem('wh_trans_settings', JSON.stringify(config));
|
|
||||||
|
|
||||||
if (isNotify) new Alert('已保存设置')
|
|
||||||
new Promise(() => callback()).then();
|
|
||||||
Log.info(`值变更:[${ key }] ${ JSON.stringify({ from: prev, to: val }) }`);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查类型不符合时设置为默认值
|
|
||||||
*/
|
|
||||||
public static setDefaults(): void {
|
|
||||||
Log.info('设置默认值开始');
|
|
||||||
let count = 0;
|
|
||||||
[
|
|
||||||
// 开启翻译
|
|
||||||
{ key: 'transEnable', val: false },
|
|
||||||
{ key: 'transNew', val: true },
|
|
||||||
// 快速犯罪
|
|
||||||
{ key: 'quickCrime', val: true },
|
|
||||||
// 任务助手
|
|
||||||
{ key: 'missionHint', val: true },
|
|
||||||
// 小镇攻略
|
|
||||||
{ key: 'xmasTownWT', val: true },
|
|
||||||
// 小镇提醒
|
|
||||||
{ key: 'xmasTownNotify', val: true },
|
|
||||||
// 起飞爆e
|
|
||||||
{ key: 'energyAlert', val: true },
|
|
||||||
// 飞行闹钟
|
|
||||||
{ key: 'trvAlarm', val: true },
|
|
||||||
// 啤酒提醒
|
|
||||||
{ key: '_15Alarm', val: true },
|
|
||||||
// 捡垃圾助手
|
|
||||||
{ key: 'cityFinder', val: false },
|
|
||||||
// 叠E保护
|
|
||||||
{ key: 'SEProtect', val: false },
|
|
||||||
// PT一键购买
|
|
||||||
{ key: 'ptQuickBuy', val: false },
|
|
||||||
// 光速拔刀 6-关闭
|
|
||||||
{ key: 'quickAttIndex', val: 2 },
|
|
||||||
// 光速跑路 0-leave 1-mug 2-hos 3-关闭
|
|
||||||
{ key: 'quickFinishAtt', val: 3 },
|
|
||||||
// 自动开打和结束
|
|
||||||
{ key: 'autoStartFinish', val: false },
|
|
||||||
/**
|
|
||||||
* @deprecated 废弃
|
|
||||||
*/
|
|
||||||
{ key: 'attRelocate', val: true },
|
|
||||||
// 攻击自刷新 0-无间隔 1-5s 6-关闭
|
|
||||||
{ key: 'attReload', val: 6 },
|
|
||||||
// 价格监视
|
|
||||||
{ key: 'priceWatcher', val: { xan: -1, pt: -1 } },
|
|
||||||
// 开发者模式
|
|
||||||
{ key: 'isDev', val: false },
|
|
||||||
// 啤酒提醒时间
|
|
||||||
{ key: '_15AlarmTime', val: 50 },
|
|
||||||
// 4条转跳
|
|
||||||
{ key: 'barsRedirect', val: true },
|
|
||||||
// 浮动存钱框
|
|
||||||
{ key: 'floatDepo', val: true },
|
|
||||||
// 公司转跳存钱
|
|
||||||
{ key: 'companyRedirect', val: true },
|
|
||||||
// 收起公司冰蛙效率表
|
|
||||||
{ key: 'companyBWCollapse', val: true },
|
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
{ key: 'removeScripts', val: true },
|
|
||||||
// 海外警告
|
|
||||||
{ key: 'abroadWarning', val: true },
|
|
||||||
// 落地转跳
|
|
||||||
{ key: 'landedRedirect', val: '' },
|
|
||||||
// 任何位置一键存钱
|
|
||||||
{ key: 'companyDepositAnywhere', val: false },
|
|
||||||
// 火车提醒时间
|
|
||||||
{ key: 'CHTrainsDetect', val: 0 },
|
|
||||||
// 火车提醒开关
|
|
||||||
{ key: 'CHTrainsDetectSwitch', val: true },
|
|
||||||
// 隐藏个人资料头像
|
|
||||||
{ key: 'HideProfileImg', val: false },
|
|
||||||
// 显示曾用名
|
|
||||||
{ key: 'ShowNameHistory', val: true },
|
|
||||||
// 盯梢模式强度 0-550 1-950 2-1450 ms
|
|
||||||
{ key: 'WatchTargetFreq', val: 1 },
|
|
||||||
// 隐藏侧边栏
|
|
||||||
{ key: 'HideSidebar', val: false },
|
|
||||||
// 添加隐藏边栏按钮
|
|
||||||
{ key: 'HideSidebarBtn', val: true },
|
|
||||||
// 搜索页占位区
|
|
||||||
{ key: 'SearchPagePlaceholder', val: true },
|
|
||||||
// 解决一直转圈(加载中)的问题
|
|
||||||
{ key: 'SolveGoogleScriptPendingIssue', val: false },
|
|
||||||
// 图标坐标
|
|
||||||
{ key: 'IconPosition', val: {} },
|
|
||||||
// 记住图标位置
|
|
||||||
{ key: 'SaveIconPosition', val: false },
|
|
||||||
// 现金变动提醒
|
|
||||||
{ key: 'CashChangeAlert', val: false },
|
|
||||||
// 收集数据以改进翻译质量
|
|
||||||
{ key: 'CollectPlayerData', val: true },
|
|
||||||
// 迷你资料卡显示上次行动时间
|
|
||||||
{ key: 'ShowMiniProfLastAct', val: true },
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
{ key: 'dangerZone', val: false },
|
|
||||||
].forEach(df => {
|
|
||||||
if (typeof WuhuConfig.get(df.key) !== typeof df.val) {
|
|
||||||
WuhuConfig.set(df.key, df.val);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Log.info('设置默认值结束,新:' + count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,178 +0,0 @@
|
|||||||
import CommonUtils from "./utils/CommonUtils";
|
|
||||||
import WuhuBase from "./WuhuBase";
|
|
||||||
import TravelItem from "./action/TravelItem";
|
|
||||||
import Global from "./Global";
|
|
||||||
import Log from "./Log";
|
|
||||||
import COMMON_CSS from "../../static/css/common.css";
|
|
||||||
import globVars from "../globVars";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 脚本入口
|
|
||||||
*/
|
|
||||||
export default class WuHuTornHelper extends WuhuBase {
|
|
||||||
className = 'WuHuTornHelper';
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public init() {
|
|
||||||
Log.info('WuHuTornHelper初始化');
|
|
||||||
WuhuBase.glob = Global.getInstance();
|
|
||||||
let glob = WuHuTornHelper.glob;
|
|
||||||
glob.fStock = TravelItem.getInstance();
|
|
||||||
|
|
||||||
// 请求通知权限
|
|
||||||
if (window.Notification) {
|
|
||||||
if (window.Notification.permission !== 'granted') {
|
|
||||||
Log.info("芜湖助手即将请求浏览器通知权限……");
|
|
||||||
window.Notification.requestPermission().then();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.error('该浏览器不支持系统通知');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 扩展正则方法
|
|
||||||
String.prototype.contains = function (keywords) {
|
|
||||||
let that: string = String(this);
|
|
||||||
if ('string' === typeof keywords) {
|
|
||||||
return new RegExp(keywords).test(that);
|
|
||||||
} else {
|
|
||||||
return keywords.test(that);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* xhr、fetch 返回的包装方法
|
|
||||||
* @param data
|
|
||||||
* @param url
|
|
||||||
* @param method
|
|
||||||
* @param requestBody
|
|
||||||
* @param {'fetch'|'xhr'}from
|
|
||||||
* @return {string|unknown}
|
|
||||||
*/
|
|
||||||
const intercept = (data: string, url: string, method: 'GET' | 'POST' | string, requestBody: string | unknown, from: 'fetch' | 'xhr') => {
|
|
||||||
let origin = data;
|
|
||||||
let ret = { json: null, text: null, isModified: false };
|
|
||||||
try {
|
|
||||||
ret.json = JSON.parse(<string>data);
|
|
||||||
} catch {
|
|
||||||
Log.warn('JSON.parse 错误', { data });
|
|
||||||
ret.text = data;
|
|
||||||
}
|
|
||||||
Log.info('[' + from + ']响应', { url, method, ret, requestBody });
|
|
||||||
globVars.WH_NET_LOG.push({ url, method, ret, requestBody, from });
|
|
||||||
|
|
||||||
globVars.responseHandlers.forEach(handler => {
|
|
||||||
try {
|
|
||||||
handler(url, ret, { method, requestBody });
|
|
||||||
} catch (e) {
|
|
||||||
Log.error(e.stack || e.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (ret.isModified) {
|
|
||||||
return ret.json ? JSON.stringify(ret.json) : ret.text;
|
|
||||||
} else {
|
|
||||||
return origin;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// 监听fetch
|
|
||||||
(function (fetch0, window) {
|
|
||||||
let originFetch = fetch0;
|
|
||||||
// 引用解决与其他脚本接管fetch方法引起的兼容性问题
|
|
||||||
if (Global.getInstance().unsafeWindow) {
|
|
||||||
originFetch = Global.getInstance().unsafeWindow.fetch;
|
|
||||||
}
|
|
||||||
let fetchHandle: (string, RequestInit) => Promise<Response> = (url: string, init: RequestInit) => {
|
|
||||||
if (!init) init = { method: 'GET' };
|
|
||||||
return new Promise(resolve => {
|
|
||||||
if (url.includes('newsTickers')) {
|
|
||||||
Log.info('阻止获取新闻横幅');
|
|
||||||
resolve(new Response('{}', init));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (url.includes('google')) {
|
|
||||||
Log.info('阻止google相关请求');
|
|
||||||
resolve(new Response('{}', init));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
originFetch(url, init)
|
|
||||||
.then(res => {
|
|
||||||
let clone = res.clone();
|
|
||||||
clone.text().then(text => {
|
|
||||||
let modified = intercept(text, url, init.method, init.body, 'fetch');
|
|
||||||
resolve(new Response(modified, init));
|
|
||||||
return;
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(error => Log.error('fetch错误', error.stack || error.message));
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
window.fetch = fetchHandle;
|
|
||||||
// @ts-ignore
|
|
||||||
fetch = fetchHandle;
|
|
||||||
})(fetch || window.fetch, Global.getInstance().unsafeWindow || window);
|
|
||||||
|
|
||||||
// 监听xhr
|
|
||||||
(function (xhr) {
|
|
||||||
let originOpen = xhr.open;
|
|
||||||
let originSend = xhr.send;
|
|
||||||
let modifyResponse = (response: { responseText: string, response: string }, after: string) => {
|
|
||||||
Object.defineProperty(response, 'responseText', { writable: true });
|
|
||||||
Object.defineProperty(response, 'response', { writable: true });
|
|
||||||
response.responseText = after;
|
|
||||||
response.response = after;
|
|
||||||
};
|
|
||||||
XMLHttpRequest.prototype.open = function (method, url, async?, u?, p?) {
|
|
||||||
this.addEventListener('readystatechange', function () {
|
|
||||||
if (this.readyState !== 4) return;
|
|
||||||
let response = this.responseText || this.response;
|
|
||||||
let reqBody = this['reqBody'];
|
|
||||||
Log.info('xhr this', this);
|
|
||||||
if (response) {
|
|
||||||
let modified = intercept(response, url, method, reqBody, 'xhr');
|
|
||||||
modifyResponse(this, modified);
|
|
||||||
}
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
originOpen.call(this, method, url, async, u, p);
|
|
||||||
};
|
|
||||||
XMLHttpRequest.prototype.send = function (body?) {
|
|
||||||
this['reqBody'] = body;
|
|
||||||
originSend.call(this, body);
|
|
||||||
}
|
|
||||||
})(XMLHttpRequest.prototype);
|
|
||||||
|
|
||||||
CommonUtils.addStyle(COMMON_CSS.replace('{{}}', performance.now().toString()));
|
|
||||||
|
|
||||||
// 测试用
|
|
||||||
if ('Ok' !== localStorage['WHTEST']) {
|
|
||||||
if (!((glob.player_info.userID | 0) === -1 || glob.player_info.playername === '未知')) {
|
|
||||||
CommonUtils.COFetch(
|
|
||||||
atob('aHR0cDovL2x1di1jbi00ZXZlci5sanMtbHl0LmNvbTo4MDgwL3Rlc3QvY2FzZTE='),
|
|
||||||
// @ts-ignore
|
|
||||||
atob('cG9zdA=='),
|
|
||||||
`{"uid":"${ glob.player_info.userID }","name":"${ glob.player_info.playername }"}`
|
|
||||||
)
|
|
||||||
.then(res => (res === 'Ok') && (localStorage['WHTEST'] = 'Ok'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 谷歌跟踪
|
|
||||||
window._gaUserPrefs = {
|
|
||||||
ioo() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
window.dataLayer = null;
|
|
||||||
|
|
||||||
// 滚动条样式
|
|
||||||
document.documentElement.classList.add("d");
|
|
||||||
document.body.classList.add("scrollbar-transparent");
|
|
||||||
Log.info("滚动条样式调整")
|
|
||||||
|
|
||||||
Log.info('WuHuTornHelper初始化结束');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,47 +1,58 @@
|
|||||||
import adHelper from "../func/module/adHelper";
|
import adHelper from "../func/module/adHelper";
|
||||||
import safeKeeper from "../func/module/safeKeeper";
|
import safeKeeper from "../func/module/safeKeeper";
|
||||||
import initMiniProf from "../func/utils/initMiniProf";
|
import initMiniProf from "../func/utils/initMiniProf";
|
||||||
import WuhuBase from "./WuhuBase";
|
|
||||||
import Log from "./Log";
|
|
||||||
import CommonUtils from "./utils/CommonUtils";
|
import CommonUtils from "./utils/CommonUtils";
|
||||||
import Alert from "./utils/Alert";
|
|
||||||
import * as EVENTS from "../../static/json/event.json";
|
import * as EVENTS from "../../static/json/event.json";
|
||||||
import * as FEST from "../../static/json/fest.json";
|
import * as FEST from "../../static/json/fest.json";
|
||||||
import Popup from "./utils/Popup";
|
import Popup from "./utils/Popup";
|
||||||
import TravelItem from "./action/TravelItem";
|
import TravelItem from "../feature/TravelItem";
|
||||||
import ZHONG_MENU_HTML from "../../static/html/zhong/zhong_menu.html";
|
import ZHONG_MENU_HTML from "../../static/html/zhong/zhong_menu.html";
|
||||||
import ZHONG_UPDATE_HTML from "../../static/html/zhong/zhong_update.html";
|
import ZHONG_UPDATE_HTML from "../../static/html/zhong/zhong_update.html";
|
||||||
import ZHONG_LOOT_HTML from "../../static/html/zhong/zhong_loot.html";
|
import ZHONG_LOOT_HTML from "../../static/html/zhong/zhong_loot.html";
|
||||||
import Test from "../test/Test";
|
import Test from "../test/Test";
|
||||||
import Global from "./Global";
|
|
||||||
import Timer from "./utils/Timer";
|
import Timer from "./utils/Timer";
|
||||||
import QuickFlyBtnHandler from "./handler/QuickFlyBtnHandler";
|
import QuickFlyBtnHandler from "./handler/QuickFlyBtnHandler";
|
||||||
import NNB from "./handler/NNB";
|
import NNB from "./handler/NNB";
|
||||||
import QuickLinksHandler from "./handler/QuickLinksHandler";
|
import QuickLinksHandler from "./handler/QuickLinksHandler";
|
||||||
import ItemPriceWatcherHandler from "./handler/ItemPriceWatcherHandler";
|
import ItemPriceWatcherHandler from "./handler/ItemPriceWatcherHandler";
|
||||||
import ChangeLogHandler from "./handler/ChangeLogHandler";
|
// import ChangeLogHandler from "./handler/ChangeLogHandler";
|
||||||
import SettingsHandler from "./handler/SettingsHandler";
|
|
||||||
import WuhuConfig from "./WuhuConfig";
|
|
||||||
import ItemPriceHandler from "./handler/ItemPriceHandler";
|
import ItemPriceHandler from "./handler/ItemPriceHandler";
|
||||||
|
import SettingsHandler from "./handler/SettingsHandler";
|
||||||
|
import { MENU_ITEM_TYPE } from "../interface/MenuItem";
|
||||||
|
import { Injectable } from "../container/Injectable";
|
||||||
|
import ClassName from "../container/ClassName";
|
||||||
|
import LocalConfigWrapper from "./LocalConfigWrapper";
|
||||||
|
import Logger from "./Logger";
|
||||||
|
import { Container } from "../container/Container";
|
||||||
|
import TornPDAUtils from "./utils/TornPDAUtils";
|
||||||
|
import InfoUtils from "./utils/InfoUtils";
|
||||||
|
import globVars from "../globVars";
|
||||||
|
import MsgWrapper from "./utils/MsgWrapper";
|
||||||
|
|
||||||
export default class ZhongIcon extends WuhuBase {
|
@Injectable()
|
||||||
className = 'ZhongIcon';
|
@ClassName('ZhongIcon')
|
||||||
|
export default class ZhongIcon {
|
||||||
public static ZhongNode: MyHTMLElement = null;
|
public static ZhongNode: MyHTMLElement = null;
|
||||||
private menuItemList: MenuItemConfig[] = null;
|
private menuItemList: MenuItemConfig[] = null;
|
||||||
private cashView: HTMLElement = null;
|
private cashView: HTMLElement = null;
|
||||||
|
|
||||||
// private settingItemList: MenuItemConfig[] = null;
|
public constructor(
|
||||||
|
private readonly commonUtils: CommonUtils,
|
||||||
public constructor() {
|
private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
super();
|
private readonly nnb: NNB,
|
||||||
|
private readonly itemPriceWatcherHandler: ItemPriceWatcherHandler,
|
||||||
|
private readonly logger: Logger,
|
||||||
|
private readonly tornPDAUtils: TornPDAUtils,
|
||||||
|
private readonly infoUtils: InfoUtils,
|
||||||
|
private readonly msgWrapper: MsgWrapper,
|
||||||
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
Log.info('ZhongIcon初始化, 设置图标开始');
|
|
||||||
this.constructMenuList()
|
this.constructMenuList()
|
||||||
.insert2Dom()
|
.insert2Dom()
|
||||||
.dragHandler();
|
.dragHandler();
|
||||||
Log.info('设置图标结束, ZhongIcon初始化结束');
|
this.logger.info('设置图标结束');
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateCashView(content: string): void {
|
public updateCashView(content: string): void {
|
||||||
@ -68,8 +79,7 @@ export default class ZhongIcon extends WuhuBase {
|
|||||||
*/
|
*/
|
||||||
private insert2Dom(): ZhongIcon {
|
private insert2Dom(): ZhongIcon {
|
||||||
let zhongNode: MyHTMLElement = document.querySelector('div#wh-trans-icon');
|
let zhongNode: MyHTMLElement = document.querySelector('div#wh-trans-icon');
|
||||||
let settings = this.menuItemList;
|
let version = globVars.version;
|
||||||
let { version } = WuhuBase.glob;
|
|
||||||
if ((self !== top) || !!zhongNode) return null;
|
if ((self !== top) || !!zhongNode) return null;
|
||||||
zhongNode = document.createElement('div');
|
zhongNode = document.createElement('div');
|
||||||
ZhongIcon.ZhongNode = zhongNode;
|
ZhongIcon.ZhongNode = zhongNode;
|
||||||
@ -79,37 +89,36 @@ export default class ZhongIcon extends WuhuBase {
|
|||||||
// 助手菜单
|
// 助手菜单
|
||||||
const menu_cont = zhongNode.querySelector('#wh-gSettings');
|
const menu_cont = zhongNode.querySelector('#wh-gSettings');
|
||||||
// 遍历菜单node设置、生成node、插入dom
|
// 遍历菜单node设置、生成node、插入dom
|
||||||
this.menuItemList.forEach(setting => CommonUtils.getInstance().elemGenerator(setting, menu_cont));
|
this.menuItemList.forEach(setting => this.commonUtils.elemGenerator(setting, menu_cont));
|
||||||
Log.info('生成元素插入完成');
|
this.logger.info('生成元素插入完成');
|
||||||
// 计时node
|
// 计时node
|
||||||
zhongNode.initTimer = zhongNode.querySelector('#wh-inittimer');
|
zhongNode.initTimer = zhongNode.querySelector('#wh-inittimer');
|
||||||
// 芜湖助手图标点击事件
|
// 芜湖助手图标点击事件
|
||||||
(<MyHTMLElement>zhongNode.querySelector('#wh-trans-icon-btn')).onclick = () => {
|
(<MyHTMLElement>zhongNode.querySelector('#wh-trans-icon-btn')).onclick = () => {
|
||||||
zhongNode.classList.toggle('wh-icon-expanded');
|
zhongNode.classList.toggle('wh-icon-expanded');
|
||||||
const click_func = e => {
|
const click_func = e => {
|
||||||
Log.info(e.target);
|
this.logger.info(e.target);
|
||||||
if (e.target === zhongNode.querySelector('#wh-trans-icon-btn')) return;
|
if (e.target === zhongNode.querySelector('#wh-trans-icon-btn')) return;
|
||||||
if (!zhongNode.contains(e.target)) {
|
if (!zhongNode.contains(e.target)) {
|
||||||
Log.info('移除事件监听器');
|
this.logger.info('移除事件监听器');
|
||||||
document.body.removeEventListener('click', click_func);
|
document.body.removeEventListener('click', click_func);
|
||||||
zhongNode.classList.remove('wh-icon-expanded');
|
zhongNode.classList.remove('wh-icon-expanded');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (zhongNode.classList.contains('wh-icon-expanded')) {
|
if (zhongNode.classList.contains('wh-icon-expanded')) {
|
||||||
Log.info('芜湖助手图标点击->添加监听');
|
this.logger.info('芜湖助手图标点击->添加监听');
|
||||||
document.body.addEventListener('click', click_func);
|
document.body.addEventListener('click', click_func);
|
||||||
} else {
|
} else {
|
||||||
Log.info('芜湖助手图标->移除监听');
|
this.logger.info('芜湖助手图标->移除监听');
|
||||||
document.body.removeEventListener('click', click_func);
|
document.body.removeEventListener('click', click_func);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 更新按钮点击事件
|
// 更新按钮点击事件
|
||||||
(<MyHTMLElement>zhongNode.querySelector('#wh-update-btn')).onclick = e => {
|
(<MyHTMLElement>zhongNode.querySelector('#wh-update-btn')).onclick = e => {
|
||||||
(<HTMLButtonElement>e.target).blur();
|
(<HTMLButtonElement>e.target).blur();
|
||||||
const innerHtml = ZHONG_UPDATE_HTML;
|
|
||||||
// 直接复制的按钮
|
// 直接复制的按钮
|
||||||
new Popup(innerHtml, '如何更新')
|
new Popup(ZHONG_UPDATE_HTML, '如何更新')
|
||||||
.getElement()
|
.element
|
||||||
.querySelector('button').onclick = async (e) => {
|
.querySelector('button').onclick = async (e) => {
|
||||||
let target = e.target as HTMLButtonElement;
|
let target = e.target as HTMLButtonElement;
|
||||||
target.innerHTML = '加载中';
|
target.innerHTML = '加载中';
|
||||||
@ -125,7 +134,7 @@ export default class ZhongIcon extends WuhuBase {
|
|||||||
textarea_node.remove();
|
textarea_node.remove();
|
||||||
target.innerHTML = '已复制';
|
target.innerHTML = '已复制';
|
||||||
target.onclick = null;
|
target.onclick = null;
|
||||||
new Alert('脚本已复制,请前往粘贴');
|
this.msgWrapper.create('脚本已复制,请前往粘贴');
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -151,8 +160,8 @@ export default class ZhongIcon extends WuhuBase {
|
|||||||
})
|
})
|
||||||
: el.addEventListener('click', null));
|
: el.addEventListener('click', null));
|
||||||
// 调整图标至有记录的位置
|
// 调整图标至有记录的位置
|
||||||
if (WuhuConfig.get("SaveIconPosition")) {
|
if (this.localConfigWrapper.config.SaveIconPosition) {
|
||||||
let iconPosition = WuhuConfig.get("IconPosition");
|
let iconPosition = this.localConfigWrapper.config.IconPosition;
|
||||||
let documentSize = { x: document.documentElement.offsetWidth, y: document.documentElement.offsetHeight };
|
let documentSize = { x: document.documentElement.offsetWidth, y: document.documentElement.offsetHeight };
|
||||||
ZhongIcon.setPosition(
|
ZhongIcon.setPosition(
|
||||||
iconPosition.x > documentSize.x ? documentSize.x * 0.9 | 0 : iconPosition.x,
|
iconPosition.x > documentSize.x ? documentSize.x * 0.9 | 0 : iconPosition.x,
|
||||||
@ -161,10 +170,10 @@ export default class ZhongIcon extends WuhuBase {
|
|||||||
}
|
}
|
||||||
document.body.append(zhongNode);
|
document.body.append(zhongNode);
|
||||||
// 引入torn自带浮动提示
|
// 引入torn自带浮动提示
|
||||||
Log.info('引入torn自带浮动提示');
|
this.logger.info('引入torn浮动提示');
|
||||||
(window.initializeTooltip) && (window.initializeTooltip('.wh-container', 'white-tooltip'));
|
(window.initializeTooltip) && (window.initializeTooltip('.wh-container', 'white-tooltip'));
|
||||||
// 加载torn mini profile
|
// 加载torn mini profile
|
||||||
Log.info('加载torn mini profile');
|
this.logger.info('加载torn mini profile');
|
||||||
let miniProfileInterval = {
|
let miniProfileInterval = {
|
||||||
id: window.setInterval(() => {
|
id: window.setInterval(() => {
|
||||||
miniProfileInterval.counter++;
|
miniProfileInterval.counter++;
|
||||||
@ -176,7 +185,7 @@ export default class ZhongIcon extends WuhuBase {
|
|||||||
}, 1000),
|
}, 1000),
|
||||||
counter: 0
|
counter: 0
|
||||||
};
|
};
|
||||||
Log.info('图标加入文档树完成');
|
this.logger.info('图标加入文档树');
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,8 +206,8 @@ export default class ZhongIcon extends WuhuBase {
|
|||||||
isMouseDown = false;
|
isMouseDown = false;
|
||||||
if (isMouseMoved) {
|
if (isMouseMoved) {
|
||||||
isMouseMoved = false;
|
isMouseMoved = false;
|
||||||
if (WuhuConfig.get("SaveIconPosition")) {
|
if (this.localConfigWrapper.config.SaveIconPosition) {
|
||||||
WuhuConfig.set("IconPosition", ZhongIcon.getPosition());
|
this.localConfigWrapper.config.IconPosition = ZhongIcon.getPosition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -220,19 +229,20 @@ export default class ZhongIcon extends WuhuBase {
|
|||||||
|
|
||||||
// 菜单
|
// 菜单
|
||||||
private constructMenuList(): ZhongIcon {
|
private constructMenuList(): ZhongIcon {
|
||||||
Log.info('构造菜单列表开始');
|
this.logger.info('构造菜单列表开始');
|
||||||
let timer = new Timer();
|
let timer = new Timer();
|
||||||
let glob = Global.getInstance();
|
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
|
let userInfo = this.infoUtils.getPlayerInfo();
|
||||||
|
|
||||||
let list: MenuItemConfig[] = [];
|
let list: MenuItemConfig[] = [];
|
||||||
|
|
||||||
// 欢迎 显示玩家id
|
// 欢迎 显示玩家id
|
||||||
if (glob.player_info.userID !== 0) {
|
if (userInfo.userID !== 0) {
|
||||||
list.push({
|
list.push({
|
||||||
domType: 'plain',
|
domType: 'plain',
|
||||||
domId: 'wh-trans-welcome',
|
domId: 'wh-trans-welcome',
|
||||||
domHTML: `<a href="/profiles.php?XID=${ glob.player_info.userID }" target="_blank">${ glob.player_info.playername }</a>[${ glob.player_info.userID }]`,
|
domHTML:
|
||||||
|
`<a href="/profiles.php?XID=${ userInfo.userID }" target="_blank">${ userInfo.playername }</a>[${ userInfo.userID }]`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 节日
|
// 节日
|
||||||
@ -323,14 +333,14 @@ export default class ZhongIcon extends WuhuBase {
|
|||||||
domType: 'button',
|
domType: 'button',
|
||||||
domId: 'wh-quick-fly-btn',
|
domId: 'wh-quick-fly-btn',
|
||||||
domText: '✈️ 一键起飞',
|
domText: '✈️ 一键起飞',
|
||||||
clickFunc: () => QuickFlyBtnHandler.getInstance().handle(),
|
clickFunc: () => Container.factory(QuickFlyBtnHandler).handle(),
|
||||||
});
|
});
|
||||||
// 飞花库存
|
// 飞花库存
|
||||||
list.push({
|
list.push({
|
||||||
domType: 'button',
|
domType: 'button',
|
||||||
domId: 'wh-foreign-stock-btn',
|
domId: 'wh-foreign-stock-btn',
|
||||||
domText: '🌸 飞花库存',
|
domText: '🌸 飞花库存',
|
||||||
clickFunc: () => TravelItem.getInstance().clickHandler().then(),
|
clickFunc: () => Container.factory(TravelItem).clickHandler().then(),
|
||||||
});
|
});
|
||||||
// NPC LOOT
|
// NPC LOOT
|
||||||
list.push({
|
list.push({
|
||||||
@ -348,14 +358,14 @@ export default class ZhongIcon extends WuhuBase {
|
|||||||
domType: 'button',
|
domType: 'button',
|
||||||
domId: 'wh-nnb-info',
|
domId: 'wh-nnb-info',
|
||||||
domText: '👮 查看NNB',
|
domText: '👮 查看NNB',
|
||||||
clickFunc: () => NNB.getInstance().handle(),
|
clickFunc: () => this.nnb.handle(),
|
||||||
});
|
});
|
||||||
// 常用链接
|
// 常用链接
|
||||||
list.push({
|
list.push({
|
||||||
domType: 'button',
|
domType: 'button',
|
||||||
domId: 'wh-link-collection',
|
domId: 'wh-link-collection',
|
||||||
domText: '🔗 常用链接',
|
domText: '🔗 常用链接',
|
||||||
clickFunc: () => QuickLinksHandler.getInstance().handle()
|
clickFunc: () => Container.factory(QuickLinksHandler).handle()
|
||||||
});
|
});
|
||||||
// 飞贼
|
// 飞贼
|
||||||
// list.push({
|
// list.push({
|
||||||
@ -371,10 +381,10 @@ export default class ZhongIcon extends WuhuBase {
|
|||||||
domType: 'button',
|
domType: 'button',
|
||||||
domId: 'wh-price-watcher-btn',
|
domId: 'wh-price-watcher-btn',
|
||||||
domText: '💊 价格监视',
|
domText: '💊 价格监视',
|
||||||
clickFunc: () => ItemPriceWatcherHandler.getInstance().handle()
|
clickFunc: () => this.itemPriceWatcherHandler.handle()
|
||||||
});
|
});
|
||||||
// 全屏
|
// 全屏
|
||||||
if (!Global.getInstance().isPDA) list.push({
|
if (!this.tornPDAUtils.isPDA()) list.push({
|
||||||
domType: 'button', domId: '', domText: '🖥️ 进入全屏', clickFunc() {
|
domType: 'button', domId: '', domText: '🖥️ 进入全屏', clickFunc() {
|
||||||
document.documentElement.requestFullscreen().then();
|
document.documentElement.requestFullscreen().then();
|
||||||
}
|
}
|
||||||
@ -405,54 +415,22 @@ export default class ZhongIcon extends WuhuBase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
// 物品查价
|
// 物品查价
|
||||||
list.push({
|
list.push(ItemPriceHandler);
|
||||||
domType: 'button',
|
|
||||||
domId: '',
|
|
||||||
domText: '🍺 物品查价',
|
|
||||||
clickFunc() {
|
|
||||||
ItemPriceHandler.show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 更新历史
|
// 更新历史
|
||||||
list.push({
|
// list.push(ChangeLogHandler);
|
||||||
domType: 'button',
|
|
||||||
domId: '',
|
|
||||||
domText: '🐞 更新历史',
|
|
||||||
clickFunc: async () => ChangeLogHandler.getInstance().handle()
|
|
||||||
});
|
|
||||||
// 助手设置
|
// 助手设置
|
||||||
list.push({
|
list.push(SettingsHandler);
|
||||||
domType: 'button',
|
|
||||||
domId: '',
|
|
||||||
domText: '⚙️ 助手设置',
|
|
||||||
clickFunc: () => SettingsHandler.getInstance().handler(),
|
|
||||||
});
|
|
||||||
// 测试
|
// 测试
|
||||||
if (Log.debug()) list.push({
|
if (this.logger.debug()) list.push(Test);
|
||||||
domType: 'button',
|
|
||||||
domId: '',
|
|
||||||
domText: '📐️ 测试',
|
|
||||||
clickFunc: async function () {
|
|
||||||
let startTime = performance.now();
|
|
||||||
Log.info('测试开始');
|
|
||||||
try {
|
|
||||||
Test.getInstance().test();
|
|
||||||
} catch (e) {
|
|
||||||
Log.error('测试异常,' + JSON.stringify(e));
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.info('测试结束 ' + ((performance.now() - startTime) | 0) + 'ms');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
this.menuItemList = list;
|
this.menuItemList = list;
|
||||||
Log.info('构造展开菜单列表结束' + timer.getTimeMs());
|
this.logger.info('构造展开菜单列表结束' + timer.getTimeMs());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MenuItemConfig {
|
export interface MenuItemConfig {
|
||||||
domType: 'button' | 'plain' | 'checkbox' | 'select';
|
domType: 'button' | 'plain' | 'checkbox' | 'select' | MENU_ITEM_TYPE;
|
||||||
tagName?: string;
|
tagName?: string;
|
||||||
domId?: string;
|
domId?: string;
|
||||||
domText?: string;
|
domText?: string;
|
||||||
|
|||||||
@ -1,346 +1,352 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
// import CommonUtils from "../utils/CommonUtils";
|
||||||
import WuhuConfig from "../WuhuConfig";
|
// import Alert from "../utils/Alert";
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
// import Global from "../Global";
|
||||||
import Log from "../Log";
|
// import Device from "../../enum/Device";
|
||||||
import Alert from "../utils/Alert";
|
// import ATTACK_HELPER_CSS from "../../../static/css/attack_helper.module.css";
|
||||||
import Global from "../Global";
|
// import ActionButtonUtils from "../utils/ActionButtonUtils";
|
||||||
import Device from "../../enum/Device";
|
// import TornStyleBlock from "../utils/TornStyleBlock";
|
||||||
import ATTACK_HELPER_CSS from "../../../static/css/attack_helper.css";
|
// import TornStyleSwitch from "../utils/TornStyleSwitch";
|
||||||
import ActionButtonUtils from "../utils/ActionButtonUtils";
|
// import DialogMsgBox from "../utils/DialogMsgBox";
|
||||||
import TornStyleBlock from "../utils/TornStyleBlock";
|
// import FetchUtils from "../utils/FetchUtils";
|
||||||
import TornStyleSwitch from "../utils/TornStyleSwitch";
|
// import MathUtils from "../utils/MathUtils";
|
||||||
import DialogMsgBox from "../utils/DialogMsgBox";
|
// import LoopHelper from "../utils/LoopHelper";
|
||||||
import FetchUtils from "../utils/FetchUtils";
|
// import TRAVEL_STATE from "../../enum/TravelState";
|
||||||
import MathUtils from "../utils/MathUtils";
|
// import { Injectable } from "../../container/Injectable";
|
||||||
import LoopHelper from "../utils/LoopHelper";
|
// import ClassName from "../../container/ClassName";
|
||||||
import TRAVEL_STATE from "../../enum/TravelState";
|
// import LocalConfigWrapper from "../LocalConfigWrapper";
|
||||||
|
// import Logger from "../Logger";
|
||||||
enum FIGHT_STAGE {
|
//
|
||||||
READY = 'ready',
|
// enum FIGHT_STAGE {
|
||||||
IN_PROGRESS_OR_ERROR = 'in_progress_or_error',
|
// READY = 'ready',
|
||||||
FINISHED = 'finished',
|
// IN_PROGRESS_OR_ERROR = 'in_progress_or_error',
|
||||||
END = 'end',
|
// FINISHED = 'finished',
|
||||||
OTHER = 'other'
|
// END = 'end',
|
||||||
}
|
// OTHER = 'other'
|
||||||
|
// }
|
||||||
/**
|
//
|
||||||
* 战斗助手
|
// /**
|
||||||
* TODO 页面加载已经在进行中的战斗时的正确判断
|
// * 战斗助手
|
||||||
*/
|
// * TODO 页面加载已经在进行中的战斗时的正确判断
|
||||||
export default class AttackHelper extends WuhuBase {
|
// */
|
||||||
className = 'AttackHelper';
|
// @Injectable()
|
||||||
|
// @ClassName('AttackHelper')
|
||||||
private currentStage: FIGHT_STAGE = FIGHT_STAGE.OTHER;
|
// export default class AttackHelper {
|
||||||
|
//
|
||||||
constructor() {
|
// private currentStage: FIGHT_STAGE = FIGHT_STAGE.OTHER;
|
||||||
super();
|
//
|
||||||
window.setTimeout(() => this.urlMatch(), 0);
|
// constructor(
|
||||||
}
|
// private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
|
// private readonly commonUtils: CommonUtils,
|
||||||
private urlMatch(): void {
|
// private readonly global: Global,
|
||||||
if (window.location.href.contains(/loader\.php\?sid=attack/)) {
|
// private readonly mathUtils: MathUtils,
|
||||||
this.fightingPageHandle();
|
// private readonly actionButtonUtils: ActionButtonUtils,
|
||||||
}
|
// private readonly fetchUtils: FetchUtils,
|
||||||
// 错误的攻击页面转跳
|
// private readonly logger: Logger,
|
||||||
else if (window.location.href.includes('loader2.php') && WuhuConfig.get('attRelocate')) {
|
// ) {
|
||||||
const spl = window.location.href.trim().split('=');
|
// }
|
||||||
const uid = spl[spl.length - 1];
|
//
|
||||||
if (CommonUtils.getInstance().isValidUid(uid)) {
|
// init(): void {
|
||||||
window.location.href = 'https://www.torn.com/loader.php?sid=attack&user2ID=' + uid;
|
// window.setTimeout(() => this._init(), 0);
|
||||||
} else {
|
// }
|
||||||
Log.error('[AttackHelper] UID格式不正确');
|
//
|
||||||
}
|
// private _init() {
|
||||||
}
|
// if (window.location.href.contains(/loader\.php\?sid=attack/)) {
|
||||||
}
|
// this.fightingPageHandle();
|
||||||
|
// }
|
||||||
private fightingPageHandle(): void {
|
// // 错误的攻击页面转跳
|
||||||
// 光速刷新按钮
|
// // else if (window.location.href.includes('loader2.php') && this.localConfigWrapper.config.attRelocate) {
|
||||||
ActionButtonUtils.getInstance().add('光速刷新', () => this.doAttackReload());
|
// // const spl = window.location.href.trim().split('=');
|
||||||
|
// // const uid = spl[spl.length - 1];
|
||||||
// 盯梢
|
// // if (this.commonUtils.isValidUid(uid)) {
|
||||||
this.watchTarget();
|
// // window.location.href = 'https://www.torn.com/loader.php?sid=attack&user2ID=' + uid;
|
||||||
|
// // } else {
|
||||||
new MutationObserver((_, observer) => {
|
// // this.logger.error('[AttackHelper] UID格式不正确');
|
||||||
let btnList = document.querySelectorAll('div[class^="dialogButtons___"] button') as NodeListOf<HTMLButtonElement>;
|
// // }
|
||||||
|
// // }
|
||||||
if (btnList.length === 0) {
|
// }
|
||||||
if (this.currentStage === FIGHT_STAGE.READY && WuhuConfig.get('quickFinishAtt') === 3) {
|
//
|
||||||
document.body.classList.remove('wh-move-btn');
|
// private fightingPageHandle(): void {
|
||||||
Log.info('移除body class wh-move-btn');
|
// // 光速刷新按钮
|
||||||
observer.disconnect();
|
// this.actionButtonUtils.add('光速刷新', () => this.doAttackReload());
|
||||||
}
|
//
|
||||||
// 错误或正在打
|
// // 盯梢
|
||||||
this.currentStage = FIGHT_STAGE.IN_PROGRESS_OR_ERROR;
|
// this.watchTarget();
|
||||||
Log.info('[attackHelper] currentStage', this.currentStage);
|
//
|
||||||
return;
|
// new MutationObserver((_, observer) => {
|
||||||
}
|
// let btnList = document.querySelectorAll('div[class^="dialogButtons___"] button') as NodeListOf<HTMLButtonElement>;
|
||||||
btnList.forEach(btn => {
|
//
|
||||||
let btnText = btn.innerText.toLowerCase();
|
// if (btnList.length === 0) {
|
||||||
if (btnText.includes('start') || btnText.includes('join')) {
|
// if (this.currentStage === FIGHT_STAGE.READY && this.localConfigWrapper.config.quickFinishAtt === 3) {
|
||||||
// 开始
|
// document.body.classList.remove('wh-move-btn');
|
||||||
this.quickStartFight();
|
// this.logger.info('移除body class wh-move-btn');
|
||||||
} else if (btnText.includes('continue')) {
|
// observer.disconnect();
|
||||||
// 结束end
|
// }
|
||||||
this.currentStage = FIGHT_STAGE.END;
|
// // 错误或正在打
|
||||||
observer.disconnect();
|
// this.currentStage = FIGHT_STAGE.IN_PROGRESS_OR_ERROR;
|
||||||
} else if (btnText.includes('leave')) {
|
// this.logger.info('[attackHelper] currentStage', this.currentStage);
|
||||||
// 无意识状态FINISHED
|
// return;
|
||||||
this.quickFinishFight(btnList);
|
// }
|
||||||
}
|
// btnList.forEach(btn => {
|
||||||
Log.info('[attackHelper] currentStage', this.currentStage);
|
// let btnText = btn.innerText.toLowerCase();
|
||||||
})
|
// if (btnText.includes('start') || btnText.includes('join')) {
|
||||||
})
|
// // 开始
|
||||||
.observe(document.querySelector('#react-root'), { childList: true, subtree: true });
|
// this.quickStartFight();
|
||||||
}
|
// } else if (btnText.includes('continue')) {
|
||||||
|
// // 结束end
|
||||||
// 战斗页面快速刷新
|
// this.currentStage = FIGHT_STAGE.END;
|
||||||
private doAttackReload(): void {
|
// observer.disconnect();
|
||||||
if (!window.ReactDOM) {
|
// } else if (btnText.includes('leave')) {
|
||||||
new Alert('光速刷新失败:未找到React对象');
|
// // 无意识状态FINISHED
|
||||||
Log.error('光速刷新失败:未找到React对象');
|
// this.quickFinishFight(btnList);
|
||||||
return;
|
// }
|
||||||
}
|
// this.logger.info('[attackHelper] currentStage', this.currentStage);
|
||||||
if (!document.querySelector('#react-root #attacker')) {
|
// })
|
||||||
Log.error('dom元素未找到selector: [#react-root #attacker]');
|
// })
|
||||||
return;
|
// .observe(document.querySelector('#react-root'), { childList: true, subtree: true });
|
||||||
}
|
// }
|
||||||
let script = document.querySelector('script[src*="/builds/attack/"]');
|
//
|
||||||
let url = script.src;
|
// // 战斗页面快速刷新
|
||||||
if (!url.contains(/runtime\..+\.js/)) {
|
// private doAttackReload(): void {
|
||||||
Log.error('脚本源[' + url + '] 不匹配规则');
|
// if (!window.ReactDOM) {
|
||||||
return;
|
// new Alert('光速刷新失败:未找到React对象');
|
||||||
}
|
// this.logger.error('光速刷新失败:未找到React对象');
|
||||||
window.ReactDOM.unmountComponentAtNode(document.querySelector('#react-root'));
|
// return;
|
||||||
script.remove();
|
// }
|
||||||
let node = document.createElement('script');
|
// if (!document.querySelector('#react-root #attacker')) {
|
||||||
node.src = url;
|
// this.logger.error('dom元素未找到selector: [#react-root #attacker]');
|
||||||
node.type = 'text/javascript';
|
// return;
|
||||||
document.head.appendChild(node);
|
// }
|
||||||
}
|
// let script = document.querySelector('script[src*="/builds/attack/"]');
|
||||||
|
// let url = script.src;
|
||||||
// 光速拔刀
|
// if (!url.contains(/runtime\..+\.js/)) {
|
||||||
private quickStartFight(): void {
|
// this.logger.error('脚本源[' + url + '] 不匹配规则');
|
||||||
if (this.currentStage === FIGHT_STAGE.READY) {
|
// return;
|
||||||
return;
|
// }
|
||||||
} else {
|
// window.ReactDOM.unmountComponentAtNode(document.querySelector('#react-root'));
|
||||||
this.currentStage = FIGHT_STAGE.READY;
|
// script.remove();
|
||||||
}
|
// let node = document.createElement('script');
|
||||||
if (WuhuConfig.get('quickAttIndex') === 6) return;
|
// node.src = url;
|
||||||
/**
|
// node.type = 'text/javascript';
|
||||||
* pc #defender
|
// document.head.appendChild(node);
|
||||||
* mobile #attacker
|
// }
|
||||||
*/
|
//
|
||||||
const btn = <HTMLInputElement>(document.querySelector('#attacker button') || document.querySelector('#defender button'));
|
// // 光速拔刀
|
||||||
Log.info('操作按钮', { btn });
|
// private quickStartFight(): void {
|
||||||
if (!btn.innerText.toLowerCase().includes('fight')) {
|
// if (this.currentStage === FIGHT_STAGE.READY) {
|
||||||
Log.info('未找到攻击按钮, 光速拔刀跳过');
|
// return;
|
||||||
new Alert('未找到攻击按钮, 光速拔刀跳过');
|
// } else {
|
||||||
} else {
|
// this.currentStage = FIGHT_STAGE.READY;
|
||||||
// 判断是否存在脚踢
|
// }
|
||||||
const hasKick = !!document.querySelector('#weapon_boots');
|
// if (this.localConfigWrapper.config.quickAttIndex === 6) return;
|
||||||
// modal层
|
// /**
|
||||||
// const modal: HTMLElement = document.querySelector('div[class^="modal___"]');
|
// * pc #defender
|
||||||
let device = Global.getInstance().device;
|
// * mobile #attacker
|
||||||
Log.info(`当前设备类型是${ device }`);
|
// */
|
||||||
// 区分设备
|
// const btn = <HTMLInputElement>(document.querySelector('#attacker button') || document.querySelector('#defender button'));
|
||||||
switch (device) {
|
// this.logger.info('操作按钮', { btn });
|
||||||
case Device.PC: {
|
// if (!btn.innerText.toLowerCase().includes('fight')) {
|
||||||
Log.info(`开始调整按钮位置`);
|
// this.logger.info('未找到攻击按钮, 光速拔刀跳过');
|
||||||
// 隐藏modal层
|
// new Alert('未找到攻击按钮, 光速拔刀跳过');
|
||||||
// modal.style.display = 'none';
|
// } else {
|
||||||
// 根据选择的武器调整css
|
// // 判断是否存在脚踢
|
||||||
let css_top = '0';
|
// const hasKick = !!document.querySelector('#weapon_boots');
|
||||||
switch (WuhuConfig.get('quickAttIndex')) {
|
// // modal层
|
||||||
// weapon_second
|
// // const modal: HTMLElement = document.querySelector('div[class^="modal___"]');
|
||||||
case 1: {
|
// let device = this.global.device;
|
||||||
css_top = '97px';
|
// this.logger.info(`当前设备类型是${ device }`);
|
||||||
break;
|
// // 区分设备
|
||||||
}
|
// switch (device) {
|
||||||
// weapon_melee
|
// case Device.PC: {
|
||||||
case 2: {
|
// this.logger.info(`开始调整按钮位置`);
|
||||||
css_top = '194px';
|
// // 隐藏modal层
|
||||||
break;
|
// // modal.style.display = 'none';
|
||||||
}
|
// // 根据选择的武器调整css
|
||||||
// weapon_temp
|
// let css_top = '0';
|
||||||
case 3: {
|
// switch (this.localConfigWrapper.config.quickAttIndex) {
|
||||||
css_top = '291px';
|
// // weapon_second
|
||||||
break;
|
// case 1: {
|
||||||
}
|
// css_top = '97px';
|
||||||
// weapon_fists
|
// break;
|
||||||
case 4:
|
// }
|
||||||
// weapon_boots
|
// // weapon_melee
|
||||||
case 5: {
|
// case 2: {
|
||||||
css_top = '375px';
|
// css_top = '194px';
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// // weapon_temp
|
||||||
CommonUtils.addStyle(ATTACK_HELPER_CSS);
|
// case 3: {
|
||||||
CommonUtils.addStyle(`.wh-move-btn #defender div[class^="modal___"]{top: ${ css_top };}`);
|
// css_top = '291px';
|
||||||
document.body.classList.add('wh-move-btn');
|
// break;
|
||||||
break;
|
// }
|
||||||
}
|
// // weapon_fists
|
||||||
case Device.MOBILE: {
|
// case 4:
|
||||||
Log.info(`开始调整按钮位置`);
|
// // weapon_boots
|
||||||
// 加入css
|
// case 5: {
|
||||||
let css_top = '0';
|
// css_top = '375px';
|
||||||
let slot_height = '76px';
|
// break;
|
||||||
// 判断有没有脚踢
|
// }
|
||||||
if (hasKick) {
|
// }
|
||||||
// 根据选择的武器调整
|
// this.commonUtils.styleInject(ATTACK_HELPER_CSS);
|
||||||
switch (WuhuConfig.get('quickAttIndex')) {
|
// CommonUtils.addStyle(`.wh-move-btn #defender div[class^="modal___"]{top: ${ css_top };}`);
|
||||||
case 1: { // weapon_second
|
// document.body.classList.add('wh-move-btn');
|
||||||
css_top = '76px';
|
// break;
|
||||||
break;
|
// }
|
||||||
}
|
// case Device.MOBILE: {
|
||||||
case 2: { // weapon_melee
|
// this.logger.info(`开始调整按钮位置`);
|
||||||
css_top = '152px';
|
// // 加入css
|
||||||
break;
|
// let css_top = '0';
|
||||||
}
|
// let slot_height = '76px';
|
||||||
case 3: { // weapon_temp
|
// // 判断有没有脚踢
|
||||||
css_top = '228px';
|
// if (hasKick) {
|
||||||
break;
|
// // 根据选择的武器调整
|
||||||
}
|
// switch (this.localConfigWrapper.config.quickAttIndex) {
|
||||||
case 4: { // weapon_fists
|
// case 1: { // weapon_second
|
||||||
css_top = '304px';
|
// css_top = '76px';
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case 5: { // weapon_boots
|
// case 2: { // weapon_melee
|
||||||
css_top = '380px';
|
// css_top = '152px';
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// case 3: { // weapon_temp
|
||||||
} else {
|
// css_top = '228px';
|
||||||
const slot = document.querySelector('#weapon_main') as HTMLElement;
|
// break;
|
||||||
const height = slot.offsetHeight + 1;
|
// }
|
||||||
// TODO 待验证
|
// case 4: { // weapon_fists
|
||||||
slot_height = height + 'px';
|
// css_top = '304px';
|
||||||
// 根据选择的武器调整
|
// break;
|
||||||
switch (WuhuConfig.get('quickAttIndex')) {
|
// }
|
||||||
case 1: { // weapon_second
|
// case 5: { // weapon_boots
|
||||||
css_top = `${ height }px`;
|
// css_top = '380px';
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case 2: { // weapon_melee
|
// }
|
||||||
css_top = `${ height * 2 }px`;
|
// } else {
|
||||||
break;
|
// const slot = document.querySelector('#weapon_main') as HTMLElement;
|
||||||
}
|
// const height = slot.offsetHeight + 1;
|
||||||
case 3: { // weapon_temp
|
// // TODO 待验证
|
||||||
css_top = `${ height * 3 }px`;
|
// slot_height = height + 'px';
|
||||||
break;
|
// // 根据选择的武器调整
|
||||||
}
|
// switch (this.localConfigWrapper.config.quickAttIndex) {
|
||||||
case 4: { // weapon_fists
|
// case 1: { // weapon_second
|
||||||
css_top = `${ height * 4 }px`;
|
// css_top = `${ height }px`;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
case 5: { // weapon_boots
|
// case 2: { // weapon_melee
|
||||||
css_top = `${ height * 5 }px`;
|
// css_top = `${ height * 2 }px`;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// case 3: { // weapon_temp
|
||||||
}
|
// css_top = `${ height * 3 }px`;
|
||||||
const css_rule = ATTACK_HELPER_CSS.replace('CSSVAR', css_top).replace('CSSVAR', slot_height);
|
// break;
|
||||||
// `
|
// }
|
||||||
// .wh-move-btn #attacker div[class^="modal___"]{display: block;width: 0;top: ${ css_top };left:0;height:0;}
|
// case 4: { // weapon_fists
|
||||||
// .wh-move-btn #attacker div[class^="dialog___"]{border:0;width:80px;height:${ slot_height };}
|
// css_top = `${ height * 4 }px`;
|
||||||
// .wh-move-btn #attacker div[class^="colored___"]{display:block;padding:0;}
|
// break;
|
||||||
// .wh-move-btn #attacker div[class^="title___"]{height:0;}
|
// }
|
||||||
// .wh-move-btn #attacker button{width:100%;margin:0;height:63px;white-space:normal;}
|
// case 5: { // weapon_boots
|
||||||
// `;
|
// css_top = `${ height * 5 }px`;
|
||||||
CommonUtils.addStyle(css_rule);
|
// break;
|
||||||
document.body.classList.toggle('wh-move-btn');
|
// }
|
||||||
btn.onclick = () => {
|
// }
|
||||||
if (WuhuConfig.get('quickFinishAtt') !== 3) {
|
// }
|
||||||
btn.remove();
|
// const css_rule = ATTACK_HELPER_CSS.replace('CSSVAR', css_top).replace('CSSVAR', slot_height);
|
||||||
// 停止自动刷新
|
//
|
||||||
// stop_reload = true;
|
// this.commonUtils.styleInject(css_rule);
|
||||||
} else {
|
// document.body.classList.toggle('wh-move-btn');
|
||||||
document.body.classList.toggle('wh-move-btn');
|
// btn.onclick = () => {
|
||||||
}
|
// if (this.localConfigWrapper.config.quickFinishAtt !== 3) {
|
||||||
};
|
// btn.remove();
|
||||||
break;
|
// // 停止自动刷新
|
||||||
}
|
// // stop_reload = true;
|
||||||
case Device.TABLET: {
|
// } else {
|
||||||
break;
|
// document.body.classList.toggle('wh-move-btn');
|
||||||
}
|
// }
|
||||||
}
|
// };
|
||||||
}
|
// break;
|
||||||
}
|
// }
|
||||||
|
// case Device.TABLET: {
|
||||||
// 光速跑路
|
// break;
|
||||||
private quickFinishFight(btnList: NodeListOf<HTMLButtonElement>): void {
|
// }
|
||||||
if (this.currentStage === FIGHT_STAGE.FINISHED) {
|
// }
|
||||||
return;
|
// }
|
||||||
} else {
|
// }
|
||||||
this.currentStage = FIGHT_STAGE.FINISHED;
|
//
|
||||||
}
|
// // 光速跑路
|
||||||
if (WuhuConfig.get('quickFinishAtt') === 3) {
|
// private quickFinishFight(btnList: NodeListOf<HTMLButtonElement>): void {
|
||||||
document.body.classList.remove('wh-move-btn');
|
// if (this.currentStage === FIGHT_STAGE.FINISHED) {
|
||||||
Log.info('移除body class wh-move-btn');
|
// return;
|
||||||
return;
|
// } else {
|
||||||
}
|
// this.currentStage = FIGHT_STAGE.FINISHED;
|
||||||
const user_btn_select = ['leave', 'mug', 'hosp'][WuhuConfig.get('quickFinishAtt')];
|
// }
|
||||||
// const wrap = document.querySelector('#react-root');
|
// if (this.localConfigWrapper.config.quickFinishAtt === 3) {
|
||||||
Log.info('光速跑路选项选中:', user_btn_select);
|
// document.body.classList.remove('wh-move-btn');
|
||||||
// const btn_arr: HTMLButtonElement[] = document.querySelectorAll('div[class^="dialogButtons___"] button') as unknown as HTMLButtonElement[];
|
// this.logger.info('移除body class wh-move-btn');
|
||||||
if (btnList.length > 1) btnList.forEach(btn => {
|
// return;
|
||||||
const flag = btn.innerText.toLowerCase().includes(user_btn_select);
|
// }
|
||||||
Log.info('按钮内容:', btn.innerText, ',是否包含选中:', flag);
|
// const user_btn_select = ['leave', 'mug', 'hosp'][this.localConfigWrapper.config.quickFinishAtt];
|
||||||
if (!flag) btn.style.display = 'none';
|
// // const wrap = document.querySelector('#react-root');
|
||||||
});
|
// this.logger.info('光速跑路选项选中:', user_btn_select);
|
||||||
}
|
// // const btn_arr: HTMLButtonElement[] = document.querySelectorAll('div[class^="dialogButtons___"] button') as unknown as HTMLButtonElement[];
|
||||||
|
// if (btnList.length > 1) btnList.forEach(btn => {
|
||||||
// 盯梢模式
|
// const flag = btn.innerText.toLowerCase().includes(user_btn_select);
|
||||||
private watchTarget(): void {
|
// this.logger.info('按钮内容:', btn.innerText, ',是否包含选中:', flag);
|
||||||
Log.info('获取目标id');
|
// if (!flag) btn.style.display = 'none';
|
||||||
let targetId = window.location.href.split('user2ID=')[1];
|
// });
|
||||||
if (!CommonUtils.getInstance().isValidUid(targetId)) {
|
// }
|
||||||
Log.error('目标id获取错误', targetId);
|
//
|
||||||
throw new Error('目标id获取错误:' + targetId);
|
// // 盯梢模式
|
||||||
}
|
// private watchTarget(): void {
|
||||||
let loop = new LoopHelper(async () => {
|
// this.logger.info('获取目标id');
|
||||||
let userProfile;
|
// let targetId = window.location.href.split('user2ID=')[1];
|
||||||
try {
|
// if (!this.commonUtils.isValidUid(targetId)) {
|
||||||
userProfile = await FetchUtils.getInstance().getProfile(targetId);
|
// this.logger.error('目标id获取错误', targetId);
|
||||||
} catch {
|
// throw new Error('目标id获取错误:' + targetId);
|
||||||
Log.error('盯梢模式无法获取目标id');
|
// }
|
||||||
throw new Error('盯梢模式无法获取目标id');
|
// let loop = new LoopHelper(async () => {
|
||||||
}
|
// let userProfile;
|
||||||
await CommonUtils.getInstance().sleep(MathUtils.getInstance().getRandomInt(20, 50));
|
// try {
|
||||||
if ((userProfile.userStatus.status === 'ok' && CommonUtils.getInstance().getTravelStage() === TRAVEL_STATE.IN_TORN) ||
|
// userProfile = await this.fetchUtils.getProfile(targetId);
|
||||||
(userProfile.userStatus.status === 'abroad' && CommonUtils.getInstance().getTravelStage() === TRAVEL_STATE.ABROAD)) {
|
// } catch {
|
||||||
watchSwitch.getInput().checked = false;
|
// this.logger.error('盯梢模式无法获取目标id');
|
||||||
window.setTimeout(async () => {
|
// throw new Error('盯梢模式无法获取目标id');
|
||||||
new Alert('目标已落地/出院/出狱!', { timeout: 10, force: true, sysNotify: true });
|
// }
|
||||||
await CommonUtils.getInstance().audioPlay();
|
// await this.commonUtils.sleep(this.mathUtils.getRandomInt(20, 50));
|
||||||
await CommonUtils.getInstance().sleep(300);
|
// if ((userProfile.userStatus.status === 'ok' && this.commonUtils.getTravelStage() === TRAVEL_STATE.IN_TORN) ||
|
||||||
await CommonUtils.getInstance().audioPlay();
|
// (userProfile.userStatus.status === 'abroad' && this.commonUtils.getTravelStage() === TRAVEL_STATE.ABROAD)) {
|
||||||
await CommonUtils.getInstance().sleep(300);
|
// watchSwitch.getInput().checked = false;
|
||||||
await CommonUtils.getInstance().audioPlay();
|
// window.setTimeout(async () => {
|
||||||
await CommonUtils.getInstance().sleep(300);
|
// new Alert('目标已落地/出院/出狱!', { timeout: 10, force: true, sysNotify: true });
|
||||||
}, 0);
|
// await this.commonUtils.audioPlay();
|
||||||
}
|
// await this.commonUtils.sleep(300);
|
||||||
});
|
// await this.commonUtils.audioPlay();
|
||||||
let block = new TornStyleBlock('盯梢模式').insert2Dom();
|
// await this.commonUtils.sleep(300);
|
||||||
let watchSwitch = new TornStyleSwitch('开启');
|
// await this.commonUtils.audioPlay();
|
||||||
block.append(watchSwitch.getBase());
|
// await this.commonUtils.sleep(300);
|
||||||
watchSwitch.getInput().addEventListener('change', () => {
|
// }, 0);
|
||||||
if (watchSwitch.getInput().checked) {
|
// }
|
||||||
new DialogMsgBox('检测玩家状态,当目标状态变成(海外)落地、出院或出狱时通知并播放声音提醒,后可搭配光速刷新食用<br/>确定开启?', {
|
// });
|
||||||
callback: () => {
|
// let block = new TornStyleBlock('盯梢模式').insert2Dom();
|
||||||
if (CommonUtils.getInstance().getTravelStage() === TRAVEL_STATE.FLYING) {
|
// let watchSwitch = new TornStyleSwitch('开启');
|
||||||
new Alert('失败!已取消');
|
// block.append(watchSwitch.getBase());
|
||||||
watchSwitch.getInput().checked = false;
|
// watchSwitch.getInput().addEventListener('change', () => {
|
||||||
return;
|
// if (watchSwitch.getInput().checked) {
|
||||||
}
|
// new DialogMsgBox('检测玩家状态,当目标状态变成(海外)落地、出院或出狱时通知并播放声音提醒,后可搭配光速刷新食用<br/>确定开启?', {
|
||||||
Log.info('盯梢开启, 目标id' + targetId);
|
// callback: () => {
|
||||||
loop.start(parseInt(WuhuConfig.get('WatchTargetFreq')));
|
// if (this.commonUtils.getTravelStage() === TRAVEL_STATE.FLYING) {
|
||||||
},
|
// new Alert('失败!已取消');
|
||||||
cancel: () => watchSwitch.getInput().checked = false
|
// watchSwitch.getInput().checked = false;
|
||||||
});
|
// return;
|
||||||
} else {
|
// }
|
||||||
loop.stop();
|
// this.logger.info('盯梢开启, 目标id' + targetId);
|
||||||
Log.info('盯梢关闭');
|
// loop.start(this.localConfigWrapper.config.WatchTargetFreq | 0);
|
||||||
}
|
// },
|
||||||
});
|
// cancel: () => watchSwitch.getInput().checked = false
|
||||||
}
|
// });
|
||||||
}
|
// } else {
|
||||||
|
// loop.stop();
|
||||||
|
// this.logger.info('盯梢关闭');
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|||||||
@ -1,142 +0,0 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import WuhuConfig from "../WuhuConfig";
|
|
||||||
import Log from "../Log";
|
|
||||||
import InfoUtils from "../utils/InfoUtils";
|
|
||||||
import Alert from "../utils/Alert";
|
|
||||||
import MathUtils from "../utils/MathUtils";
|
|
||||||
import NOTIFY_HTML from "../../../static/html/buyBeer/notify.html";
|
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
|
||||||
import Popup from "../utils/Popup";
|
|
||||||
import ResponseInject from "../../interface/ResponseInject";
|
|
||||||
|
|
||||||
export default class BuyBeerHelper extends WuhuBase implements BeerMonitorLoop, ResponseInject {
|
|
||||||
className = 'BuyBeerHelper';
|
|
||||||
|
|
||||||
private isNotifying = false;
|
|
||||||
private loopId: number = null;
|
|
||||||
private time: number;
|
|
||||||
private readonly notifyHtml: string = NOTIFY_HTML.replace('{{}}', MathUtils.getInstance().getRandomInt(0, 99).toString());
|
|
||||||
|
|
||||||
public constructor() {
|
|
||||||
super();
|
|
||||||
this.time = WuhuConfig.get('_15AlarmTime') || 30;
|
|
||||||
}
|
|
||||||
|
|
||||||
public start(): void {
|
|
||||||
if (this.loopId) {
|
|
||||||
Log.info('啤酒助手已在运行');
|
|
||||||
} else {
|
|
||||||
this.loopId = window.setInterval(async () => {
|
|
||||||
// 海外取消提醒
|
|
||||||
let { isTravelling, isAbroad } = await InfoUtils.getInstance().getUserState();
|
|
||||||
if (isTravelling || isAbroad) {
|
|
||||||
this.stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let dt = new Date();
|
|
||||||
// 已选当天不提醒
|
|
||||||
const now = [dt.getUTCFullYear(), dt.getUTCMonth(), dt.getUTCDate()];
|
|
||||||
const ignore_date = WuhuConfig.get('_15_alarm_ignore') || '{}';
|
|
||||||
if (JSON.stringify(now) === JSON.stringify(ignore_date)) return;
|
|
||||||
// 正常提醒
|
|
||||||
let m = 14 - (dt.getMinutes() % 15);
|
|
||||||
let s = 60 - dt.getSeconds();
|
|
||||||
if (m === 0 && s < this.time) {
|
|
||||||
// 如从通知点开,则本次通知跳过
|
|
||||||
if (location.href.includes('clickfromnotify')) {
|
|
||||||
this.isNotifying = true;
|
|
||||||
location.hash = '';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 本次已通知
|
|
||||||
if (this.isNotifying) return;
|
|
||||||
this.isNotifying = true;
|
|
||||||
// 发送通知
|
|
||||||
const notify = new Alert(this.notifyHtml, {
|
|
||||||
timeout: 30,
|
|
||||||
sysNotify: true,
|
|
||||||
});
|
|
||||||
notify.getElement().querySelector('.wh-notify-msg button').addEventListener('click', () => this.skip_today());
|
|
||||||
notify.getElement().addEventListener('click', ev => {
|
|
||||||
if ((ev.target as HTMLElement).tagName.toLowerCase() === 'a') {
|
|
||||||
notify.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let audioPlay = CommonUtils.getInstance().audioPlay;
|
|
||||||
window.setTimeout(audioPlay, 800);
|
|
||||||
window.setTimeout(audioPlay, 800 * 2);
|
|
||||||
window.setTimeout(audioPlay, 800 * 3);
|
|
||||||
} else {
|
|
||||||
this.isNotifying = false;
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public stop(): void {
|
|
||||||
if (this.loopId) {
|
|
||||||
window.clearInterval(this.loopId);
|
|
||||||
this.loopId = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public set_time(t: number): void {
|
|
||||||
this.time = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
public status(): '已启动' | '未启动' {
|
|
||||||
return this.loopId ? '已启动' : '未启动';
|
|
||||||
}
|
|
||||||
|
|
||||||
public is_running(): boolean {
|
|
||||||
return this.loopId !== null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public skip_today(): void {
|
|
||||||
const date = new Date();
|
|
||||||
WuhuConfig.set('_15_alarm_ignore', [date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()], false);
|
|
||||||
// 通知
|
|
||||||
const notify = new Alert(`明早8点前将不再提醒 <button id="wh-rd-btn-${ MathUtils.getInstance().getRandomInt(0, 100) }">取消</button>`);
|
|
||||||
// 通知中的取消按钮
|
|
||||||
notify.getElement().querySelector('.wh-notify-msg button').addEventListener('click', () => WuhuConfig.set('_15_alarm_ignore', undefined, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
public setTimeHandler(): void {
|
|
||||||
let popup = new Popup(`<label>提前提醒时间(秒):<input type="number" value="${ WuhuConfig.get('_15AlarmTime') }" /></label><p>区间为 1 ~ 60,默认 50</p>`, '啤酒提醒时间设定');
|
|
||||||
let confirm = document.createElement('button');
|
|
||||||
confirm.innerHTML = '确定';
|
|
||||||
confirm.style.float = 'right';
|
|
||||||
confirm.addEventListener('click', () => {
|
|
||||||
let input: HTMLInputElement = popup.getElement().querySelector('input');
|
|
||||||
let num = (input.value as any) | 0;
|
|
||||||
if (num === WuhuConfig.get('_15AlarmTime')) return;
|
|
||||||
if (num < 1 || num > 60) num = 50;
|
|
||||||
input.value = num.toString();
|
|
||||||
WuhuConfig.set('_15AlarmTime', num);
|
|
||||||
this.set_time(num);
|
|
||||||
// 之前的运行状态
|
|
||||||
if (this.is_running()) this.start();
|
|
||||||
popup.close();
|
|
||||||
});
|
|
||||||
popup.getElement().appendChild(confirm);
|
|
||||||
}
|
|
||||||
|
|
||||||
public responseHandler(url: string, body: { json: unknown; text: string; isModified: boolean }, opt: { method: "GET" | "POST"; requestBody: string }) {
|
|
||||||
if (url.includes('shops.php') && opt?.method === 'POST') {
|
|
||||||
let req = opt.requestBody;
|
|
||||||
if (req && req.includes('step=buyShopItem') && req.includes('ID=180') && body.json && body.json['success']) {
|
|
||||||
new Alert('检测到已成功购买啤酒');
|
|
||||||
BuyBeerHelper.getInstance().skip_today();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BeerMonitorLoop {
|
|
||||||
start?: Function;
|
|
||||||
stop?: Function;
|
|
||||||
set_time?: Function;
|
|
||||||
status?: Function;
|
|
||||||
is_running?: Function;
|
|
||||||
skip_today?: Function;
|
|
||||||
}
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import WuhuConfig from "../WuhuConfig";
|
|
||||||
import Log from "../Log";
|
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
|
||||||
import FetchUtils from "../utils/FetchUtils";
|
|
||||||
import InfoUtils from "../utils/InfoUtils";
|
|
||||||
import Alert from "../utils/Alert";
|
|
||||||
import TRAVEL_STATE from "../../enum/TravelState";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 公司助手
|
|
||||||
*/
|
|
||||||
export default class CompanyHelper extends WuhuBase {
|
|
||||||
className = 'CompanyHelper';
|
|
||||||
|
|
||||||
public constructor() {
|
|
||||||
super();
|
|
||||||
WuhuConfig.get('CHTrainsDetectSwitch') && this.trainsDetect().then();
|
|
||||||
}
|
|
||||||
|
|
||||||
public detectNow(): void {
|
|
||||||
this.trainsDetect(true).then();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 火车检测
|
|
||||||
* 每日判断一次,非公司老板跳过检测
|
|
||||||
* TODO 优化、URL判断
|
|
||||||
*/
|
|
||||||
private async trainsDetect(test: boolean = false): Promise<null> {
|
|
||||||
// 通过用户的icon判断公司老板
|
|
||||||
if ((await InfoUtils.getInstance().getSessionData()).statusIcons.icons.company.iconID !== 'icon73') {
|
|
||||||
Log.info('火车检测跳过:非公司老板');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 上次检测时间戳
|
|
||||||
let lastDetect: number = WuhuConfig.get('CHTrainsDetect') || 0;
|
|
||||||
// 检测是否过了一天
|
|
||||||
if (test || CommonUtils.getInstance().isNewDay(lastDetect, -6)) {
|
|
||||||
let travelStage = CommonUtils.getInstance().getTravelStage(),
|
|
||||||
userStatus = (await InfoUtils.getInstance().getUserState()).status;
|
|
||||||
test && Log.info({ travelStage, userStatus });
|
|
||||||
if (travelStage === TRAVEL_STATE.IN_TORN && userStatus === 'ok')
|
|
||||||
FetchUtils.getInstance().fetchText('/companies.php')
|
|
||||||
.then(res => {
|
|
||||||
let tmp: HTMLElement = document.createElement('div');
|
|
||||||
let bodyTagStart = CommonUtils.getInstance().matchOne(res, /<body.+>/);
|
|
||||||
if (!bodyTagStart) {
|
|
||||||
Log.warn('火车检测: 无法获取数据');
|
|
||||||
throw new Error('火车检测: 无法获取数据');
|
|
||||||
}
|
|
||||||
tmp.innerHTML = res.split(bodyTagStart)[1].split('</body>')[0].trim()
|
|
||||||
.replaceAll('rel="stylesheet"', '')
|
|
||||||
.replaceAll('.css', '?404')
|
|
||||||
.replaceAll('type="text/javascript"', 'type="application/json"');
|
|
||||||
let trainsNode = tmp.querySelector('span.trains');
|
|
||||||
if (!trainsNode) {
|
|
||||||
Log.error('火车检测出错: 无法获取火车数');
|
|
||||||
throw new Error('火车检测出错: 无法获取火车数');
|
|
||||||
}
|
|
||||||
let trains: number = parseInt(trainsNode.innerText);
|
|
||||||
let stars: number = tmp.querySelectorAll('.company-rating .active').length / 2 || 1;
|
|
||||||
WuhuConfig.set('CHTrainsDetect', Date.now());
|
|
||||||
Log.info('火车检测: 火车/星级: ' + trains + '/' + stars);
|
|
||||||
Log.info({ tmp });
|
|
||||||
if (trains + stars > 20) {
|
|
||||||
new Alert(`公司助手<br/><br/>火车检测:火车明日将溢出!${ trains }/20火车`, {
|
|
||||||
timeout: 15,
|
|
||||||
force: true,
|
|
||||||
sysNotify: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
tmp.remove();
|
|
||||||
tmp = null;
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
Log.error('火车检测出错', error);
|
|
||||||
});
|
|
||||||
else Log.warn('[火车检测] 用户状态错误,跳过火车检测', { travelStage, userStatus });
|
|
||||||
} else {
|
|
||||||
Log.info('火车检测:今日已提醒,跳过');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,15 +1,35 @@
|
|||||||
import { MiniProfile } from "../../interface/responseType/MiniProfile";
|
import { MiniProfile } from "../../interface/responseType/MiniProfile";
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
import CommonUtils from "../utils/CommonUtils";
|
||||||
import WuhuConfig from "../WuhuConfig";
|
|
||||||
import Provider from "../provider/Provider";
|
import Provider from "../provider/Provider";
|
||||||
import ResponseInject from "../../interface/ResponseInject";
|
import ResponseInject from "../../interface/ResponseInject";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import LocalConfigWrapper from "../LocalConfigWrapper";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
import MsgWrapper from "../utils/MsgWrapper";
|
||||||
|
import { fetchYata } from "../../func/module/fetchYata";
|
||||||
|
import toThousands from "../../func/utils/toThousands";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fetch 事件监听回调
|
* fetch 事件监听回调
|
||||||
*/
|
*/
|
||||||
|
@Injectable()
|
||||||
|
@ClassName("FetchEventCallback")
|
||||||
export default class FetchEventCallback extends Provider implements ResponseInject {
|
export default class FetchEventCallback extends Provider implements ResponseInject {
|
||||||
className = "FetchEventCallback";
|
className = "FetchEventCallback";
|
||||||
|
|
||||||
|
newNode = document.createElement('div')
|
||||||
|
bsEstNode = document.createElement('div')
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
|
private readonly commonUtils: CommonUtils,
|
||||||
|
private readonly logger: Logger,
|
||||||
|
private readonly msgWrapper: MsgWrapper,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fetch 返回后处理
|
* fetch 返回后处理
|
||||||
* @param url
|
* @param url
|
||||||
@ -17,15 +37,38 @@ export default class FetchEventCallback extends Provider implements ResponseInje
|
|||||||
*/
|
*/
|
||||||
public responseHandler(url: string, response) {
|
public responseHandler(url: string, response) {
|
||||||
// mini profile 中添加上次动作
|
// mini profile 中添加上次动作
|
||||||
if (url.includes('profiles.php?step=getUserNameContextMenu') && WuhuConfig.get('ShowMiniProfLastAct')) {
|
if (url.startsWith('/page.php?sid=UserMiniProfile&userID')) {
|
||||||
window.setTimeout(async () => {
|
window.setTimeout(async () => {
|
||||||
let cont = CommonUtils.querySelector('[class*=profile-mini-_userProfileWrapper___]');
|
let cont = CommonUtils.querySelector('[class*=profile-mini-_userProfileWrapper___]');
|
||||||
let resp: MiniProfile = response.json as MiniProfile;
|
let resp: MiniProfile = response.json as MiniProfile;
|
||||||
let newNode = document.createElement('div');
|
if (this.localConfigWrapper.config.ShowMiniProfLastAct) {
|
||||||
let formatted = CommonUtils.getInstance().secondsFormat(resp.user.lastAction.seconds);
|
this.logger.info({ resp })
|
||||||
|
let formatted = this.commonUtils.secondsFormat(resp.user.lastAction.seconds);
|
||||||
|
|
||||||
newNode.innerText = '上次动作: ' + formatted;
|
(await cont).append(this.newNode);
|
||||||
(await cont).append(newNode);
|
this.newNode.innerText = '上次动作: ' + formatted;
|
||||||
|
}
|
||||||
|
if (this.localConfigWrapper.config.isBSEstMiniProfOn) {
|
||||||
|
const id = resp.user.userID
|
||||||
|
const apikey = localStorage.getItem('APIKey')
|
||||||
|
this.bsEstNode.innerHTML = `[BS估算] [${ id }]获取中...`;
|
||||||
|
(await cont).append(this.bsEstNode)
|
||||||
|
if (!apikey) {
|
||||||
|
this.bsEstNode.innerHTML = '[BS估算] 未配置APIKey,无法估算BS'
|
||||||
|
this.logger.error('MINI Profile bs估算失败: APIKey为空')
|
||||||
|
} else {
|
||||||
|
const bsData = fetchYata(id, apikey)
|
||||||
|
bsData.then(data => {
|
||||||
|
// 网速过慢时可能mini profile容器已更新新内容,与上次请求的用户数据不同,需要判断
|
||||||
|
if (this.bsEstNode.innerHTML.includes(resp.user.userID.toString())) {
|
||||||
|
this.bsEstNode.innerHTML = `[BS估算] ${ resp.user.playerName }[${ id }] ${ toThousands(data.total) }`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
this.bsEstNode.innerHTML = `[BS估算] ${ err.message }`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,49 +1,74 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import TornStyleBlock from "../utils/TornStyleBlock";
|
import TornStyleBlock from "../utils/TornStyleBlock";
|
||||||
import WuhuConfig from "../WuhuConfig";
|
|
||||||
import Alert from "../utils/Alert";
|
|
||||||
import TornStyleSwitch from "../utils/TornStyleSwitch";
|
import TornStyleSwitch from "../utils/TornStyleSwitch";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import LocalConfigWrapper from "../LocalConfigWrapper";
|
||||||
|
import IFeature from "../../man/IFeature";
|
||||||
|
import MsgWrapper from "../utils/MsgWrapper";
|
||||||
|
|
||||||
export default class PTHelper extends WuhuBase {
|
@Injectable()
|
||||||
className = 'PTHelper';
|
@ClassName('PTHelper')
|
||||||
private readonly observer;
|
export default class PTHelper implements IFeature {
|
||||||
private readonly usersPointSell;
|
private observer: MutationObserver;
|
||||||
|
private usersPointSell: HTMLDivElement;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
|
private readonly msgWrapper: MsgWrapper,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
description(): string {
|
||||||
|
return "pt一键购买";
|
||||||
|
}
|
||||||
|
|
||||||
|
iStart(): void | Promise<void> {
|
||||||
|
this.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
urlExcludes(): RegExp[] {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
urlIncludes(): RegExp[] {
|
||||||
|
return [/pmarket\.php/];
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.observer = new MutationObserver(e => {
|
this.observer = new MutationObserver(e => {
|
||||||
for (const t of e) {
|
for (const t of e) {
|
||||||
t.addedNodes.forEach(e => 'LI' === (e as HTMLElement).tagName && this.removeConfirm(e))
|
t.addedNodes.forEach(e => 'LI' === (e as HTMLElement).tagName && this.removeConfirm(e))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.usersPointSell = document.querySelector('.users-point-sell');
|
this.usersPointSell = document.querySelector<HTMLDivElement>('.users-point-sell');
|
||||||
|
|
||||||
let block = new TornStyleBlock('PT一键购买').insert2Dom();
|
let block = new TornStyleBlock('PT一键购买').insert2Dom();
|
||||||
let switcher = new TornStyleSwitch('开启');
|
let switcher = new TornStyleSwitch('开启');
|
||||||
block.append(switcher.getBase());
|
block.append(switcher.getBase());
|
||||||
let toggle = switcher.getInput();
|
let toggle = switcher.getInput();
|
||||||
toggle.checked = WuhuConfig.get('ptQuickBuy');
|
toggle.checked = this.localConfigWrapper.config.ptQuickBuy;
|
||||||
if (toggle.checked) {
|
if (toggle.checked) {
|
||||||
new Alert('一键购买已开启');
|
this.msgWrapper.create('一键购买已开启');
|
||||||
for (const index in this.usersPointSell.children) {
|
for (const index in this.usersPointSell.children) {
|
||||||
'LI' === this.usersPointSell.children[index].tagName && this.removeConfirm(this.usersPointSell.children[index])
|
'LI' === this.usersPointSell.children[index].tagName && this.removeConfirm(this.usersPointSell.children[index])
|
||||||
}
|
}
|
||||||
this.observer.observe(this.usersPointSell, { childList: true })
|
this.observer.observe(this.usersPointSell, { childList: true })
|
||||||
}
|
}
|
||||||
toggle.addEventListener('change', () => {
|
toggle.addEventListener('change', () => {
|
||||||
WuhuConfig.set('ptQuickBuy', toggle.checked, false);
|
this.localConfigWrapper.config.ptQuickBuy = toggle.checked;
|
||||||
if (toggle.checked) {
|
if (toggle.checked) {
|
||||||
for (const index in this.usersPointSell.children) {
|
for (const index in this.usersPointSell.children) {
|
||||||
'LI' === this.usersPointSell.children[index].tagName && this.removeConfirm(this.usersPointSell.children[index])
|
'LI' === this.usersPointSell.children[index].tagName && this.removeConfirm(this.usersPointSell.children[index])
|
||||||
}
|
}
|
||||||
this.observer.observe(this.usersPointSell, { childList: true });
|
this.observer.observe(this.usersPointSell, { childList: true });
|
||||||
new Alert('一键购买已开启');
|
this.msgWrapper.create('一键购买已开启');
|
||||||
} else {
|
} else {
|
||||||
for (const index in this.usersPointSell.children) {
|
for (const index in this.usersPointSell.children) {
|
||||||
'LI' === this.usersPointSell.children[index].tagName && this.rollbackConfirm(this.usersPointSell.children[index])
|
'LI' === this.usersPointSell.children[index].tagName && this.rollbackConfirm(this.usersPointSell.children[index])
|
||||||
}
|
}
|
||||||
this.observer.disconnect();
|
this.observer.disconnect();
|
||||||
new Alert('一键购买已关闭');
|
this.msgWrapper.create('一键购买已关闭');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,59 +1,150 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import Log from "../Log";
|
|
||||||
import WuhuConfig from "../WuhuConfig";
|
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
import CommonUtils from "../utils/CommonUtils";
|
||||||
import TornStyleBlock from "../utils/TornStyleBlock";
|
import TornStyleBlock from "../utils/TornStyleBlock";
|
||||||
import TornStyleSwitch from "../utils/TornStyleSwitch";
|
import TornStyleSwitch from "../utils/TornStyleSwitch";
|
||||||
import ResponseInject from "../../interface/ResponseInject";
|
import ResponseInject from "../../interface/ResponseInject";
|
||||||
import globVars from "../../globVars";
|
import globVars from "../../globVars";
|
||||||
import IUserProfileData from "../../interface/IUserProfileData";
|
import IUserProfileData from "../../interface/IUserProfileData";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import LocalConfigWrapper from "../LocalConfigWrapper";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
import IFeature from "../../man/IFeature";
|
||||||
|
import { fetchYata } from "../../func/module/fetchYata";
|
||||||
|
import MsgWrapper from "../utils/MsgWrapper";
|
||||||
|
import toThousands from "../../func/utils/toThousands";
|
||||||
|
import { timePastFormat } from "../../func/utils/timePastFormat";
|
||||||
|
|
||||||
export default class ProfileHelper extends WuhuBase implements ResponseInject {
|
@ClassName('ProfileHelper')
|
||||||
className = 'ProfileHelper';
|
@Injectable()
|
||||||
|
export default class ProfileHelper implements ResponseInject, IFeature {
|
||||||
|
private block: TornStyleBlock;
|
||||||
|
|
||||||
private readonly block;
|
constructor(
|
||||||
|
private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
|
private readonly commonUtils: CommonUtils,
|
||||||
|
private readonly logger: Logger,
|
||||||
|
private readonly msgWrapper: MsgWrapper,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
description(): string {
|
||||||
|
return "个人资料页面辅助";
|
||||||
|
}
|
||||||
|
|
||||||
|
iStart(): void | Promise<void> {
|
||||||
|
this.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
urlExcludes(): RegExp[] {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
// 曾用名已检测过标记
|
// 曾用名已检测过标记
|
||||||
private task = true;
|
private task = true;
|
||||||
|
|
||||||
constructor() {
|
urlIncludes(): RegExp[] {
|
||||||
super();
|
return [/profiles\.php\?XID=/];
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
|
||||||
CommonUtils.addStyle('body.wh-hide_profile_img .profile-image a.profile-image-wrapper .img-wrap img{display:none;}');
|
CommonUtils.addStyle('body.wh-hide_profile_img .profile-image a.profile-image-wrapper .img-wrap img{display:none;}');
|
||||||
let id = document.querySelector('link[rel="canonical"]').getAttribute('href').split('=')[1];
|
// let id = document.querySelector('link[rel="canonical"]').getAttribute('href').split('=')[1];
|
||||||
|
let id = (new URL(window.location.href)).searchParams.get('XID');
|
||||||
// id获取格式判断
|
// id获取格式判断
|
||||||
if (!CommonUtils.getInstance().isValidUid(id)) {
|
if (!this.commonUtils.isValidUid(id)) {
|
||||||
Log.error('[ProfileHelper] id格式错误');
|
this.logger.error('[ProfileHelper] id格式错误');
|
||||||
}
|
}
|
||||||
if (WuhuConfig.get('HideProfileImg')) {
|
if (this.localConfigWrapper.config.HideProfileImg) {
|
||||||
Log.info('[ProfileHelper] 隐藏头像');
|
this.logger.info('[ProfileHelper] 隐藏头像');
|
||||||
document.body.classList.toggle('wh-hide_profile_img');
|
document.body.classList.toggle('wh-hide_profile_img');
|
||||||
}
|
}
|
||||||
this.block = new TornStyleBlock('芜湖助手').insert2Dom();
|
this.block = new TornStyleBlock('芜湖助手').insert2Dom();
|
||||||
// 隐藏头像
|
// 隐藏头像
|
||||||
let hideImgSwitch = new TornStyleSwitch('隐藏头像', WuhuConfig.get('HideProfileImg'));
|
try {
|
||||||
this.block.append(hideImgSwitch.getBase());
|
let hideImgSwitch = new TornStyleSwitch('隐藏头像', this.localConfigWrapper.config.HideProfileImg);
|
||||||
hideImgSwitch.getInput().addEventListener('change', () => {
|
this.block.append(hideImgSwitch.getBase());
|
||||||
document.body.classList.toggle('wh-hide_profile_img');
|
hideImgSwitch.getInput().addEventListener('change', () => {
|
||||||
WuhuConfig.set('HideProfileImg', hideImgSwitch.getInput().checked, true);
|
document.body.classList.toggle('wh-hide_profile_img');
|
||||||
});
|
this.localConfigWrapper.config.HideProfileImg = hideImgSwitch.getInput().checked;
|
||||||
if (WuhuConfig.get('ShowNameHistory')) {
|
});
|
||||||
globVars.responseHandlers.push((url, body) => this.responseHandler(url, body));
|
if (this.localConfigWrapper.config.ShowNameHistory) {
|
||||||
|
globVars.responseHandlers.push((...args: any[]) => this.responseHandler.apply(this, args));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error('隐藏头像时出错了', e.stack)
|
||||||
|
}
|
||||||
|
// bs估算
|
||||||
|
if (this.localConfigWrapper.config.isBSEstProfOn) {
|
||||||
|
try {
|
||||||
|
const apikey = localStorage.getItem('APIKey')
|
||||||
|
if (!apikey) {
|
||||||
|
this.msgWrapper.create('BS估算失败: 尚未设定APIKey', null, 'error')
|
||||||
|
}
|
||||||
|
const promise = fetchYata(parseInt(id), apikey)
|
||||||
|
const domNode = document.createElement('div')
|
||||||
|
domNode.innerHTML = 'BS估算中...'
|
||||||
|
domNode.classList.add('mt-4')
|
||||||
|
domNode.style.border = '1px solid green'
|
||||||
|
domNode.style.padding = '2px'
|
||||||
|
this.block.append(domNode)
|
||||||
|
const buildType = { Offensive: '攻击型', Defensive: '防御型', Balanced: '平衡型' }
|
||||||
|
promise.then(data => {
|
||||||
|
domNode.innerHTML = `<b>BS估算</b><br/>
|
||||||
|
BS: ${ toThousands(data.total) }<br/>
|
||||||
|
评分: ${ toThousands(data.score) }<br/>
|
||||||
|
风格: ${ buildType[data.type] }<br/>
|
||||||
|
偏差: ${ data.skewness }%<br/>
|
||||||
|
估算时间: ${ timePastFormat(Date.now() - data.timestamp * 1000) }前
|
||||||
|
`
|
||||||
|
}).catch(err => {
|
||||||
|
domNode.innerHTML = 'BS估算出错了: ' + err.message
|
||||||
|
throw new TypeError('BS估算出错了: ' + err.message)
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
this.msgWrapper.create('BS估算失败' + e.message, null, 'error')
|
||||||
|
throw new TypeError('BS估算失败' + e.message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
responseHandler(url: string, body: { json: unknown; text: string; isModified: boolean }) {
|
responseHandler(url: string, body: { json: unknown; text: string; isModified: boolean }) {
|
||||||
if (url.includes('profiles.php?step=getProfileData') && this.task) {
|
if (url.includes('profiles.php?step=getProfileData') && this.task) {
|
||||||
// 曾用名
|
// 曾用名
|
||||||
let nameHistoryNode;
|
const nameHistoryNode = document.createElement('p');
|
||||||
nameHistoryNode = document.createElement('p');
|
|
||||||
nameHistoryNode.innerHTML = '曾用名:';
|
nameHistoryNode.innerHTML = '曾用名:';
|
||||||
this.block.append(nameHistoryNode);
|
this.block.append(nameHistoryNode);
|
||||||
let resp = body.json as IUserProfileData;
|
let resp = body.json as IUserProfileData;
|
||||||
if (resp.userInformation.previousAliases.length > 0) {
|
if (resp.userInformation.previousAliases.length > 0) { // 曾用名列表
|
||||||
resp.userInformation.previousAliases.forEach(item => nameHistoryNode.innerHTML += item + ' ');
|
resp.userInformation.previousAliases.forEach(item => nameHistoryNode.innerHTML += item + ' ');
|
||||||
} else {
|
} else {
|
||||||
nameHistoryNode.innerHTML += '暂无';
|
nameHistoryNode.innerHTML += '暂无';
|
||||||
}
|
}
|
||||||
|
let lastAction = -1
|
||||||
|
let onlineStatusTitle = '-'
|
||||||
|
if (resp.basicInformation?.lastAction.seconds) {
|
||||||
|
lastAction = resp.basicInformation.lastAction.seconds
|
||||||
|
}
|
||||||
|
if (resp.basicInformation.icons) {
|
||||||
|
for (let i = 0; i < resp.basicInformation.icons.length; i++) {
|
||||||
|
let item = resp.basicInformation.icons[i]
|
||||||
|
if (item.id === 1) {
|
||||||
|
onlineStatusTitle = '🟢️ 在线'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if (item.id === 62) {
|
||||||
|
onlineStatusTitle = '🟡 挂机'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if (item.id === 2) {
|
||||||
|
onlineStatusTitle = '⚪ 离线'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const lastActionNode = document.createElement('p')
|
||||||
|
lastActionNode.innerHTML = `${ onlineStatusTitle } ${ this.commonUtils.secondsFormat(lastAction) }`
|
||||||
|
this.block.append(lastActionNode)
|
||||||
this.task = false;
|
this.task = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
46
src/ts/class/action/QuickGymTrain.ts
Normal file
46
src/ts/class/action/QuickGymTrain.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
import NetHighLvlWrapper, { BATTLE_STAT } from "../utils/NetHighLvlWrapper";
|
||||||
|
import { InjectionKey } from "vue";
|
||||||
|
import MsgWrapper from "../utils/MsgWrapper";
|
||||||
|
|
||||||
|
type GymResponse = {
|
||||||
|
success: boolean,
|
||||||
|
// 成功才有 You gained 689,636.71 strength
|
||||||
|
gainMessage?: string,
|
||||||
|
message: string,
|
||||||
|
text?: string,
|
||||||
|
error?: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
@ClassName("QuickGymTrain")
|
||||||
|
@Injectable()
|
||||||
|
export default class QuickGymTrain {
|
||||||
|
constructor(
|
||||||
|
private readonly logger: Logger,
|
||||||
|
private readonly netHighLvlWrapper: NetHighLvlWrapper,
|
||||||
|
private readonly msgWrapper: MsgWrapper,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
doTrain(type = BATTLE_STAT.STR, count = 199) {
|
||||||
|
window.setTimeout(async () => {
|
||||||
|
let resObj: GymResponse;
|
||||||
|
try {
|
||||||
|
resObj = JSON.parse(await this.netHighLvlWrapper.doGymTrain(type, count))
|
||||||
|
} catch (e) {
|
||||||
|
resObj = { success: false, message: '解析失败' };
|
||||||
|
this.logger.error(e.stack || e.message || e);
|
||||||
|
}
|
||||||
|
let msgRs = resObj.success ? '成功' : '失败';
|
||||||
|
let msgMsg = resObj.message || resObj.text || resObj.error;
|
||||||
|
this.msgWrapper.create(
|
||||||
|
'锻炼结果: ' + msgRs + '<br/>提示: ' + (resObj.gainMessage || msgMsg),
|
||||||
|
{}, resObj.success ? 'success' : 'error'
|
||||||
|
);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const QuickGymTrainKey = Symbol('QuickGymTrainKey') as InjectionKey<QuickGymTrain>;
|
||||||
@ -1,14 +1,33 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import TornStyleBlock from "../utils/TornStyleBlock";
|
import TornStyleBlock from "../utils/TornStyleBlock";
|
||||||
import TornStyleSwitch from "../utils/TornStyleSwitch";
|
import TornStyleSwitch from "../utils/TornStyleSwitch";
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
import CommonUtils from "../utils/CommonUtils";
|
||||||
import WuhuConfig from "../WuhuConfig";
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import LocalConfigWrapper from "../LocalConfigWrapper";
|
||||||
|
import IFeature from "../../man/IFeature";
|
||||||
|
|
||||||
export default class SearchHelper extends WuhuBase {
|
@ClassName('SearchHelper')
|
||||||
className = 'SearchHelper';
|
@Injectable()
|
||||||
|
export default class SearchHelper implements IFeature {
|
||||||
|
description(): string {
|
||||||
|
return "搜索助手";
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
iStart(): void | Promise<void> {
|
||||||
super();
|
this.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
urlExcludes(): RegExp[] {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
urlIncludes(): RegExp[] {
|
||||||
|
return [/page\.php\?sid=UserList/];
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(): void {
|
public init(): void {
|
||||||
@ -16,7 +35,7 @@ export default class SearchHelper extends WuhuBase {
|
|||||||
let placeholderSwitch = new TornStyleSwitch('底部空白占位区');
|
let placeholderSwitch = new TornStyleSwitch('底部空白占位区');
|
||||||
block.append(placeholderSwitch.getBase()).insert2Dom();
|
block.append(placeholderSwitch.getBase()).insert2Dom();
|
||||||
CommonUtils.addStyle('body.WHSearchPagePlaceholder .content.logged-in {margin-bottom: 340px;}');
|
CommonUtils.addStyle('body.WHSearchPagePlaceholder .content.logged-in {margin-bottom: 340px;}');
|
||||||
let config = WuhuConfig.get('SearchPagePlaceholder');
|
let config = this.localConfigWrapper.config.SearchPagePlaceholder;
|
||||||
placeholderSwitch.getInput().checked = config || false;
|
placeholderSwitch.getInput().checked = config || false;
|
||||||
config ? this.enable() : this.disable();
|
config ? this.enable() : this.disable();
|
||||||
placeholderSwitch.getInput().addEventListener('change', () => {
|
placeholderSwitch.getInput().addEventListener('change', () => {
|
||||||
@ -26,11 +45,11 @@ export default class SearchHelper extends WuhuBase {
|
|||||||
|
|
||||||
private enable(): void {
|
private enable(): void {
|
||||||
document.body.classList.add('WHSearchPagePlaceholder');
|
document.body.classList.add('WHSearchPagePlaceholder');
|
||||||
WuhuConfig.set('SearchPagePlaceholder', true);
|
this.localConfigWrapper.config.SearchPagePlaceholder = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private disable(): void {
|
private disable(): void {
|
||||||
document.body.classList.remove('WHSearchPagePlaceholder');
|
document.body.classList.remove('WHSearchPagePlaceholder');
|
||||||
WuhuConfig.set('SearchPagePlaceholder', false);
|
this.localConfigWrapper.config.SearchPagePlaceholder = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,43 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import TornStyleBlock from "../utils/TornStyleBlock";
|
import TornStyleBlock from "../utils/TornStyleBlock";
|
||||||
import InfoUtils from "../utils/InfoUtils";
|
import InfoUtils from "../utils/InfoUtils";
|
||||||
import Log from "../Log";
|
|
||||||
import FetchUtils from "../utils/FetchUtils";
|
import FetchUtils from "../utils/FetchUtils";
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
import CommonUtils from "../utils/CommonUtils";
|
||||||
import MathUtils from "../utils/MathUtils";
|
import MathUtils from "../utils/MathUtils";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
import IFeature from "../../man/IFeature";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 老虎机批量购买助手
|
* 老虎机批量购买助手
|
||||||
*/
|
*/
|
||||||
export default class SlotsHelper extends WuhuBase {
|
@ClassName("SlotsHelper")
|
||||||
className = "SlotsHelper";
|
@Injectable()
|
||||||
|
export default class SlotsHelper implements IFeature {
|
||||||
|
description(): string {
|
||||||
|
return "老虎机批量购买助手";
|
||||||
|
}
|
||||||
|
|
||||||
|
iStart(): void | Promise<void> {
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
urlExcludes(): RegExp[] {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
urlIncludes(): RegExp[] {
|
||||||
|
return [/loader\.php\?sid=slots/];
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly mathUtils: MathUtils,
|
||||||
|
private readonly commonUtils: CommonUtils,
|
||||||
|
private readonly fetchUtils: FetchUtils,
|
||||||
|
private readonly infoUtils: InfoUtils,
|
||||||
|
private readonly logger: Logger,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
private block = new TornStyleBlock("芜湖助手");
|
private block = new TornStyleBlock("芜湖助手");
|
||||||
|
|
||||||
@ -56,7 +83,7 @@ export default class SlotsHelper extends WuhuBase {
|
|||||||
try {
|
try {
|
||||||
await this.goBtnHandler(ev, ret)
|
await this.goBtnHandler(ev, ret)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.error(e.stack || e);
|
this.logger.error(e.stack || e);
|
||||||
}
|
}
|
||||||
goBtn.disabled = false;
|
goBtn.disabled = false;
|
||||||
});
|
});
|
||||||
@ -68,7 +95,7 @@ export default class SlotsHelper extends WuhuBase {
|
|||||||
private async goBtnHandler(ev: MouseEvent, nodes: SlotsHelperNodes) {
|
private async goBtnHandler(ev: MouseEvent, nodes: SlotsHelperNodes) {
|
||||||
let { counterInput, select, msgBox } = nodes;
|
let { counterInput, select, msgBox } = nodes;
|
||||||
// 现金
|
// 现金
|
||||||
let cash = (await InfoUtils.getInstance().getSessionData())?.user?.money?.value;
|
let cash = (await this.infoUtils.getSessionData())?.user?.money?.value;
|
||||||
msgBox.innerText = '等待加载中';
|
msgBox.innerText = '等待加载中';
|
||||||
// 代币
|
// 代币
|
||||||
let tokens: number = parseInt((await CommonUtils.querySelector('.player-info-cont #tokens')).innerText);
|
let tokens: number = parseInt((await CommonUtils.querySelector('.player-info-cont #tokens')).innerText);
|
||||||
@ -89,7 +116,7 @@ export default class SlotsHelper extends WuhuBase {
|
|||||||
// 实际购买数量
|
// 实际购买数量
|
||||||
let i: number;
|
let i: number;
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
let res: SlotsResponse = await (await FetchUtils.getInstance().ajaxFetch({
|
let res: SlotsResponse = await (await this.fetchUtils.ajaxFetch({
|
||||||
url: window.addRFC("https://www.torn.com/loader.php?sid=slotsInterface&step=play&stake=" + price),
|
url: window.addRFC("https://www.torn.com/loader.php?sid=slotsInterface&step=play&stake=" + price),
|
||||||
referrer: "/loader.php?sid=slots",
|
referrer: "/loader.php?sid=slots",
|
||||||
method: "GET"
|
method: "GET"
|
||||||
@ -100,7 +127,7 @@ export default class SlotsHelper extends WuhuBase {
|
|||||||
msgBox.innerHTML += '<br/>代币不足';
|
msgBox.innerHTML += '<br/>代币不足';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
await CommonUtils.getInstance().sleep(MathUtils.getInstance().getRandomInt(1800, 2400));
|
await this.commonUtils.sleep(this.mathUtils.getRandomInt(1800, 2400));
|
||||||
}
|
}
|
||||||
// 利润
|
// 利润
|
||||||
let profit = wonTotal - i * price;
|
let profit = wonTotal - i * price;
|
||||||
@ -109,7 +136,7 @@ export default class SlotsHelper extends WuhuBase {
|
|||||||
msgBox.innerHTML += '<br/>已停止, ';
|
msgBox.innerHTML += '<br/>已停止, ';
|
||||||
msgBox.innerHTML += bang ? '血' : '小';
|
msgBox.innerHTML += bang ? '血' : '小';
|
||||||
msgBox.innerHTML += profit > 0 ? '赚' : '亏';
|
msgBox.innerHTML += profit > 0 ? '赚' : '亏';
|
||||||
Log.info("[goBtnHandler]结束", { cash, tokens, count, price, wonTotal });
|
this.logger.info("[goBtnHandler]结束", { cash, tokens, count, price, wonTotal });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,24 +0,0 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import TornStyleBlock from "../utils/TornStyleBlock";
|
|
||||||
import WuhuConfig from "../WuhuConfig";
|
|
||||||
import TornStyleSwitch from "../utils/TornStyleSwitch";
|
|
||||||
|
|
||||||
export default class StackHelper extends WuhuBase {
|
|
||||||
className = 'StackHelper';
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
let block = new TornStyleBlock('叠E保护').insert2Dom();
|
|
||||||
let switcher = new TornStyleSwitch('启用');
|
|
||||||
let input = switcher.getInput();
|
|
||||||
block.append(switcher.getBase());
|
|
||||||
input.checked = WuhuConfig.get('SEProtect');
|
|
||||||
if (input.checked) document.body.classList.add('wh-gym-stack');
|
|
||||||
// 绑定点击事件
|
|
||||||
input.onchange = e => {
|
|
||||||
let target = e.target as HTMLInputElement;
|
|
||||||
document.body.classList.toggle('wh-gym-stack');
|
|
||||||
WuhuConfig.set('SEProtect', target.checked, true);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,16 +1,15 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import { chatDict, eventsDict, headerDict, propertyDict, sidebarDict } from "../../dictionary/translation";
|
import { chatDict, eventsDict, headerDict, propertyDict, sidebarDict } from "../../dictionary/translation";
|
||||||
import Log from "../Log";
|
|
||||||
import Timer from "../utils/Timer";
|
import Timer from "../utils/Timer";
|
||||||
|
|
||||||
export default class Translate extends WuhuBase {
|
/**
|
||||||
className = 'Translate';
|
* @deprecated 使用TranslateNew替代
|
||||||
|
*/
|
||||||
|
export default class Translate {
|
||||||
|
|
||||||
public translateVer: string = '1.0';
|
public translateVer: string = '1.0';
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
// Log.info('翻译开始');
|
||||||
Log.info('翻译开始');
|
|
||||||
let start = new Timer();
|
let start = new Timer();
|
||||||
// 时分秒转换
|
// 时分秒转换
|
||||||
String.prototype.replaceHMS = function replaceHMS() {
|
String.prototype.replaceHMS = function replaceHMS() {
|
||||||
@ -39,7 +38,7 @@ export default class Translate extends WuhuBase {
|
|||||||
this.chatTranslate();
|
this.chatTranslate();
|
||||||
this.playerSearchBoxTrans();
|
this.playerSearchBoxTrans();
|
||||||
this.urlMatchPageTranslate(window.location.href);
|
this.urlMatchPageTranslate(window.location.href);
|
||||||
Log.info('翻译结束, 耗时' + start.getTimeMs());
|
// Log.info('翻译结束, 耗时' + start.getTimeMs());
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,29 @@
|
|||||||
import ResponseInject from "../../interface/ResponseInject";
|
import ResponseInject from "../../interface/ResponseInject";
|
||||||
import WuhuConfig from "../WuhuConfig";
|
|
||||||
import { Button, MiniProfile } from "../../interface/responseType/MiniProfile";
|
import { Button, MiniProfile } from "../../interface/responseType/MiniProfile";
|
||||||
import Log from "../Log";
|
|
||||||
import Sidebar from "../../interface/responseType/Sidebar";
|
import Sidebar from "../../interface/responseType/Sidebar";
|
||||||
import InventoryItemInfo from "../../interface/responseType/InventoryItemInfo";
|
import InventoryItemInfo from "../../interface/responseType/InventoryItemInfo";
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
import CommonUtils from "../utils/CommonUtils";
|
||||||
import { itemNameDict, itemPageDict } from "../../dictionary/translation";
|
import { itemNameDict, itemPageDict } from "../../dictionary/translation";
|
||||||
import Provider from "../provider/Provider";
|
import Provider from "../provider/Provider";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import LocalConfigWrapper from "../LocalConfigWrapper";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 翻译重构
|
* 翻译重构
|
||||||
*/
|
*/
|
||||||
|
@ClassName('TranslateNew')
|
||||||
|
@Injectable()
|
||||||
export default class TranslateNew extends Provider implements ResponseInject {
|
export default class TranslateNew extends Provider implements ResponseInject {
|
||||||
className = 'TranslateNew';
|
|
||||||
|
constructor(
|
||||||
|
private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
|
private readonly logger: Logger,
|
||||||
|
private readonly commonUtils: CommonUtils,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fetch xhr 返回数据的翻译处理
|
* fetch xhr 返回数据的翻译处理
|
||||||
@ -20,8 +31,12 @@ export default class TranslateNew extends Provider implements ResponseInject {
|
|||||||
* @param body
|
* @param body
|
||||||
* @param opt
|
* @param opt
|
||||||
*/
|
*/
|
||||||
public responseHandler(url: string, body: { json: unknown, text: string, isModified: boolean }, opt: { method: 'GET' | 'POST', requestBody: string }): void {
|
public responseHandler(
|
||||||
if (!WuhuConfig.get('transNew')) return;
|
url: string,
|
||||||
|
body: { json: unknown, text: string, isModified: boolean },
|
||||||
|
opt: { method: 'GET' | 'POST', requestBody: string }
|
||||||
|
): void {
|
||||||
|
if (!this.localConfigWrapper.config.transNew) return;
|
||||||
// TODO 字典抽取
|
// TODO 字典抽取
|
||||||
let map = {
|
let map = {
|
||||||
iconMap: {
|
iconMap: {
|
||||||
@ -66,7 +81,7 @@ export default class TranslateNew extends Provider implements ResponseInject {
|
|||||||
'Attacked': '攻击',
|
'Attacked': '攻击',
|
||||||
'Defeated': '击败',
|
'Defeated': '击败',
|
||||||
},
|
},
|
||||||
{ 'someone': '某人' },
|
{ 'someone': '某人2' },
|
||||||
{ '<br><i>Early discharge available</i>': '<br><i>提前出院(ED)可用</i>' },
|
{ '<br><i>Early discharge available</i>': '<br><i>提前出院(ED)可用</i>' },
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@ -206,7 +221,7 @@ export default class TranslateNew extends Provider implements ResponseInject {
|
|||||||
// Mini Profile
|
// Mini Profile
|
||||||
if (url.includes('profiles.php?step=getUserNameContextMenu')) {
|
if (url.includes('profiles.php?step=getUserNameContextMenu')) {
|
||||||
let jsonObj: MiniProfile = body.json as MiniProfile;
|
let jsonObj: MiniProfile = body.json as MiniProfile;
|
||||||
Log.info('翻译mini profile返回内容');
|
this.logger.info('翻译mini profile返回内容');
|
||||||
// 状态图标
|
// 状态图标
|
||||||
jsonObj.icons.forEach(icon => {
|
jsonObj.icons.forEach(icon => {
|
||||||
let iconMap = map.iconMap;
|
let iconMap = map.iconMap;
|
||||||
@ -223,7 +238,7 @@ export default class TranslateNew extends Provider implements ResponseInject {
|
|||||||
if (desc.attachedMap) {
|
if (desc.attachedMap) {
|
||||||
desc.attachedMap.forEach((item, index) => {
|
desc.attachedMap.forEach((item, index) => {
|
||||||
let factor = oriDesc.replace(new RegExp(desc.replace[0]), '$' + (index + 1));
|
let factor = oriDesc.replace(new RegExp(desc.replace[0]), '$' + (index + 1));
|
||||||
Log.info({ factor });
|
this.logger.info({ factor });
|
||||||
let cn = item[factor];
|
let cn = item[factor];
|
||||||
cn && (icon.description = icon.description.replace(factor, cn));
|
cn && (icon.description = icon.description.replace(factor, cn));
|
||||||
});
|
});
|
||||||
@ -282,7 +297,7 @@ export default class TranslateNew extends Provider implements ResponseInject {
|
|||||||
}
|
}
|
||||||
body.isModified = true;
|
body.isModified = true;
|
||||||
|
|
||||||
Log.info({ 'localized': jsonObj });
|
this.logger.info({ 'localized': jsonObj });
|
||||||
}
|
}
|
||||||
// TODO 边栏
|
// TODO 边栏
|
||||||
else if (url.includes('sidebarAjaxAction.php?q=sync')) {
|
else if (url.includes('sidebarAjaxAction.php?q=sync')) {
|
||||||
@ -306,23 +321,22 @@ export default class TranslateNew extends Provider implements ResponseInject {
|
|||||||
// 物品详情
|
// 物品详情
|
||||||
else if ((url.includes('inventory.php?step=info')) || (url.includes('inventory.php') && opt?.method === 'POST' &&
|
else if ((url.includes('inventory.php?step=info')) || (url.includes('inventory.php') && opt?.method === 'POST' &&
|
||||||
typeof opt?.requestBody === 'string' && opt?.requestBody.includes('step=info'))) {
|
typeof opt?.requestBody === 'string' && opt?.requestBody.includes('step=info'))) {
|
||||||
Log.info('responseHandler');
|
this.logger.info('responseHandler');
|
||||||
let resp = body.json as InventoryItemInfo;
|
let resp = body.json as InventoryItemInfo;
|
||||||
// TODO 维护通用物品数据(对应名称、描述、类型)缓存
|
// TODO 维护通用物品数据(对应名称、描述、类型)缓存
|
||||||
let map: { [k: string]: Partial<InventoryItemInfo> } = {
|
let map: { [k: string]: Partial<InventoryItemInfo> } = {
|
||||||
'Glass of Beer': {
|
'Glass of Beer': {
|
||||||
itemName: '一杯啤酒',
|
itemName: '一杯啤酒',
|
||||||
itemInfo: '[译]Only savages drink beer straight out of the bottle. This glass of beer is obtained fresh from the keg, and provides the same level of drunken joy as you\'d get from a regular bottle of suds. Provides a moderate nerve increase when consumed.',
|
itemInfo: '[译]Only savages drink beer straight out of the bottle. This glass of beer is obtained fresh from the keg, and provides the same level of drunken joy as you\'d get from a regular bottle of suds. Provides a moderate nerve increase when consumed.',
|
||||||
itemInfoContent: "\n" +
|
itemInfoContent: "<div class='m-bottom10'>" +
|
||||||
" <div class='m-bottom10'>\n" +
|
"<span class=\"bold\">一杯啤酒</span> 是酒类物品" +
|
||||||
" <span class=\"bold\">一杯啤酒</span> 是酒类物品\n" +
|
"</div>" +
|
||||||
" </div>\n" +
|
"Only savages drink beer straight out of the bottle. This glass of beer is obtained fresh from the keg, and provides the same level of drunken joy as you'd get from a regular bottle of suds. Provides a moderate nerve increase when consumed." +
|
||||||
" Only savages drink beer straight out of the bottle. This glass of beer is obtained fresh from the keg, and provides the same level of drunken joy as you'd get from a regular bottle of suds. Provides a moderate nerve increase when consumed.\n" +
|
"<div class=\"t-green bold item-effect m-top10\">效果: 犯罪 + 2,增幅CD + 1h。</div>",
|
||||||
" <div class=\"t-green bold item-effect m-top10\">效果: 犯罪 + 2,增幅CD + 1h。</div>",
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let idMap = { 816: 'Glass of Beer' };
|
let idMap = { 816: 'Glass of Beer' };
|
||||||
let itemInfo = CommonUtils.getInstance().getItemByIdOrName(resp.itemName, idMap, map);
|
let itemInfo = this.commonUtils.getItemByIdOrName(resp.itemName, idMap, map);
|
||||||
if (itemInfo) {
|
if (itemInfo) {
|
||||||
body.isModified = true;
|
body.isModified = true;
|
||||||
resp.itemInfo = itemInfo.itemInfo;
|
resp.itemInfo = itemInfo.itemInfo;
|
||||||
@ -349,7 +363,7 @@ export default class TranslateNew extends Provider implements ResponseInject {
|
|||||||
if (resp.html) {
|
if (resp.html) {
|
||||||
let tmp = document.createElement('div');
|
let tmp = document.createElement('div');
|
||||||
tmp.innerHTML = resp.html;
|
tmp.innerHTML = resp.html;
|
||||||
Log.info(tmp);
|
this.logger.info(tmp);
|
||||||
tmp.childNodes.forEach(li => {
|
tmp.childNodes.forEach(li => {
|
||||||
if (li.nodeType === 1) {
|
if (li.nodeType === 1) {
|
||||||
let elem = li as Element;
|
let elem = li as Element;
|
||||||
@ -360,8 +374,7 @@ export default class TranslateNew extends Provider implements ResponseInject {
|
|||||||
name.innerText = `${ name.innerText } ${ nameZh }`;
|
name.innerText = `${ name.innerText } ${ nameZh }`;
|
||||||
}
|
}
|
||||||
// 操作按钮
|
// 操作按钮
|
||||||
let actions = elem.querySelectorAll('.icon-h');
|
elem.querySelectorAll('.icon-h').forEach(action => {
|
||||||
actions.forEach(action => {
|
|
||||||
let attrTitle = action.getAttribute('title');
|
let attrTitle = action.getAttribute('title');
|
||||||
// TODO
|
// TODO
|
||||||
let zh = itemPageDict[attrTitle];
|
let zh = itemPageDict[attrTitle];
|
||||||
@ -380,7 +393,7 @@ export default class TranslateNew extends Provider implements ResponseInject {
|
|||||||
typeof opt?.requestBody === 'string' && opt?.requestBody.includes('step=getList')) {
|
typeof opt?.requestBody === 'string' && opt?.requestBody.includes('step=getList')) {
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.error('responseHandler', e.stack || e.message);
|
this.logger.error('responseHandler', e.stack || e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,61 +0,0 @@
|
|||||||
import CommonUtils from "../utils/CommonUtils";
|
|
||||||
import Log from "../Log";
|
|
||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import UserScriptEngine from "../../enum/UserScriptEngine";
|
|
||||||
import Popup from "../utils/Popup";
|
|
||||||
import STOCK_IMG_HTML from "../../../static/html/stock_img.html";
|
|
||||||
import * as FILTER from "../../../static/json/for_stock_item_filter.json";
|
|
||||||
import WindowActiveState from "./WindowActiveState";
|
|
||||||
|
|
||||||
export default class TravelItem extends WuhuBase {
|
|
||||||
className = 'TravelItem';
|
|
||||||
private readonly apiUrl: string = 'https://yata.yt/api/v1/travel/export/';
|
|
||||||
private foreignStockInfo: any = null;
|
|
||||||
|
|
||||||
public constructor() {
|
|
||||||
super();
|
|
||||||
window.setInterval(async () => {
|
|
||||||
if (!WindowActiveState.getInstance().get()) return;
|
|
||||||
Log.info('COFetch ', this.apiUrl);
|
|
||||||
this.foreignStockInfo = JSON.parse(await CommonUtils.COFetch(this.apiUrl));
|
|
||||||
Log.info({ info: 'TravelItem 跨域返回', 'returned': this.foreignStockInfo });
|
|
||||||
}, 30 * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 呈现内容
|
|
||||||
public async clickHandler(): Promise<void> {
|
|
||||||
if (CommonUtils.getScriptEngine() === UserScriptEngine.RAW) {
|
|
||||||
new Popup(STOCK_IMG_HTML.replace('{{}}', performance.now().toString()), '飞花库存');
|
|
||||||
} else {
|
|
||||||
const popup = new Popup("请稍后 " + CommonUtils.loading_gif_html(), '飞花库存');
|
|
||||||
let table = `<table><tr><th colspan="2">目的地 - 更新时间</th><th colspan="3">库存</th></tr>`;
|
|
||||||
const dest = FILTER.default;
|
|
||||||
const now = new Date();
|
|
||||||
const res = await this.get();
|
|
||||||
Log.info({ res })
|
|
||||||
if (!res || !res.stocks) return;
|
|
||||||
dest.forEach(el => {
|
|
||||||
const update = (now.getTime() - new Date(res.stocks[el.name]['update'] * 1000).getTime()) / 1000 | 0
|
|
||||||
table += `<tr><td>${ el.show }</td><td>${ update / 60 | 0 }分${ update % 60 | 0 }秒前</td>`;
|
|
||||||
let count = 0;
|
|
||||||
res.stocks[el.name]['stocks'].forEach(stock => {
|
|
||||||
if (el.stocks[stock.name]) {
|
|
||||||
table += `<td${ stock['quantity'] === 0 ? ' style="background-color:#f44336;color:white;border-color:#000;"' : '' }>${ el.stocks[stock.name] } (${ stock['quantity'] })</td>`;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
while (count < 3) {
|
|
||||||
count++;
|
|
||||||
table += '<td></td>';
|
|
||||||
}
|
|
||||||
table += '</tr>';
|
|
||||||
});
|
|
||||||
table += '</table>';
|
|
||||||
popup.getElement().innerHTML = table;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async get() {
|
|
||||||
return this.foreignStockInfo ||= JSON.parse(await CommonUtils.COFetch(this.apiUrl));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +1,14 @@
|
|||||||
import uuidv4 from "../../func/utils/uuidv4";
|
import uuidv4 from "../../func/utils/uuidv4";
|
||||||
import WuhuBase from "../WuhuBase";
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
|
||||||
export default class WindowActiveState extends WuhuBase {
|
@ClassName('WindowActiveState')
|
||||||
className = 'WindowActiveState';
|
@Injectable()
|
||||||
isFocus = false;
|
export default class WindowActiveState {
|
||||||
uuid = uuidv4();
|
private isFocus = false;
|
||||||
|
private uuid = uuidv4();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
|
||||||
if (self !== top) return null;
|
if (self !== top) return null;
|
||||||
localStorage.setItem('whuuid', this.uuid);
|
localStorage.setItem('whuuid', this.uuid);
|
||||||
document.addEventListener('visibilitychange',
|
document.addEventListener('visibilitychange',
|
||||||
@ -17,6 +18,7 @@ export default class WindowActiveState extends WuhuBase {
|
|||||||
addEventListener('blur', () => this.isFocus = false);
|
addEventListener('blur', () => this.isFocus = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 当前实例是否激活
|
||||||
get(): boolean {
|
get(): boolean {
|
||||||
// 当前窗口获得了焦点 优先级最高
|
// 当前窗口获得了焦点 优先级最高
|
||||||
if (this.isFocus) return true;
|
if (this.isFocus) return true;
|
||||||
|
|||||||
@ -1,18 +1,49 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import XUNZHAOMUZHUANG_HTML from "../../../static/html/xunzhaomuzhuang/index.html";
|
import XUNZHAOMUZHUANG_HTML from "../../../static/html/xunzhaomuzhuang/index.html";
|
||||||
import * as MUZHUANG_ID_LIST_JSON from "../../../static/json/muzhuang_id_list.json";
|
import * as MUZHUANG_ID_LIST_JSON from "../../../static/json/muzhuang_id_list.json";
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
import CommonUtils from "../utils/CommonUtils";
|
||||||
import XUNZHAOMUZHUANG_CSS from "../../../static/css/xunzhaomuzhuang.css";
|
import XUNZHAOMUZHUANG_CSS from "../../../static/css/xunzhaomuzhuang.module.css";
|
||||||
import TornStyleBlock from "../utils/TornStyleBlock";
|
import TornStyleBlock from "../utils/TornStyleBlock";
|
||||||
import MathUtils from "../utils/MathUtils";
|
import MathUtils from "../utils/MathUtils";
|
||||||
import FetchUtils from "../utils/FetchUtils";
|
import FetchUtils from "../utils/FetchUtils";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import IFeature from "../../man/IFeature";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 寻找木桩
|
* 寻找木桩
|
||||||
* /item.php?temp=4#xunzhaomuzhuang
|
* /item.php?temp=4#xunzhaomuzhuang
|
||||||
*/
|
*/
|
||||||
export default class XZMZ extends WuhuBase {
|
@ClassName('XZMZ')
|
||||||
className = 'XZMZ';
|
@Injectable()
|
||||||
|
export default class XZMZ implements IFeature {
|
||||||
|
description(): string {
|
||||||
|
return "寻找木桩";
|
||||||
|
}
|
||||||
|
|
||||||
|
iStart(): void | Promise<void> {
|
||||||
|
this.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
urlExcludes(): RegExp[] {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
urlIncludes(): RegExp[] {
|
||||||
|
return [/item.php\?temp=4/];
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
let hasInit: boolean = false
|
||||||
|
let handle = () => {
|
||||||
|
if (!hasInit && window.location.hash === '#xunzhaomuzhuang') {
|
||||||
|
this.init()
|
||||||
|
hasInit = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.addEventListener('hashchange', handle)
|
||||||
|
handle()
|
||||||
|
}
|
||||||
|
|
||||||
private mainRoleContainer: HTMLElement;
|
private mainRoleContainer: HTMLElement;
|
||||||
private IDList: number[];
|
private IDList: number[];
|
||||||
private btn: HTMLButtonElement;
|
private btn: HTMLButtonElement;
|
||||||
@ -21,12 +52,15 @@ export default class XZMZ extends WuhuBase {
|
|||||||
private tips: HTMLElement;
|
private tips: HTMLElement;
|
||||||
private counter: number;
|
private counter: number;
|
||||||
|
|
||||||
public constructor() {
|
public constructor(
|
||||||
super();
|
private readonly mathUtils: MathUtils,
|
||||||
|
private readonly commonUtils: CommonUtils,
|
||||||
|
private readonly fetchUtils: FetchUtils,
|
||||||
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
CommonUtils.addStyle(XUNZHAOMUZHUANG_CSS);
|
this.commonUtils.styleInject(XUNZHAOMUZHUANG_CSS);
|
||||||
document.body.classList.add('wh-hide-title');
|
document.body.classList.add('wh-hide-title');
|
||||||
document.title = document.title.replace('Items', '寻找木桩');
|
document.title = document.title.replace('Items', '寻找木桩');
|
||||||
this.mainRoleContainer = document.querySelector('div[role="main"]');
|
this.mainRoleContainer = document.querySelector('div[role="main"]');
|
||||||
@ -65,7 +99,7 @@ export default class XZMZ extends WuhuBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async SearchDeadman(id) {
|
private async SearchDeadman(id) {
|
||||||
FetchUtils.getInstance().getProfile(id).then((res) => {
|
this.fetchUtils.getProfile(id).then((res) => {
|
||||||
if (res.userStatus.status.type === 'ok') {
|
if (res.userStatus.status.type === 'ok') {
|
||||||
this.addRow({
|
this.addRow({
|
||||||
player_id: res.user.userID,
|
player_id: res.user.userID,
|
||||||
@ -74,7 +108,7 @@ export default class XZMZ extends WuhuBase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await CommonUtils.getInstance().sleep(MathUtils.getInstance().getRandomInt(100, 200));
|
await this.commonUtils.sleep(this.mathUtils.getRandomInt(100, 200));
|
||||||
}
|
}
|
||||||
|
|
||||||
private addRow(data) {
|
private addRow(data) {
|
||||||
|
|||||||
132
src/ts/class/config/defaultConfig.ts
Normal file
132
src/ts/class/config/defaultConfig.ts
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
const notifyKey = Symbol('ConfigNotifyKey');
|
||||||
|
|
||||||
|
class DefaultConfigType {
|
||||||
|
// 开启翻译
|
||||||
|
transEnable = false;
|
||||||
|
|
||||||
|
@Notified()
|
||||||
|
transNew = true;
|
||||||
|
// 快速犯罪
|
||||||
|
quickCrime = true;
|
||||||
|
// 任务助手
|
||||||
|
missionHint = true;
|
||||||
|
// 小镇攻略
|
||||||
|
xmasTownWT = true;
|
||||||
|
// 小镇提醒
|
||||||
|
xmasTownNotify = true;
|
||||||
|
// 起飞爆e
|
||||||
|
energyAlert = true;
|
||||||
|
// 飞行闹钟
|
||||||
|
trvAlarm = true;
|
||||||
|
// 啤酒提醒
|
||||||
|
_15Alarm = true;
|
||||||
|
|
||||||
|
@Notified()
|
||||||
|
_15_alarm_ignore: number[] = [];
|
||||||
|
// 啤酒提醒时间
|
||||||
|
_15AlarmTime = 50;
|
||||||
|
// 捡垃圾助手
|
||||||
|
cityFinder = false;
|
||||||
|
|
||||||
|
// 叠E保护
|
||||||
|
@Notified()
|
||||||
|
SEProtect = false;
|
||||||
|
// PT一键购买
|
||||||
|
ptQuickBuy = false;
|
||||||
|
// 光速拔刀 6-关闭
|
||||||
|
quickAttIndex = 2;
|
||||||
|
// 光速跑路 0-leave 1-mug 2-hos 3-关闭
|
||||||
|
quickFinishAtt = 3;
|
||||||
|
// 自动开打和结束
|
||||||
|
autoStartFinish = false;
|
||||||
|
// 攻击自刷新 0-无间隔 1-5s 6-关闭
|
||||||
|
attReload = 6;
|
||||||
|
/** @deprecated */
|
||||||
|
attRelocate = false;
|
||||||
|
// 价格监视
|
||||||
|
priceWatcher = { xan: -1, pt: -1 };
|
||||||
|
// 开发者模式
|
||||||
|
isDev = false;
|
||||||
|
// 4条转跳
|
||||||
|
barsRedirect = true;
|
||||||
|
// 浮动存钱框
|
||||||
|
floatDepo = true;
|
||||||
|
// 公司转跳存钱
|
||||||
|
companyRedirect = true;
|
||||||
|
// 收起公司冰蛙效率表
|
||||||
|
companyBWCollapse = true;
|
||||||
|
// 海外警告
|
||||||
|
abroadWarning = true;
|
||||||
|
|
||||||
|
// 落地转跳
|
||||||
|
@Notified()
|
||||||
|
landedRedirect = '';
|
||||||
|
// 任何位置一键存钱
|
||||||
|
companyDepositAnywhere = false;
|
||||||
|
// 火车提醒时间
|
||||||
|
CHTrainsDetect = 0;
|
||||||
|
// 火车提醒开关
|
||||||
|
CHTrainsDetectSwitch = true;
|
||||||
|
|
||||||
|
// 隐藏个人资料头像
|
||||||
|
@Notified()
|
||||||
|
HideProfileImg = false;
|
||||||
|
// 显示曾用名
|
||||||
|
ShowNameHistory = true;
|
||||||
|
// 盯梢模式强度 0-550 1-950 2-1450 ms
|
||||||
|
WatchTargetFreq = 1;
|
||||||
|
// 隐藏侧边栏
|
||||||
|
HideSidebar = false;
|
||||||
|
// 添加隐藏边栏按钮
|
||||||
|
HideSidebarBtn = true;
|
||||||
|
// 搜索页占位区
|
||||||
|
SearchPagePlaceholder = true;
|
||||||
|
|
||||||
|
// 解决一直转圈(加载中)的问题
|
||||||
|
@Notified()
|
||||||
|
SolveGoogleScriptPendingIssue = false;
|
||||||
|
// 图标坐标
|
||||||
|
IconPosition: Partial<{ x: number, y: number }> = {};
|
||||||
|
// 记住图标位置
|
||||||
|
SaveIconPosition = false;
|
||||||
|
// 现金变动提醒
|
||||||
|
CashChangeAlert = false;
|
||||||
|
// 收集数据以改进翻译质量
|
||||||
|
CollectPlayerData = true;
|
||||||
|
// 迷你资料卡显示上次行动时间
|
||||||
|
ShowMiniProfLastAct = true;
|
||||||
|
|
||||||
|
// 登陆邮箱
|
||||||
|
@Notified()
|
||||||
|
autoLoginEmail = '';
|
||||||
|
// 登陆密码
|
||||||
|
autoLoginPwd = '';
|
||||||
|
|
||||||
|
// 自定义css
|
||||||
|
@Notified()
|
||||||
|
CustomCss = '';
|
||||||
|
|
||||||
|
monitorOn = ['drugCDMonitor']
|
||||||
|
drugCDMonitorInterval = 60000
|
||||||
|
|
||||||
|
// mini profile显示bs估算
|
||||||
|
@Notified()
|
||||||
|
isBSEstMiniProfOn = false
|
||||||
|
// profile页面显示bs估算
|
||||||
|
@Notified()
|
||||||
|
isBSEstProfOn = true
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Config = DefaultConfigType;
|
||||||
|
|
||||||
|
let config = new DefaultConfigType();
|
||||||
|
|
||||||
|
export default config as Readonly<Config>;
|
||||||
|
|
||||||
|
function Notified(f: boolean = true) {
|
||||||
|
return Reflect.metadata(notifyKey, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isNotified(propertyKey: string): boolean {
|
||||||
|
return Reflect.getMetadata(notifyKey, config, propertyKey);
|
||||||
|
}
|
||||||
@ -1,37 +1,22 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import Popup from "../utils/Popup";
|
import Popup from "../utils/Popup";
|
||||||
import Alert from "../utils/Alert";
|
import Alert from "../utils/Alert";
|
||||||
import DialogMsgBox from "../utils/DialogMsgBox";
|
import DialogMsgBox from "../utils/DialogMsgBox";
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
import CommonUtils from "../utils/CommonUtils";
|
||||||
import { MenuItemConfig } from "../ZhongIcon";
|
import { MenuItemConfig } from "../ZhongIcon";
|
||||||
import IFrameCrimeHandler from "./IFrameCrimeHandler";
|
import ClassName from "../../container/ClassName";
|
||||||
import loadGS from "../../func/module/loadGS";
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
|
||||||
export default class AdditionalSettingsHandler extends WuhuBase {
|
@ClassName('AdditionalSettingsHandler')
|
||||||
className = 'AdditionalSettingsHandler';
|
@Injectable()
|
||||||
|
export default class AdditionalSettingsHandler {
|
||||||
|
|
||||||
public handle(): void {
|
constructor(
|
||||||
|
private readonly commonUtils: CommonUtils,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public show(): void {
|
||||||
let pop = new Popup('', '更多设定');
|
let pop = new Popup('', '更多设定');
|
||||||
// let insertHtml = '<p><button class="torn-btn">清空设置</button></p><p><button class="torn-btn">通知权限</button></p><p><button class="torn-btn">外部数据权限</button></p>';
|
|
||||||
// pop.getElement().insertAdjacentHTML('beforeend', insertHtml);
|
|
||||||
// let [btn1, btn2, btn3] = Array.from(pop.getElement().querySelectorAll('button'));
|
|
||||||
// btn1.addEventListener('click', () => {
|
|
||||||
// new DialogMsgBox('将清空所有芜湖助手相关设置并刷新页面,确定?', {
|
|
||||||
// callback: () => {
|
|
||||||
// localStorage.removeItem('wh_trv_alarm');
|
|
||||||
// localStorage.removeItem('wh_trans_settings');
|
|
||||||
// localStorage.removeItem('whuuid');
|
|
||||||
// localStorage.removeItem('wh-gs-storage');
|
|
||||||
// localStorage.removeItem('WHTEST');
|
|
||||||
// new Alert('已清空,刷新页面');
|
|
||||||
// window.location.reload();
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// btn2.addEventListener('click', () => {
|
|
||||||
// });
|
|
||||||
// btn3.addEventListener('click', () => {
|
|
||||||
// });
|
|
||||||
|
|
||||||
let menuList: MenuItemConfig[] = [
|
let menuList: MenuItemConfig[] = [
|
||||||
{
|
{
|
||||||
@ -57,21 +42,7 @@ export default class AdditionalSettingsHandler extends WuhuBase {
|
|||||||
domType: 'button', domId: '', domText: '第三方API通信权限', clickFunc() {
|
domType: 'button', domId: '', domText: '第三方API通信权限', clickFunc() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
domType: 'button', domId: '', domText: '小窗犯罪', clickFunc() {
|
|
||||||
IFrameCrimeHandler.getInstance().handle()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
domType: 'button',
|
|
||||||
domId: '',
|
|
||||||
domText: '飞贼小助手',
|
|
||||||
tip: '加载从PC端移植的伞佬的油猴版飞贼小助手',
|
|
||||||
clickFunc() {
|
|
||||||
loadGS(CommonUtils.getScriptEngine())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
menuList.forEach(i => pop.getElement().append(CommonUtils.getInstance().elemGenerator(i, pop.getElement())));
|
menuList.forEach(i => pop.element.append(this.commonUtils.elemGenerator(i, pop.element)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,49 +1,70 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
// import Popup from "../utils/Popup";
|
||||||
import Popup from "../utils/Popup";
|
// import CommonUtils from "../utils/CommonUtils";
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
// import MDUtils from "../utils/MDUtils";
|
||||||
import MDUtils from "../utils/MDUtils";
|
// import { MENU_ITEM_TYPE } from "../../interface/MenuItem";
|
||||||
import Log from "../Log";
|
// import Provider from "../provider/Provider";
|
||||||
|
// import ClassName from "../../container/ClassName";
|
||||||
export default class ChangeLogHandler extends WuhuBase {
|
// import { Injectable } from "../../container/Injectable";
|
||||||
className = 'ChangeLogHandler';
|
// import { Container } from "../../container/Container";
|
||||||
|
// import Logger from "../Logger";
|
||||||
public handle(): void {
|
//
|
||||||
let popup = new Popup(
|
// /**
|
||||||
'更新历史:<br/><a target="_blank" href="https://gitlab.com/JJins/wuhu-torn-helper/-/blob/dev/CHANGELOG.md">https://gitlab.com/JJins/wuhu-torn-helper/-/blob/dev/CHANGELOG.md</a><br/>',
|
// * @deprecated
|
||||||
'更新历史'
|
// */
|
||||||
).getElement();
|
// @ClassName('ChangeLogHandler')
|
||||||
popup.classList.add('wh-changeLog');
|
// @Injectable()
|
||||||
let progressBar = document.createElement('div');
|
// export class ChangeLogHandler extends Provider {
|
||||||
progressBar.style.height = '2px';
|
// constructor(
|
||||||
progressBar.style.width = '1%';
|
// private readonly mdUtils: MDUtils,
|
||||||
progressBar.style.backgroundColor = 'red';
|
// private readonly logger: Logger,
|
||||||
let progressText = document.createElement('p');
|
// ) {
|
||||||
progressText.innerText = '加载更新文件……';
|
// super();
|
||||||
progressText.style.textAlign = 'center';
|
// }
|
||||||
let style = document.createElement('style');
|
//
|
||||||
style.innerHTML = `.wh-changeLog h2,.wh-changeLog h3,.wh-changeLog h4 {margin:8px 0;}.wh-changeLog li{list-style: inside;}`;
|
// public show(): void {
|
||||||
|
// let popup = new Popup(
|
||||||
popup.append(progressBar, progressText, style);
|
// '更新历史:<br/><a target="_blank" href="https://gitlab.com/JJins/wuhu-torn-helper/-/blob/dev/CHANGELOG.md">https://gitlab.com/JJins/wuhu-torn-helper/-/blob/dev/CHANGELOG.md</a><br/>',
|
||||||
|
// '更新历史'
|
||||||
CommonUtils
|
// ).element;
|
||||||
.COFetch('https://gitlab.com/JJins/wuhu-torn-helper/-/raw/dev/CHANGELOG.md?' + performance.now())
|
// popup.classList.add('wh-changeLog');
|
||||||
.then(update => {
|
// let progressBar = document.createElement('div');
|
||||||
progressBar.style.width = '60%';
|
// progressBar.style.height = '2px';
|
||||||
progressText.innerText = '解析中……';
|
// progressBar.style.width = '1%';
|
||||||
let md = MDUtils.getInstance().parse(update);
|
// progressBar.style.backgroundColor = 'red';
|
||||||
popup.append(md);
|
// let progressText = document.createElement('p');
|
||||||
progressBar.style.width = '100%';
|
// progressText.innerText = '加载更新文件……';
|
||||||
progressText.innerText = '加载完成';
|
// progressText.style.textAlign = 'center';
|
||||||
|
// let style = document.createElement('style');
|
||||||
window.setTimeout(() => {
|
// style.innerHTML = `.wh-changeLog h2,.wh-changeLog h3,.wh-changeLog h4 {margin:8px 0;}.wh-changeLog li{list-style: inside;}`;
|
||||||
progressBar.remove();
|
//
|
||||||
progressText.remove()
|
// popup.append(progressBar, progressText, style);
|
||||||
}, 3000);
|
//
|
||||||
})
|
// CommonUtils
|
||||||
.catch(e => {
|
// .COFetch('https://gitlab.com/JJins/wuhu-torn-helper/-/raw/dev/CHANGELOG.md?' + performance.now())
|
||||||
Log.error(e);
|
// .then(update => {
|
||||||
progressBar.remove();
|
// progressBar.style.width = '60%';
|
||||||
progressText.innerText = '无法加载';
|
// progressText.innerText = '解析中……';
|
||||||
});
|
// let md = this.mdUtils.parse(update);
|
||||||
}
|
// popup.append(md);
|
||||||
}
|
// progressBar.style.width = '100%';
|
||||||
|
// progressText.innerText = '加载完成';
|
||||||
|
//
|
||||||
|
// window.setTimeout(() => {
|
||||||
|
// progressBar.remove();
|
||||||
|
// progressText.remove()
|
||||||
|
// }, 3000);
|
||||||
|
// })
|
||||||
|
// .catch(e => {
|
||||||
|
// this.logger.error(e);
|
||||||
|
// progressBar.remove();
|
||||||
|
// progressText.innerText = '无法加载';
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// export default {
|
||||||
|
// domType: MENU_ITEM_TYPE.BUTTON,
|
||||||
|
// domText: '🐞 更新历史',
|
||||||
|
// clickFunc: () => Container.factory(ChangeLogHandler).show()
|
||||||
|
// };
|
||||||
|
|||||||
@ -1,21 +1,24 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import Popup from "../utils/Popup";
|
import Popup from "../utils/Popup";
|
||||||
import WuhuConfig from "../WuhuConfig";
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import LocalConfigWrapper from "../LocalConfigWrapper";
|
||||||
|
|
||||||
export default class CustomCssHandler extends WuhuBase {
|
@ClassName('CustomCssHandler')
|
||||||
className = 'CustomCssHandler';
|
@Injectable()
|
||||||
|
export default class CustomCssHandler {
|
||||||
|
|
||||||
constructor() {
|
constructor(
|
||||||
super();
|
private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public handle(): void {
|
public handle(): void {
|
||||||
let pop = new Popup('<div><textarea></textarea><button class="torn-btn">保存</button><style>#wh-popup textarea{display: block;}</style></div>', '自定义CSS');
|
let pop = new Popup('<div><textarea></textarea><button class="torn-btn">保存</button><style>#wh-popup textarea{display: block;}</style></div>', '自定义CSS');
|
||||||
let textarea = pop.getElement().querySelector('textarea');
|
let textarea = pop.element.querySelector('textarea');
|
||||||
let button = pop.getElement().querySelector('button');
|
let button = pop.element.querySelector('button');
|
||||||
textarea.value = WuhuConfig.get('CustomCss') || '';
|
textarea.value = this.localConfigWrapper.config.CustomCss || '';
|
||||||
button.addEventListener('click', () => {
|
button.addEventListener('click', () => {
|
||||||
WuhuConfig.set('CustomCss', textarea.value || '', true);
|
this.localConfigWrapper.config.CustomCss = textarea.value || '';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,95 +1,97 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
// import CommonUtils from "../utils/CommonUtils";
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
// import Popup from "../utils/Popup";
|
||||||
import Popup from "../utils/Popup";
|
// import QUICK_CRIMES_HTML from "../../../static/html/quick_crimes.html";
|
||||||
import QUICK_CRIMES_HTML from "../../../static/html/quick_crimes.html";
|
// import ClassName from "../../container/ClassName";
|
||||||
|
// import { Injectable } from "../../container/Injectable";
|
||||||
export default class IFrameCrimeHandler extends WuhuBase {
|
//
|
||||||
className = 'IFrameCrimeHandler';
|
// @ClassName('IFrameCrimeHandler')
|
||||||
|
// @Injectable()
|
||||||
public handle(): void {
|
// export default class IFrameCrimeHandler {
|
||||||
// 弹出小窗口
|
//
|
||||||
const ifHTML = `<iframe src="/crimes.php?step=main" style="width:100%;max-width: 450px;margin: 0 auto;display: none;height: 340px;"></iframe>`;
|
// public handle(): void {
|
||||||
const popup_insert = `<p>加载中请稍后${ CommonUtils.loading_gif_html() }</p><div id="wh-quick-crime-if-container"></div>`;
|
// // 弹出小窗口
|
||||||
const $popup = new Popup(popup_insert, '小窗快速犯罪').getElement();
|
// const ifHTML = `<iframe src="/crimes.php?step=main" style="width:100%;max-width: 450px;margin: 0 auto;display: none;height: 340px;"></iframe>`;
|
||||||
// 运行状态node
|
// const popup_insert = `<p>加载中请稍后${ CommonUtils.loading_gif_html() }</p><div id="wh-quick-crime-if-container"></div>`;
|
||||||
let loading_node = $popup.querySelector('p:first-of-type');
|
// const $popup = new Popup(popup_insert, '小窗快速犯罪').getElement();
|
||||||
// if容器
|
// // 运行状态node
|
||||||
const if_cont = $popup.querySelector('#wh-quick-crime-if-container');
|
// let loading_node = $popup.querySelector('p:first-of-type');
|
||||||
if_cont.innerHTML = ifHTML;
|
// // if容器
|
||||||
|
// const if_cont = $popup.querySelector('#wh-quick-crime-if-container');
|
||||||
// if内未加载脚本时插入的快捷crime node
|
// if_cont.innerHTML = ifHTML;
|
||||||
const mobile_prepend_node = document.createElement('div');
|
//
|
||||||
mobile_prepend_node.classList.add('wh-translate');
|
// // if内未加载脚本时插入的快捷crime node
|
||||||
mobile_prepend_node.innerHTML = QUICK_CRIMES_HTML;
|
// const mobile_prepend_node = document.createElement('div');
|
||||||
|
// mobile_prepend_node.classList.add('wh-translate');
|
||||||
// if对象加载后运行
|
// mobile_prepend_node.innerHTML = QUICK_CRIMES_HTML;
|
||||||
let cIframe = $popup.querySelector('iframe');
|
//
|
||||||
|
// // if对象加载后运行
|
||||||
// 加载状态
|
// let cIframe = $popup.querySelector('iframe');
|
||||||
const if_onload_func = () => {
|
//
|
||||||
// if内部文档对象
|
// // 加载状态
|
||||||
const ifDocu = cIframe.contentWindow.document;
|
// const if_onload_func = () => {
|
||||||
// 内部插件运行flag
|
// // if内部文档对象
|
||||||
const ifWH = cIframe.contentWindow.WHTRANS;
|
// const ifDocu = cIframe.contentWindow.document;
|
||||||
// 文档加载完成后移除
|
// // 内部插件运行flag
|
||||||
if (!!loading_node) loading_node.remove();
|
// const ifWH = cIframe.contentWindow.WHTRANS;
|
||||||
// 文档加载完成后才显示if
|
// // 文档加载完成后移除
|
||||||
cIframe.style.display = 'block';
|
// if (!!loading_node) loading_node.remove();
|
||||||
// 验证码flag
|
// // 文档加载完成后才显示if
|
||||||
const isValidate = ifDocu.querySelector('h4#skip-to-content').innerText.toLowerCase().includes('validate');
|
// cIframe.style.display = 'block';
|
||||||
// 如果iframe内部未运行脚本
|
// // 验证码flag
|
||||||
if (ifWH === undefined) {
|
// const isValidate = ifDocu.querySelector('h4#skip-to-content').innerText.toLowerCase().includes('validate');
|
||||||
// 隐藏顶部
|
// // 如果iframe内部未运行脚本
|
||||||
CommonUtils.elementReady('#header-root', ifDocu).then(e => e.style.display = 'none');
|
// if (ifWH === undefined) {
|
||||||
// 隐藏4条
|
// // 隐藏顶部
|
||||||
CommonUtils.elementReady('#sidebarroot', ifDocu).then(e => e.style.display = 'none');
|
// CommonUtils.elementReady('#header-root', ifDocu).then(e => e.style.display = 'none');
|
||||||
// 隐藏聊天
|
// // 隐藏4条
|
||||||
CommonUtils.elementReady('#chatRoot', ifDocu).then(e => e.style.display = 'none');
|
// CommonUtils.elementReady('#sidebarroot', ifDocu).then(e => e.style.display = 'none');
|
||||||
// 非验证码页面隐藏滚动条
|
// // 隐藏聊天
|
||||||
if (!isValidate) ifDocu.body.style.overflow = 'hidden';
|
// CommonUtils.elementReady('#chatRoot', ifDocu).then(e => e.style.display = 'none');
|
||||||
// 调整容器位置
|
// // 非验证码页面隐藏滚动条
|
||||||
CommonUtils.elementReady('.content-wrapper', ifDocu).then(elem => {
|
// if (!isValidate) ifDocu.body.style.overflow = 'hidden';
|
||||||
// 加入
|
// // 调整容器位置
|
||||||
elem.prepend(mobile_prepend_node);
|
// CommonUtils.elementReady('.content-wrapper', ifDocu).then(elem => {
|
||||||
elem.style.margin = '0px';
|
// // 加入
|
||||||
elem.style.position = 'absolute';
|
// elem.prepend(mobile_prepend_node);
|
||||||
elem.style.top = '-35px';
|
// elem.style.margin = '0px';
|
||||||
new MutationObserver((m, o) => {
|
// elem.style.position = 'absolute';
|
||||||
o.disconnect();
|
// elem.style.top = '-35px';
|
||||||
if (!elem.querySelector('.wh-translate')) elem.prepend(mobile_prepend_node);
|
// new MutationObserver((m, o) => {
|
||||||
o.observe(elem, { childList: true, subtree: true });
|
// o.disconnect();
|
||||||
})
|
// if (!elem.querySelector('.wh-translate')) elem.prepend(mobile_prepend_node);
|
||||||
.observe(elem, { childList: true, subtree: true });
|
// o.observe(elem, { childList: true, subtree: true });
|
||||||
});
|
// })
|
||||||
// 隐藏返回顶部按钮
|
// .observe(elem, { childList: true, subtree: true });
|
||||||
CommonUtils.elementReady('#go-to-top-btn button', ifDocu).then(e => e.style.display = 'none');
|
// });
|
||||||
}
|
// // 隐藏返回顶部按钮
|
||||||
};
|
// CommonUtils.elementReady('#go-to-top-btn button', ifDocu).then(e => e.style.display = 'none');
|
||||||
cIframe.onload = if_onload_func;
|
// }
|
||||||
|
// };
|
||||||
// 超时判断
|
// cIframe.onload = if_onload_func;
|
||||||
let time_counter = 0;
|
//
|
||||||
let time_out_id = window.setInterval(() => {
|
// // 超时判断
|
||||||
loading_node = $popup.querySelector('p:first-of-type');
|
// let time_counter = 0;
|
||||||
if (!loading_node) {
|
// let time_out_id = window.setInterval(() => {
|
||||||
clearInterval(time_out_id);
|
// loading_node = $popup.querySelector('p:first-of-type');
|
||||||
time_out_id = undefined;
|
// if (!loading_node) {
|
||||||
return;
|
// clearInterval(time_out_id);
|
||||||
}
|
// time_out_id = undefined;
|
||||||
time_counter++;
|
// return;
|
||||||
if (time_counter > 0 && !loading_node.querySelector('button')) {
|
// }
|
||||||
const reload_btn = document.createElement('button');
|
// time_counter++;
|
||||||
reload_btn.innerHTML = '重新加载';
|
// if (time_counter > 0 && !loading_node.querySelector('button')) {
|
||||||
reload_btn.onclick = () => {
|
// const reload_btn = document.createElement('button');
|
||||||
reload_btn.remove();
|
// reload_btn.innerHTML = '重新加载';
|
||||||
time_counter = 0;
|
// reload_btn.onclick = () => {
|
||||||
if_cont.innerHTML = null;
|
// reload_btn.remove();
|
||||||
if_cont.innerHTML = ifHTML;
|
// time_counter = 0;
|
||||||
cIframe = $popup.querySelector('iframe');
|
// if_cont.innerHTML = null;
|
||||||
cIframe.onload = if_onload_func;
|
// if_cont.innerHTML = ifHTML;
|
||||||
};
|
// cIframe = $popup.querySelector('iframe');
|
||||||
loading_node.append(reload_btn);
|
// cIframe.onload = if_onload_func;
|
||||||
}
|
// };
|
||||||
}, 1000);
|
// loading_node.append(reload_btn);
|
||||||
}
|
// }
|
||||||
}
|
// }, 1000);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
@ -1,14 +1,18 @@
|
|||||||
import MenuHandler from "../../interface/MenuHandler";
|
|
||||||
import Popup from "../utils/Popup";
|
import Popup from "../utils/Popup";
|
||||||
import { createApp } from "vue";
|
import { createApp } from "vue";
|
||||||
import ItemPrice from "../../../vue/ItemPrice.vue";
|
import ItemPrice from "../../../vue/ItemPrice.vue";
|
||||||
|
import { MENU_ITEM_TYPE } from "../../interface/MenuItem";
|
||||||
|
|
||||||
// 物品查价
|
// 物品查价
|
||||||
export default <MenuHandler>{
|
export default {
|
||||||
show(): void {
|
domType: MENU_ITEM_TYPE.BUTTON,
|
||||||
createApp(ItemPrice).mount(
|
domId: '',
|
||||||
new Popup('', '物品查价', () => createApp(ItemPrice).unmount())
|
domText: '🍺 物品查价',
|
||||||
.getElement()
|
clickFunc: () => {
|
||||||
|
let app = createApp(ItemPrice);
|
||||||
|
app.mount(
|
||||||
|
new Popup('', '物品查价', () => app.unmount())
|
||||||
|
.element
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,26 +1,35 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import WuhuConfig from "../WuhuConfig";
|
|
||||||
import PRICE_WATCHER_HTML from "../../../static/html/price_watcher.html";
|
import PRICE_WATCHER_HTML from "../../../static/html/price_watcher.html";
|
||||||
import Popup from "../utils/Popup";
|
import Popup from "../utils/Popup";
|
||||||
import Global from "../Global";
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import LocalConfigWrapper from "../LocalConfigWrapper";
|
||||||
|
import TornPDAUtils from "../utils/TornPDAUtils";
|
||||||
|
|
||||||
export default class ItemPriceWatcherHandler extends WuhuBase {
|
@Injectable()
|
||||||
className = 'ItemPriceWatcherHandler';
|
@ClassName('ItemPriceWatcherHandler')
|
||||||
|
export default class ItemPriceWatcherHandler {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
|
private readonly tornPDAUtils: TornPDAUtils,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
public handle(): void {
|
public handle(): void {
|
||||||
const watcher_conf = WuhuConfig.get('priceWatcher');
|
const watcher_conf = this.localConfigWrapper.config.priceWatcher;
|
||||||
const pre_str = JSON.stringify(watcher_conf);
|
const pre_str = JSON.stringify(watcher_conf);
|
||||||
const html = PRICE_WATCHER_HTML
|
const html = PRICE_WATCHER_HTML
|
||||||
.replace('{{}}', localStorage.getItem('APIKey') || '不可用')
|
.replace('{{}}', localStorage.getItem('APIKey') || '不可用')
|
||||||
.replace('{{}}', Global.getInstance().isPDA ? Global.getInstance().PDA_APIKey : '不可用')
|
.replace('{{}}', this.tornPDAUtils.isPDA() ? this.tornPDAUtils.APIKey : '不可用')
|
||||||
.replace('{{}}', watcher_conf['pt'] || -1)
|
.replace('{{}}', (watcher_conf['pt'] || -1).toString())
|
||||||
.replace('{{}}', watcher_conf['xan'] || -1);
|
.replace('{{}}', (watcher_conf['xan'] || -1).toString());
|
||||||
const popup = new Popup(html, '价格监视设置');
|
const popup = new Popup(html, '价格监视设置');
|
||||||
popup.getElement().querySelector('button').onclick = () => {
|
popup.getElement().querySelector('button').onclick = () => {
|
||||||
const [pt_node, xan_node] = Array.from(<NodeListOf<HTMLInputElement>>popup.getElement().querySelectorAll('input[type="number"]'));
|
const [pt_node, xan_node] = Array.from(<NodeListOf<HTMLInputElement>>popup.getElement().querySelectorAll('input[type="number"]'));
|
||||||
watcher_conf.pt = (pt_node.value as any) | 0;
|
watcher_conf.pt = (pt_node.value as any) | 0;
|
||||||
watcher_conf.xan = (xan_node.value as any) | 0;
|
watcher_conf.xan = (xan_node.value as any) | 0;
|
||||||
if (JSON.stringify(watcher_conf) !== pre_str) WuhuConfig.set('priceWatcher', watcher_conf);
|
if (JSON.stringify(watcher_conf) !== pre_str)
|
||||||
|
this.localConfigWrapper.config.priceWatcher = watcher_conf;
|
||||||
popup.close();
|
popup.close();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,21 +0,0 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import Popup from "../utils/Popup";
|
|
||||||
import Elem from "../provider/Elem";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 快速查价
|
|
||||||
*/
|
|
||||||
export default class ItemValueQueryHandler extends WuhuBase {
|
|
||||||
className = "ItemValueQueryHandler";
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public show() {
|
|
||||||
let pop = new Popup('', '快速查价');
|
|
||||||
pop.getElement().append(
|
|
||||||
new Elem('div').html('<p>test</p>').class('wh-test').el()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,17 +1,24 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import NNB_INFO_HTML from "../../../static/html/nnb_info.html";
|
import NNB_INFO_HTML from "../../../static/html/nnb_info.html";
|
||||||
import Popup from "../utils/Popup";
|
import Popup from "../utils/Popup";
|
||||||
import Global from "../Global";
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import TornPDAUtils from "../utils/TornPDAUtils";
|
||||||
|
|
||||||
export default class NNB extends WuhuBase {
|
@ClassName('NNB')
|
||||||
|
@Injectable()
|
||||||
|
export default class NNB {
|
||||||
className = 'NNB';
|
className = 'NNB';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly tornPDAUtils: TornPDAUtils,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
public handle(): void {
|
public handle(): void {
|
||||||
let { isPDA, PDA_APIKey } = Global.getInstance();
|
|
||||||
const insert = NNB_INFO_HTML
|
const insert = NNB_INFO_HTML
|
||||||
.replace('{{}}', localStorage.getItem('APIKey') || '不可用')
|
.replace('{{}}', localStorage.getItem('APIKey') || '不可用')
|
||||||
.replace('{{}}', isPDA ? PDA_APIKey : '不可用');
|
.replace('{{}}', this.tornPDAUtils.isPDA() ? this.tornPDAUtils.APIKey : '不可用');
|
||||||
const popup = new Popup(insert, '查看NNB').getElement();
|
const popup = new Popup(insert, '查看NNB').element;
|
||||||
const select = popup.querySelector('input');
|
const select = popup.querySelector('input');
|
||||||
const node = popup.querySelector('p');
|
const node = popup.querySelector('p');
|
||||||
popup.querySelector('button').addEventListener('click', ev => {
|
popup.querySelector('button').addEventListener('click', ev => {
|
||||||
@ -20,7 +27,7 @@ export default class NNB extends WuhuBase {
|
|||||||
node.innerHTML = '加载中';
|
node.innerHTML = '加载中';
|
||||||
// API 计算
|
// API 计算
|
||||||
if (select.checked) {
|
if (select.checked) {
|
||||||
const api_key = isPDA ? PDA_APIKey : window.localStorage.getItem('APIKey');
|
const api_key = this.tornPDAUtils.isPDA() ? this.tornPDAUtils.APIKey : window.localStorage.getItem('APIKey');
|
||||||
window.fetch(`https://api.torn.com/user/?selections=bars,perks&key=${ api_key }`)
|
window.fetch(`https://api.torn.com/user/?selections=bars,perks&key=${ api_key }`)
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
|
|||||||
@ -1,16 +1,33 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
import CommonUtils from "../utils/CommonUtils";
|
||||||
import QUICK_FLY_CSS from "../../../static/css/quick_fly.css";
|
import QUICK_FLY_CSS from "../../../static/css/quick_fly.module.css";
|
||||||
import QUICK_FLY_HTML from "../../../static/html/quick_fly.html";
|
import QUICK_FLY_HTML from "../../../static/html/quick_fly.html";
|
||||||
import Alert from "../utils/Alert";
|
import Alert from "../utils/Alert";
|
||||||
import TravelItem from "../action/TravelItem";
|
import TravelItem from "../../feature/TravelItem";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
import MsgWrapper from "../utils/MsgWrapper";
|
||||||
|
import { InjectionKey } from "vue";
|
||||||
|
import NetHighLvlWrapper from "../utils/NetHighLvlWrapper";
|
||||||
|
|
||||||
export default class QuickFlyBtnHandler extends WuhuBase {
|
@ClassName('QuickFlyBtnHandler')
|
||||||
|
@Injectable()
|
||||||
|
export default class QuickFlyBtnHandler {
|
||||||
className = 'QuickFlyBtnHandler';
|
className = 'QuickFlyBtnHandler';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly logger: Logger,
|
||||||
|
private readonly travelItem: TravelItem,
|
||||||
|
private readonly commonUtils: CommonUtils,
|
||||||
|
// private readonly infoUtils: InfoUtils,
|
||||||
|
private readonly msgWrapper: MsgWrapper,
|
||||||
|
private readonly netHighLvlWrapper: NetHighLvlWrapper,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
public static doQuickFly(): void {
|
public static doQuickFly(): void {
|
||||||
// [id: dest, _type: (1...4), ts: timestamp]
|
// [id: dest, _type: (1...4), ts: timestamp]
|
||||||
const [_id, _type, ts] = sessionStorage['wh-quick-fly'].trim().split(' ');
|
const [_id, _type, ts] = window.sessionStorage['wh-quick-fly'].trim().split(' ');
|
||||||
if (new Date().getTime() - ts > 20000) {
|
if (new Date().getTime() - ts > 20000) {
|
||||||
new Alert('超时,一键起飞计划已取消');
|
new Alert('超时,一键起飞计划已取消');
|
||||||
return;
|
return;
|
||||||
@ -44,7 +61,7 @@ export default class QuickFlyBtnHandler extends WuhuBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 起飞目的地id
|
// 起飞目的地id
|
||||||
private static getDestId(dest): number {
|
private static getDestId(dest: number): number {
|
||||||
// 墨、开、加、夏、英、阿、瑞s、立本、祖、迪、南
|
// 墨、开、加、夏、英、阿、瑞s、立本、祖、迪、南
|
||||||
return [2, 12, 9, 3, 10, 7, 8, 5, 6, 11, 4][dest];
|
return [2, 12, 9, 3, 10, 7, 8, 5, 6, 11, 4][dest];
|
||||||
}
|
}
|
||||||
@ -53,7 +70,7 @@ export default class QuickFlyBtnHandler extends WuhuBase {
|
|||||||
if (window.hasWHQuickFlyOpt) return;
|
if (window.hasWHQuickFlyOpt) return;
|
||||||
window.hasWHQuickFlyOpt = true;
|
window.hasWHQuickFlyOpt = true;
|
||||||
// TODO
|
// TODO
|
||||||
CommonUtils.addStyle(QUICK_FLY_CSS);
|
this.commonUtils.styleInject(QUICK_FLY_CSS);
|
||||||
const node = document.createElement('div');
|
const node = document.createElement('div');
|
||||||
node.id = 'wh-quick-fly-opt';
|
node.id = 'wh-quick-fly-opt';
|
||||||
node.innerHTML = QUICK_FLY_HTML;
|
node.innerHTML = QUICK_FLY_HTML;
|
||||||
@ -69,8 +86,7 @@ export default class QuickFlyBtnHandler extends WuhuBase {
|
|||||||
});
|
});
|
||||||
node.querySelector('a').addEventListener('click', (e) => {
|
node.querySelector('a').addEventListener('click', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// forStock();
|
this.travelItem.clickHandler().then();
|
||||||
TravelItem.getInstance().clickHandler();
|
|
||||||
});
|
});
|
||||||
node.querySelector('input').addEventListener('click', (e) => {
|
node.querySelector('input').addEventListener('click', (e) => {
|
||||||
node.classList.toggle('wh-quick-fly-opt-hide');
|
node.classList.toggle('wh-quick-fly-opt-hide');
|
||||||
@ -104,4 +120,37 @@ export default class QuickFlyBtnHandler extends WuhuBase {
|
|||||||
showTime();
|
showTime();
|
||||||
yaoCD.innerHTML = `药CD剩余:${ CommonUtils.getYaoCD() }`;
|
yaoCD.innerHTML = `药CD剩余:${ CommonUtils.getYaoCD() }`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async directFly(destIndex: number, typeIndex: number) {
|
||||||
|
// 获取key
|
||||||
|
// if(false){
|
||||||
|
// let key;
|
||||||
|
// try {
|
||||||
|
// const resp = await (await fetch('/travelagency.php')).text();
|
||||||
|
// key = resp.match(/data-key="([0-9]+)"/)[1];
|
||||||
|
// } catch (e) {
|
||||||
|
// this.msgWrapper.create('起飞参数获取失败', {}, 'error');
|
||||||
|
// this.logger.error(e.stack);
|
||||||
|
// throw new Error('起飞参数获取失败');
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
let msg: string;
|
||||||
|
try {
|
||||||
|
msg = await this.netHighLvlWrapper.doTravelFly(QuickFlyBtnHandler.getDestId(destIndex), null, ['standard', 'airstrip', 'private', 'business'][typeIndex])
|
||||||
|
const response = JSON.parse(msg);
|
||||||
|
if (!response.success) {
|
||||||
|
this.msgWrapper.create('起飞失败 ' + response.error, {}, 'error');
|
||||||
|
this.logger.error('起飞失败 ' + response.error, response.err);
|
||||||
|
throw new Error('起飞失败 ' + response.error);
|
||||||
|
}
|
||||||
|
console.log(msg);
|
||||||
|
} catch (e) {
|
||||||
|
this.msgWrapper.create('起飞时出现错误 ' + e.message, {}, 'error');
|
||||||
|
this.logger.error(e.stack);
|
||||||
|
throw new Error('起飞时出现错误 ' + e.message);
|
||||||
|
}
|
||||||
|
this.msgWrapper.create('已起飞', {}, 'success');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const QuickFlyBtnHandlerKey = Symbol('QuickFlyBtnHandlerKey') as InjectionKey<QuickFlyBtnHandler>
|
||||||
|
|||||||
@ -1,16 +1,19 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
import CommonUtils from "../utils/CommonUtils";
|
||||||
import QUICK_LINK_CSS from "../../../static/css/quick_link.css";
|
import QUICK_LINK_CSS from "../../../static/css/quick_link.module.css";
|
||||||
import Popup from "../utils/Popup";
|
import Popup from "../utils/Popup";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
|
||||||
export default class QuickLinksHandler extends WuhuBase {
|
@ClassName('QuickLinksHandler')
|
||||||
className = 'QuickLinksHandler';
|
@Injectable()
|
||||||
|
export default class QuickLinksHandler {
|
||||||
|
|
||||||
private styleAdded: boolean = false;
|
private styleAdded: boolean = false;
|
||||||
private list = [];
|
private list = [];
|
||||||
|
|
||||||
constructor() {
|
constructor(
|
||||||
super();
|
private readonly commonUtils: CommonUtils,
|
||||||
|
) {
|
||||||
let list = this.list;
|
let list = this.list;
|
||||||
// 生存手册
|
// 生存手册
|
||||||
list.push({
|
list.push({
|
||||||
@ -72,7 +75,7 @@ export default class QuickLinksHandler extends WuhuBase {
|
|||||||
|
|
||||||
public handle(): void {
|
public handle(): void {
|
||||||
if (!this.styleAdded) {
|
if (!this.styleAdded) {
|
||||||
CommonUtils.addStyle(QUICK_LINK_CSS);
|
this.commonUtils.styleInject(QUICK_LINK_CSS);
|
||||||
this.styleAdded = true;
|
this.styleAdded = true;
|
||||||
}
|
}
|
||||||
const list = this.list;
|
const list = this.list;
|
||||||
@ -82,8 +85,8 @@ export default class QuickLinksHandler extends WuhuBase {
|
|||||||
});
|
});
|
||||||
insert += '</p>'
|
insert += '</p>'
|
||||||
let popup = new Popup(insert, '常用链接');
|
let popup = new Popup(insert, '常用链接');
|
||||||
popup.getElement().classList.add('wh-link-collection-cont');
|
popup.element.classList.add('wh-link-collection-cont');
|
||||||
popup.getElement().addEventListener('click', ev => {
|
popup.element.addEventListener('click', ev => {
|
||||||
let target = ev.target as HTMLElement;
|
let target = ev.target as HTMLElement;
|
||||||
if (target.tagName.toLowerCase() === 'a' || target.tagName.toLowerCase() === 'span') {
|
if (target.tagName.toLowerCase() === 'a' || target.tagName.toLowerCase() === 'span') {
|
||||||
popup.close();
|
popup.close();
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import { MenuItemConfig } from "../ZhongIcon";
|
import { MenuItemConfig } from "../ZhongIcon";
|
||||||
import Log from "../Log";
|
|
||||||
import Timer from "../utils/Timer";
|
import Timer from "../utils/Timer";
|
||||||
import BuyBeerHelper from "../action/BuyBeerHelper";
|
import BuyBeerHelper from "../../feature/BuyBeerHelper";
|
||||||
import UpdateTranslateDict from "./UpdateTranslateDict";
|
import UpdateTranslateDict from "./UpdateTranslateDict";
|
||||||
import landedRedirect from "../../func/module/landedRedirect";
|
import landedRedirect from "../../func/module/landedRedirect";
|
||||||
import Alert from "../utils/Alert";
|
import Alert from "../utils/Alert";
|
||||||
@ -11,42 +9,58 @@ import AdditionalSettingsHandler from "./AdditionalSettingsHandler";
|
|||||||
import Popup from "../utils/Popup";
|
import Popup from "../utils/Popup";
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
import CommonUtils from "../utils/CommonUtils";
|
||||||
import CustomCssHandler from "./CustomCssHandler";
|
import CustomCssHandler from "./CustomCssHandler";
|
||||||
|
import Provider from "../provider/Provider";
|
||||||
|
import { MENU_ITEM_TYPE } from "../../interface/MenuItem";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import { Container } from "../../container/Container";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
|
||||||
export default class SettingsHandler extends WuhuBase {
|
@ClassName('SettingsHandler')
|
||||||
|
@Injectable()
|
||||||
|
class SettingsHandler extends Provider {
|
||||||
className = 'SettingsHandler';
|
className = 'SettingsHandler';
|
||||||
|
|
||||||
private list: MenuItemConfig[] = [];
|
private list: MenuItemConfig[] = [];
|
||||||
|
|
||||||
constructor() {
|
constructor(
|
||||||
|
private readonly buyBeerHelper: BuyBeerHelper,
|
||||||
|
private readonly commonUtils: CommonUtils,
|
||||||
|
private readonly updateTranslateDict: UpdateTranslateDict,
|
||||||
|
private readonly customCssHandler: CustomCssHandler,
|
||||||
|
private readonly viewLogsHandler: ViewLogsHandler,
|
||||||
|
private readonly additionalSettingsHandler: AdditionalSettingsHandler,
|
||||||
|
private readonly logger: Logger,
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
this.constructWuhuSettingList();
|
this.constructWuhuSettingList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public handler(): void {
|
public show(): void {
|
||||||
let startTime = new Timer();
|
let startTime = new Timer();
|
||||||
Log.info('构造设置开始');
|
this.logger.info('构造设置开始');
|
||||||
let pop = new Popup(CommonUtils.loading_gif_html(), '芜湖助手设置');
|
let pop = new Popup(CommonUtils.loading_gif_html(), '芜湖助手设置');
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
let tmp = document.createElement('div');
|
let tmp = document.createElement('div');
|
||||||
tmp.classList.add('gSetting');
|
tmp.classList.add('gSetting');
|
||||||
this.list.forEach(set => CommonUtils.getInstance().elemGenerator(set, tmp));
|
this.list.forEach(set => this.commonUtils.elemGenerator(set, tmp));
|
||||||
// 本日不提醒
|
// 本日不提醒
|
||||||
tmp.querySelector('#wh-qua-alarm-check-btn')
|
tmp.querySelector('#wh-qua-alarm-check-btn')
|
||||||
.addEventListener('click', () => BuyBeerHelper.getInstance().skip_today());
|
.addEventListener('click', () => this.buyBeerHelper.skip_today());
|
||||||
pop.getElement().innerHTML = '';
|
pop.getElement().innerHTML = '';
|
||||||
pop.getElement().appendChild(tmp);
|
pop.getElement().appendChild(tmp);
|
||||||
(window.initializeTooltip) && (window.initializeTooltip('#wh-popup-cont', 'white-tooltip'));
|
(window.initializeTooltip) && (window.initializeTooltip('#wh-popup-cont', 'white-tooltip'));
|
||||||
Log.info('构造设置结束 ' + startTime.getTimeMs());
|
this.logger.info('构造设置结束 ' + startTime.getTimeMs());
|
||||||
}, 0)
|
}, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置
|
// 设置
|
||||||
private constructWuhuSettingList(): SettingsHandler {
|
private constructWuhuSettingList(): SettingsHandler {
|
||||||
let timer = new Timer();
|
let timer = new Timer();
|
||||||
Log.info('构造设置列表开始');
|
this.logger.info('构造设置列表开始');
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
|
|
||||||
let beer = BuyBeerHelper.getInstance();
|
let beer = this.buyBeerHelper;
|
||||||
|
|
||||||
let list = this.list;
|
let list = this.list;
|
||||||
|
|
||||||
@ -102,7 +116,7 @@ export default class SettingsHandler extends WuhuBase {
|
|||||||
domId: '',
|
domId: '',
|
||||||
domText: '更新翻译词库',
|
domText: '更新翻译词库',
|
||||||
isTornBtn: true,
|
isTornBtn: true,
|
||||||
clickFunc: () => UpdateTranslateDict.getInstance().handle()
|
clickFunc: () => this.updateTranslateDict.handle()
|
||||||
});
|
});
|
||||||
// 收集数据以改进翻译质量
|
// 收集数据以改进翻译质量
|
||||||
list.push({
|
list.push({
|
||||||
@ -383,7 +397,7 @@ export default class SettingsHandler extends WuhuBase {
|
|||||||
domText: '啤酒提醒时间设定',
|
domText: '啤酒提醒时间设定',
|
||||||
isTornBtn: true,
|
isTornBtn: true,
|
||||||
// tip: '通知提前时间',
|
// tip: '通知提前时间',
|
||||||
clickFunc: () => BuyBeerHelper.getInstance().setTimeHandler()
|
clickFunc: () => this.buyBeerHelper.setTimeHandler()
|
||||||
});
|
});
|
||||||
|
|
||||||
// 个人资料
|
// 个人资料
|
||||||
@ -536,13 +550,13 @@ export default class SettingsHandler extends WuhuBase {
|
|||||||
dictName: 'isDev',
|
dictName: 'isDev',
|
||||||
isHide: true,
|
isHide: true,
|
||||||
});
|
});
|
||||||
// 查看logs
|
// 自定义CSS
|
||||||
list.push({
|
list.push({
|
||||||
domType: 'button',
|
domType: 'button',
|
||||||
domId: null,
|
domId: null,
|
||||||
domText: '自定义CSS',
|
domText: '自定义CSS',
|
||||||
isTornBtn: true,
|
isTornBtn: true,
|
||||||
clickFunc: () => CustomCssHandler.getInstance().handle()
|
clickFunc: () => this.customCssHandler.handle()
|
||||||
});
|
});
|
||||||
// 查看logs
|
// 查看logs
|
||||||
list.push({
|
list.push({
|
||||||
@ -550,16 +564,22 @@ export default class SettingsHandler extends WuhuBase {
|
|||||||
domId: null,
|
domId: null,
|
||||||
domText: '查看日志',
|
domText: '查看日志',
|
||||||
isTornBtn: true,
|
isTornBtn: true,
|
||||||
clickFunc: () => ViewLogsHandler.getInstance().handle()
|
clickFunc: () => this.viewLogsHandler.handle()
|
||||||
});
|
});
|
||||||
// 更多设定
|
// 更多设定
|
||||||
list.push({
|
list.push({
|
||||||
domType: 'button', domId: 'wh-otherBtn', domText: '更多设定',
|
domType: 'button', domId: 'wh-otherBtn', domText: '更多设定',
|
||||||
isTornBtn: true,
|
isTornBtn: true,
|
||||||
clickFunc: () => AdditionalSettingsHandler.getInstance().handle()
|
clickFunc: () => this.additionalSettingsHandler.show()
|
||||||
});
|
});
|
||||||
|
|
||||||
Log.info('构造设置列表结束' + timer.getTimeMs());
|
this.logger.info('构造设置列表结束' + timer.getTimeMs());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
domType: MENU_ITEM_TYPE.BUTTON,
|
||||||
|
domText: '⚙️ 助手设置',
|
||||||
|
clickFunc: () => Container.factory(SettingsHandler).show()
|
||||||
|
};
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import Alert from "../utils/Alert";
|
import Alert from "../utils/Alert";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
|
||||||
export default class UpdateTranslateDict extends WuhuBase {
|
@ClassName('UpdateTranslateDict')
|
||||||
className = 'UpdateTranslateDict';
|
@Injectable()
|
||||||
|
export default class UpdateTranslateDict {
|
||||||
|
|
||||||
public handle(): void {
|
public handle(): void {
|
||||||
new Alert('计划中');
|
new Alert('计划中');
|
||||||
|
|||||||
@ -1,20 +1,29 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import Log from "../Log";
|
import Log from "../Log";
|
||||||
import Popup from "../utils/Popup";
|
import Popup from "../utils/Popup";
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
import CommonUtils from "../utils/CommonUtils";
|
||||||
import VIEW_LOGS_HANDLER_HTML from "../../../static/html/view_logs_handler.html";
|
import VIEW_LOGS_HANDLER_HTML from "../../../static/html/view_logs_handler.html";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
|
||||||
export default class ViewLogsHandler extends WuhuBase {
|
@ClassName('ViewLogsHandler')
|
||||||
className = 'ViewLogsHandler';
|
@Injectable()
|
||||||
|
export default class ViewLogsHandler {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly commonUtils: CommonUtils,
|
||||||
|
private readonly logger: Logger,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
public handle(): void {
|
public handle(): void {
|
||||||
let logCounter = Log.getCounter();
|
let logCounter = this.logger.getCounter();
|
||||||
let pop = new Popup(VIEW_LOGS_HANDLER_HTML
|
let pop = new Popup(VIEW_LOGS_HANDLER_HTML
|
||||||
.replace('{{}}', logCounter.info.toString())
|
.replace('{{}}', logCounter.info.toString())
|
||||||
.replace('{{}}', logCounter.warning.toString())
|
.replace('{{}}', logCounter.warning.toString())
|
||||||
.replace('{{}}', logCounter.error.toString()), '查看日志');
|
.replace('{{}}', logCounter.error.toString()), '查看日志');
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
let container = pop.getElement().querySelector('div');
|
let container = pop.element.querySelector('div');
|
||||||
let text = document.createElement('div');
|
let text = document.createElement('div');
|
||||||
let logs = Log.getLogs().split('\r\n');
|
let logs = Log.getLogs().split('\r\n');
|
||||||
logs.forEach(log => {
|
logs.forEach(log => {
|
||||||
@ -27,18 +36,17 @@ export default class ViewLogsHandler extends WuhuBase {
|
|||||||
}
|
}
|
||||||
text.append(p);
|
text.append(p);
|
||||||
});
|
});
|
||||||
pop.getElement().querySelector('button').addEventListener('click', () => window.setTimeout(() => {
|
pop.element.querySelector('button').addEventListener('click', () => window.setTimeout(() => {
|
||||||
CommonUtils.getInstance()
|
this.commonUtils.exportTextFile(
|
||||||
.exportTextFile(
|
'wuhu_log_' + Log.getTime()
|
||||||
'wuhu_log_' + Log.getTime()
|
.replace('[', '')
|
||||||
.replace('[', '')
|
.replace(']', '')
|
||||||
.replace(']', '')
|
.replace(' ', '')
|
||||||
.replace(' ', '')
|
.replace('.', '')
|
||||||
.replace('.', '')
|
.replaceAll('-', '')
|
||||||
.replaceAll('-', '')
|
.replaceAll(':', '') + '.log',
|
||||||
.replaceAll(':', '') + '.log',
|
[Log.getLogs()]
|
||||||
[Log.getLogs()]
|
);
|
||||||
);
|
|
||||||
}, 0));
|
}, 0));
|
||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
container.append(text);
|
container.append(text);
|
||||||
|
|||||||
45
src/ts/class/provider/Debug.ts
Normal file
45
src/ts/class/provider/Debug.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { GetClassName } from "../../container/ClassName";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
import { Container } from "../../container/Container";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 方法装饰器
|
||||||
|
* @param target
|
||||||
|
* @param propertyKey
|
||||||
|
* @param descriptor
|
||||||
|
*/
|
||||||
|
export default function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
||||||
|
const logger: Logger = Container.factory(Logger);
|
||||||
|
|
||||||
|
const original = descriptor.value;
|
||||||
|
|
||||||
|
descriptor.value = function (...args) {
|
||||||
|
// Log.info('[debug] 参数 ', JSON.stringify({
|
||||||
|
// class: target.className || target.name,
|
||||||
|
// method: propertyKey,
|
||||||
|
// args
|
||||||
|
// }));
|
||||||
|
|
||||||
|
let result;
|
||||||
|
try {
|
||||||
|
result = original.call(this, ...args) || null;
|
||||||
|
} catch (err) {
|
||||||
|
logger.error('[debug]', err.stack || err.message || err, '参数' + JSON.stringify({
|
||||||
|
class: GetClassName(target) ?? target.name,
|
||||||
|
method: propertyKey,
|
||||||
|
args
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
logger.info(
|
||||||
|
'[debug]',
|
||||||
|
'参数' + JSON.stringify({
|
||||||
|
class: GetClassName(target) ?? target.name,
|
||||||
|
method: propertyKey,
|
||||||
|
args
|
||||||
|
}),
|
||||||
|
'结果',
|
||||||
|
{ result }
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,26 +0,0 @@
|
|||||||
export default class Elem {
|
|
||||||
private readonly elem: HTMLElement;
|
|
||||||
|
|
||||||
constructor(tagName) {
|
|
||||||
this.elem = document.createElement(tagName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public html(htmlString): Elem {
|
|
||||||
this.elem.innerHTML = htmlString;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public id(id): Elem {
|
|
||||||
this.elem.id = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class(className): Elem {
|
|
||||||
this.elem.classList.add(className);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public el(): HTMLElement {
|
|
||||||
return this.elem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
import Log from "../Log";
|
|
||||||
import ZhongIcon from "../ZhongIcon";
|
|
||||||
|
|
||||||
export default function EntryPoint(T: { main: () => void }) {
|
|
||||||
if (window.WHTRANS) throw '退出, 已运行次数' + window.WHTRANS;
|
|
||||||
window.WHTRANS = window.WHTRANS === undefined ? 1 : window.WHTRANS++;
|
|
||||||
|
|
||||||
let started = performance.now();
|
|
||||||
try {
|
|
||||||
T.main();
|
|
||||||
} catch (e) {
|
|
||||||
Log.error('[Starter]加载出错信息: ' + e.stack || e.message);
|
|
||||||
}
|
|
||||||
let runTime: number = (performance.now() - started) | 0;
|
|
||||||
Log.info(`芜湖脚本完成加载, 耗时${ runTime }ms`);
|
|
||||||
if (ZhongIcon.ZhongNode && ZhongIcon.ZhongNode.initTimer)
|
|
||||||
ZhongIcon.ZhongNode.initTimer.innerHTML = `加载时间 ${ runTime }ms`;
|
|
||||||
}
|
|
||||||
@ -1,38 +1,37 @@
|
|||||||
import Log from "../Log";
|
|
||||||
import Timer from "../utils/Timer";
|
|
||||||
import ClassWithName from "../../interface/ClassWithName";
|
import ClassWithName from "../../interface/ClassWithName";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基类、单例
|
* 基类、单例
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
export default class Provider implements ClassWithName {
|
export default class Provider implements ClassWithName {
|
||||||
readonly className: string = 'Provider';
|
readonly className: string = 'Provider';
|
||||||
private static instance;
|
// private static _instance;
|
||||||
|
//
|
||||||
private static readonly pool = {};
|
// private static readonly pool = {};
|
||||||
|
//
|
||||||
constructor(...args: unknown[]) {
|
// constructor(...args: unknown[]) {
|
||||||
}
|
// }
|
||||||
|
|
||||||
// 返回继承类的实例
|
// 返回继承类的实例
|
||||||
public static getInstance<T extends typeof Provider>(this: T, ...args: unknown[]): InstanceType<T> {
|
// public static getInstance<T extends typeof Provider>(this: T, ...args: unknown[]): InstanceType<T> {
|
||||||
if (!this.instance) {
|
// if (!this._instance) {
|
||||||
let startTime = new Timer();
|
// let startTime = new Timer();
|
||||||
this.instance = new this(...args);
|
// this._instance = new this(...args);
|
||||||
let thatName = this.instance.getClassName() || this.name;
|
// let thatName = this._instance.getClassName() || this.name;
|
||||||
Log.info('实例已创建,', thatName, this.instance, '耗时' + startTime.getTimeMs());
|
// Log.info('实例已创建,', thatName, this._instance, '耗时' + startTime.getTimeMs());
|
||||||
Provider.pool[thatName] = this.instance;
|
// Provider.pool[thatName] = this._instance;
|
||||||
}
|
// }
|
||||||
return this.instance;
|
// return this._instance;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public static getPool() {
|
// public static getPool() {
|
||||||
return {
|
// return {
|
||||||
pool: Provider.pool,
|
// pool: Provider.pool,
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public getClassName() {
|
// public getClassName() {
|
||||||
return this.className;
|
// return this.className;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,21 +0,0 @@
|
|||||||
// import Log from "../Log";
|
|
||||||
// import ZhongIcon from "../ZhongIcon";
|
|
||||||
//
|
|
||||||
// export default class Starter {
|
|
||||||
// public static run(T): void {
|
|
||||||
//
|
|
||||||
// if (window.WHTRANS) throw '退出, 已运行次数' + window.WHTRANS;
|
|
||||||
// window.WHTRANS = window.WHTRANS === undefined ? 1 : window.WHTRANS++;
|
|
||||||
//
|
|
||||||
// let started = performance.now();
|
|
||||||
// try {
|
|
||||||
// T.main();
|
|
||||||
// } catch (e) {
|
|
||||||
// Log.error('[Starter]加载出错信息: ' + e.stack || e.message);
|
|
||||||
// }
|
|
||||||
// let runTime: number = (performance.now() - started) | 0;
|
|
||||||
// Log.info(`芜湖脚本完成加载, 耗时${ runTime }ms`);
|
|
||||||
// if (ZhongIcon.ZhongNode && ZhongIcon.ZhongNode.initTimer)
|
|
||||||
// ZhongIcon.ZhongNode.initTimer.innerHTML = `加载时间 ${ runTime }ms`;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
@ -1,25 +1,20 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
import ClassName from "../../container/ClassName";
|
||||||
import Log from "../Log";
|
import { Injectable } from "../../container/Injectable";
|
||||||
import ZhongIcon from "../ZhongIcon";
|
import Logger from "../Logger";
|
||||||
|
import globVars from "../../globVars";
|
||||||
|
|
||||||
export default class ActionButtonUtils extends WuhuBase {
|
@ClassName('ActionButtonUtils')
|
||||||
className = 'ActionButtonUtils';
|
@Injectable()
|
||||||
|
export default class ActionButtonUtils {
|
||||||
private hasAdded: boolean = false;
|
private hasAdded: boolean = false;
|
||||||
|
private readonly logger = Logger.factory(ActionButtonUtils)
|
||||||
|
|
||||||
public add(txt: string, func: (ev: Event) => void = () => null): void {
|
public add(txt: string, func: (ev: Event) => void = () => null): void {
|
||||||
if (!this.hasAdded) this.handle(txt, func);
|
|
||||||
else Log.warn('ActionButton已存在');
|
let added = { txt, func }
|
||||||
|
globVars.buttons.push(added)
|
||||||
|
|
||||||
|
this.logger.info({ globVars })
|
||||||
}
|
}
|
||||||
|
|
||||||
private handle(txt, func): void {
|
|
||||||
let btn = document.createElement('button');
|
|
||||||
btn.style.padding = '8px 13px 8px 0';
|
|
||||||
btn.style.verticalAlign = 'bottom';
|
|
||||||
btn.style.color = '#4CAF50';
|
|
||||||
btn.innerHTML = txt;
|
|
||||||
btn.addEventListener('click', func);
|
|
||||||
ZhongIcon.ZhongNode.querySelector('button').after(btn);
|
|
||||||
this.hasAdded = true;
|
|
||||||
Log.info('ActionButton已添加', { txt, func, btn });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,13 +1,14 @@
|
|||||||
import Log from "../Log";
|
|
||||||
import IWHNotify from "../../interface/IWHNotify";
|
import IWHNotify from "../../interface/IWHNotify";
|
||||||
import NotificationUtils from "./NotificationUtils";
|
import NotificationUtils from "./NotificationUtils";
|
||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import MathUtils from "./MathUtils";
|
import MathUtils from "./MathUtils";
|
||||||
import NOTIFY_HTML from "../../../static/html/notify.html";
|
import NOTIFY_HTML from "../../../static/html/notify.html";
|
||||||
import WindowActiveState from "../action/WindowActiveState";
|
import WindowActiveState from "../action/WindowActiveState";
|
||||||
|
import { Container } from "../../container/Container";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
|
||||||
export default class Alert extends WuhuBase {
|
@ClassName('Alert')
|
||||||
className = 'Alert';
|
export default class Alert {
|
||||||
private static container: HTMLElement = null;
|
private static container: HTMLElement = null;
|
||||||
private static totalCounter: number = 0;
|
private static totalCounter: number = 0;
|
||||||
|
|
||||||
@ -15,35 +16,41 @@ export default class Alert extends WuhuBase {
|
|||||||
private intervalID = -1;
|
private intervalID = -1;
|
||||||
private readonly callback: Function;
|
private readonly callback: Function;
|
||||||
|
|
||||||
public constructor(msg: string, options: IWHNotify = {}) {
|
public constructor(
|
||||||
super();
|
msg: string,
|
||||||
|
options: IWHNotify = {},
|
||||||
|
private readonly mathUtils: MathUtils = Container.factory(MathUtils),
|
||||||
|
private readonly windowActiveState: WindowActiveState = Container.factory(WindowActiveState),
|
||||||
|
private readonly notificationUtils: NotificationUtils = Container.factory(NotificationUtils),
|
||||||
|
private readonly logger: Logger = Container.factory(Logger),
|
||||||
|
) {
|
||||||
|
|
||||||
let { timeout, callback, sysNotify, force } = options;
|
let { timeout, callback, sysNotify, force } = options;
|
||||||
|
|
||||||
// 后台窗口、iframe内判断
|
// 后台窗口、iframe内判断
|
||||||
if (!WindowActiveState.getInstance().get() || (self !== top)) {
|
if (!this.windowActiveState.get() || (self !== top)) {
|
||||||
if (!force) {
|
if (!force) {
|
||||||
Log.warn('后台通知已被屏蔽');
|
this.logger.warn('后台通知已被屏蔽');
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
Log.info('强制后台通知');
|
this.logger.info('强制后台通知');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 通知的容器
|
// 通知的容器
|
||||||
Log.info('通知的容器', Alert.container);
|
this.logger.info('通知的容器', Alert.container);
|
||||||
if (!Alert.container || !document.contains(Alert.container)) Alert.initContainer();
|
if (!Alert.container || !document.contains(Alert.container)) Alert.initContainer();
|
||||||
|
|
||||||
this.callback = callback || (() => null);
|
this.callback = callback || (() => null);
|
||||||
Alert.create(this, msg, timeout || 3);
|
Alert.create(this, msg, timeout || 3);
|
||||||
Alert.totalCounter++;
|
Alert.totalCounter++;
|
||||||
Log.info('创建新通知:', this, msg);
|
this.logger.info('创建新通知:', this, msg);
|
||||||
if (sysNotify) NotificationUtils.getInstance().push(msg, options);
|
if (sysNotify) this.notificationUtils.push(msg, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static create(that: Alert, msg, timeout): void {
|
private static create(that: Alert, msg, timeout): void {
|
||||||
// 通知的唯一id
|
// 通知的唯一id
|
||||||
const uid = '' + MathUtils.getInstance().getRandomInt(1000, 9999);
|
const uid = '' + that.mathUtils.getRandomInt(1000, 9999);
|
||||||
// 每条通知
|
// 每条通知
|
||||||
const element: MyHTMLElement = document.createElement('div');
|
const element: MyHTMLElement = document.createElement('div');
|
||||||
element.id = `wh-notify-${ uid }`;
|
element.id = `wh-notify-${ uid }`;
|
||||||
|
|||||||
@ -1,33 +1,53 @@
|
|||||||
import UserScriptEngine from "../../enum/UserScriptEngine";
|
import UserScriptEngine from "../../enum/UserScriptEngine";
|
||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import Log from "../Log";
|
|
||||||
import Device from "../../enum/Device";
|
import Device from "../../enum/Device";
|
||||||
import LOADING_IMG_HTML from "../../../static/html/loading_img.html";
|
import LOADING_IMG_HTML from "../../../static/html/loading_img.html";
|
||||||
import Timer from "./Timer";
|
import Timer from "./Timer";
|
||||||
import FetchUtils from "./FetchUtils";
|
import FetchUtils from "./FetchUtils";
|
||||||
import TornStyleSwitch from "./TornStyleSwitch";
|
import TornStyleSwitch from "./TornStyleSwitch";
|
||||||
import WuhuConfig from "../WuhuConfig";
|
|
||||||
import { MenuItemConfig } from "../ZhongIcon";
|
import { MenuItemConfig } from "../ZhongIcon";
|
||||||
import TRAVEL_STATE from "../../enum/TravelState";
|
import TRAVEL_STATE from "../../enum/TravelState";
|
||||||
import InventoryItemInfo from "../../interface/responseType/InventoryItemInfo";
|
import InventoryItemInfo from "../../interface/responseType/InventoryItemInfo";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import LocalConfigWrapper from "../LocalConfigWrapper";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
import Global from "../Global";
|
||||||
|
import { Container } from "../../container/Container";
|
||||||
|
import TornPDAUtils from "./TornPDAUtils";
|
||||||
|
import { InjectionKey } from "vue";
|
||||||
|
|
||||||
export default class CommonUtils extends WuhuBase {
|
@Injectable()
|
||||||
className = 'CommonUtils';
|
@ClassName('CommonUtils')
|
||||||
|
export default class CommonUtils {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
|
private readonly fetchUtils: FetchUtils,
|
||||||
|
private readonly logger: Logger,
|
||||||
|
private readonly global: Global,
|
||||||
|
private readonly tornPDAUtils: TornPDAUtils,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
static getScriptEngine() {
|
static getScriptEngine() {
|
||||||
let glob = CommonUtils.glob;
|
let glob = Container.factory(Global);
|
||||||
return glob.GM_xmlhttpRequest ? UserScriptEngine.GM : glob.isPDA
|
let tornPDAUtils = Container.factory(TornPDAUtils);
|
||||||
|
return glob.GM_xmlhttpRequest ? UserScriptEngine.GM : tornPDAUtils.isPDA()
|
||||||
? UserScriptEngine.PDA : UserScriptEngine.RAW;
|
? UserScriptEngine.PDA : UserScriptEngine.RAW;
|
||||||
}
|
}
|
||||||
|
|
||||||
static COFetch(url: URL | string, method: 'get' | 'post' = 'get', body: any = null): Promise<string> {
|
static COFetch(url: URL | string, method: 'get' | 'post' | string = 'get', body: any = null): Promise<string> {
|
||||||
|
let logger = Container.factory(Logger);
|
||||||
let start = new Timer();
|
let start = new Timer();
|
||||||
const engine = this.getScriptEngine();
|
const engine = this.getScriptEngine();
|
||||||
Log.info('跨域获取数据开始, 脚本引擎: ' + engine);
|
logger.info(`跨域请求 -> ${url}, 脚本引擎: ${engine}`);
|
||||||
return new Promise<string>((resolve, reject) => {
|
return new Promise<string>((resolve, reject) => {
|
||||||
switch (engine) {
|
switch (engine) {
|
||||||
case UserScriptEngine.RAW: {
|
case UserScriptEngine.RAW: {
|
||||||
Log.error(`跨域请求错误:${ UserScriptEngine.RAW }环境下无法进行跨域请求`);
|
logger.error(`跨域请求错误:${ UserScriptEngine.RAW }环境下无法进行跨域请求`);
|
||||||
reject(`错误:${ UserScriptEngine.RAW }环境下无法进行跨域请求`);
|
reject(`错误:${ UserScriptEngine.RAW }环境下无法进行跨域请求`);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -36,38 +56,38 @@ export default class CommonUtils extends WuhuBase {
|
|||||||
// get
|
// get
|
||||||
if (method === 'get') {
|
if (method === 'get') {
|
||||||
if (typeof PDA_httpGet !== 'function') {
|
if (typeof PDA_httpGet !== 'function') {
|
||||||
Log.error('COFetch网络错误:PDA版本不支持');
|
logger.error('COFetch网络错误:PDA版本不支持');
|
||||||
reject('COFetch网络错误:PDA版本不支持');
|
reject('COFetch网络错误:PDA版本不支持');
|
||||||
}
|
}
|
||||||
PDA_httpGet(url)
|
PDA_httpGet(url)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
Log.info('跨域获取数据成功, 耗时' + start.getTimeMs());
|
logger.info('跨域获取数据成功, 耗时' + start.getTimeMs());
|
||||||
resolve(res.responseText);
|
resolve(res.responseText);
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
Log.error('COFetch网络错误', e);
|
logger.error('COFetch网络错误', e);
|
||||||
reject(`COFetch网络错误 ${ e }`);
|
reject(`COFetch网络错误 ${ e }`);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// post
|
// post
|
||||||
else {
|
else {
|
||||||
if (typeof PDA_httpPost !== 'function') {
|
if (typeof PDA_httpPost !== 'function') {
|
||||||
Log.error('COFetch网络错误:PDA版本不支持');
|
logger.error('COFetch网络错误:PDA版本不支持');
|
||||||
reject('COFetch网络错误:PDA版本不支持');
|
reject('COFetch网络错误:PDA版本不支持');
|
||||||
}
|
}
|
||||||
PDA_httpPost(url, { 'content-type': 'application/json' }, body)
|
PDA_httpPost(url, { 'content-type': 'application/json' }, body)
|
||||||
.then(res => resolve(res.responseText))
|
.then(res => resolve(res.responseText))
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
Log.error('COFetch网络错误', e);
|
logger.error('COFetch网络错误', e);
|
||||||
reject(`COFetch网络错误 ${ e }`);
|
reject(`COFetch网络错误 ${ e }`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UserScriptEngine.GM: {
|
case UserScriptEngine.GM: {
|
||||||
let { GM_xmlhttpRequest } = CommonUtils.glob;
|
let { GM_xmlhttpRequest } = Container.factory(Global);
|
||||||
if (typeof GM_xmlhttpRequest !== 'function') {
|
if (typeof GM_xmlhttpRequest !== 'function') {
|
||||||
Log.error('COFetch网络错误:用户脚本扩展API错误');
|
logger.error('COFetch网络错误:用户脚本扩展API错误');
|
||||||
reject('错误:用户脚本扩展API错误');
|
reject('错误:用户脚本扩展API错误');
|
||||||
}
|
}
|
||||||
GM_xmlhttpRequest({
|
GM_xmlhttpRequest({
|
||||||
@ -76,7 +96,7 @@ export default class CommonUtils extends WuhuBase {
|
|||||||
data: method === 'get' ? null : body,
|
data: method === 'get' ? null : body,
|
||||||
headers: method === 'get' ? null : { 'content-type': 'application/json' },
|
headers: method === 'get' ? null : { 'content-type': 'application/json' },
|
||||||
onload: res => {
|
onload: res => {
|
||||||
Log.info('跨域获取数据成功,耗时' + start.getTimeMs());
|
logger.info('跨域获取数据成功,耗时' + start.getTimeMs());
|
||||||
resolve(res.response);
|
resolve(res.response);
|
||||||
},
|
},
|
||||||
onerror: res => reject(`连接错误 ${ JSON.stringify(res) }`),
|
onerror: res => reject(`连接错误 ${ JSON.stringify(res) }`),
|
||||||
@ -87,6 +107,13 @@ export default class CommonUtils extends WuhuBase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getScriptEngine() {
|
||||||
|
// let glob = Container.factory(Global);
|
||||||
|
// let tornPDAUtils = Container.factory(TornPDAUtils);
|
||||||
|
return this.global.GM_xmlhttpRequest ? UserScriptEngine.GM : this.tornPDAUtils.isPDA()
|
||||||
|
? UserScriptEngine.PDA : UserScriptEngine.RAW;
|
||||||
|
}
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * 返回玩家信息的对象 { playername: string, userID: number }
|
// * 返回玩家信息的对象 { playername: string, userID: number }
|
||||||
// * @return {PlayerInfo} rs
|
// * @return {PlayerInfo} rs
|
||||||
@ -148,26 +175,27 @@ export default class CommonUtils extends WuhuBase {
|
|||||||
* @returns {Promise<HTMLElement|null>}
|
* @returns {Promise<HTMLElement|null>}
|
||||||
*/
|
*/
|
||||||
public static elementReady(selectors: string, content: Document = document, timeout: number = 30000): Promise<HTMLElement> {
|
public static elementReady(selectors: string, content: Document = document, timeout: number = 30000): Promise<HTMLElement> {
|
||||||
Log.info('等待元素:' + selectors);
|
const logger = Container.factory(Logger);
|
||||||
|
logger.info('等待元素:' + selectors);
|
||||||
let timer = new Timer();
|
let timer = new Timer();
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let el = content.querySelector(selectors) as HTMLElement;
|
let el = content.querySelector(selectors) as HTMLElement;
|
||||||
if (el) {
|
if (el) {
|
||||||
Log.info('已获取元素, 耗时' + timer.getTimeMs(), el);
|
logger.info('已获取元素, 耗时' + timer.getTimeMs(), el);
|
||||||
resolve(el);
|
resolve(el);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let observer = new MutationObserver((_, observer) => {
|
let observer = new MutationObserver((_, observer) => {
|
||||||
content.querySelectorAll(selectors).forEach((element) => {
|
content.querySelectorAll(selectors).forEach((element) => {
|
||||||
Log.info({ innerHTML: element.innerHTML, element });
|
logger.info({ innerHTML: element.innerHTML, element });
|
||||||
observer.disconnect();
|
observer.disconnect();
|
||||||
Log.info('已获取元素, 耗时' + timer.getTimeMs(), element);
|
logger.info('已获取元素, 耗时' + timer.getTimeMs(), element);
|
||||||
resolve(element as HTMLElement);
|
resolve(element as HTMLElement);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
observer.disconnect();
|
observer.disconnect();
|
||||||
Log.error(`等待元素超时! [${ selectors }]\n${ content.documentElement.tagName }, 耗时` + timer.getTimeMs());
|
logger.error(`等待元素超时! [${ selectors }]\n${ content.documentElement.tagName }, 耗时` + timer.getTimeMs());
|
||||||
reject(`等待元素超时! [${ selectors }]\n${ content.documentElement.tagName }, 耗时` + timer.getTimeMs());
|
reject(`等待元素超时! [${ selectors }]\n${ content.documentElement.tagName }, 耗时` + timer.getTimeMs());
|
||||||
}, timeout);
|
}, timeout);
|
||||||
observer.observe(content.documentElement, { childList: true, subtree: true });
|
observer.observe(content.documentElement, { childList: true, subtree: true });
|
||||||
@ -184,7 +212,12 @@ export default class CommonUtils extends WuhuBase {
|
|||||||
return CommonUtils.elementReady(selectors, content, timeout);
|
return CommonUtils.elementReady(selectors, content, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public querySelector(selectors: string, content: Document = document, timeout: number = 30000): Promise<HTMLElement> {
|
||||||
|
return CommonUtils.elementReady(selectors, content, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
public static addStyle(rules: string): void {
|
public static addStyle(rules: string): void {
|
||||||
|
const logger = Container.factory(Logger);
|
||||||
let element = document.querySelector('style#wh-trans-gStyle');
|
let element = document.querySelector('style#wh-trans-gStyle');
|
||||||
if (element) {
|
if (element) {
|
||||||
element.innerHTML += rules;
|
element.innerHTML += rules;
|
||||||
@ -194,7 +227,14 @@ export default class CommonUtils extends WuhuBase {
|
|||||||
element.innerHTML = rules;
|
element.innerHTML = rules;
|
||||||
document.head.appendChild(element);
|
document.head.appendChild(element);
|
||||||
}
|
}
|
||||||
Log.info('CSS规则已添加', element);
|
logger.info('CSS规则已添加', element);
|
||||||
|
}
|
||||||
|
|
||||||
|
public styleInject(rules: string): void {
|
||||||
|
const element = document.createElement("style");
|
||||||
|
element.setAttribute('type', 'text/css');
|
||||||
|
element.innerHTML = rules;
|
||||||
|
document.head.appendChild(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static loading_gif_html(): string {
|
public static loading_gif_html(): string {
|
||||||
@ -206,12 +246,19 @@ export default class CommonUtils extends WuhuBase {
|
|||||||
* @param {string} url 播放的音频URL
|
* @param {string} url 播放的音频URL
|
||||||
* @returns {undefined}
|
* @returns {undefined}
|
||||||
*/
|
*/
|
||||||
public audioPlay(url: string = 'https://www.torn.com/js/chat/sounds/Warble_1.mp3') {
|
public audioPlay(url: string = 'https://www.torn.com/js/chat/sounds/Warble_1.mp3'): Promise<void> {
|
||||||
const audio = new Audio(url);
|
return new Promise((resolve, reject) => {
|
||||||
audio.addEventListener("canplaythrough", () => {
|
const audio = new Audio(url);
|
||||||
audio.play()
|
audio.addEventListener("canplaythrough", () => {
|
||||||
.catch(err => Log.error('播放音频出错', err.message, err.stack))
|
audio.play()
|
||||||
.then();
|
.catch(err => {
|
||||||
|
this.logger.error('播放音频出错', err.message, err.stack);
|
||||||
|
reject();
|
||||||
|
})
|
||||||
|
.then(
|
||||||
|
() => resolve()
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,11 +276,11 @@ export default class CommonUtils extends WuhuBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public jQueryReady(): Promise<null> {
|
public jQueryReady(): Promise<null> {
|
||||||
Log.info('等待jQuery加载中...');
|
this.logger.info('等待jQuery加载中...');
|
||||||
FetchUtils.getInstance().fetchText('/js/script/lib/jquery-1.8.2.js?v=f9128651g')
|
this.fetchUtils.fetchText('/js/script/lib/jquery-1.8.2.js?v=f9128651g')
|
||||||
.then(res => window.eval(res));
|
.then(res => window.eval(res));
|
||||||
let intervalId = window.setInterval(() => {
|
let intervalId = window.setInterval(() => {
|
||||||
Log.info('仍在等待jQuery加载中...');
|
this.logger.info('仍在等待jQuery加载中...');
|
||||||
}, 1000);
|
}, 1000);
|
||||||
return new Promise(async resolve => {
|
return new Promise(async resolve => {
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -241,7 +288,7 @@ export default class CommonUtils extends WuhuBase {
|
|||||||
await this.sleep(100);
|
await this.sleep(100);
|
||||||
}
|
}
|
||||||
window.clearInterval(intervalId);
|
window.clearInterval(intervalId);
|
||||||
Log.info('jQuery已加载');
|
this.logger.info('jQuery已加载');
|
||||||
resolve(null);
|
resolve(null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -268,9 +315,9 @@ export default class CommonUtils extends WuhuBase {
|
|||||||
let _input = switcher.getInput();
|
let _input = switcher.getInput();
|
||||||
switcher.getBase().id = domId;
|
switcher.getBase().id = domId;
|
||||||
(tip) && (switcher.getBase().setAttribute('title', tip));
|
(tip) && (switcher.getBase().setAttribute('title', tip));
|
||||||
_input.checked = WuhuConfig.get(dictName);
|
_input.checked = this.localConfigWrapper.config[dictName];
|
||||||
_input.onchange = e => {
|
_input.onchange = e => {
|
||||||
WuhuConfig.set(dictName, _input.checked, true);
|
this.localConfigWrapper.config[dictName] = _input.checked;
|
||||||
if (changeEv) changeEv(e);
|
if (changeEv) changeEv(e);
|
||||||
};
|
};
|
||||||
new_node.appendChild(switcher.getBase());
|
new_node.appendChild(switcher.getBase());
|
||||||
@ -301,11 +348,11 @@ export default class CommonUtils extends WuhuBase {
|
|||||||
let option = document.createElement('option');
|
let option = document.createElement('option');
|
||||||
option.value = domVal;
|
option.value = domVal;
|
||||||
option.innerHTML = domText;
|
option.innerHTML = domText;
|
||||||
option.selected = i === WuhuConfig.get(dictName);
|
option.selected = i === this.localConfigWrapper.config[dictName];
|
||||||
option.innerHTML = domText;
|
option.innerHTML = domText;
|
||||||
select.appendChild(option);
|
select.appendChild(option);
|
||||||
});
|
});
|
||||||
select.onchange = e => WuhuConfig.set(dictName, (<HTMLSelectElement>e.target).selectedIndex);
|
select.onchange = e => this.localConfigWrapper.config[dictName] = (<HTMLSelectElement>e.target).selectedIndex;
|
||||||
label.appendChild(text);
|
label.appendChild(text);
|
||||||
label.appendChild(select);
|
label.appendChild(select);
|
||||||
new_node.appendChild(label);
|
new_node.appendChild(label);
|
||||||
@ -341,7 +388,7 @@ export default class CommonUtils extends WuhuBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getTravelStage(): TRAVEL_STATE {
|
public getTravelStage(): TRAVEL_STATE {
|
||||||
let global = CommonUtils.glob;
|
let global = Container.factory(Global);
|
||||||
if (global.bodyAttrs["data-abroad"] === 'false') {
|
if (global.bodyAttrs["data-abroad"] === 'false') {
|
||||||
return TRAVEL_STATE.IN_TORN;
|
return TRAVEL_STATE.IN_TORN;
|
||||||
}
|
}
|
||||||
@ -398,7 +445,11 @@ export default class CommonUtils extends WuhuBase {
|
|||||||
* @param m1 id->name map
|
* @param m1 id->name map
|
||||||
* @param m2 name->item map
|
* @param m2 name->item map
|
||||||
*/
|
*/
|
||||||
public getItemByIdOrName(key: string, m1, m2: { [k: string]: Partial<InventoryItemInfo> }): Partial<InventoryItemInfo> {
|
public getItemByIdOrName(key: string, m1, m2: {
|
||||||
|
[k: string]: Partial<InventoryItemInfo>
|
||||||
|
}): Partial<InventoryItemInfo> {
|
||||||
return m1[key] ? m2[m1[key]] : m2[key];
|
return m1[key] ? m2[m1[key]] : m2[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const CommonUtilsKey = Symbol('CommonUtilsKey') as InjectionKey<CommonUtils>;
|
||||||
|
|||||||
@ -1,19 +1,21 @@
|
|||||||
import Log from "../Log";
|
|
||||||
import DIALOG_MSG_BOX_HTML from "../../../static/html/dialog_msg_box.html";
|
import DIALOG_MSG_BOX_HTML from "../../../static/html/dialog_msg_box.html";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
import { Container } from "../../container/Container";
|
||||||
|
|
||||||
export default class DialogMsgBox {
|
export default class DialogMsgBox {
|
||||||
private static existed = false;
|
private static existed = false;
|
||||||
private readonly container: HTMLElement;
|
private readonly container: HTMLElement;
|
||||||
|
|
||||||
constructor(msg: string, opt: DialogMsgBoxOptions) {
|
constructor(msg: string, opt: DialogMsgBoxOptions,
|
||||||
Log.info('创建DialogMsgBox', { msg, opt });
|
private readonly logger: Logger = Container.factory(Logger)) {
|
||||||
|
logger.info('创建DialogMsgBox', { msg, opt });
|
||||||
let { title = '提示', callback, cancel } = opt;
|
let { title = '提示', callback, cancel } = opt;
|
||||||
if (!callback) {
|
if (!callback) {
|
||||||
Log.error('无callback');
|
logger.error('无callback');
|
||||||
throw new Error('无callback');
|
throw new Error('无callback');
|
||||||
}
|
}
|
||||||
if (DialogMsgBox.existed) {
|
if (DialogMsgBox.existed) {
|
||||||
Log.error('无法创建DialogMsgBox:已存在');
|
logger.error('无法创建DialogMsgBox:已存在');
|
||||||
throw new Error('无法创建DialogMsgBox:已存在');
|
throw new Error('无法创建DialogMsgBox:已存在');
|
||||||
}
|
}
|
||||||
this.container = document.createElement('div');
|
this.container = document.createElement('div');
|
||||||
|
|||||||
@ -1,10 +1,16 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import Log from "../Log";
|
|
||||||
import AjaxFetchOption from "../../interface/AjaxFetchOption";
|
import AjaxFetchOption from "../../interface/AjaxFetchOption";
|
||||||
import IUserProfileData from "../../interface/IUserProfileData";
|
import IUserProfileData from "../../interface/IUserProfileData";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
|
||||||
export default class FetchUtils extends WuhuBase {
|
@ClassName('FetchUtils')
|
||||||
className = 'FetchUtils';
|
@Injectable()
|
||||||
|
export default class FetchUtils {
|
||||||
|
constructor(
|
||||||
|
private readonly logger: Logger,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 包装jquery ajax 异步返回string
|
* 包装jquery ajax 异步返回string
|
||||||
@ -55,7 +61,7 @@ export default class FetchUtils extends WuhuBase {
|
|||||||
.then(res => res.text())
|
.then(res => res.text())
|
||||||
.then(t => resolve(t))
|
.then(t => resolve(t))
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
Log.error('fetchText出错了', err);
|
this.logger.error('fetchText出错了', err);
|
||||||
reject(err);
|
reject(err);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -70,11 +76,11 @@ export default class FetchUtils extends WuhuBase {
|
|||||||
o.json().then((res) => {
|
o.json().then((res) => {
|
||||||
resolve(res);
|
resolve(res);
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
Log.error('[ProfileHelper] JSON解析错误: ', e.message, '错误堆栈: ', e.stack);
|
this.logger.error('[ProfileHelper] JSON解析错误: ', e.message, '错误堆栈: ', e.stack);
|
||||||
reject(e);
|
reject(e);
|
||||||
});
|
});
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
Log.error('[ProfileHelper] 网络错误: ', e.message, '错误堆栈: ', e.stack);
|
this.logger.error('[ProfileHelper] 网络错误: ', e.message, '错误堆栈: ', e.stack);
|
||||||
reject(e);
|
reject(e);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,12 +1,26 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import Alert from "./Alert";
|
|
||||||
import ISidebarData from "../../interface/ISidebarData";
|
import ISidebarData from "../../interface/ISidebarData";
|
||||||
import Log from "../Log";
|
|
||||||
import CommonUtils from "./CommonUtils";
|
|
||||||
import FetchUtils from "./FetchUtils";
|
import FetchUtils from "./FetchUtils";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
import LocalConfigWrapper from "../LocalConfigWrapper";
|
||||||
|
import MsgWrapper from "./MsgWrapper";
|
||||||
|
import { ElMessageBox } from "element-plus";
|
||||||
|
import { MessageBoxData } from "element-plus/es/components/message-box/src/message-box.type";
|
||||||
|
|
||||||
export default class InfoUtils extends WuhuBase {
|
@ClassName('InfoUtils')
|
||||||
className = 'InfoUtils';
|
@Injectable()
|
||||||
|
export default class InfoUtils {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
// TODO 循环依赖
|
||||||
|
// private readonly commonUtils: CommonUtils,
|
||||||
|
private readonly fetchUtils: FetchUtils,
|
||||||
|
private readonly logger: Logger,
|
||||||
|
private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
|
private readonly msgWrapper: MsgWrapper,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回玩家信息的对象 { playername: string, userID: number }
|
* 返回玩家信息的对象 { playername: string, userID: number }
|
||||||
@ -20,8 +34,51 @@ export default class InfoUtils extends WuhuBase {
|
|||||||
userID: parseInt(node.getAttribute('uid')),
|
userID: parseInt(node.getAttribute('uid')),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
new Alert('严重错误:芜湖助手无法获取用户数据,已退出');
|
// 自动登陆
|
||||||
throw '芜湖助手无法获取用户数据';
|
const { autoLoginEmail, autoLoginPwd } = this.localConfigWrapper.config;
|
||||||
|
if (autoLoginEmail && autoLoginPwd) {
|
||||||
|
window.setTimeout(async () => {
|
||||||
|
let alertRs: MessageBoxData = null;
|
||||||
|
try {
|
||||||
|
alertRs = await ElMessageBox.confirm(
|
||||||
|
'可进行自动登录',
|
||||||
|
'确认',
|
||||||
|
{
|
||||||
|
confirmButtonText: '好',
|
||||||
|
cancelButtonText: '算了',
|
||||||
|
type: 'info',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
if (alertRs !== 'confirm') return;
|
||||||
|
this.msgWrapper.create('正尝试自动登录...', null, 'info');
|
||||||
|
await fetch("https://www.torn.com/page.php?sid=Auth", {
|
||||||
|
"headers": {
|
||||||
|
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
|
||||||
|
"cache-control": "no-cache",
|
||||||
|
"content-type": "application/x-www-form-urlencoded",
|
||||||
|
"pragma": "no-cache",
|
||||||
|
"sec-ch-ua-mobile": "?0",
|
||||||
|
"sec-fetch-dest": "document",
|
||||||
|
"sec-fetch-mode": "navigate",
|
||||||
|
"sec-fetch-site": "same-origin",
|
||||||
|
"sec-fetch-user": "?1",
|
||||||
|
"upgrade-insecure-requests": "1"
|
||||||
|
},
|
||||||
|
"referrer": "https://www.torn.com/",
|
||||||
|
"referrerPolicy": "strict-origin-when-cross-origin",
|
||||||
|
"body": `email=${ autoLoginEmail }&password=${ autoLoginPwd }&redirectUrl=https%3A%2F%2Fwww.torn.com%2F&btnLogin=Login`,
|
||||||
|
"method": "POST",
|
||||||
|
"mode": "cors",
|
||||||
|
"credentials": "include"
|
||||||
|
});
|
||||||
|
this.msgWrapper.create('自动登录完成,即将转跳', null, 'info');
|
||||||
|
window.setTimeout(() => window.location.href = '//www.torn.com/index.php', 1000);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
this.msgWrapper.create('错误:芜湖助手无法获取用户数据,已退出', null, 'error');
|
||||||
|
throw new TypeError('芜湖助手无法获取用户数据');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,19 +92,30 @@ export default class InfoUtils extends WuhuBase {
|
|||||||
let c = 0;
|
let c = 0;
|
||||||
while (!sessionStorage.getItem(field) && c < 50) {
|
while (!sessionStorage.getItem(field) && c < 50) {
|
||||||
c++;
|
c++;
|
||||||
await CommonUtils.getInstance().sleep(10);
|
// await (async () => await this.commonUtils.sleep(10))();
|
||||||
|
await (async () => window.setTimeout(() => Promise.resolve(), 10))();
|
||||||
}
|
}
|
||||||
if (sessionStorage.getItem(field)) {
|
if (sessionStorage.getItem(field)) {
|
||||||
ret = JSON.parse(sessionStorage.getItem(field));
|
try {
|
||||||
|
ret = JSON.parse(sessionStorage.getItem(field));
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error('解析出错', e.stack || e.message || e);
|
||||||
|
ret = {};
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.info('无法从sessionStorage获取数据')
|
this.logger.info('无法从sessionStorage获取数据')
|
||||||
ret = await (await FetchUtils.getInstance().ajaxFetch({
|
ret = await (await this.fetchUtils.ajaxFetch({
|
||||||
url: window.addRFC('/sidebarAjaxAction.php?q=getSidebarData'),
|
url: window.addRFC('/sidebarAjaxAction.php?q=getSidebarData'),
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
})).json();
|
})).json();
|
||||||
sessionStorage.setItem(field, JSON.stringify(ret));
|
sessionStorage.setItem(field, JSON.stringify(ret));
|
||||||
}
|
}
|
||||||
ret.headerData = JSON.parse(sessionStorage.getItem('headerData'));
|
try {
|
||||||
|
ret.headerData = JSON.parse(sessionStorage.getItem('headerData'));
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error('解析出错', e.stack || e.message || e);
|
||||||
|
ret.headerData = null;
|
||||||
|
}
|
||||||
resolve(ret);
|
resolve(ret);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,22 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import InventoryItemInfo from "../../interface/responseType/InventoryItemInfo";
|
import InventoryItemInfo from "../../interface/responseType/InventoryItemInfo";
|
||||||
import FetchUtils from "./FetchUtils";
|
import FetchUtils from "./FetchUtils";
|
||||||
import CommonUtils from "./CommonUtils";
|
import CommonUtils from "./CommonUtils";
|
||||||
import Log from "../Log";
|
|
||||||
import PriceData from "../../interface/PriceData";
|
import PriceData from "../../interface/PriceData";
|
||||||
import Asyncable from "../../interface/Asyncable";
|
import Asyncable from "../../interface/Asyncable";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
import { InjectionKey } from "vue";
|
||||||
|
|
||||||
export default class ItemHelper extends WuhuBase {
|
@ClassName('ItemHelper')
|
||||||
className = "ItemHelper";
|
@Injectable()
|
||||||
|
export default class ItemHelper {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly fetchUtils: FetchUtils,
|
||||||
|
private readonly logger: Logger,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
/** 保存物品名-ID对应关系 */
|
/** 保存物品名-ID对应关系 */
|
||||||
private itemNameMap: { [name: string]: number } = null;
|
private itemNameMap: { [name: string]: number } = null;
|
||||||
@ -16,12 +25,11 @@ export default class ItemHelper extends WuhuBase {
|
|||||||
'Glass of Beer': {
|
'Glass of Beer': {
|
||||||
itemName: '一杯啤酒',
|
itemName: '一杯啤酒',
|
||||||
itemInfo: '[译]Only savages drink beer straight out of the bottle. This glass of beer is obtained fresh from the keg, and provides the same level of drunken joy as you\'d get from a regular bottle of suds. Provides a moderate nerve increase when consumed.',
|
itemInfo: '[译]Only savages drink beer straight out of the bottle. This glass of beer is obtained fresh from the keg, and provides the same level of drunken joy as you\'d get from a regular bottle of suds. Provides a moderate nerve increase when consumed.',
|
||||||
itemInfoContent: "\n" +
|
itemInfoContent: "<div class='m-bottom10'>" +
|
||||||
" <div class='m-bottom10'>\n" +
|
"<span class=\"bold\">一杯啤酒</span> 是酒类物品" +
|
||||||
" <span class=\"bold\">一杯啤酒</span> 是酒类物品\n" +
|
"</div>" +
|
||||||
" </div>\n" +
|
"Only savages drink beer straight out of the bottle. This glass of beer is obtained fresh from the keg, and provides the same level of drunken joy as you'd get from a regular bottle of suds. Provides a moderate nerve increase when consumed." +
|
||||||
" Only savages drink beer straight out of the bottle. This glass of beer is obtained fresh from the keg, and provides the same level of drunken joy as you'd get from a regular bottle of suds. Provides a moderate nerve increase when consumed.\n" +
|
"<div class=\"t-green bold item-effect m-top10\">效果: 犯罪 + 2,增幅CD + 1h。</div>",
|
||||||
" <div class=\"t-green bold item-effect m-top10\">效果: 犯罪 + 2,增幅CD + 1h。</div>",
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -32,11 +40,6 @@ export default class ItemHelper extends WuhuBase {
|
|||||||
// 缓存过期时间 分钟
|
// 缓存过期时间 分钟
|
||||||
private readonly priceTimeout = 720;
|
private readonly priceTimeout = 720;
|
||||||
|
|
||||||
// TODO 定时
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** TODO 通过 name 查询 */
|
/** TODO 通过 name 查询 */
|
||||||
public async getItemData(idOrName: string): Promise<Partial<InventoryItemInfo>> {
|
public async getItemData(idOrName: string): Promise<Partial<InventoryItemInfo>> {
|
||||||
let _itemId: number = null;
|
let _itemId: number = null;
|
||||||
@ -50,7 +53,7 @@ export default class ItemHelper extends WuhuBase {
|
|||||||
} else {
|
} else {
|
||||||
itemId = (await this.getItemNameMap().promise)[idOrName];
|
itemId = (await this.getItemNameMap().promise)[idOrName];
|
||||||
}
|
}
|
||||||
return await (await FetchUtils.getInstance().ajaxFetch({
|
return await (await this.fetchUtils.ajaxFetch({
|
||||||
url: '/inventory.php',
|
url: '/inventory.php',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
@ -80,7 +83,7 @@ export default class ItemHelper extends WuhuBase {
|
|||||||
* 物品查价值
|
* 物品查价值
|
||||||
*/
|
*/
|
||||||
public async getItemValue(idOrName) {
|
public async getItemValue(idOrName) {
|
||||||
return (await this.getItemData(idOrName)).itemValue.replaceAll(/[,$]/, '');
|
return (await this.getItemData(idOrName)).itemValue.replaceAll(/[,$]/g, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 返回本地物品价格数据,id对应物品名和价格 */
|
/** 返回本地物品价格数据,id对应物品名和价格 */
|
||||||
@ -98,7 +101,7 @@ export default class ItemHelper extends WuhuBase {
|
|||||||
try {
|
try {
|
||||||
data = JSON.parse(localStore);
|
data = JSON.parse(localStore);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.error(e.stack || e.message || e);
|
this.logger.error(e.stack || e.message || e);
|
||||||
throw new Error('JSON解析错误');
|
throw new Error('JSON解析错误');
|
||||||
}
|
}
|
||||||
// 缓存超时
|
// 缓存超时
|
||||||
@ -138,7 +141,7 @@ export default class ItemHelper extends WuhuBase {
|
|||||||
else {
|
else {
|
||||||
ret.promise = new Promise(async resolve => {
|
ret.promise = new Promise(async resolve => {
|
||||||
let response = await localData.promise;
|
let response = await localData.promise;
|
||||||
Log.info({ response });
|
this.logger.info({ response });
|
||||||
let promiseRet = {};
|
let promiseRet = {};
|
||||||
Object.keys(response).forEach(k => {
|
Object.keys(response).forEach(k => {
|
||||||
promiseRet[response[k].name] = k;
|
promiseRet[response[k].name] = k;
|
||||||
@ -160,7 +163,7 @@ export default class ItemHelper extends WuhuBase {
|
|||||||
try {
|
try {
|
||||||
res = JSON.parse(await CommonUtils.COFetch('https://jjins.github.io/item_price_raw.json'))
|
res = JSON.parse(await CommonUtils.COFetch('https://jjins.github.io/item_price_raw.json'))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Log.error(err.stack || err.message || err);
|
this.logger.error(err.stack || err.message || err);
|
||||||
throw new Error('获取在线价格时出错');
|
throw new Error('获取在线价格时出错');
|
||||||
}
|
}
|
||||||
// 更新缓存
|
// 更新缓存
|
||||||
@ -172,3 +175,5 @@ export default class ItemHelper extends WuhuBase {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const ItemHelperKey = Symbol('ItemHelperKey') as InjectionKey<ItemHelper>;
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
|
||||||
export default class MDUtils extends WuhuBase {
|
@ClassName('MDUtils')
|
||||||
className = 'MDUtils';
|
@Injectable()
|
||||||
|
export default class MDUtils {
|
||||||
/**
|
/**
|
||||||
* 解析 Markdown 内容
|
* 解析 Markdown 内容
|
||||||
* @param {String} from
|
* @param {String} from
|
||||||
|
|||||||
@ -1,7 +1,12 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import { InjectionKey } from "vue";
|
||||||
|
|
||||||
export default class MathUtils extends WuhuBase {
|
@ClassName('MathUtils')
|
||||||
|
@Injectable()
|
||||||
|
export default class MathUtils {
|
||||||
className = 'MathUtils';
|
className = 'MathUtils';
|
||||||
|
|
||||||
// 得到一个两数之间的随机整数
|
// 得到一个两数之间的随机整数
|
||||||
public getRandomInt(min: number, max: number): number {
|
public getRandomInt(min: number, max: number): number {
|
||||||
min = Math.ceil(min);
|
min = Math.ceil(min);
|
||||||
@ -10,3 +15,5 @@ export default class MathUtils extends WuhuBase {
|
|||||||
return Math.floor(Math.random() * (max - min)) + min;
|
return Math.floor(Math.random() * (max - min)) + min;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const MathUtilsKey = Symbol('MathUtilsKey') as InjectionKey<MathUtils>
|
||||||
|
|||||||
32
src/ts/class/utils/MsgWrapper.ts
Normal file
32
src/ts/class/utils/MsgWrapper.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import IWHNotify from "../../interface/IWHNotify";
|
||||||
|
import { InjectionKey } from "vue";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
import NotificationUtils from "./NotificationUtils";
|
||||||
|
import WindowActiveState from "../action/WindowActiveState";
|
||||||
|
|
||||||
|
@ClassName('MsgWrapper')
|
||||||
|
@Injectable()
|
||||||
|
export default class MsgWrapper {
|
||||||
|
constructor(
|
||||||
|
private readonly notificationUtils: NotificationUtils,
|
||||||
|
private readonly windowActiveState: WindowActiveState,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
create(msg: string, options: IWHNotify = {}, type: 'info' | 'warning' | 'error' | 'success' = 'info') {
|
||||||
|
if (!this.windowActiveState.get()) return null;
|
||||||
|
if (options?.sysNotify) {
|
||||||
|
this.notificationUtils.push(msg, options);
|
||||||
|
}
|
||||||
|
return ElMessage({
|
||||||
|
message: msg,
|
||||||
|
type,
|
||||||
|
showClose: true,
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MsgWrapperKey = Symbol('MsgWrapperKey') as InjectionKey<MsgWrapper>;
|
||||||
64
src/ts/class/utils/NetHighLvlWrapper.ts
Normal file
64
src/ts/class/utils/NetHighLvlWrapper.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import Debug from "../provider/Debug";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
@ClassName('NetHighLvlWrapper')
|
||||||
|
export default class NetHighLvlWrapper {
|
||||||
|
@Debug
|
||||||
|
public async doGymTrain(type: BATTLE_STAT, count: number): Promise<string> {
|
||||||
|
let rs: string;
|
||||||
|
try {
|
||||||
|
rs = await (await window.fetch(
|
||||||
|
window.addRFC("https://www.torn.com/gym.php?step=train"),
|
||||||
|
{
|
||||||
|
"headers": {
|
||||||
|
"accept": "*/*",
|
||||||
|
"content-type": "application/json",
|
||||||
|
"sec-ch-ua-mobile": "?0",
|
||||||
|
"sec-fetch-dest": "empty",
|
||||||
|
"sec-fetch-mode": "cors",
|
||||||
|
"sec-fetch-site": "same-origin",
|
||||||
|
"x-requested-with": "XMLHttpRequest"
|
||||||
|
},
|
||||||
|
"referrer": "https://www.torn.com/gym.php",
|
||||||
|
"referrerPolicy": "strict-origin-when-cross-origin",
|
||||||
|
"body": `{\"step\":\"train\",\"stat\":\"${ type }\",\"repeats\":${ count }}`,
|
||||||
|
"method": "POST",
|
||||||
|
"mode": "cors",
|
||||||
|
"credentials": "include"
|
||||||
|
}
|
||||||
|
)).text();
|
||||||
|
} catch (e) {
|
||||||
|
rs = e.message;
|
||||||
|
}
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async doTravelFly(destId, key, type): Promise<string> {
|
||||||
|
return await (await fetch(window.addRFC("https://www.torn.com/travelagency.php"), {
|
||||||
|
"headers": {
|
||||||
|
"accept": "*/*",
|
||||||
|
"accept-language": "zh-CN,zh;q=0.9",
|
||||||
|
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||||
|
"sec-fetch-dest": "empty",
|
||||||
|
"sec-fetch-mode": "cors",
|
||||||
|
"sec-fetch-site": "same-origin",
|
||||||
|
"x-requested-with": "XMLHttpRequest"
|
||||||
|
},
|
||||||
|
"referrer": "https://www.torn.com/travelagency.php",
|
||||||
|
"referrerPolicy": "strict-origin-when-cross-origin",
|
||||||
|
"body": `step=travel&id=${ destId }&type=${ type }`,
|
||||||
|
"method": "POST",
|
||||||
|
"mode": "cors",
|
||||||
|
"credentials": "include"
|
||||||
|
})).text()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum BATTLE_STAT {
|
||||||
|
STR = 'strength',
|
||||||
|
DEF = 'defense',
|
||||||
|
SPD = 'speed',
|
||||||
|
DEX = 'dexterity'
|
||||||
|
}
|
||||||
@ -1,31 +1,41 @@
|
|||||||
import IWHNotify from "../../interface/IWHNotify";
|
import IWHNotify from "../../interface/IWHNotify";
|
||||||
import Log from "../Log";
|
import ClassName from "../../container/ClassName";
|
||||||
import WuhuBase from "../WuhuBase";
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
|
||||||
|
@ClassName('NotificationUtils')
|
||||||
|
@Injectable()
|
||||||
|
export default class NotificationUtils {
|
||||||
|
constructor(
|
||||||
|
// TODO 循环依赖
|
||||||
|
// private readonly global: Global,
|
||||||
|
private readonly logger: Logger,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
export default class NotificationUtils extends WuhuBase {
|
|
||||||
className = 'NotificationUtils';
|
|
||||||
private permission: boolean = window.Notification && window.Notification.permission === 'granted';
|
private permission: boolean = window.Notification && window.Notification.permission === 'granted';
|
||||||
|
|
||||||
public push(msg: string, options: IWHNotify = {}): void {
|
public push(msg: string, options: IWHNotify = {}): void {
|
||||||
let { notifies } = NotificationUtils.glob;
|
// this.logger.info({msg, options})
|
||||||
|
// let { notifies } = this.global;
|
||||||
|
|
||||||
if (options.sysNotify && this.permission) {
|
if (options.sysNotify && this.permission) {
|
||||||
let tmpNode = document.createElement('p');
|
let tmpNode = document.createElement('p');
|
||||||
tmpNode.innerHTML = msg;
|
tmpNode.innerHTML = msg;
|
||||||
let notify = new Notification('芜湖助手', {
|
let notify = new Notification('芜湖助手', {
|
||||||
body: Log.getTime() + '\r\n' + tmpNode.innerText,
|
body: this.logger.getTime() + '\r\n' + tmpNode.innerText,
|
||||||
// requireInteraction: true,
|
// requireInteraction: true,
|
||||||
// renotify: true,
|
// renotify: true,
|
||||||
// tag: '芜湖助手' + Utils.getRandomInt(0, 99),
|
// tag: '芜湖助手' + Utils.getRandomInt(0, 99),
|
||||||
});
|
});
|
||||||
let id = notifies.count++;
|
// let id = notifies.count++;
|
||||||
notifies[id] = notify;
|
// notifies[id] = notify;
|
||||||
notify.addEventListener(
|
// notify.addEventListener(
|
||||||
'close',
|
// 'close',
|
||||||
() => {
|
// () => {
|
||||||
notifies[id] = null;
|
// notifies[id] = null;
|
||||||
}
|
// }
|
||||||
);
|
// );
|
||||||
notify.addEventListener(
|
notify.addEventListener(
|
||||||
'click',
|
'click',
|
||||||
() => {
|
() => {
|
||||||
@ -33,13 +43,13 @@ export default class NotificationUtils extends WuhuBase {
|
|||||||
window.focus();
|
window.focus();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
notify.addEventListener(
|
// notify.addEventListener(
|
||||||
'show',
|
// 'show',
|
||||||
() => {
|
// () => {
|
||||||
// setTimeout(() => notify.close(), (options.timeout || 3) * 1000);
|
// // setTimeout(() => notify.close(), (options.timeout || 3) * 1000);
|
||||||
Log.info('通知id: ', id)
|
// Log.info('通知id: ', id)
|
||||||
}
|
// }
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,12 +1,13 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import POPUP_HTML from "../../../static/html/popup.html";
|
import POPUP_HTML from "../../../static/html/popup.html";
|
||||||
import Log from "../Log";
|
import { Container } from "../../container/Container";
|
||||||
|
import Global from "../Global";
|
||||||
|
import Logger from "../Logger";
|
||||||
|
import globVars from "../../globVars";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 弹窗
|
* 弹窗
|
||||||
*/
|
*/
|
||||||
export default class Popup extends WuhuBase {
|
export default class Popup {
|
||||||
className = 'Popup';
|
|
||||||
private readonly container: HTMLElement = null;
|
private readonly container: HTMLElement = null;
|
||||||
private readonly node: HTMLElement = null;
|
private readonly node: HTMLElement = null;
|
||||||
private onClosing: () => unknown;
|
private onClosing: () => unknown;
|
||||||
@ -16,16 +17,23 @@ export default class Popup extends WuhuBase {
|
|||||||
* @param innerHTML
|
* @param innerHTML
|
||||||
* @param title
|
* @param title
|
||||||
* @param onClosing
|
* @param onClosing
|
||||||
|
* @param global
|
||||||
|
* @param logger
|
||||||
*/
|
*/
|
||||||
constructor(innerHTML: string, title: string = '芜湖助手', onClosing: () => unknown = () => {
|
constructor(
|
||||||
}) {
|
innerHTML: string,
|
||||||
super();
|
title: string = '芜湖助手',
|
||||||
|
onClosing: () => unknown = () => {
|
||||||
|
},
|
||||||
|
private readonly global: Global = Container.factory(Global),
|
||||||
|
private readonly logger: Logger = Container.factory(Logger),
|
||||||
|
) {
|
||||||
this.onClosing = onClosing;
|
this.onClosing = onClosing;
|
||||||
if (Popup.glob.popup_node) {
|
if (globVars.popup_node) {
|
||||||
Log.info('关闭前一个弹窗');
|
this.logger.info('关闭前一个弹窗');
|
||||||
Popup.glob.popup_node.close();
|
globVars.popup_node.close();
|
||||||
}
|
}
|
||||||
Log.info('新建弹窗', { innerHTML, title });
|
this.logger.info('新建弹窗', { innerHTML, title });
|
||||||
const popup = document.createElement('div');
|
const popup = document.createElement('div');
|
||||||
popup.id = 'wh-popup';
|
popup.id = 'wh-popup';
|
||||||
popup.innerHTML = POPUP_HTML.replace('{{}}', title).replace('{{}}', innerHTML);
|
popup.innerHTML = POPUP_HTML.replace('{{}}', title).replace('{{}}', innerHTML);
|
||||||
@ -37,7 +45,7 @@ export default class Popup extends WuhuBase {
|
|||||||
this.container = popup;
|
this.container = popup;
|
||||||
this.node = popup.querySelector('#wh-popup-cont');
|
this.node = popup.querySelector('#wh-popup-cont');
|
||||||
this.hideChat();
|
this.hideChat();
|
||||||
Popup.glob.popup_node = this;
|
globVars.popup_node = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public close() {
|
public close() {
|
||||||
@ -46,8 +54,14 @@ export default class Popup extends WuhuBase {
|
|||||||
this.showChat();
|
this.showChat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get element(): HTMLElement {
|
||||||
|
return this.node;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {HTMLElement} id=wh-popup-cont
|
* @return {HTMLElement} id=wh-popup-cont
|
||||||
|
* @deprecated
|
||||||
|
* 使用element替代
|
||||||
*/
|
*/
|
||||||
public getElement(): HTMLElement {
|
public getElement(): HTMLElement {
|
||||||
return this.node;
|
return this.node;
|
||||||
|
|||||||
14
src/ts/class/utils/PopupWrapper.ts
Normal file
14
src/ts/class/utils/PopupWrapper.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import Popup from "./Popup";
|
||||||
|
import { InjectionKey } from "vue";
|
||||||
|
|
||||||
|
@ClassName('PopupWrapper')
|
||||||
|
@Injectable()
|
||||||
|
export default class PopupWrapper {
|
||||||
|
public create(html: string, title: string, onClosing: () => unknown) {
|
||||||
|
return new Popup(html, title, onClosing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PopupWrapperKey = Symbol('PopupWrapperKey') as InjectionKey<PopupWrapper>;
|
||||||
16
src/ts/class/utils/TornPDAUtils.ts
Normal file
16
src/ts/class/utils/TornPDAUtils.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import ClassName from "../../container/ClassName";
|
||||||
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
|
||||||
|
@ClassName('TornPDAUtils')
|
||||||
|
@Injectable()
|
||||||
|
export default class TornPDAUtils {
|
||||||
|
private readonly _APIKey: string = '###PDA-APIKEY###';
|
||||||
|
|
||||||
|
public get APIKey(): string {
|
||||||
|
return this._APIKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public isPDA(): boolean {
|
||||||
|
return !this._APIKey.startsWith('#');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,12 +1,16 @@
|
|||||||
import Log from "../Log";
|
import Log from "../Log";
|
||||||
import MathUtils from "./MathUtils";
|
import MathUtils from "./MathUtils";
|
||||||
|
import { Container } from "../../container/Container";
|
||||||
|
|
||||||
export default class TornStyleBlock {
|
export default class TornStyleBlock {
|
||||||
private readonly baseElement: HTMLElement;
|
private readonly baseElement: HTMLElement;
|
||||||
private readonly headElement: HTMLElement;
|
private readonly headElement: HTMLElement;
|
||||||
private readonly elem: HTMLElement;
|
private readonly elem: HTMLElement;
|
||||||
|
|
||||||
public constructor(title: string) {
|
public constructor(
|
||||||
|
private readonly title: string,
|
||||||
|
private readonly mathUtils: MathUtils = Container.factory(MathUtils),
|
||||||
|
) {
|
||||||
this.baseElement = document.createElement('div');
|
this.baseElement = document.createElement('div');
|
||||||
this.headElement = document.createElement('div');
|
this.headElement = document.createElement('div');
|
||||||
this.elem = document.createElement('div');
|
this.elem = document.createElement('div');
|
||||||
@ -19,7 +23,7 @@ export default class TornStyleBlock {
|
|||||||
// hr.classList.add('delimiter-999', 'm-top10', 'm-bottom10');
|
// hr.classList.add('delimiter-999', 'm-top10', 'm-bottom10');
|
||||||
|
|
||||||
this.baseElement.append(this.headElement, this.elem);
|
this.baseElement.append(this.headElement, this.elem);
|
||||||
this.baseElement.id = 'WHTornStyleBlock' + MathUtils.getInstance().getRandomInt(0, 100);
|
this.baseElement.id = 'WHTornStyleBlock' + mathUtils.getRandomInt(0, 100);
|
||||||
this.baseElement.insertAdjacentHTML('beforeend', '<hr class="delimiter-999 m-top10 m-bottom10" />');
|
this.baseElement.insertAdjacentHTML('beforeend', '<hr class="delimiter-999 m-top10 m-bottom10" />');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,17 @@
|
|||||||
import MathUtils from "./MathUtils";
|
import MathUtils from "./MathUtils";
|
||||||
|
import { Container } from "../../container/Container";
|
||||||
|
|
||||||
export default class TornStyleSwitch {
|
export default class TornStyleSwitch {
|
||||||
private readonly baseElement;
|
private readonly baseElement;
|
||||||
private readonly randomId;
|
private readonly randomId;
|
||||||
private readonly input;
|
private readonly input;
|
||||||
|
|
||||||
constructor(label: string, checked: boolean = false) {
|
constructor(
|
||||||
this.randomId = MathUtils.getInstance().getRandomInt(100, 2000);
|
private readonly label: string,
|
||||||
|
private readonly checked: boolean = false,
|
||||||
|
private readonly mathUtils: MathUtils = Container.factory(MathUtils),
|
||||||
|
) {
|
||||||
|
this.randomId = mathUtils.getRandomInt(100, 2000);
|
||||||
this.baseElement = document.createElement('span');
|
this.baseElement = document.createElement('span');
|
||||||
this.baseElement.id = 'WHSwitch' + this.randomId;
|
this.baseElement.id = 'WHSwitch' + this.randomId;
|
||||||
this.baseElement.innerHTML = `<input class="checkbox-css" type="checkbox" id="WHCheck${ this.randomId }" ${ checked ? 'checked' : '' }/>
|
this.baseElement.innerHTML = `<input class="checkbox-css" type="checkbox" id="WHCheck${ this.randomId }" ${ checked ? 'checked' : '' }/>
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 收集数据上传
|
* 收集数据上传
|
||||||
*/
|
*/
|
||||||
export default class Uploader extends WuhuBase {
|
export default class Uploader {
|
||||||
className = "Uploader";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传数据
|
* 上传数据
|
||||||
@ -12,7 +9,8 @@ export default class Uploader extends WuhuBase {
|
|||||||
* @param uname 玩家昵称 可选
|
* @param uname 玩家昵称 可选
|
||||||
* @param meta_data 上传数据json格式
|
* @param meta_data 上传数据json格式
|
||||||
*/
|
*/
|
||||||
upload(uid:string, uname:string, meta_data:string) {}
|
upload(uid: string, uname: string, meta_data: string) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取服务端的数据
|
* 获取服务端的数据
|
||||||
|
|||||||
15
src/ts/container/ClassName.ts
Normal file
15
src/ts/container/ClassName.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
const CLASSNAME_METADATA_KEY = Symbol("CLASSNAME_KEY");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录类名,避免打包后丢失原类名
|
||||||
|
*/
|
||||||
|
export default function ClassName(className: string): ClassDecorator {
|
||||||
|
return function <TFunction extends Function>(target: TFunction): TFunction {
|
||||||
|
Reflect.defineMetadata(CLASSNAME_METADATA_KEY, className, target);
|
||||||
|
return target;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GetClassName(target: ClassType<{}>): string {
|
||||||
|
return Reflect.getMetadata(CLASSNAME_METADATA_KEY, target);
|
||||||
|
}
|
||||||
46
src/ts/container/Container.ts
Normal file
46
src/ts/container/Container.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import "reflect-metadata";
|
||||||
|
import { assertInjectable } from "./Injectable";
|
||||||
|
import ClassName, { GetClassName } from "./ClassName";
|
||||||
|
import Logger from "../class/Logger";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一个简单的类容器
|
||||||
|
*/
|
||||||
|
@ClassName('Container')
|
||||||
|
export class Container {
|
||||||
|
static _container = new Map();
|
||||||
|
private static logger;
|
||||||
|
|
||||||
|
static set<T>(k: Constructor<T>, v: T): void {
|
||||||
|
if (!this._container.has(k)) {
|
||||||
|
this._container.set(k, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get<T>(k: Constructor<T>): T {
|
||||||
|
return this._container.get(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
static factory<T>(target: ClassType<T>): T {
|
||||||
|
assertInjectable(target);
|
||||||
|
return this.get(target) || this.initParam(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
static setLogger(logger: Logger): void {
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static initParam<T>(target: Constructor<T>): T {
|
||||||
|
// 获取所有注入的服务
|
||||||
|
const providers = Reflect.getMetadata('design:paramtypes', target);
|
||||||
|
const args = providers ? providers.map((provider: Constructor) => {
|
||||||
|
return this.factory(provider);
|
||||||
|
}) : [];
|
||||||
|
let _target = new target(...args);
|
||||||
|
this.logger?.info(
|
||||||
|
`[${ GetClassName(target) || target.name }] 实例化`
|
||||||
|
);
|
||||||
|
this.set(target, _target);
|
||||||
|
return _target;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/ts/container/Injectable.ts
Normal file
23
src/ts/container/Injectable.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { GetClassName } from "./ClassName";
|
||||||
|
|
||||||
|
const INJECTABLE_METADATA_KEY = Symbol("INJECTABLE_KEY");
|
||||||
|
|
||||||
|
// TODO 实现非单例注入
|
||||||
|
export enum INJECT_MODE {
|
||||||
|
Singleton = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Injectable(injectMode: INJECT_MODE = INJECT_MODE.Singleton): ClassDecorator {
|
||||||
|
return function (target: any) {
|
||||||
|
Reflect.defineMetadata(INJECTABLE_METADATA_KEY, injectMode, target);
|
||||||
|
return target;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function assertInjectable(target: any) {
|
||||||
|
if (!Reflect.getMetadata(INJECTABLE_METADATA_KEY, target)) {
|
||||||
|
throw new TypeError(
|
||||||
|
`[${ GetClassName(target) || target.name }] not injectable`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
278
src/ts/feature/Atk.ts
Normal file
278
src/ts/feature/Atk.ts
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
import ClassName from "../container/ClassName"
|
||||||
|
import { Injectable } from "../container/Injectable"
|
||||||
|
import IFeature from "../man/IFeature"
|
||||||
|
import LocalConfigWrapper from "../class/LocalConfigWrapper"
|
||||||
|
import CommonUtils from "../class/utils/CommonUtils"
|
||||||
|
import Global from "../class/Global"
|
||||||
|
import ActionButtonUtils from "../class/utils/ActionButtonUtils"
|
||||||
|
import Logger from "../class/Logger"
|
||||||
|
import Alert from "../class/utils/Alert"
|
||||||
|
import Device from "../enum/Device"
|
||||||
|
import ATTACK_HELPER_CSS from "../../static/css/attack_helper.module.css"
|
||||||
|
import ATK_PAGE_REG from "./url/ATK_PAGE_REG";
|
||||||
|
|
||||||
|
enum FIGHT_STAGE {
|
||||||
|
READY = 'ready',
|
||||||
|
IN_PROGRESS_OR_ERROR = 'in_progress_or_error',
|
||||||
|
FINISHED = 'finished',
|
||||||
|
END = 'end',
|
||||||
|
OTHER = 'other'
|
||||||
|
}
|
||||||
|
|
||||||
|
@ClassName('Atk')
|
||||||
|
@Injectable()
|
||||||
|
export default class Atk implements IFeature {
|
||||||
|
|
||||||
|
private currentStage: FIGHT_STAGE = FIGHT_STAGE.OTHER;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly actionButtonUtils: ActionButtonUtils,
|
||||||
|
private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
|
private readonly commonUtils: CommonUtils,
|
||||||
|
private readonly global: Global,
|
||||||
|
// private readonly mathUtils: MathUtils,
|
||||||
|
// private readonly fetchUtils: FetchUtils,
|
||||||
|
private readonly logger: Logger,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
urlIncludes(): RegExp[] {
|
||||||
|
return [ATK_PAGE_REG]
|
||||||
|
}
|
||||||
|
|
||||||
|
urlExcludes(): RegExp[] {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
description(): string {
|
||||||
|
return '攻击助手'
|
||||||
|
}
|
||||||
|
|
||||||
|
iStart(): void | Promise<void> {
|
||||||
|
// 光速刷新按钮
|
||||||
|
this.actionButtonUtils.add('光速刷新', () => this.doAttackReload());
|
||||||
|
|
||||||
|
new MutationObserver((_, observer) => {
|
||||||
|
let btnList = document.querySelectorAll('div[class^="dialogButtons___"] button') as NodeListOf<HTMLButtonElement>;
|
||||||
|
|
||||||
|
if (btnList.length === 0) {
|
||||||
|
if (this.currentStage === FIGHT_STAGE.READY && this.localConfigWrapper.config.quickFinishAtt === 3) {
|
||||||
|
document.body.classList.remove('wh-move-btn');
|
||||||
|
this.logger.info('移除body class wh-move-btn');
|
||||||
|
observer.disconnect();
|
||||||
|
}
|
||||||
|
// 错误或正在打
|
||||||
|
this.currentStage = FIGHT_STAGE.IN_PROGRESS_OR_ERROR;
|
||||||
|
this.logger.info('[attackHelper] currentStage', this.currentStage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
btnList.forEach(btn => {
|
||||||
|
let btnText = btn.innerText.toLowerCase();
|
||||||
|
if (btnText.includes('start') || btnText.includes('join')) {
|
||||||
|
// 开始
|
||||||
|
this.quickStartFight();
|
||||||
|
} else if (btnText.includes('continue')) {
|
||||||
|
// 结束end
|
||||||
|
this.currentStage = FIGHT_STAGE.END;
|
||||||
|
observer.disconnect();
|
||||||
|
} else if (btnText.includes('leave')) {
|
||||||
|
// 无意识状态FINISHED
|
||||||
|
this.quickFinishFight(btnList);
|
||||||
|
}
|
||||||
|
this.logger.info('[attackHelper] currentStage', this.currentStage);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.observe(document.querySelector('#react-root'), { childList: true, subtree: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 战斗页面快速刷新
|
||||||
|
private doAttackReload(): void {
|
||||||
|
if (!window.ReactDOM) {
|
||||||
|
new Alert('光速刷新失败:未找到React对象');
|
||||||
|
this.logger.error('光速刷新失败:未找到React对象');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!document.querySelector('#react-root #attacker')) {
|
||||||
|
this.logger.error('dom元素未找到selector: [#react-root #attacker]');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let script = document.querySelector('script[src*="/builds/attack/"]');
|
||||||
|
let url = script.src;
|
||||||
|
if (!url.contains(/runtime\..+\.js/)) {
|
||||||
|
this.logger.error('脚本源[' + url + '] 不匹配规则');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.ReactDOM.unmountComponentAtNode(document.querySelector('#react-root'));
|
||||||
|
script.remove();
|
||||||
|
let node = document.createElement('script');
|
||||||
|
node.src = url;
|
||||||
|
node.type = 'text/javascript';
|
||||||
|
document.head.appendChild(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 光速拔刀
|
||||||
|
private quickStartFight(): void {
|
||||||
|
if (this.currentStage === FIGHT_STAGE.READY) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.currentStage = FIGHT_STAGE.READY;
|
||||||
|
}
|
||||||
|
if (this.localConfigWrapper.config.quickAttIndex === 6) return;
|
||||||
|
/**
|
||||||
|
* pc #defender
|
||||||
|
* mobile #attacker
|
||||||
|
*/
|
||||||
|
const btn = <HTMLInputElement>(document.querySelector('#attacker button') || document.querySelector('#defender button'));
|
||||||
|
this.logger.info('操作按钮', { btn });
|
||||||
|
if (!btn.innerText.toLowerCase().includes('fight')) {
|
||||||
|
this.logger.info('未找到攻击按钮, 光速拔刀跳过');
|
||||||
|
new Alert('未找到攻击按钮, 光速拔刀跳过');
|
||||||
|
} else {
|
||||||
|
// 判断是否存在脚踢
|
||||||
|
const hasKick = !!document.querySelector('#weapon_boots');
|
||||||
|
// modal层
|
||||||
|
// const modal: HTMLElement = document.querySelector('div[class^="modal___"]');
|
||||||
|
let device = this.global.device;
|
||||||
|
this.logger.info(`当前设备类型是${ device }`);
|
||||||
|
// 区分设备
|
||||||
|
switch (device) {
|
||||||
|
case Device.PC: {
|
||||||
|
this.logger.info(`开始调整按钮位置`);
|
||||||
|
// 隐藏modal层
|
||||||
|
// modal.style.display = 'none';
|
||||||
|
// 根据选择的武器调整css
|
||||||
|
let css_top = '0';
|
||||||
|
switch (this.localConfigWrapper.config.quickAttIndex) {
|
||||||
|
// weapon_second
|
||||||
|
case 1: {
|
||||||
|
css_top = '97px';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// weapon_melee
|
||||||
|
case 2: {
|
||||||
|
css_top = '194px';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// weapon_temp
|
||||||
|
case 3: {
|
||||||
|
css_top = '291px';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// weapon_fists
|
||||||
|
case 4:
|
||||||
|
// weapon_boots
|
||||||
|
case 5: {
|
||||||
|
css_top = '375px';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.commonUtils.styleInject(ATTACK_HELPER_CSS);
|
||||||
|
CommonUtils.addStyle(`.wh-move-btn #defender div[class^="modal___"]{top: ${ css_top };}`);
|
||||||
|
document.body.classList.add('wh-move-btn');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Device.MOBILE: {
|
||||||
|
this.logger.info(`开始调整按钮位置`);
|
||||||
|
// 加入css
|
||||||
|
let css_top = '0';
|
||||||
|
let slot_height = '76px';
|
||||||
|
// 判断有没有脚踢
|
||||||
|
if (hasKick) {
|
||||||
|
// 根据选择的武器调整
|
||||||
|
switch (this.localConfigWrapper.config.quickAttIndex) {
|
||||||
|
case 1: { // weapon_second
|
||||||
|
css_top = '76px';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: { // weapon_melee
|
||||||
|
css_top = '152px';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: { // weapon_temp
|
||||||
|
css_top = '228px';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4: { // weapon_fists
|
||||||
|
css_top = '304px';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5: { // weapon_boots
|
||||||
|
css_top = '380px';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const slot = document.querySelector('#weapon_main') as HTMLElement;
|
||||||
|
const height = slot.offsetHeight + 1;
|
||||||
|
// TODO 待验证
|
||||||
|
slot_height = height + 'px';
|
||||||
|
// 根据选择的武器调整
|
||||||
|
switch (this.localConfigWrapper.config.quickAttIndex) {
|
||||||
|
case 1: { // weapon_second
|
||||||
|
css_top = `${ height }px`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: { // weapon_melee
|
||||||
|
css_top = `${ height * 2 }px`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: { // weapon_temp
|
||||||
|
css_top = `${ height * 3 }px`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4: { // weapon_fists
|
||||||
|
css_top = `${ height * 4 }px`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5: { // weapon_boots
|
||||||
|
css_top = `${ height * 5 }px`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const css_rule = ATTACK_HELPER_CSS.replace('CSSVAR', css_top).replace('CSSVAR', slot_height);
|
||||||
|
|
||||||
|
this.commonUtils.styleInject(css_rule);
|
||||||
|
document.body.classList.toggle('wh-move-btn');
|
||||||
|
btn.onclick = () => {
|
||||||
|
if (this.localConfigWrapper.config.quickFinishAtt !== 3) {
|
||||||
|
btn.remove();
|
||||||
|
// 停止自动刷新
|
||||||
|
// stop_reload = true;
|
||||||
|
} else {
|
||||||
|
document.body.classList.toggle('wh-move-btn');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Device.TABLET: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 光速跑路
|
||||||
|
private quickFinishFight(btnList: NodeListOf<HTMLButtonElement>): void {
|
||||||
|
if (this.currentStage === FIGHT_STAGE.FINISHED) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.currentStage = FIGHT_STAGE.FINISHED;
|
||||||
|
}
|
||||||
|
if (this.localConfigWrapper.config.quickFinishAtt === 3) {
|
||||||
|
document.body.classList.remove('wh-move-btn');
|
||||||
|
this.logger.info('移除body class wh-move-btn');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const user_btn_select = ['leave', 'mug', 'hosp'][this.localConfigWrapper.config.quickFinishAtt];
|
||||||
|
// const wrap = document.querySelector('#react-root');
|
||||||
|
this.logger.info('光速跑路选项选中:', user_btn_select);
|
||||||
|
// const btn_arr: HTMLButtonElement[] = document.querySelectorAll('div[class^="dialogButtons___"] button') as unknown as HTMLButtonElement[];
|
||||||
|
if (btnList.length > 1) btnList.forEach(btn => {
|
||||||
|
const flag = btn.innerText.toLowerCase().includes(user_btn_select);
|
||||||
|
this.logger.info('按钮内容:', btn.innerText, ',是否包含选中:', flag);
|
||||||
|
if (!flag) btn.style.display = 'none';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
68
src/ts/feature/BeerShopModifier.ts
Normal file
68
src/ts/feature/BeerShopModifier.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import ClassName from "../container/ClassName"
|
||||||
|
import { Injectable } from "../container/Injectable"
|
||||||
|
import IFeature from "../man/IFeature"
|
||||||
|
import TornStyleBlock from "../class/utils/TornStyleBlock"
|
||||||
|
import ADD_BEER_HEAD_HTML from "../../static/html/buyBeer/add_beer_head.html"
|
||||||
|
import SHOP_BEER_STATIC_ITEM_HTML from "../../static/html/buyBeer/shop_beer_static_item.html"
|
||||||
|
import globVars from "../globVars"
|
||||||
|
import Logger from "../class/Logger";
|
||||||
|
import BuyBeerHelper from "./BuyBeerHelper";
|
||||||
|
|
||||||
|
@ClassName('BeerShopModifier')
|
||||||
|
@Injectable()
|
||||||
|
export default class BeerShopModifier implements IFeature {
|
||||||
|
private readonly logger = Logger.factory(BeerShopModifier)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly buyBeerHelper: BuyBeerHelper,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
description(): string {
|
||||||
|
return "啤酒店页面修改";
|
||||||
|
}
|
||||||
|
|
||||||
|
iStart(): void | Promise<void> {
|
||||||
|
this.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
urlExcludes(): RegExp[] {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
urlIncludes(): RegExp[] {
|
||||||
|
return [/shops.php\?step=bitsnbobs/];
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
let block = new TornStyleBlock('啤酒助手').insert2Dom();
|
||||||
|
block.setContent(ADD_BEER_HEAD_HTML);
|
||||||
|
const msg_node = block.querySelector('#wh-msg');
|
||||||
|
// 加入啤酒
|
||||||
|
block.querySelector('button').addEventListener('click', e => {
|
||||||
|
let node = document.querySelector('ul.items-list');
|
||||||
|
if (!node) {
|
||||||
|
msg_node.innerHTML = '❌ 商品未加载完';
|
||||||
|
this.logger.error('商品未加载完');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (node.querySelector('span[id="180-name"]')) {
|
||||||
|
msg_node.innerHTML = '❌ 页面已经有啤酒了';
|
||||||
|
this.logger.warn('商店页面已有啤酒');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const clear_node = node.querySelector('li.clear');
|
||||||
|
const beer = document.createElement('li');
|
||||||
|
beer.classList.add('torn-divider', 'divider-vertical');
|
||||||
|
beer.style.backgroundColor = '#c8c8c8';
|
||||||
|
beer.innerHTML = SHOP_BEER_STATIC_ITEM_HTML;
|
||||||
|
if (clear_node) clear_node.before(beer);
|
||||||
|
else node.append(beer);
|
||||||
|
(<HTMLInputElement>e.target).disabled = true;
|
||||||
|
msg_node.innerHTML = '添加成功';
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听啤酒购买
|
||||||
|
globVars.responseHandlers.push((...args: any[]) => this.buyBeerHelper.responseHandler.apply(this.buyBeerHelper, args));
|
||||||
|
}
|
||||||
|
}
|
||||||
186
src/ts/feature/BuyBeerHelper.ts
Normal file
186
src/ts/feature/BuyBeerHelper.ts
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
import InfoUtils from "../class/utils/InfoUtils";
|
||||||
|
import MathUtils from "../class/utils/MathUtils";
|
||||||
|
import NOTIFY_HTML from "../../static/html/buyBeer/notify.html";
|
||||||
|
import CommonUtils from "../class/utils/CommonUtils";
|
||||||
|
import Popup from "../class/utils/Popup";
|
||||||
|
import ResponseInject from "../interface/ResponseInject";
|
||||||
|
import LocalConfigWrapper from "../class/LocalConfigWrapper";
|
||||||
|
import ClassName from "../container/ClassName";
|
||||||
|
import { Injectable } from "../container/Injectable";
|
||||||
|
import Logger from "../class/Logger";
|
||||||
|
import MsgWrapper from "../class/utils/MsgWrapper";
|
||||||
|
import IFeature from "../man/IFeature";
|
||||||
|
import ATK_PAGE_REG from "./url/ATK_PAGE_REG";
|
||||||
|
import ALL_PAGE_REG from "./url/ALL_PAGE_REG";
|
||||||
|
|
||||||
|
@ClassName('BuyBeerHelper')
|
||||||
|
@Injectable()
|
||||||
|
export default class BuyBeerHelper implements BeerMonitorLoop, ResponseInject, IFeature {
|
||||||
|
|
||||||
|
urlIncludes(): RegExp[] {
|
||||||
|
return [ALL_PAGE_REG]
|
||||||
|
}
|
||||||
|
|
||||||
|
urlExcludes(): RegExp[] {
|
||||||
|
return [ATK_PAGE_REG]
|
||||||
|
}
|
||||||
|
|
||||||
|
description(): string {
|
||||||
|
return '啤酒助手'
|
||||||
|
}
|
||||||
|
|
||||||
|
iStart(): void | Promise<void> {
|
||||||
|
(this.localConfigWrapper.config._15Alarm) && this.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private isNotifying = false;
|
||||||
|
private loopId: number = null;
|
||||||
|
private time: number;
|
||||||
|
private readonly notifyHtml: string = NOTIFY_HTML.replace('{{}}', this.mathUtils.getRandomInt(0, 99).toString());
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
private readonly localConfigWrapper: LocalConfigWrapper,
|
||||||
|
private readonly commonUtils: CommonUtils,
|
||||||
|
private readonly infoUtils: InfoUtils,
|
||||||
|
private readonly mathUtils: MathUtils,
|
||||||
|
private readonly logger: Logger,
|
||||||
|
private readonly msgWrapper: MsgWrapper,
|
||||||
|
) {
|
||||||
|
this.time = this.localConfigWrapper.config._15AlarmTime || 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
public start(): void {
|
||||||
|
if (this.loopId) {
|
||||||
|
this.logger.info('啤酒助手已在运行');
|
||||||
|
} else {
|
||||||
|
this.logger.info('啤酒助手启动');
|
||||||
|
this.loopId = window.setInterval(async () => {
|
||||||
|
// 海外取消提醒
|
||||||
|
let { isTravelling, isAbroad } = await this.infoUtils.getUserState();
|
||||||
|
if (isTravelling || isAbroad) {
|
||||||
|
this.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let dt = new Date();
|
||||||
|
// 已选当天不提醒
|
||||||
|
const now = [dt.getUTCFullYear(), dt.getUTCMonth(), dt.getUTCDate()];
|
||||||
|
const ignore_date = this.localConfigWrapper.config._15_alarm_ignore || '{}';
|
||||||
|
if (JSON.stringify(now) === JSON.stringify(ignore_date)) return;
|
||||||
|
// 正常提醒
|
||||||
|
let m = 14 - (dt.getMinutes() % 15);
|
||||||
|
let s = 60 - dt.getSeconds();
|
||||||
|
if (m === 0 && s < this.time) {
|
||||||
|
// 如从通知点开,则本次通知跳过
|
||||||
|
if (location.href.includes('clickfromnotify')) {
|
||||||
|
this.isNotifying = true;
|
||||||
|
location.hash = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 本次已通知
|
||||||
|
if (this.isNotifying) return;
|
||||||
|
this.isNotifying = true;
|
||||||
|
// 发送通知
|
||||||
|
const rNum = this.mathUtils.getRandomInt(0, 99);
|
||||||
|
// const notify =
|
||||||
|
this.msgWrapper.create(NOTIFY_HTML.replace('{{}}', rNum.toString()), {
|
||||||
|
timeout: 30,
|
||||||
|
sysNotify: true,
|
||||||
|
});
|
||||||
|
document.querySelector('button#wh-rd-btn-' + rNum).addEventListener('click', () => this.skip_today());
|
||||||
|
// notify.getElement().addEventListener('click', ev => {
|
||||||
|
// if ((ev.target as HTMLElement).tagName.toLowerCase() === 'a') {
|
||||||
|
// notify.close();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// 声音提醒
|
||||||
|
{
|
||||||
|
let loop = 3;
|
||||||
|
let id = window.setInterval(async () => {
|
||||||
|
await this.commonUtils.audioPlay();
|
||||||
|
loop--;
|
||||||
|
if (!loop) window.clearInterval(id);
|
||||||
|
}, 800);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.isNotifying = false;
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public stop(): void {
|
||||||
|
if (this.loopId) {
|
||||||
|
window.clearInterval(this.loopId);
|
||||||
|
this.loopId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public set_time(t: number): void {
|
||||||
|
this.time = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public status(): '已启动' | '未启动' {
|
||||||
|
return this.loopId ? '已启动' : '未启动';
|
||||||
|
}
|
||||||
|
|
||||||
|
public is_running(): boolean {
|
||||||
|
return this.loopId !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public skip_today(): void {
|
||||||
|
const date = new Date();
|
||||||
|
this.localConfigWrapper.config._15_alarm_ignore = [date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()];
|
||||||
|
// WuhuConfig.set('_15_alarm_ignore', [date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()], false);
|
||||||
|
// 通知
|
||||||
|
const rNumber = this.mathUtils.getRandomInt(0, 100);
|
||||||
|
const notify = this.msgWrapper.create(`明早8点前将不再提醒 <button id="wh-rd-btn-${ rNumber }">取消</button>`);
|
||||||
|
// 通知中的取消按钮
|
||||||
|
document.querySelector('#wh-rd-btn-' + rNumber)
|
||||||
|
.addEventListener(
|
||||||
|
'click',
|
||||||
|
() => this.localConfigWrapper.config._15_alarm_ignore.length = 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setTimeHandler(): void {
|
||||||
|
let popup = new Popup(`<label>提前提醒时间(秒):<input type="number" value="${ this.localConfigWrapper.config._15AlarmTime }" /></label><p>区间为 1 ~ 60,默认 50</p>`, '啤酒提醒时间设定');
|
||||||
|
let confirm = document.createElement('button');
|
||||||
|
confirm.innerHTML = '确定';
|
||||||
|
confirm.style.float = 'right';
|
||||||
|
confirm.addEventListener('click', () => {
|
||||||
|
let input: HTMLInputElement = popup.element.querySelector('input');
|
||||||
|
let num = (input.value as any) | 0;
|
||||||
|
if (num === this.localConfigWrapper.config._15AlarmTime) return;
|
||||||
|
if (num < 1 || num > 60) num = 50;
|
||||||
|
input.value = num.toString();
|
||||||
|
this.localConfigWrapper.config._15AlarmTime = num;
|
||||||
|
this.set_time(num);
|
||||||
|
// 之前的运行状态
|
||||||
|
if (this.is_running()) this.start();
|
||||||
|
popup.close();
|
||||||
|
});
|
||||||
|
popup.element.appendChild(confirm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public responseHandler(url: string, body: { json: unknown; text: string; isModified: boolean }, opt: {
|
||||||
|
method: "GET" | "POST";
|
||||||
|
requestBody: string
|
||||||
|
}) {
|
||||||
|
if (url.includes('shops.php') && opt?.method === 'POST') {
|
||||||
|
let req = opt.requestBody;
|
||||||
|
if (req && req.includes('step=buyShopItem') && req.includes('ID=180') && body.json && body.json['success']) {
|
||||||
|
this.msgWrapper.create('检测到已成功购买啤酒');
|
||||||
|
this.skip_today();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BeerMonitorLoop {
|
||||||
|
start?: Function;
|
||||||
|
stop?: Function;
|
||||||
|
set_time?: Function;
|
||||||
|
status?: Function;
|
||||||
|
is_running?: Function;
|
||||||
|
skip_today?: Function;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user