更新
This commit is contained in:
parent
7e52b9c382
commit
ee8b660539
4338
package-lock.json
generated
4338
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -2,13 +2,13 @@
|
|||||||
"name": "wuhu-torn-helper",
|
"name": "wuhu-torn-helper",
|
||||||
"version": "0.8.2",
|
"version": "0.8.2",
|
||||||
"description": "芜湖助手",
|
"description": "芜湖助手",
|
||||||
"dependencies": {},
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"release": "rollup -c rollup-prod.config.js && node build.js",
|
"release": "rollup -c rollup-prod.config.js && node build.js",
|
||||||
"watch": "rollup -c -w"
|
"watch": "rollup -c -w"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-json": "^4.1.0",
|
"@rollup/plugin-json": "^4.1.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": "^18.0.6",
|
||||||
@ -16,10 +16,8 @@
|
|||||||
"rollup": "^2.79.0",
|
"rollup": "^2.79.0",
|
||||||
"rollup-plugin-html-literals": "^1.1.5",
|
"rollup-plugin-html-literals": "^1.1.5",
|
||||||
"rollup-plugin-serve": "^2.0.1",
|
"rollup-plugin-serve": "^2.0.1",
|
||||||
"rollup-plugin-string": "^3.0.0",
|
"rollup-plugin-string-html": "^1.0.0",
|
||||||
"rollup-plugin-uglify": "^6.0.4",
|
|
||||||
"tslib": "^2.4.0",
|
"tslib": "^2.4.0",
|
||||||
"typescript": "^4.8.3",
|
"typescript": "^4.8.3"
|
||||||
"uglify-js": "^3.16.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,5 @@
|
|||||||
import typescript from "@rollup/plugin-typescript";
|
import terser from "@rollup/plugin-terser";
|
||||||
import json from "@rollup/plugin-json";
|
import devConfig from "./rollup.config";
|
||||||
import { string } from "rollup-plugin-string";
|
|
||||||
import { uglify } from "rollup-plugin-uglify";
|
|
||||||
|
|
||||||
export default {
|
devConfig.plugins.push(terser());
|
||||||
input: 'src/ts/index.ts',
|
export default devConfig;
|
||||||
output: {
|
|
||||||
file: 'dist/bundle.min.js',
|
|
||||||
format: 'iife',
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
typescript(),
|
|
||||||
json(),
|
|
||||||
string({
|
|
||||||
include: ["**/*.html", "**/*.css"]
|
|
||||||
}),
|
|
||||||
uglify(),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import typescript from "@rollup/plugin-typescript";
|
import typescript from "@rollup/plugin-typescript";
|
||||||
import json from "@rollup/plugin-json";
|
import json from "@rollup/plugin-json";
|
||||||
// import template from "rollup-plugin-html-literals";
|
import html from "rollup-plugin-string-html";
|
||||||
import { string } from "rollup-plugin-string";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
input: 'src/ts/index.ts',
|
input: 'src/ts/index.ts',
|
||||||
@ -10,15 +9,22 @@ export default {
|
|||||||
format: 'iife',
|
format: 'iife',
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
// template({
|
|
||||||
// include: '*.html',
|
|
||||||
// failOnError: true
|
|
||||||
// }),
|
|
||||||
typescript(),
|
typescript(),
|
||||||
json(),
|
json(),
|
||||||
string({
|
html({
|
||||||
include: ["**/*.html", "**/*.css"]
|
include: ["**/*.html", "**/*.css"],
|
||||||
|
minifier: {
|
||||||
|
includeAutoGeneratedTags: true,
|
||||||
|
removeAttributeQuotes: true,
|
||||||
|
removeComments: true,
|
||||||
|
removeRedundantAttributes: true,
|
||||||
|
removeScriptTypeAttributes: true,
|
||||||
|
removeStyleLinkTypeAttributes: true,
|
||||||
|
sortClassName: true,
|
||||||
|
useShortDoctype: true,
|
||||||
|
collapseWhitespace: true,
|
||||||
|
minifyCSS: true,
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
// uglify(),
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import ZhongIcon from "./ZhongIcon";
|
|||||||
import Alert from "./utils/Alert";
|
import Alert from "./utils/Alert";
|
||||||
import FetchEventCallback from "./action/FetchEventCallback";
|
import FetchEventCallback from "./action/FetchEventCallback";
|
||||||
import globVars from "../globVars";
|
import globVars from "../globVars";
|
||||||
import Translate from "./action/Translate";
|
import TranslateNew from "./action/TranslateNew";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 脚本不区分页面的通用功能入口
|
* 脚本不区分页面的通用功能入口
|
||||||
@ -66,9 +66,9 @@ export class Common extends WuhuBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fetch方法处理
|
// fetch方法处理
|
||||||
FetchEventCallback.getInstance();
|
globVars.responseHandlers.push(FetchEventCallback.getInstance().responseHandler);
|
||||||
// fetch方法处理-翻译
|
// fetch方法处理-翻译
|
||||||
globVars.responseHandlers.push(Translate.responseHandler);
|
globVars.responseHandlers.push(TranslateNew.getInstance().responseHandler);
|
||||||
|
|
||||||
// 存钱相关
|
// 存钱相关
|
||||||
depoHelper();
|
depoHelper();
|
||||||
|
|||||||
@ -4,28 +4,25 @@ export default class Log {
|
|||||||
|
|
||||||
public static info(...o): void {
|
public static info(...o): void {
|
||||||
Log.counter.info++;
|
Log.counter.info++;
|
||||||
let time = this.getTime();
|
let flag = '%c WH %cIFO%c' + this.getTime() + '%c';
|
||||||
let flag = '[WH] IFO';
|
|
||||||
if (this.debug()) {
|
if (this.debug()) {
|
||||||
console.log(flag, time, ...o);
|
console.log(flag, 'background:grey;color:white;', '', 'color:grey;', '', ...o);
|
||||||
}
|
}
|
||||||
this.saveLogs(flag, time, ...o);
|
this.saveLogs(flag, ...o);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static error(...o): void {
|
public static error(...o): void {
|
||||||
Log.counter.error++;
|
Log.counter.error++;
|
||||||
let time = this.getTime();
|
let flag = '%c WH %cERR%c' + this.getTime() + '%c';
|
||||||
let flag = '[WH] ERR';
|
console.error(flag, 'background:grey;color:white;', 'background:red;color:white;', 'color:grey;', '', ...o);
|
||||||
console.error(flag, time, ...o);
|
this.saveLogs(flag, ...o);
|
||||||
this.saveLogs(flag, time, ...o);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static warn(...o): void {
|
public static warn(...o): void {
|
||||||
Log.counter.warning++;
|
Log.counter.warning++;
|
||||||
let time = this.getTime();
|
let flag = '%c WH %cWRN%c' + this.getTime() + '%c';
|
||||||
let flag = '[WH] WRN';
|
console.warn(flag, 'background:grey;color:white;', 'background:#ff9800;color:white;', 'color:grey;', '', ...o);
|
||||||
(this.debug()) && (console.warn(flag, time, ...o));
|
this.saveLogs(flag, ...o);
|
||||||
this.saveLogs(flag, time, ...o);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static debug(): boolean {
|
public static debug(): boolean {
|
||||||
@ -47,7 +44,7 @@ export default class Log {
|
|||||||
let minutes = ('0' + d.getMinutes()).slice(-2);
|
let minutes = ('0' + d.getMinutes()).slice(-2);
|
||||||
let seconds = ('0' + d.getSeconds()).slice(-2);
|
let seconds = ('0' + d.getSeconds()).slice(-2);
|
||||||
let ms = ('00' + d.getMilliseconds()).slice(-3);
|
let ms = ('00' + d.getMilliseconds()).slice(-3);
|
||||||
return `[${ year }-${ month }-${ date } ${ hours }:${ minutes }:${ seconds }.${ ms }]`;
|
return `${ year }-${ month }-${ date } ${ hours }:${ minutes }:${ seconds }.${ ms }`;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getLogs() {
|
public static getLogs() {
|
||||||
@ -56,7 +53,7 @@ export default class Log {
|
|||||||
|
|
||||||
private static saveLogs(...o) {
|
private static saveLogs(...o) {
|
||||||
o.forEach(item => {
|
o.forEach(item => {
|
||||||
if (typeof item === 'string') this.logs += item;
|
if (typeof item === 'string') this.logs += item.replaceAll('%c', '');
|
||||||
else if (item !== null && item !== undefined) {
|
else if (item !== null && item !== undefined) {
|
||||||
let json = '{}';
|
let json = '{}';
|
||||||
let name = Object.getPrototypeOf(item).constructor.name;
|
let name = Object.getPrototypeOf(item).constructor.name;
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import WuhuBase from "./WuhuBase";
|
|||||||
import CommonUtils from "./utils/CommonUtils";
|
import CommonUtils from "./utils/CommonUtils";
|
||||||
import Log from "./Log";
|
import Log from "./Log";
|
||||||
import WuhuConfig from "./WuhuConfig";
|
import WuhuConfig from "./WuhuConfig";
|
||||||
import Alert from "./utils/Alert";
|
|
||||||
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";
|
||||||
@ -98,16 +97,7 @@ export default class UrlPattern extends WuhuBase {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 监听啤酒购买
|
// 监听啤酒购买
|
||||||
let buyBeerResultMonitor = (url, body, opt) => {
|
globVars.responseHandlers.push(BuyBeerHelper.getInstance().responseHandler);
|
||||||
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 重构、与翻译解藕
|
// 快速crime TODO 重构、与翻译解藕
|
||||||
|
|||||||
@ -33,8 +33,8 @@ export default class WuhuBase extends Provider {
|
|||||||
if (condition) throw '芜湖';
|
if (condition) throw '芜湖';
|
||||||
}
|
}
|
||||||
|
|
||||||
public getClassName() {
|
// public getClassName() {
|
||||||
return this.className;
|
// return this.className;
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,8 +7,9 @@ import MathUtils from "../utils/MathUtils";
|
|||||||
import NOTIFY_HTML from "../../static/html/buyBeer/notify.html";
|
import NOTIFY_HTML from "../../static/html/buyBeer/notify.html";
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
import CommonUtils from "../utils/CommonUtils";
|
||||||
import Popup from "../utils/Popup";
|
import Popup from "../utils/Popup";
|
||||||
|
import ResponseInject from "../../interface/ResponseInject";
|
||||||
|
|
||||||
export default class BuyBeerHelper extends WuhuBase implements BeerMonitorLoop {
|
export default class BuyBeerHelper extends WuhuBase implements BeerMonitorLoop, ResponseInject {
|
||||||
className = 'BuyBeerHelper';
|
className = 'BuyBeerHelper';
|
||||||
|
|
||||||
private isNotifying = false;
|
private isNotifying = false;
|
||||||
@ -119,6 +120,16 @@ export default class BuyBeerHelper extends WuhuBase implements BeerMonitorLoop {
|
|||||||
});
|
});
|
||||||
popup.getElement().appendChild(confirm);
|
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 {
|
export interface BeerMonitorLoop {
|
||||||
|
|||||||
0
src/ts/class/action/BuyBeerResult.ts
Normal file
0
src/ts/class/action/BuyBeerResult.ts
Normal file
@ -1,26 +1,21 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
|
||||||
import { MiniProfile } from "../../interface/responseType/MiniProfile";
|
import { MiniProfile } from "../../interface/responseType/MiniProfile";
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
import CommonUtils from "../utils/CommonUtils";
|
||||||
import globVars from "../../globVars";
|
|
||||||
import WuhuConfig from "../WuhuConfig";
|
import WuhuConfig from "../WuhuConfig";
|
||||||
|
import Provider from "../provider/Provider";
|
||||||
|
import ResponseInject from "../../interface/ResponseInject";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fetch 事件监听回调
|
* fetch 事件监听回调
|
||||||
*/
|
*/
|
||||||
export default class FetchEventCallback extends WuhuBase {
|
export default class FetchEventCallback extends Provider implements ResponseInject {
|
||||||
className = "FetchEventCallback";
|
className = "FetchEventCallback";
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
globVars.responseHandlers.push((url, response) => this.handler(response, url))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fetch 返回后处理
|
* fetch 返回后处理
|
||||||
* @param response
|
|
||||||
* @param url
|
* @param url
|
||||||
|
* @param response
|
||||||
*/
|
*/
|
||||||
public handler(response, url: string) {
|
public responseHandler(url: string, response) {
|
||||||
// mini profile 中添加上次动作
|
// mini profile 中添加上次动作
|
||||||
if (url.includes('profiles.php?step=getUserNameContextMenu') && WuhuConfig.get('ShowMiniProfLastAct')) {
|
if (url.includes('profiles.php?step=getUserNameContextMenu') && WuhuConfig.get('ShowMiniProfLastAct')) {
|
||||||
window.setTimeout(async () => {
|
window.setTimeout(async () => {
|
||||||
|
|||||||
@ -4,11 +4,18 @@ 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 FetchUtils from "../utils/FetchUtils";
|
import ResponseInject from "../../interface/ResponseInject";
|
||||||
|
import globVars from "../../globVars";
|
||||||
|
import IUserProfileData from "../../interface/IUserProfileData";
|
||||||
|
|
||||||
export default class ProfileHelper extends WuhuBase {
|
export default class ProfileHelper extends WuhuBase implements ResponseInject {
|
||||||
className = 'ProfileHelper';
|
className = 'ProfileHelper';
|
||||||
|
|
||||||
|
private readonly block;
|
||||||
|
|
||||||
|
// 曾用名已检测过标记
|
||||||
|
private task = true;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
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;}');
|
||||||
@ -21,27 +28,33 @@ export default class ProfileHelper extends WuhuBase {
|
|||||||
Log.info('[ProfileHelper] 隐藏头像');
|
Log.info('[ProfileHelper] 隐藏头像');
|
||||||
document.body.classList.toggle('wh-hide_profile_img');
|
document.body.classList.toggle('wh-hide_profile_img');
|
||||||
}
|
}
|
||||||
let block = new TornStyleBlock('芜湖助手').insert2Dom();
|
this.block = new TornStyleBlock('芜湖助手').insert2Dom();
|
||||||
// 隐藏头像
|
// 隐藏头像
|
||||||
let hideImgSwitch = new TornStyleSwitch('隐藏头像', WuhuConfig.get('HideProfileImg'));
|
let hideImgSwitch = new TornStyleSwitch('隐藏头像', WuhuConfig.get('HideProfileImg'));
|
||||||
block.append(hideImgSwitch.getBase());
|
this.block.append(hideImgSwitch.getBase());
|
||||||
hideImgSwitch.getInput().addEventListener('change', () => {
|
hideImgSwitch.getInput().addEventListener('change', () => {
|
||||||
document.body.classList.toggle('wh-hide_profile_img');
|
document.body.classList.toggle('wh-hide_profile_img');
|
||||||
WuhuConfig.set('HideProfileImg', hideImgSwitch.getInput().checked, true);
|
WuhuConfig.set('HideProfileImg', hideImgSwitch.getInput().checked, true);
|
||||||
});
|
});
|
||||||
|
if (WuhuConfig.get('ShowNameHistory')) {
|
||||||
|
globVars.responseHandlers.push((url, body) => this.responseHandler(url, body));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
responseHandler(url: string, body: { json: unknown; text: string; isModified: boolean }) {
|
||||||
|
if (url.includes('profiles.php?step=getProfileData') && this.task) {
|
||||||
// 曾用名
|
// 曾用名
|
||||||
let nameHistoryNode;
|
let nameHistoryNode;
|
||||||
if (WuhuConfig.get('ShowNameHistory')) {
|
|
||||||
nameHistoryNode = document.createElement('p');
|
nameHistoryNode = document.createElement('p');
|
||||||
nameHistoryNode.innerHTML = '曾用名:';
|
nameHistoryNode.innerHTML = '曾用名:';
|
||||||
block.append(nameHistoryNode);
|
this.block.append(nameHistoryNode);
|
||||||
FetchUtils.getInstance().getProfile(id).then((res) => {
|
let resp = body.json as IUserProfileData;
|
||||||
if (res.userInformation.previousAliases.length > 0) {
|
if (resp.userInformation.previousAliases.length > 0) {
|
||||||
res.userInformation.previousAliases.forEach(item => nameHistoryNode.innerHTML += item + ' ');
|
resp.userInformation.previousAliases.forEach(item => nameHistoryNode.innerHTML += item + ' ');
|
||||||
} else {
|
} else {
|
||||||
nameHistoryNode.innerHTML += '暂无';
|
nameHistoryNode.innerHTML += '暂无';
|
||||||
}
|
}
|
||||||
});
|
this.task = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,20 +1,7 @@
|
|||||||
import WuhuBase from "../WuhuBase";
|
import WuhuBase from "../WuhuBase";
|
||||||
import {
|
import { chatDict, eventsDict, headerDict, propertyDict, sidebarDict } from "../../dictionary/translation";
|
||||||
chatDict,
|
|
||||||
eventsDict,
|
|
||||||
headerDict,
|
|
||||||
itemNameDict,
|
|
||||||
itemPageDict,
|
|
||||||
propertyDict,
|
|
||||||
sidebarDict
|
|
||||||
} from "../../dictionary/translation";
|
|
||||||
import Log from "../Log";
|
import Log from "../Log";
|
||||||
import Timer from "../utils/Timer";
|
import Timer from "../utils/Timer";
|
||||||
import { Button, MiniProfile } from "../../interface/responseType/MiniProfile";
|
|
||||||
import WuhuConfig from "../WuhuConfig";
|
|
||||||
import Sidebar from "../../interface/responseType/Sidebar";
|
|
||||||
import CommonUtils from "../utils/CommonUtils";
|
|
||||||
import InventoryItemInfo from "../../interface/responseType/InventoryItemInfo";
|
|
||||||
|
|
||||||
export default class Translate extends WuhuBase {
|
export default class Translate extends WuhuBase {
|
||||||
className = 'Translate';
|
className = 'Translate';
|
||||||
@ -303,369 +290,4 @@ export default class Translate extends WuhuBase {
|
|||||||
observer.observe(document.body, opt);
|
observer.observe(document.body, opt);
|
||||||
}).observe(document.body, opt);
|
}).observe(document.body, opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* fetch xhr 返回数据的翻译处理
|
|
||||||
* @param url
|
|
||||||
* @param body
|
|
||||||
* @param opt
|
|
||||||
*/
|
|
||||||
public static responseHandler(url: string, body: { json: unknown, text: string, isModified: boolean }, opt: { method: 'GET' | 'POST', requestBody: string }): void {
|
|
||||||
if (!WuhuConfig.get('transNew')) return;
|
|
||||||
// TODO 字典抽取
|
|
||||||
let map = {
|
|
||||||
iconMap: {
|
|
||||||
'Online': { title: "在线" },
|
|
||||||
'Level 100': { title: "100 级" },
|
|
||||||
'Jail': {
|
|
||||||
title: "坐牢", description: {
|
|
||||||
map: {
|
|
||||||
'Being questioned for suspicious online activity.': '因可疑的网上活动而被盘问。',
|
|
||||||
'Suspect of a presidential assassination': '刺杀总统的嫌疑人',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'Federal jail': {
|
|
||||||
title: "联邦监狱(FJ)", description: {
|
|
||||||
map: {
|
|
||||||
'Account marked for deletion': '账号标记删除',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'Idle': { title: "暂离" },
|
|
||||||
'Offline': { title: "离线" },
|
|
||||||
'Enby': { title: "中性" },
|
|
||||||
'Male': { title: "男性" },
|
|
||||||
'Female': { title: "女性" },
|
|
||||||
'Donator': { title: "DP捐助者" },
|
|
||||||
'Subscriber': { title: "蓝星订阅者" },
|
|
||||||
'Traveling': { title: "旅行中" },
|
|
||||||
'Hospital': {
|
|
||||||
title: "已入院",
|
|
||||||
description: {
|
|
||||||
map: {
|
|
||||||
'Fell from a two story building while on a hitman mission': '在执行刺杀任务时从二楼摔下',
|
|
||||||
'Overdosed on Xanax': '吃 Xan 后 OD',
|
|
||||||
'Mauled by a guard dog': '被看门狗咬',
|
|
||||||
},
|
|
||||||
replace: [/(Hospitalized|Mugged|Attacked|Defeated) by (someone|<a.+\/a>)(.+Early discharge available.+)?/, '被 $2 $1$3'],
|
|
||||||
attachedMap: [
|
|
||||||
{
|
|
||||||
'Hospitalized': '强制住院',
|
|
||||||
'Mugged': '抢劫',
|
|
||||||
'Attacked': '攻击',
|
|
||||||
'Defeated': '击败',
|
|
||||||
},
|
|
||||||
{ 'someone': '某人' },
|
|
||||||
{ '<br><i>Early discharge available</i>': '<br><i>提前出院(ED)可用</i>' },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'Bounty': {
|
|
||||||
title: "被悬赏",
|
|
||||||
description: { replace: [/On this person's head for (\$[,0-9]+)( : .+)?/, '$1 悬赏此人$2'] }
|
|
||||||
},
|
|
||||||
'Married': {
|
|
||||||
title: "已婚", description: { replace: [/To/, '和'] }
|
|
||||||
},
|
|
||||||
'Company': {
|
|
||||||
title: "公司",
|
|
||||||
description: {
|
|
||||||
replace: [/([a-zA-Z ]+)( of )(.+) \(([aA-zZ ]+)\)$/, "【$3】$4的$1"],
|
|
||||||
attachedMap: [
|
|
||||||
{
|
|
||||||
'Director': '老板',
|
|
||||||
'Salesperson': '销售员',
|
|
||||||
},
|
|
||||||
{}, {},
|
|
||||||
{
|
|
||||||
'Private Security Firm': '安保公司 (PSF)',
|
|
||||||
'Lingerie Store': '内衣店 (LS)',
|
|
||||||
'Adult Novelties': '成人用品店 (AN)',
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'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]"] }
|
|
||||||
},
|
|
||||||
'Bazaar': {
|
|
||||||
title: "摊位",
|
|
||||||
description: {
|
|
||||||
map: {
|
|
||||||
'This person has items in their bazaar for sale':
|
|
||||||
'此人在摊位上有物品出售'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
buttonMap: {
|
|
||||||
message: {
|
|
||||||
'Add $0 to your enemy list': '添加 $0 到敌人列表',
|
|
||||||
'Add $0 to your friend list': '添加 $0 到好友列表',
|
|
||||||
'You are currently traveling': '你在天上',
|
|
||||||
'Initiate a chat with $0': '与 $0 私聊',
|
|
||||||
'You are not in Torn': '你不在城内',
|
|
||||||
"View $0's personal statistics": '查看 $0 的个人统计数据',
|
|
||||||
"Place a bounty on $0": '对 $0 发起悬赏',
|
|
||||||
"Report $0 to staff": '向工作人员举报 $0',
|
|
||||||
"Send $0 a message": '发邮件给 $0',
|
|
||||||
"View $0's display case": '查看 $0 的展柜',
|
|
||||||
"$0 is currently in hospital": '$0 正在住院',
|
|
||||||
"$0 has not been online in the last 6 hours": '$0 超 6 小时未在线',
|
|
||||||
"Give some money to $0": '给 $0 一些钱',
|
|
||||||
"$0's bazaar is closed": '$0 的摊位已关闭',
|
|
||||||
"View $0's bazaar": '查看 $0 的摊位',
|
|
||||||
"Initiate a trade with $0": '与 $0 交易',
|
|
||||||
"$0 has no items in their bazaar": '$0 的摊位是空的',
|
|
||||||
"$0 is currently in jail": '$0 目前在坐牢',
|
|
||||||
"Pay $0's bail": '支付 $0 的保释金',
|
|
||||||
"Bust $0 out of jail": '把 $0 从监狱里踢出来',
|
|
||||||
"$0 is currently in federal jail": '$0 目前在联邦监狱(FJ)',
|
|
||||||
"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: {
|
|
||||||
'Mexico': '墨西哥',
|
|
||||||
'Cayman Islands': '开曼群岛',
|
|
||||||
'Canada': '加拿大',
|
|
||||||
'Hawaii': '夏威夷',
|
|
||||||
'United Kingdom': '英国',
|
|
||||||
'Argentina': '阿根廷',
|
|
||||||
'Switzerland': '瑞士',
|
|
||||||
'Japan': '日本',
|
|
||||||
'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;
|
|
||||||
let oriTitle = icon.title;
|
|
||||||
if (iconMap[oriTitle]) {
|
|
||||||
icon.title = iconMap[oriTitle].title;
|
|
||||||
let desc = iconMap[oriTitle].description;
|
|
||||||
let oriDesc = icon.description;
|
|
||||||
if (icon.description && desc) {
|
|
||||||
if (desc.map && desc.map[oriDesc]) {
|
|
||||||
icon.description = desc.map[oriDesc];
|
|
||||||
} else if (desc.replace) {
|
|
||||||
icon.description = oriDesc.replace(new RegExp(desc.replace[0]), desc.replace[1]);
|
|
||||||
if (desc.attachedMap) {
|
|
||||||
desc.attachedMap.forEach((item, index) => {
|
|
||||||
let factor = oriDesc.replace(new RegExp(desc.replace[0]), '$' + (index + 1));
|
|
||||||
Log.info({ factor });
|
|
||||||
let cn = item[factor];
|
|
||||||
cn && (icon.description = icon.description.replace(factor, cn));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 离线转钱警告
|
|
||||||
if (jsonObj.user.sendMoneyWarning) {
|
|
||||||
let daysMatch = jsonObj.user.sendMoneyWarning.match(/[0-9]+/);
|
|
||||||
if (daysMatch.length !== 0)
|
|
||||||
jsonObj.user.sendMoneyWarning = `警告:此人已离线 ${ daysMatch[0] } 天`;
|
|
||||||
}
|
|
||||||
// 按钮
|
|
||||||
let buttons = jsonObj.profileButtons.buttons;
|
|
||||||
let buttonKeyList = Object.keys(buttons);
|
|
||||||
let username = jsonObj.user.playerName;
|
|
||||||
let msgMap = map.buttonMap.message;
|
|
||||||
buttonKeyList.forEach(buttonKey => {
|
|
||||||
if (buttons[buttonKey].state === 'hidden') return;
|
|
||||||
let button: Button = buttons[buttonKey];
|
|
||||||
let oriMsg = button.message.replace(username, '$0');
|
|
||||||
if (msgMap[oriMsg]) {
|
|
||||||
button.message = msgMap[oriMsg].replace('$0', username);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// TODO 称号
|
|
||||||
// 用户状态
|
|
||||||
let status = jsonObj.userStatus.status.type;
|
|
||||||
switch (status) {
|
|
||||||
case 'traveling-to': {
|
|
||||||
let origin = jsonObj.userStatus.status.to.simpleName;
|
|
||||||
let cn = map.destinationMap[origin]
|
|
||||||
cn && (jsonObj.userStatus.status.to.simpleName = cn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'traveling-from': {
|
|
||||||
let origin = jsonObj.userStatus.status.from.simpleName;
|
|
||||||
let cn = map.destinationMap[origin]
|
|
||||||
cn && (jsonObj.userStatus.status.from.simpleName = cn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'abroad': {
|
|
||||||
let origin = jsonObj.userStatus.status.in.simpleName;
|
|
||||||
let cn = map.destinationMap[origin]
|
|
||||||
cn && (jsonObj.userStatus.status.in.simpleName = cn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'jail': {
|
|
||||||
let origin = jsonObj.userStatus.status.description;
|
|
||||||
let cn = map.iconMap.Jail.description.map[origin];
|
|
||||||
cn && (jsonObj.userStatus.status.description = cn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
body.isModified = true;
|
|
||||||
|
|
||||||
Log.info({ 'localized': 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;
|
|
||||||
}
|
|
||||||
// 物品详情
|
|
||||||
else if (url.includes('inventory.php') && opt?.method === 'POST' &&
|
|
||||||
typeof opt?.requestBody === 'string' && opt?.requestBody.includes('step=info')) {
|
|
||||||
let resp = body.json as InventoryItemInfo;
|
|
||||||
// TODO 维护通用物品数据(对应名称、描述、类型)缓存
|
|
||||||
let map: { [k: string]: Partial<InventoryItemInfo> } = {
|
|
||||||
'Glass of Beer': {
|
|
||||||
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.',
|
|
||||||
itemInfoContent: "\n" +
|
|
||||||
" <div class='m-bottom10'>\n" +
|
|
||||||
" <span class=\"bold\">一杯啤酒</span> 是酒类物品\n" +
|
|
||||||
" </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.\n" +
|
|
||||||
" <div class=\"t-green bold item-effect m-top10\">效果: 犯罪 + 2,增幅CD + 1h。</div>",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let idMap = { 816: 'Glass of Beer' };
|
|
||||||
let itemInfo = CommonUtils.getInstance().getItemByIdOrName(resp.itemName, idMap, map);
|
|
||||||
if (itemInfo) {
|
|
||||||
body.isModified = true;
|
|
||||||
resp.itemInfo = itemInfo.itemInfo;
|
|
||||||
resp.itemName = itemInfo.itemName;
|
|
||||||
resp.itemInfoContent = itemInfo.itemInfoContent;
|
|
||||||
}
|
|
||||||
// TODO 老字典
|
|
||||||
let itemName = itemNameDict[resp.itemName];
|
|
||||||
if (itemName) {
|
|
||||||
body.isModified = true;
|
|
||||||
resp.itemInfoContent = resp.itemInfoContent
|
|
||||||
.replace('The ', '')
|
|
||||||
.replace(resp.itemName, `${ itemName }(${ resp.itemName })`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 物品列表
|
|
||||||
else if ((url.includes('item.php') || url.includes('inventory.php')) && opt?.method === 'POST' &&
|
|
||||||
typeof opt?.requestBody === 'string' && (opt?.requestBody.includes('step=getCategoryList') || opt?.requestBody.includes('step=getList'))) {
|
|
||||||
let resp = body.json as { html: string };
|
|
||||||
if (resp.html) {
|
|
||||||
let tmp = document.createElement('div');
|
|
||||||
tmp.innerHTML = resp.html;
|
|
||||||
Log.info(tmp);
|
|
||||||
tmp.childNodes.forEach(li => {
|
|
||||||
if (li.nodeType === 1) {
|
|
||||||
let elem = li as Element;
|
|
||||||
// 物品名
|
|
||||||
let name = elem.querySelector('.name-wrap .name');
|
|
||||||
let nameZh = itemNameDict[name.innerText.trim()];
|
|
||||||
if (nameZh) {
|
|
||||||
name.innerText = `${ name.innerText } ${ nameZh }`;
|
|
||||||
}
|
|
||||||
// 操作按钮
|
|
||||||
let actions = elem.querySelectorAll('.icon-h');
|
|
||||||
actions.forEach(action => {
|
|
||||||
let attrTitle = action.getAttribute('title');
|
|
||||||
// TODO
|
|
||||||
let zh = itemPageDict[attrTitle];
|
|
||||||
if (zh) {
|
|
||||||
action.setAttribute('title', zh);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
resp.html = tmp.innerHTML;
|
|
||||||
body.isModified = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO 物品列表json版
|
|
||||||
else if (url.includes('inventory.php') && opt?.method === 'POST' &&
|
|
||||||
typeof opt?.requestBody === 'string' && opt?.requestBody.includes('step=getList')) {
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
Log.error('responseHandler', e.stack || e.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
382
src/ts/class/action/TranslateNew.ts
Normal file
382
src/ts/class/action/TranslateNew.ts
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
import ResponseInject from "../../interface/ResponseInject";
|
||||||
|
import WuhuConfig from "../WuhuConfig";
|
||||||
|
import { Button, MiniProfile } from "../../interface/responseType/MiniProfile";
|
||||||
|
import Log from "../Log";
|
||||||
|
import Sidebar from "../../interface/responseType/Sidebar";
|
||||||
|
import InventoryItemInfo from "../../interface/responseType/InventoryItemInfo";
|
||||||
|
import CommonUtils from "../utils/CommonUtils";
|
||||||
|
import { itemNameDict, itemPageDict } from "../../dictionary/translation";
|
||||||
|
import Provider from "../provider/Provider";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 翻译重构
|
||||||
|
*/
|
||||||
|
export default class TranslateNew extends Provider implements ResponseInject {
|
||||||
|
className = 'TranslateNew';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fetch xhr 返回数据的翻译处理
|
||||||
|
* @param url
|
||||||
|
* @param body
|
||||||
|
* @param opt
|
||||||
|
*/
|
||||||
|
public responseHandler(url: string, body: { json: unknown, text: string, isModified: boolean }, opt: { method: 'GET' | 'POST', requestBody: string }): void {
|
||||||
|
if (!WuhuConfig.get('transNew')) return;
|
||||||
|
// TODO 字典抽取
|
||||||
|
let map = {
|
||||||
|
iconMap: {
|
||||||
|
'Online': { title: "在线" },
|
||||||
|
'Level 100': { title: "100 级" },
|
||||||
|
'Jail': {
|
||||||
|
title: "坐牢", description: {
|
||||||
|
map: {
|
||||||
|
'Being questioned for suspicious online activity.': '因可疑的网上活动而被盘问。',
|
||||||
|
'Suspect of a presidential assassination': '刺杀总统的嫌疑人',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Federal jail': {
|
||||||
|
title: "联邦监狱(FJ)", description: {
|
||||||
|
map: {
|
||||||
|
'Account marked for deletion': '账号标记删除',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Idle': { title: "暂离" },
|
||||||
|
'Offline': { title: "离线" },
|
||||||
|
'Enby': { title: "中性" },
|
||||||
|
'Male': { title: "男性" },
|
||||||
|
'Female': { title: "女性" },
|
||||||
|
'Donator': { title: "DP捐助者" },
|
||||||
|
'Subscriber': { title: "蓝星订阅者" },
|
||||||
|
'Traveling': { title: "旅行中" },
|
||||||
|
'Hospital': {
|
||||||
|
title: "已入院",
|
||||||
|
description: {
|
||||||
|
map: {
|
||||||
|
'Fell from a two story building while on a hitman mission': '在执行刺杀任务时从二楼摔下',
|
||||||
|
'Overdosed on Xanax': '吃 Xan 后 OD',
|
||||||
|
'Mauled by a guard dog': '被看门狗咬',
|
||||||
|
},
|
||||||
|
replace: [/(Hospitalized|Mugged|Attacked|Defeated) by (someone|<a.+\/a>)(.+Early discharge available.+)?/, '被 $2 $1$3'],
|
||||||
|
attachedMap: [
|
||||||
|
{
|
||||||
|
'Hospitalized': '强制住院',
|
||||||
|
'Mugged': '抢劫',
|
||||||
|
'Attacked': '攻击',
|
||||||
|
'Defeated': '击败',
|
||||||
|
},
|
||||||
|
{ 'someone': '某人' },
|
||||||
|
{ '<br><i>Early discharge available</i>': '<br><i>提前出院(ED)可用</i>' },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Bounty': {
|
||||||
|
title: "被悬赏",
|
||||||
|
description: { replace: [/On this person's head for (\$[,0-9]+)( : .+)?/, '$1 悬赏此人$2'] }
|
||||||
|
},
|
||||||
|
'Married': {
|
||||||
|
title: "已婚", description: { replace: [/To/, '和'] }
|
||||||
|
},
|
||||||
|
'Company': {
|
||||||
|
title: "公司",
|
||||||
|
description: {
|
||||||
|
replace: [/([a-zA-Z ]+)( of )(.+) \(([aA-zZ ]+)\)$/, "【$3】$4的$1"],
|
||||||
|
attachedMap: [
|
||||||
|
{
|
||||||
|
'Director': '老板',
|
||||||
|
'Salesperson': '销售员',
|
||||||
|
},
|
||||||
|
{}, {},
|
||||||
|
{
|
||||||
|
'Private Security Firm': '安保公司 (PSF)',
|
||||||
|
'Lingerie Store': '内衣店 (LS)',
|
||||||
|
'Adult Novelties': '成人用品店 (AN)',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'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]"] }
|
||||||
|
},
|
||||||
|
'Bazaar': {
|
||||||
|
title: "摊位",
|
||||||
|
description: {
|
||||||
|
map: {
|
||||||
|
'This person has items in their bazaar for sale':
|
||||||
|
'此人在摊位上有物品出售'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
buttonMap: {
|
||||||
|
message: {
|
||||||
|
'Add $0 to your enemy list': '添加 $0 到敌人列表',
|
||||||
|
'Add $0 to your friend list': '添加 $0 到好友列表',
|
||||||
|
'You are currently traveling': '你在天上',
|
||||||
|
'Initiate a chat with $0': '与 $0 私聊',
|
||||||
|
'You are not in Torn': '你不在城内',
|
||||||
|
"View $0's personal statistics": '查看 $0 的个人统计数据',
|
||||||
|
"Place a bounty on $0": '对 $0 发起悬赏',
|
||||||
|
"Report $0 to staff": '向工作人员举报 $0',
|
||||||
|
"Send $0 a message": '发邮件给 $0',
|
||||||
|
"View $0's display case": '查看 $0 的展柜',
|
||||||
|
"$0 is currently in hospital": '$0 正在住院',
|
||||||
|
"$0 has not been online in the last 6 hours": '$0 超 6 小时未在线',
|
||||||
|
"Give some money to $0": '给 $0 一些钱',
|
||||||
|
"$0's bazaar is closed": '$0 的摊位已关闭',
|
||||||
|
"View $0's bazaar": '查看 $0 的摊位',
|
||||||
|
"Initiate a trade with $0": '与 $0 交易',
|
||||||
|
"$0 has no items in their bazaar": '$0 的摊位是空的',
|
||||||
|
"$0 is currently in jail": '$0 目前在坐牢',
|
||||||
|
"Pay $0's bail": '支付 $0 的保释金',
|
||||||
|
"Bust $0 out of jail": '把 $0 从监狱里踢出来',
|
||||||
|
"$0 is currently in federal jail": '$0 目前在联邦监狱(FJ)',
|
||||||
|
"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: {
|
||||||
|
'Mexico': '墨西哥',
|
||||||
|
'Cayman Islands': '开曼群岛',
|
||||||
|
'Canada': '加拿大',
|
||||||
|
'Hawaii': '夏威夷',
|
||||||
|
'United Kingdom': '英国',
|
||||||
|
'Argentina': '阿根廷',
|
||||||
|
'Switzerland': '瑞士',
|
||||||
|
'Japan': '日本',
|
||||||
|
'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;
|
||||||
|
let oriTitle = icon.title;
|
||||||
|
if (iconMap[oriTitle]) {
|
||||||
|
icon.title = iconMap[oriTitle].title;
|
||||||
|
let desc = iconMap[oriTitle].description;
|
||||||
|
let oriDesc = icon.description;
|
||||||
|
if (icon.description && desc) {
|
||||||
|
if (desc.map && desc.map[oriDesc]) {
|
||||||
|
icon.description = desc.map[oriDesc];
|
||||||
|
} else if (desc.replace) {
|
||||||
|
icon.description = oriDesc.replace(new RegExp(desc.replace[0]), desc.replace[1]);
|
||||||
|
if (desc.attachedMap) {
|
||||||
|
desc.attachedMap.forEach((item, index) => {
|
||||||
|
let factor = oriDesc.replace(new RegExp(desc.replace[0]), '$' + (index + 1));
|
||||||
|
Log.info({ factor });
|
||||||
|
let cn = item[factor];
|
||||||
|
cn && (icon.description = icon.description.replace(factor, cn));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 离线转钱警告
|
||||||
|
if (jsonObj.user.sendMoneyWarning) {
|
||||||
|
let daysMatch = jsonObj.user.sendMoneyWarning.match(/[0-9]+/);
|
||||||
|
if (daysMatch.length !== 0)
|
||||||
|
jsonObj.user.sendMoneyWarning = `警告:此人已离线 ${ daysMatch[0] } 天`;
|
||||||
|
}
|
||||||
|
// 按钮
|
||||||
|
let buttons = jsonObj.profileButtons.buttons;
|
||||||
|
let buttonKeyList = Object.keys(buttons);
|
||||||
|
let username = jsonObj.user.playerName;
|
||||||
|
let msgMap = map.buttonMap.message;
|
||||||
|
buttonKeyList.forEach(buttonKey => {
|
||||||
|
if (buttons[buttonKey].state === 'hidden') return;
|
||||||
|
let button: Button = buttons[buttonKey];
|
||||||
|
let oriMsg = button.message.replace(username, '$0');
|
||||||
|
if (msgMap[oriMsg]) {
|
||||||
|
button.message = msgMap[oriMsg].replace('$0', username);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// TODO 称号
|
||||||
|
// 用户状态
|
||||||
|
let status = jsonObj.userStatus.status.type;
|
||||||
|
switch (status) {
|
||||||
|
case 'traveling-to': {
|
||||||
|
let origin = jsonObj.userStatus.status.to.simpleName;
|
||||||
|
let cn = map.destinationMap[origin]
|
||||||
|
cn && (jsonObj.userStatus.status.to.simpleName = cn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'traveling-from': {
|
||||||
|
let origin = jsonObj.userStatus.status.from.simpleName;
|
||||||
|
let cn = map.destinationMap[origin]
|
||||||
|
cn && (jsonObj.userStatus.status.from.simpleName = cn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'abroad': {
|
||||||
|
let origin = jsonObj.userStatus.status.in.simpleName;
|
||||||
|
let cn = map.destinationMap[origin]
|
||||||
|
cn && (jsonObj.userStatus.status.in.simpleName = cn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'jail': {
|
||||||
|
let origin = jsonObj.userStatus.status.description;
|
||||||
|
let cn = map.iconMap.Jail.description.map[origin];
|
||||||
|
cn && (jsonObj.userStatus.status.description = cn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body.isModified = true;
|
||||||
|
|
||||||
|
Log.info({ 'localized': 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;
|
||||||
|
}
|
||||||
|
// 物品详情
|
||||||
|
else if ((url.includes('inventory.php?step=info')) || (url.includes('inventory.php') && opt?.method === 'POST' &&
|
||||||
|
typeof opt?.requestBody === 'string' && opt?.requestBody.includes('step=info'))) {
|
||||||
|
Log.info('responseHandler');
|
||||||
|
let resp = body.json as InventoryItemInfo;
|
||||||
|
// TODO 维护通用物品数据(对应名称、描述、类型)缓存
|
||||||
|
let map: { [k: string]: Partial<InventoryItemInfo> } = {
|
||||||
|
'Glass of Beer': {
|
||||||
|
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.',
|
||||||
|
itemInfoContent: "\n" +
|
||||||
|
" <div class='m-bottom10'>\n" +
|
||||||
|
" <span class=\"bold\">一杯啤酒</span> 是酒类物品\n" +
|
||||||
|
" </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.\n" +
|
||||||
|
" <div class=\"t-green bold item-effect m-top10\">效果: 犯罪 + 2,增幅CD + 1h。</div>",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let idMap = { 816: 'Glass of Beer' };
|
||||||
|
let itemInfo = CommonUtils.getInstance().getItemByIdOrName(resp.itemName, idMap, map);
|
||||||
|
if (itemInfo) {
|
||||||
|
body.isModified = true;
|
||||||
|
resp.itemInfo = itemInfo.itemInfo;
|
||||||
|
resp.itemName = itemInfo.itemName;
|
||||||
|
resp.itemInfoContent = itemInfo.itemInfoContent;
|
||||||
|
}
|
||||||
|
// TODO 老字典
|
||||||
|
let itemName = itemNameDict[resp.itemName];
|
||||||
|
if (itemName) {
|
||||||
|
body.isModified = true;
|
||||||
|
resp.itemInfoContent = resp.itemInfoContent
|
||||||
|
.replace('The ', '')
|
||||||
|
.replace(resp.itemName, `${ itemName }(${ resp.itemName })`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 物品列表
|
||||||
|
else if ((url.includes('item.php') || url.includes('inventory.php')) && opt?.method === 'POST' &&
|
||||||
|
typeof opt?.requestBody === 'string' && (opt?.requestBody.includes('step=getCategoryList') || opt?.requestBody.includes('step=getList'))) {
|
||||||
|
let resp = body.json as { html: string };
|
||||||
|
if (resp.html) {
|
||||||
|
let tmp = document.createElement('div');
|
||||||
|
tmp.innerHTML = resp.html;
|
||||||
|
Log.info(tmp);
|
||||||
|
tmp.childNodes.forEach(li => {
|
||||||
|
if (li.nodeType === 1) {
|
||||||
|
let elem = li as Element;
|
||||||
|
// 物品名
|
||||||
|
let name = elem.querySelector('.name-wrap .name');
|
||||||
|
let nameZh = itemNameDict[name.innerText.trim()];
|
||||||
|
if (nameZh) {
|
||||||
|
name.innerText = `${ name.innerText } ${ nameZh }`;
|
||||||
|
}
|
||||||
|
// 操作按钮
|
||||||
|
let actions = elem.querySelectorAll('.icon-h');
|
||||||
|
actions.forEach(action => {
|
||||||
|
let attrTitle = action.getAttribute('title');
|
||||||
|
// TODO
|
||||||
|
let zh = itemPageDict[attrTitle];
|
||||||
|
if (zh) {
|
||||||
|
action.setAttribute('title', zh);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
resp.html = tmp.innerHTML;
|
||||||
|
body.isModified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO 物品列表json版
|
||||||
|
else if (url.includes('inventory.php') && opt?.method === 'POST' &&
|
||||||
|
typeof opt?.requestBody === 'string' && opt?.requestBody.includes('step=getList')) {
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
Log.error('responseHandler', e.stack || e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/ts/class/handler/ItemValueQueryHandler.ts
Normal file
21
src/ts/class/handler/ItemValueQueryHandler.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
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()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/ts/class/provider/Elem.ts
Normal file
26
src/ts/class/provider/Elem.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -30,4 +30,8 @@ export default class Provider {
|
|||||||
pool: Provider.pool,
|
pool: Provider.pool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getClassName() {
|
||||||
|
return this.className;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
116
src/ts/class/utils/ItemHelper.ts
Normal file
116
src/ts/class/utils/ItemHelper.ts
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import WuhuBase from "../WuhuBase";
|
||||||
|
import InventoryItemInfo from "../../interface/responseType/InventoryItemInfo";
|
||||||
|
import FetchUtils from "./FetchUtils";
|
||||||
|
import CommonUtils from "./CommonUtils";
|
||||||
|
import Log from "../Log";
|
||||||
|
|
||||||
|
export default class ItemHelper extends WuhuBase {
|
||||||
|
className = "ItemHelper";
|
||||||
|
itemValueMap: { [k: string]: Partial<InventoryItemInfo> } = {
|
||||||
|
'Glass of Beer': {
|
||||||
|
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.',
|
||||||
|
itemInfoContent: "\n" +
|
||||||
|
" <div class='m-bottom10'>\n" +
|
||||||
|
" <span class=\"bold\">一杯啤酒</span> 是酒类物品\n" +
|
||||||
|
" </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.\n" +
|
||||||
|
" <div class=\"t-green bold item-effect m-top10\">效果: 犯罪 + 2,增幅CD + 1h。</div>",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
itemPriceMap = {
|
||||||
|
205: { name: 'Vicodin', price: 1300 },
|
||||||
|
};
|
||||||
|
// 缓存过期时间 分钟
|
||||||
|
private readonly priceTimeout = 720;
|
||||||
|
|
||||||
|
// TODO 定时
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getItemData(idOrName: string): Promise<Partial<InventoryItemInfo>> {
|
||||||
|
return await (await FetchUtils.getInstance().ajaxFetch({
|
||||||
|
url: `/inventory.php?step=info&itemID=${ idOrName }&armouryID=0&asObject=true`,
|
||||||
|
method: 'GET',
|
||||||
|
referrer: 'bazaar.php',
|
||||||
|
})).json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物品查价-缓存
|
||||||
|
* @param idOrName
|
||||||
|
*/
|
||||||
|
public getItemPrice(idOrName) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物品查价-API
|
||||||
|
* @param idOrName
|
||||||
|
*/
|
||||||
|
public getItemPriceApi(idOrName) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物品查价值
|
||||||
|
*/
|
||||||
|
public async getItemValue(idOrName) {
|
||||||
|
return (await this.getItemData(idOrName)).itemValue.replaceAll(/[,$]/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
public getLocalPriceData(): { priceData: PriceData, promise: Promise<PriceData> } {
|
||||||
|
// 获取本地缓存
|
||||||
|
let localStore = localStorage.getItem('WHItemPrice');
|
||||||
|
let res = { priceData: null, promise: null };
|
||||||
|
let data: PriceData = null;
|
||||||
|
// 无缓存
|
||||||
|
if (!localStore) {
|
||||||
|
res.promise = this.fetchPriceData();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
// 解析缓存
|
||||||
|
try {
|
||||||
|
data = JSON.parse(localStore);
|
||||||
|
} catch (e) {
|
||||||
|
Log.error(e.stack || e.message || e);
|
||||||
|
throw new Error('JSON解析错误');
|
||||||
|
}
|
||||||
|
// 缓存超时
|
||||||
|
if (Date.now() - data.timestamp > this.priceTimeout * 60000) {
|
||||||
|
res.priceData = null;
|
||||||
|
res.promise = this.fetchPriceData();
|
||||||
|
} else {
|
||||||
|
res.priceData = data;
|
||||||
|
res.promise = null;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async fetchPriceData(): Promise<PriceData> {
|
||||||
|
let res = null;
|
||||||
|
// 获取在线价格
|
||||||
|
try {
|
||||||
|
res = JSON.parse(await CommonUtils.COFetch('https://jjins.github.io/item_price_raw.json'))
|
||||||
|
} catch (err) {
|
||||||
|
Log.error(err.stack || err.message || err);
|
||||||
|
throw new Error('获取在线价格时出错');
|
||||||
|
}
|
||||||
|
// 更新缓存
|
||||||
|
let localData: PriceData = {
|
||||||
|
timestamp: Date.now(),
|
||||||
|
data: res,
|
||||||
|
};
|
||||||
|
localStorage.setItem('WHItemPrice', JSON.stringify(localData));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PriceData {
|
||||||
|
timestamp: number
|
||||||
|
data: {
|
||||||
|
[k: number]: {
|
||||||
|
name: string
|
||||||
|
price: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,11 +2,19 @@ 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 Log from "../Log";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 弹窗
|
||||||
|
*/
|
||||||
export default class Popup extends WuhuBase {
|
export default class Popup extends WuhuBase {
|
||||||
className = 'Popup';
|
className = 'Popup';
|
||||||
private readonly container: HTMLElement = null;
|
private readonly container: HTMLElement = null;
|
||||||
private readonly node: HTMLElement = null;
|
private readonly node: HTMLElement = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造新弹窗
|
||||||
|
* @param innerHTML
|
||||||
|
* @param title
|
||||||
|
*/
|
||||||
constructor(innerHTML: string, title: string = '芜湖助手') {
|
constructor(innerHTML: string, title: string = '芜湖助手') {
|
||||||
super();
|
super();
|
||||||
if (Popup.glob.popup_node) {
|
if (Popup.glob.popup_node) {
|
||||||
|
|||||||
@ -1,13 +1,22 @@
|
|||||||
import toThousands from "../utils/toThousands";
|
import toThousands from "../utils/toThousands";
|
||||||
import CommonUtils from "../../class/utils/CommonUtils";
|
import CommonUtils from "../../class/utils/CommonUtils";
|
||||||
import Log from "../../class/Log";
|
|
||||||
import CITY_FINDER_CSS from "../../static/css/city_finder.css";
|
import CITY_FINDER_CSS from "../../static/css/city_finder.css";
|
||||||
import TornStyleBlock from "../../class/utils/TornStyleBlock";
|
import TornStyleBlock from "../../class/utils/TornStyleBlock";
|
||||||
|
import ItemHelper from "../../class/utils/ItemHelper";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2023-02-22 修改物品价格查询逻辑,缓存优先
|
||||||
|
* @param _base
|
||||||
|
*/
|
||||||
export default function cityFinder(_base: TornStyleBlock): void {
|
export default function cityFinder(_base: TornStyleBlock): void {
|
||||||
CommonUtils.addStyle(CITY_FINDER_CSS);
|
CommonUtils.addStyle(CITY_FINDER_CSS);
|
||||||
// 物品名与价格
|
// 物品名与价格
|
||||||
let items = null;
|
let items: {
|
||||||
|
[k: number]: {
|
||||||
|
name: string
|
||||||
|
price: number
|
||||||
|
}
|
||||||
|
} = null;
|
||||||
// const base = document.createElement('div');
|
// const base = document.createElement('div');
|
||||||
// base.id = 'wh-city-finder';
|
// base.id = 'wh-city-finder';
|
||||||
// const container = document.createElement('div');
|
// const container = document.createElement('div');
|
||||||
@ -24,12 +33,13 @@ export default function cityFinder(_base: TornStyleBlock): void {
|
|||||||
_base.append(header, info);
|
_base.append(header, info);
|
||||||
document.body.classList.add('wh-city-finds');
|
document.body.classList.add('wh-city-finds');
|
||||||
|
|
||||||
CommonUtils.COFetch('https://jjins.github.io/item_price_raw.json')
|
// CommonUtils.COFetch('https://jjins.github.io/item_price_raw.json')
|
||||||
.then(r => items = JSON.parse(r))
|
// .then(r => items = JSON.parse(r))
|
||||||
.catch(err => {
|
// .catch(err => {
|
||||||
Log.error(err);
|
// Log.error(err);
|
||||||
items = undefined
|
// items = undefined
|
||||||
});
|
// });
|
||||||
|
let itemHelper = ItemHelper.getInstance();
|
||||||
CommonUtils.elementReady('div.leaflet-marker-pane').then(elem => {
|
CommonUtils.elementReady('div.leaflet-marker-pane').then(elem => {
|
||||||
// document.querySelector('.content-wrapper').prepend(base);
|
// document.querySelector('.content-wrapper').prepend(base);
|
||||||
|
|
||||||
@ -73,29 +83,40 @@ export default function cityFinder(_base: TornStyleBlock): void {
|
|||||||
header.innerHTML = `捡垃圾助手 - ${ founds.length } 个物品,总价值 $${ toThousands(total) }`;
|
header.innerHTML = `捡垃圾助手 - ${ founds.length } 个物品,总价值 $${ toThousands(total) }`;
|
||||||
// _base.setTitle(`捡垃圾助手 - ${ founds.length } 个物品,总价值 $${ toThousands(total) }`);
|
// _base.setTitle(`捡垃圾助手 - ${ founds.length } 个物品,总价值 $${ toThousands(total) }`);
|
||||||
};
|
};
|
||||||
// 未取到数据时添加循环来调用函数
|
// // 未取到数据时添加循环来调用函数
|
||||||
if (items === null) {
|
// if (items === null) {
|
||||||
// 15s超时
|
// // 15s超时
|
||||||
let timeout = 30;
|
// let timeout = 30;
|
||||||
const interval = window.setInterval(() => {
|
// const interval = window.setInterval(() => {
|
||||||
timeout--;
|
// timeout--;
|
||||||
if (items !== null) {
|
// if (items !== null) {
|
||||||
|
// displayNamePrice();
|
||||||
|
// window.clearInterval(interval);
|
||||||
|
// }
|
||||||
|
// if (0 === timeout) {
|
||||||
|
// Log.info('获取物品名称与价格信息超时')
|
||||||
|
// window.clearInterval(interval)
|
||||||
|
// }
|
||||||
|
// }, 500);
|
||||||
|
// }
|
||||||
|
// // 无法跨域获取数据时
|
||||||
|
// else if (items === undefined) {
|
||||||
|
// info.innerHTML += '(当前平台暂不支持查询价格)';
|
||||||
|
// }
|
||||||
|
// // 调用函数
|
||||||
|
// else {
|
||||||
|
// displayNamePrice();
|
||||||
|
// }
|
||||||
|
|
||||||
|
let priceData = itemHelper.getLocalPriceData();
|
||||||
|
if (priceData.priceData) {
|
||||||
|
items = priceData.priceData.data;
|
||||||
displayNamePrice();
|
displayNamePrice();
|
||||||
window.clearInterval(interval);
|
} else {
|
||||||
}
|
window.setTimeout(async () => {
|
||||||
if (0 === timeout) {
|
items = (await priceData.promise).data;
|
||||||
Log.info('获取物品名称与价格信息超时')
|
|
||||||
window.clearInterval(interval)
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
// 无法跨域获取数据时
|
|
||||||
else if (items === undefined) {
|
|
||||||
info.innerHTML += '(当前平台暂不支持查询价格)';
|
|
||||||
}
|
|
||||||
// 调用函数
|
|
||||||
else {
|
|
||||||
displayNamePrice();
|
displayNamePrice();
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
22
src/ts/interface/ResponseInject.ts
Normal file
22
src/ts/interface/ResponseInject.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* 处理网络请求响应的类型
|
||||||
|
*/
|
||||||
|
export default interface ResponseInject {
|
||||||
|
/**
|
||||||
|
* @param url 请求url
|
||||||
|
* @param body 响应体代理
|
||||||
|
* @param opt 请求参数
|
||||||
|
*/
|
||||||
|
responseHandler(
|
||||||
|
url: string,
|
||||||
|
body: {
|
||||||
|
json: unknown,
|
||||||
|
text: string,
|
||||||
|
isModified: boolean
|
||||||
|
},
|
||||||
|
opt: {
|
||||||
|
method: 'GET' | 'POST',
|
||||||
|
requestBody: string
|
||||||
|
}
|
||||||
|
): void
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
* 物品详情
|
* 物品详情
|
||||||
*/
|
*/
|
||||||
export default interface InventoryItemInfo {
|
export default interface InventoryItemInfo {
|
||||||
itemID: 816
|
itemID: number
|
||||||
itemInfo: string
|
itemInfo: string
|
||||||
// html 格式
|
// html 格式
|
||||||
itemInfoContent: string
|
itemInfoContent: string
|
||||||
@ -10,4 +10,5 @@ export default interface InventoryItemInfo {
|
|||||||
// html 格式
|
// html 格式
|
||||||
itemRareTitle: string
|
itemRareTitle: string
|
||||||
itemType: "Item"
|
itemType: "Item"
|
||||||
|
itemValue: string
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,9 @@ import CommonUtils from "../class/utils/CommonUtils";
|
|||||||
import Popup from "../class/utils/Popup";
|
import Popup from "../class/utils/Popup";
|
||||||
import CompanyHelper from "../class/action/CompanyHelper";
|
import CompanyHelper from "../class/action/CompanyHelper";
|
||||||
import globVars from "../globVars";
|
import globVars from "../globVars";
|
||||||
|
import FetchUtils from "../class/utils/FetchUtils";
|
||||||
|
import ItemValueQueryHandler from "../class/handler/ItemValueQueryHandler";
|
||||||
|
import createApp from "vue";
|
||||||
|
|
||||||
export default class Test extends WuhuBase {
|
export default class Test extends WuhuBase {
|
||||||
className = 'Test';
|
className = 'Test';
|
||||||
@ -12,10 +15,17 @@ export default class Test extends WuhuBase {
|
|||||||
let popup = new Popup(CommonUtils.getInstance().getTravelStage().toString());
|
let popup = new Popup(CommonUtils.getInstance().getTravelStage().toString());
|
||||||
popup.getElement()['__POOL__'] = Test.getPool();
|
popup.getElement()['__POOL__'] = Test.getPool();
|
||||||
Log.info({ NET: globVars.WH_NET_LOG });
|
Log.info({ NET: globVars.WH_NET_LOG });
|
||||||
|
FetchUtils.getInstance().ajaxFetch({
|
||||||
|
url: '/inventory.php?step=info&itemID=205&armouryID=0&asObject=true',
|
||||||
|
|
||||||
|
method: 'GET',
|
||||||
|
referrer: 'bazaar.php',
|
||||||
|
});
|
||||||
|
ItemValueQueryHandler.getInstance().show();
|
||||||
// this.case1()
|
// this.case1()
|
||||||
// this.case2()
|
// this.case2()
|
||||||
// this.case3().then();
|
// this.case3().then();
|
||||||
|
createApp()
|
||||||
}
|
}
|
||||||
|
|
||||||
private case1() {
|
private case1() {
|
||||||
|
|||||||
16538
src/ts/test/vue.js
Normal file
16538
src/ts/test/vue.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,6 @@
|
|||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
"sourceMap": false,
|
"sourceMap": false,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
// "strict": true,
|
"strict": false
|
||||||
"jsx": "react-native"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user