更新
This commit is contained in:
parent
6a0d0e064a
commit
1e151060f3
@ -4,6 +4,14 @@
|
||||
|
||||
# CHANGE
|
||||
|
||||
## 0.8.0
|
||||
|
||||
2023年01月16日
|
||||
|
||||
### 修改
|
||||
|
||||
- 完善新的翻译部分
|
||||
|
||||
## 0.7.9
|
||||
|
||||
2023年01月09日
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wuhu-torn-helper",
|
||||
"version": "0.7.9",
|
||||
"version": "0.8.0",
|
||||
"description": "芜湖助手",
|
||||
"dependencies": {},
|
||||
"scripts": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -11,6 +11,9 @@ import Log from "./Log";
|
||||
import FetchUtils from "./utils/FetchUtils";
|
||||
import ZhongIcon from "./ZhongIcon";
|
||||
import Alert from "./utils/Alert";
|
||||
import FetchEventCallback from "./action/FetchEventCallback";
|
||||
import globVars from "../globVars";
|
||||
import Translate from "./action/Translate";
|
||||
|
||||
/**
|
||||
* 脚本不区分页面的通用功能入口
|
||||
@ -62,6 +65,11 @@ export class Common extends WuhuBase {
|
||||
});
|
||||
}
|
||||
|
||||
// fetch方法处理
|
||||
FetchEventCallback.getInstance();
|
||||
// fetch方法处理-翻译
|
||||
globVars.responseHandlers.push(Translate.responseHandler);
|
||||
|
||||
// 存钱相关
|
||||
depoHelper();
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ import ProfileHelper from "./action/ProfileHelper";
|
||||
import SearchHelper from "./action/SearchHelper";
|
||||
import TornStyleSwitch from "./utils/TornStyleSwitch";
|
||||
import SlotsHelper from "./action/SlotsHelper";
|
||||
import globVars from "../globVars";
|
||||
|
||||
/**
|
||||
* 脚本区分页面的功能入口
|
||||
@ -97,15 +98,16 @@ export default class UrlPattern extends WuhuBase {
|
||||
});
|
||||
|
||||
// 监听啤酒购买
|
||||
$(document).ajaxComplete((_, xhr, settings) => {
|
||||
Log.info({ xhr, settings });
|
||||
let { data } = settings, { responseText } = xhr;
|
||||
let response = JSON.parse(responseText);
|
||||
if (data.includes('step=buyShopItem') && data.includes('ID=180') && response['success']) {
|
||||
new Alert('已检测成功购买啤酒');
|
||||
let buyBeerResultMonitor = (url, body, opt) => {
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
globVars.responseHandlers.push(buyBeerResultMonitor);
|
||||
}
|
||||
|
||||
// 快速crime TODO 重构、与翻译解藕
|
||||
|
||||
@ -43,6 +43,7 @@ export default class WuhuConfig extends WuhuBase {
|
||||
[
|
||||
// 开启翻译
|
||||
{ key: 'transEnable', val: false },
|
||||
{ key: 'transNew', val: true },
|
||||
// 快速犯罪
|
||||
{ key: 'quickCrime', val: true },
|
||||
// 任务助手
|
||||
|
||||
@ -4,10 +4,7 @@ import TravelItem from "./action/TravelItem";
|
||||
import Global from "./Global";
|
||||
import Log from "./Log";
|
||||
import COMMON_CSS from "../static/css/common.css";
|
||||
import Timer from "./utils/Timer";
|
||||
import Translate from "./action/Translate";
|
||||
import globVars from "../globVars";
|
||||
import FetchEventCallback from "./action/FetchEventCallback";
|
||||
|
||||
/**
|
||||
* 脚本入口
|
||||
@ -45,15 +42,49 @@ export default class WuHuTornHelper extends WuhuBase {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
let ori_fetch = fetch || window.fetch;
|
||||
(function (fetch0, window) {
|
||||
let originFetch = fetch0;
|
||||
// 引用解决与其他脚本接管fetch方法引起的兼容性问题
|
||||
if (Global.getInstance().unsafeWindow) {
|
||||
ori_fetch = Global.getInstance().unsafeWindow.fetch;
|
||||
originFetch = Global.getInstance().unsafeWindow.fetch;
|
||||
}
|
||||
let fetchHandle: (string, RequestInit) => Promise<Response> = (url: string, init: RequestInit) => {
|
||||
let startTime = new Timer();
|
||||
Log.info({ info: 'fetching', init, url });
|
||||
if (!init) init = { method: 'GET' };
|
||||
return new Promise(resolve => {
|
||||
if (url.includes('newsTickers')) {
|
||||
Log.info('阻止获取新闻横幅');
|
||||
@ -65,33 +96,53 @@ export default class WuHuTornHelper extends WuhuBase {
|
||||
resolve(new Response('{}', init));
|
||||
return;
|
||||
}
|
||||
ori_fetch(url, init)
|
||||
originFetch(url, init)
|
||||
.then(res => {
|
||||
let clone = res.clone();
|
||||
clone.text().then(text => {
|
||||
let jsonObj = {};
|
||||
try {
|
||||
jsonObj = JSON.parse(text);
|
||||
} catch {
|
||||
}
|
||||
globVars.WH_FETCH_LOG.push({ body: Object.keys(jsonObj).length ? jsonObj : text, url });
|
||||
Log.info({
|
||||
info: 'fetch响应,耗时' + startTime.getTimeMs(),
|
||||
response: { text, res, jsonObj }
|
||||
});
|
||||
let localized = Translate.responseHandler(text, url);
|
||||
FetchEventCallback.getInstance().handler(text, url);
|
||||
resolve(new Response(localized ? JSON.stringify(localized) : text, init));
|
||||
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));
|
||||
})
|
||||
};
|
||||
if (Global.getInstance().unsafeWindow) {
|
||||
Global.getInstance().unsafeWindow.fetch = fetchHandle;
|
||||
}
|
||||
|
||||
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()));
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import WuhuBase from "../WuhuBase";
|
||||
import { MiniProfile } from "../../interface/responseType/MiniProfile";
|
||||
import CommonUtils from "../utils/CommonUtils";
|
||||
import globVars from "../../globVars";
|
||||
|
||||
/**
|
||||
* fetch 事件监听回调
|
||||
@ -10,24 +11,26 @@ export default class FetchEventCallback extends WuhuBase {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
globVars.responseHandlers.push((url, response) => this.handler(response, url))
|
||||
}
|
||||
|
||||
public handler(response: string, url: string): void {
|
||||
window.setTimeout(async () => {
|
||||
/**
|
||||
* fetch 返回后处理
|
||||
* @param response
|
||||
* @param url
|
||||
*/
|
||||
public handler(response, url: string) {
|
||||
// mini profile 中添加上次动作
|
||||
if (url.includes('profiles.php?step=getUserNameContextMenu')) {
|
||||
window.setTimeout(async () => {
|
||||
let cont = await CommonUtils.querySelector('[class*=profile-mini-_userProfileWrapper___]');
|
||||
let resp: MiniProfile = null;
|
||||
try {
|
||||
resp = JSON.parse(response);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
let resp: MiniProfile = response.json as MiniProfile;
|
||||
let newNode = document.createElement('div');
|
||||
let formatted = CommonUtils.getInstance().secondsFormat(resp.user.lastAction.seconds);
|
||||
|
||||
newNode.innerText = '上次动作: ' + formatted;
|
||||
cont.append(newNode);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,9 @@ import TornStyleBlock from "../utils/TornStyleBlock";
|
||||
import Timer from "../utils/Timer";
|
||||
import FetchUtils from "../utils/FetchUtils";
|
||||
|
||||
/**
|
||||
* 彩票助手
|
||||
*/
|
||||
export default class LotteryHelper extends WuhuBase {
|
||||
className = 'LotteryHelper';
|
||||
private loopFlag = true;
|
||||
|
||||
@ -7,7 +7,7 @@ import CommonUtils from "../utils/CommonUtils";
|
||||
import MathUtils from "../utils/MathUtils";
|
||||
|
||||
/**
|
||||
* 老虎机批量购买
|
||||
* 老虎机批量购买助手
|
||||
*/
|
||||
export default class SlotsHelper extends WuhuBase {
|
||||
className = "SlotsHelper";
|
||||
|
||||
@ -3,6 +3,8 @@ import { chatDict, eventsDict, headerDict, propertyDict, sidebarDict } from "../
|
||||
import Log from "../Log";
|
||||
import Timer from "../utils/Timer";
|
||||
import { Button, MiniProfile } from "../../interface/responseType/MiniProfile";
|
||||
import WuhuConfig from "../WuhuConfig";
|
||||
import Sidebar from "../../interface/responseType/Sidebar";
|
||||
|
||||
export default class Translate extends WuhuBase {
|
||||
className = 'Translate';
|
||||
@ -292,13 +294,13 @@ export default class Translate extends WuhuBase {
|
||||
}).observe(document.body, opt);
|
||||
}
|
||||
|
||||
public static responseHandler(body: string, url: string): unknown {
|
||||
let ret: unknown = null;
|
||||
try {
|
||||
// Mini Profile
|
||||
if (url.includes('profiles.php?step=getUserNameContextMenu')) {
|
||||
let jsonObj: MiniProfile = JSON.parse(body);
|
||||
Log.info('翻译mini profile返回内容');
|
||||
/**
|
||||
* fetch xhr 返回数据的翻译处理
|
||||
* @param url
|
||||
* @param body
|
||||
*/
|
||||
public static responseHandler(url: string, body: { json: unknown, text: string, isModified: boolean }): void {
|
||||
if (!WuhuConfig.get('transNew')) return;
|
||||
// TODO 字典抽取
|
||||
let map = {
|
||||
iconMap: {
|
||||
@ -373,6 +375,21 @@ export default class Translate extends WuhuBase {
|
||||
]
|
||||
}
|
||||
},
|
||||
'Job': {
|
||||
title: "系统公司",
|
||||
description: {
|
||||
replace: [/([a-zA-Z ]+) (in|at) (.+)$/, "$3的$1"],
|
||||
attachedMap: [
|
||||
{
|
||||
'Manager': '经理',
|
||||
},
|
||||
{},
|
||||
{
|
||||
'a Grocery Store': '杂货店',
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
'Faction': {
|
||||
title: "帮派",
|
||||
description: { replace: [/([aA-zZ ]+)( of )(.+)/, "[$3] 帮派的 [$1]"] }
|
||||
@ -413,6 +430,8 @@ export default class Translate extends WuhuBase {
|
||||
"NPC's cannot be bountied": 'NPC 不能被悬赏',
|
||||
"$0 is hiding out abroad": '$0 正在海外躲藏',
|
||||
"$0 has no items in their display cabinet": '$0 的展柜是空的',
|
||||
"You do not have enough energy to attack $0": '你没有足够的能量攻击 $0',
|
||||
"You have not met this person recently or they have blocked you": '最近你没有遇见此人,或已被屏蔽',
|
||||
},
|
||||
},
|
||||
destinationMap: {
|
||||
@ -427,8 +446,46 @@ export default class Translate extends WuhuBase {
|
||||
'China': '中国',
|
||||
'UAE': '阿联酋(UAE)',
|
||||
'South Africa': '南非',
|
||||
},
|
||||
barMap: {
|
||||
'Chain': { name: '连击' },
|
||||
'Energy': { name: '能量' },
|
||||
'Happy': { name: '快乐' },
|
||||
'Life': { name: '血量' },
|
||||
'Nerve': { name: '犯罪' },
|
||||
},
|
||||
areaMap: {
|
||||
calendar: { name: '日历', shortName: '日历' },
|
||||
traveling: { name: '飞行中', shortName: '飞行' },
|
||||
casino: { name: '赌场' },
|
||||
city: { name: '城市' },
|
||||
crimes: { name: '犯罪' },
|
||||
education: { name: '教育', shortName: '教育' },
|
||||
forums: { name: '论坛' },
|
||||
gym: { name: '健身房' },
|
||||
hall_of_fame: { name: '名人堂', shortName: '排名' },
|
||||
home: { name: '主页', shortName: '主页' },
|
||||
hospital: { name: '医院' },
|
||||
items: { name: '物品' },
|
||||
jail: { name: '监狱' },
|
||||
job: { name: '工作', shortName: '工作' },
|
||||
missions: { name: '任务' },
|
||||
my_faction: { name: '帮派', shortName: '帮派' },
|
||||
newspaper: { name: '报纸', shortName: '报纸' },
|
||||
properties: { name: '住宅', shortName: '住宅' },
|
||||
recruit_citizens: { name: '招募玩家', shortName: '招募' },
|
||||
},
|
||||
accountMap: {
|
||||
awards: { name: '奖章' },
|
||||
events: { name: '通知' },
|
||||
messages: { name: '邮件' }
|
||||
}
|
||||
};
|
||||
try {
|
||||
// Mini Profile
|
||||
if (url.includes('profiles.php?step=getUserNameContextMenu')) {
|
||||
let jsonObj: MiniProfile = body.json as MiniProfile;
|
||||
Log.info('翻译mini profile返回内容');
|
||||
// 状态图标
|
||||
jsonObj.icons.forEach(icon => {
|
||||
let iconMap = map.iconMap;
|
||||
@ -502,15 +559,31 @@ export default class Translate extends WuhuBase {
|
||||
break;
|
||||
}
|
||||
}
|
||||
body.isModified = true;
|
||||
|
||||
Log.info({ 'localized': jsonObj });
|
||||
|
||||
ret = jsonObj;
|
||||
}
|
||||
// TODO 边栏
|
||||
else if (url.includes('sidebarAjaxAction.php?q=sync')) {
|
||||
let response = body.json as Sidebar;
|
||||
|
||||
type target = { [k: string]: { name: string, shortName?: string } };
|
||||
let nameMapReplace = (target: target, _map: target) => {
|
||||
Object.keys(target).forEach(key => {
|
||||
if (target[key] && _map[key]) {
|
||||
target[key].name = _map[key].name;
|
||||
if (target[key].shortName && _map[key].shortName) {
|
||||
target[key].shortName = _map[key].shortName;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
nameMapReplace(response.areas, map.areaMap);
|
||||
nameMapReplace(response.account, map.accountMap);
|
||||
body.isModified = true;
|
||||
}
|
||||
} catch (e) {
|
||||
Log.error('responseHandler', e.stack || e.message);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,6 +89,13 @@ export default class SettingsHandler extends WuhuBase {
|
||||
dictName: 'transEnable',
|
||||
isHide: true,
|
||||
});
|
||||
list.push({
|
||||
domType: 'checkbox',
|
||||
domId: '',
|
||||
domText: ' 新翻译',
|
||||
dictName: 'transNew',
|
||||
tip: '改进后的翻译,更好的性能',
|
||||
});
|
||||
// 更新翻译词库
|
||||
list.push({
|
||||
domType: 'button',
|
||||
|
||||
@ -362,6 +362,12 @@ export default class CommonUtils extends WuhuBase {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 把秒数字格式化为
|
||||
*
|
||||
* `日 时 分 秒`
|
||||
* @param s
|
||||
*/
|
||||
public secondsFormat(s: number): string {
|
||||
let gap = '日 时 分 秒'.split(' ');
|
||||
let last = s;
|
||||
|
||||
@ -1,5 +1,15 @@
|
||||
/**
|
||||
* 通用全局参数
|
||||
*/
|
||||
export default {
|
||||
// 监听到的fetch数据
|
||||
WH_FETCH_LOG: [] as { body: unknown | string, url: string }[],
|
||||
map: {} as { [key: string]: unknown },
|
||||
};
|
||||
WH_NET_LOG: [],
|
||||
map: {},
|
||||
responseHandlers: [],
|
||||
} as IGlobVars;
|
||||
|
||||
interface IGlobVars {
|
||||
WH_NET_LOG: unknown[],
|
||||
map: { [key: string]: unknown },
|
||||
responseHandlers: ((url: string, responseBody: { json: unknown, text: string, isModified: boolean }, opt: { method: string, requestBody: unknown }) => void)[],
|
||||
}
|
||||
|
||||
43
src/ts/interface/responseType/Sidebar.ts
Normal file
43
src/ts/interface/responseType/Sidebar.ts
Normal file
@ -0,0 +1,43 @@
|
||||
export default interface Sidebar {
|
||||
account: {
|
||||
awards: Area,
|
||||
events: Area,
|
||||
messages: Area,
|
||||
},
|
||||
areas: {
|
||||
calendar: Area,
|
||||
casino: Area,
|
||||
city: Area,
|
||||
crimes: Area,
|
||||
education: Area,
|
||||
forums: Area,
|
||||
gym: Area,
|
||||
hall_of_fame: Area,
|
||||
home: Area,
|
||||
hospital: Area,
|
||||
items: Area,
|
||||
jail: Area,
|
||||
job: Area,
|
||||
missions: Area,
|
||||
my_faction: Area,
|
||||
newspaper: Area,
|
||||
properties: Area,
|
||||
recruit_citizens: Area,
|
||||
},
|
||||
bars: {
|
||||
chain: Bar,
|
||||
energy: Bar,
|
||||
happy: Bar,
|
||||
life: Bar,
|
||||
nerve: Bar,
|
||||
},
|
||||
}
|
||||
|
||||
interface Bar {
|
||||
name: string
|
||||
}
|
||||
|
||||
interface Area {
|
||||
name: string,
|
||||
shortName?: string,
|
||||
}
|
||||
@ -11,7 +11,7 @@ export default class Test extends WuhuBase {
|
||||
public test(): void {
|
||||
let popup = new Popup(CommonUtils.getInstance().getTravelStage().toString());
|
||||
popup.getElement()['__POOL__'] = Test.getPool();
|
||||
Log.info({ WH_FETCH_LOG: globVars.WH_FETCH_LOG });
|
||||
Log.info({ NET: globVars.WH_NET_LOG });
|
||||
|
||||
// this.case1()
|
||||
// this.case2()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user