### 添加

- 快捷功能-PI存钱

### 修改

- 上次动作的url判断修复
- profile页面中添加了更明显的上次动作时间
- 快速取钱功能添加了常用输入
This commit is contained in:
Liwanyi 2024-03-15 16:06:23 +08:00
parent 5ec20fa327
commit 234022c80c
13 changed files with 281 additions and 24 deletions

View File

@ -1,10 +1,19 @@
# TODO
- 翻译baza npc商店、imarket、imarket搜索结果
- log重构通知重构
# CHANGE
## 1.1.7
2024年03月15日
### 添加
- 快捷功能-PI存钱
### 修改
- 上次动作的url判断修复
- profile页面中添加了更明显的上次动作时间
- 快速取钱功能添加了常用输入
## 1.1.6
2024年01月08日

32
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "wuhu-torn-helper",
"version": "1.1.1",
"version": "1.1.7",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "wuhu-torn-helper",
"version": "1.1.1",
"version": "1.1.7",
"devDependencies": {
"@element-plus/icons-vue": "^2.1.0",
"@rollup/plugin-alias": "^4.0.3",
@ -1577,10 +1577,24 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001528",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001528.tgz",
"integrity": "sha512-0Db4yyjR9QMNlsxh+kKWzQtkyflkG/snYheSzkjmvdEtEXB1+jt7A2HmSEiO6XIJPIbo92lHNGNySvE5pZcs5Q==",
"dev": true
"version": "1.0.30001597",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz",
"integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/browserslist"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
]
},
"node_modules/chalk": {
"version": "4.1.2",
@ -8747,9 +8761,9 @@
}
},
"caniuse-lite": {
"version": "1.0.30001528",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001528.tgz",
"integrity": "sha512-0Db4yyjR9QMNlsxh+kKWzQtkyflkG/snYheSzkjmvdEtEXB1+jt7A2HmSEiO6XIJPIbo92lHNGNySvE5pZcs5Q==",
"version": "1.0.30001597",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz",
"integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==",
"dev": true
},
"chalk": {

View File

@ -1,6 +1,6 @@
{
"name": "wuhu-torn-helper",
"version": "1.1.6",
"version": "1.1.7",
"description": "芜湖助手",
"scripts": {
"release": "cross-env NODE_ENV=production rollup -c && node build.mjs",

File diff suppressed because one or more lines are too long

View File

@ -20,6 +20,7 @@ import FetchUtils from "./utils/FetchUtils";
@ClassName('Initializer')
export default class Initializer {
private readonly logger: Logger = Logger.factory(Initializer)
constructor(
private readonly global: Global,
private readonly infoUtils: InfoUtils,
@ -142,6 +143,7 @@ export default class Initializer {
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);

View File

@ -30,7 +30,7 @@ export default class FetchEventCallback extends Provider implements ResponseInje
*/
public responseHandler(url: string, response) {
// mini profile 中添加上次动作
if (url.startsWith('/profiles.php?step=getMiniProfile&XID=') && this.localConfigWrapper.config.ShowMiniProfLastAct) {
if (url.startsWith('/page.php?sid=UserMiniProfile&userID') && this.localConfigWrapper.config.ShowMiniProfLastAct) {
window.setTimeout(async () => {
let cont = CommonUtils.querySelector('[class*=profile-mini-_userProfileWrapper___]');
let resp: MiniProfile = response.json as MiniProfile;

View File

@ -70,16 +70,40 @@ export default class ProfileHelper implements ResponseInject, IFeature {
responseHandler(url: string, body: { json: unknown; text: string; isModified: boolean }) {
if (url.includes('profiles.php?step=getProfileData') && this.task) {
// 曾用名
let nameHistoryNode;
nameHistoryNode = document.createElement('p');
const nameHistoryNode = document.createElement('p');
nameHistoryNode.innerHTML = '曾用名:';
this.block.append(nameHistoryNode);
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 + ' ');
} else {
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 = '<li class="user-status-16-Online left"></li> 在线'
break
}
if (item.id === 62) {
onlineStatusTitle = '<li class="user-status-16-Away left"></li> 挂机'
break
}
if (item.id === 2) {
onlineStatusTitle = '<li class="user-status-16-Offline left"></li> 离线'
break
}
}
}
const lastActionNode = document.createElement('p')
lastActionNode.innerHTML = `${ onlineStatusTitle } ${ this.commonUtils.secondsFormat(lastAction) }`
this.block.append(lastActionNode)
this.task = false;
}
}

View File

@ -55,7 +55,7 @@ export default class CompanyHelper implements IFeature {
*/
private async trainsDetect(test: boolean = false): Promise<null> {
// 通过用户的icon判断公司老板
if ((await this.infoUtils.getSessionData()).statusIcons.icons.company.iconID !== 'icon73') {
if ((await this.infoUtils.getSessionData()).statusIcons.icons.company?.iconID !== 'icon73') {
this.logger.info('火车检测跳过:非公司老板');
return;
}

View File

@ -22,3 +22,7 @@ export const fetchCurrentMoney = async (action?: string): Promise<number> => {
export const fetchCurrentCompanyAvailableMoney = () => {
return fetchCurrentMoney("companyAction");
};
export const fetchCurrentPropVaultAvailableMoney = () => {
return fetchCurrentMoney("propertyDepositAction");
};

View File

@ -38,7 +38,10 @@ export default interface IUserProfileData {
}
};
medalInformation: unknown;
basicInformation: unknown;
basicInformation: {
icons: { id: number, title: string }[],
lastAction: { seconds: number }
};
personalInformation: unknown;
competitionStatus: unknown;
staffTools: null;

View File

@ -124,6 +124,13 @@ onMounted(() => {
</template>
</el-input>
</el-form-item>
<el-button-group>
<el-button type="primary" @click="()=>inputMoney='1000000'">1m</el-button>
<el-button type="primary" @click="()=>inputMoney='2000000'">2m</el-button>
<el-button type="primary" @click="()=>inputMoney='5000000'">5m</el-button>
<el-button type="primary" @click="()=>inputMoney='10000000'">10m</el-button>
<el-button type="primary" @click="()=>inputMoney='20000000'">20m</el-button>
</el-button-group>
</el-form>
</template>

View File

@ -158,6 +158,7 @@ import PTMarketView from "./PTMarketView.vue"
import QuickCrime from "./QuickCrime.vue"
import UpdateDate from "./UpdateScript.vue"
import VirusProgramming from "./VirusProgramming.vue"
import PropertyVault from "./PropertyVault.vue";
const logger = inject(LoggerKey)
const quickGymTrain = inject(QuickGymTrainKey)
@ -234,6 +235,10 @@ const menuItemList: MenuItem[] = [
title: '💰 公司存钱',
template: CompanyWithdraw,
},
{
title: '💰 PI存钱',
template: PropertyVault,
},
{
title: '📦 物品',
template: InventoryView,

189
src/vue/PropertyVault.vue Normal file
View File

@ -0,0 +1,189 @@
<script lang="ts" setup>
import { inject, onMounted, ref } from "vue"
import { LoggerKey } from "../ts/class/Logger"
import { fetchCurrentMoney, fetchCurrentPropVaultAvailableMoney } from "../ts/func/utils/fetchCurrentMoney"
import { ElMessage } from "element-plus"
import toThousands from "../ts/func/utils/toThousands"
const logger = inject(LoggerKey)
const inputMoney = ref('')
const inputWithdrawMoney = ref('')
const formModel = ref({
cash: 0, vault: 0,
})
const propId = ref(-1)
const updateCash = async () => {
formModel.value.cash = await fetchCurrentMoney()
return formModel.value.cash
}
const updateVault = async () => {
formModel.value.vault = await fetchCurrentPropVaultAvailableMoney()
return formModel.value.vault
}
/**
* 存取钱通用
* @param amount
* @param action {'deposit' | 'withdraw'}
*/
const deposit = async (amount: number, action: 'deposit' | 'withdraw' = 'deposit') => {
if (amount < 1) {
ElMessage.error('数额不能小于1')
logger.error('数额不能小于1')
throw new Error('数额不能小于1')
}
if (propId.value === -1) {
ElMessage.error('未获取到房产id')
logger.error('未获取到房产id')
throw new Error('未获取到房产id')
}
let response: string
try {
response = await (await fetch(window.addRFC("https://www.torn.com/properties.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/properties.php",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": "step=vaultProperty&" + action + "=" + amount + "&ID=" + propId.value,
"method": "POST",
"mode": "cors",
"credentials": "include"
})).text()
} catch (e) {
ElMessage.error('请求出错 ' + e.message)
logger.error(e.stack)
throw e
}
let error: string, text: string
try {
let json = JSON.parse(response)
error = json.error
text = json.text
} catch (e) {
}
if (error) {
ElMessage.error('$' + toThousands(amount) + ' 存取请求失败 ' + text)
logger.error('存取请求失败 ' + text)
throw new Error('存取请求失败 ' + text)
} else {
ElMessage.success('$' + toThousands(amount) + ' 存取请求完成')
}
if (action === 'deposit') {
inputWithdrawMoney.value = ''
} else {
inputMoney.value = ''
}
updateVault().then()
updateCash().then()
}
const getPropId = async () => {
let response: string
try {
response = await (await fetch("https://www.torn.com/properties.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/properties.php",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": "p=options&tab=vault&step=options",
"method": "POST",
"mode": "cors",
"credentials": "include"
})).text()
} catch (e) {
ElMessage.error('获取房产id失败请重试')
logger.error('获取房产id失败', e)
throw e
}
const reg = /&ID=(\d+)"/
const match = response.match(reg)
if (match) {
propId.value = Number(match[1])
} else {
ElMessage.error('获取房产id失败报文未能成功匹配')
logger.error('获取房产id失败报文未能成功匹配')
throw new Error('获取房产id失败报文未能成功匹配')
}
}
onMounted(async () => {
await getPropId()
await updateCash()
await updateVault()
})
</script>
<template>
<div class="gap4">
<el-card shadow="never">当前默认房产id{{ propId }}</el-card>
<el-card shadow="never">
<template #header>
存钱{{ toThousands(formModel.cash) }}
</template>
<el-row>
<el-col :span="3">
<el-button @click="async ()=>inputMoney=String(await updateCash())">$</el-button>
</el-col>
<el-col :span="18">
<el-input v-model="inputMoney"/>
</el-col>
<el-col :span="3">
<el-button @click="()=>{deposit(Number(inputMoney),'deposit');inputMoney=''}">确定</el-button>
</el-col>
</el-row>
</el-card>
<el-card shadow="never">
<template #header>
取钱{{ toThousands(formModel.vault) }}
</template>
<el-row>
<el-button-group>
<el-button type="primary" @click="()=>inputWithdrawMoney='1000000'">1m</el-button>
<el-button type="primary" @click="()=>inputWithdrawMoney='2000000'">2m</el-button>
<el-button type="primary" @click="()=>inputWithdrawMoney='5000000'">5m</el-button>
<el-button type="primary" @click="()=>inputWithdrawMoney='10000000'">10m</el-button>
<el-button type="primary" @click="()=>inputWithdrawMoney='20000000'">20m</el-button>
</el-button-group>
</el-row>
<el-row>
<el-col :span="3">
<el-button @click="async ()=>inputWithdrawMoney=String(await updateVault())">$</el-button>
</el-col>
<el-col :span="18">
<el-input v-model="inputWithdrawMoney"/>
</el-col>
<el-col :span="3">
<el-button @click="()=>{deposit(Number(inputWithdrawMoney),'withdraw');inputWithdrawMoney=''}">确定
</el-button>
</el-col>
</el-row>
</el-card>
</div>
</template>
<style scoped>
.gap4 .el-card {
margin-bottom: 4px;
}
</style>