This commit is contained in:
Liwanyi 2023-06-19 17:27:58 +08:00
parent 55ff6e7a5a
commit 8146b165f9
15 changed files with 304 additions and 142 deletions

View File

@ -5,6 +5,15 @@
# CHANGE
## 1.0.5
2023年06月19日
### 修改
- 移除原菜单
- 调整了新菜单的样式、部分逻辑
## 1.0.4
2023年06月16日

View File

@ -1,6 +1,6 @@
{
"name": "wuhu-torn-helper",
"version": "1.0.4",
"version": "1.0.5",
"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

@ -282,3 +282,7 @@ div#wh-popup::after {
.non-selection {
user-select: none;
}
.el-overlay {
backdrop-filter: blur(20px);
}

View File

@ -1,6 +1,5 @@
import WuhuBase from "./class/WuhuBase";
import WuHuTornHelper from "./class/WuhuTornHelper";
import ZhongIcon from "./class/ZhongIcon";
import { Common } from "./class/Common";
import UrlRouter from "./class/UrlRouter";
import translateMain from "./func/translate/translateMain";
@ -13,7 +12,7 @@ import { Injectable } from "./container/Injectable";
@Injectable()
export default class App {
constructor(
private readonly icon: ZhongIcon,
// private readonly icon: ZhongIcon,
private readonly wuhuBase: WuhuBase,
private readonly tornHelper: WuHuTornHelper,
private readonly common: Common,
@ -31,7 +30,7 @@ export default class App {
this.tornHelper.init();
// 插件图标和设置菜单
this.icon.init();
// this.icon.init();
let tmp = () => {
// 所有页面通用

View File

@ -6,7 +6,6 @@ import AttackHelper from "./action/AttackHelper";
import SidebarHelper from "./action/SidebarHelper";
import CommonUtils from "./utils/CommonUtils";
import FetchUtils from "./utils/FetchUtils";
import ZhongIcon from "./ZhongIcon";
import FetchEventCallback from "./action/FetchEventCallback";
import globVars from "../globVars";
import TranslateNew from "./action/TranslateNew";
@ -35,7 +34,7 @@ export class Common {
private readonly tornPDAUtils: TornPDAUtils,
private readonly logger: Logger,
private readonly buyBeerHelper: BuyBeerHelper,
private readonly icon: ZhongIcon,
// private readonly icon: ZhongIcon,
private readonly fetchUtils: FetchUtils,
private readonly moduleLoader: ModuleLoader,
private readonly msgWrapper: MsgWrapper,
@ -132,7 +131,7 @@ export class Common {
this.logger.info("现金变动提醒", mutations);
mutations.forEach(item => {
if (item.attributeName === 'data-money') {
this.icon.updateCashView(userMoney.innerText);
// this.icon.updateCashView(userMoney.innerText);
this.msgWrapper.create(
'现金变动 ' + item.oldValue + ' ➡️ ' + userMoney.innerText,
{ sysNotify: true }

View File

@ -10,7 +10,7 @@ import Logger from "../Logger";
@ClassName('ChangeLogHandler')
@Injectable()
class ChangeLogHandler extends Provider {
export class ChangeLogHandler extends Provider {
constructor(
private readonly mdUtils: MDUtils,
private readonly logger: Logger,

View File

@ -1,7 +1,7 @@
import "reflect-metadata";
import ZhongIcon from "../ZhongIcon";
import { Container } from "../../container/Container";
import Logger from "../Logger";
import globVars from "../../globVars";
export default function EntryPoint(T: { main: () => void }) {
if (window.WHTRANS) {
@ -20,9 +20,10 @@ export default function EntryPoint(T: { main: () => void }) {
logger.error('[Starter]加载出错信息: ' + e.stack || e.message);
}
let runTime: number = (performance.now() - started) | 0;
globVars.loadTime = runTime;
logger.info(`芜湖脚本完成加载, 耗时${ runTime }ms`);
if (ZhongIcon.ZhongNode && ZhongIcon.ZhongNode.initTimer)
ZhongIcon.ZhongNode.initTimer.innerHTML = `加载时间 ${ runTime }ms`;
// if (ZhongIcon.ZhongNode && ZhongIcon.ZhongNode.initTimer)
// ZhongIcon.ZhongNode.initTimer.innerHTML = `加载时间 ${ runTime }ms`;
};
const evHandler = () => {
// console.log('document.readyState: ' + document.readyState);

View File

@ -1,7 +1,7 @@
import ZhongIcon from "../ZhongIcon";
import ClassName from "../../container/ClassName";
import { Injectable } from "../../container/Injectable";
import Logger from "../Logger";
import globVars from "../../globVars";
@ClassName('ActionButtonUtils')
@Injectable()
@ -16,6 +16,10 @@ export default class ActionButtonUtils {
public add(txt: string, func: (ev: Event) => void = () => null): void {
if (!this.hasAdded) this.handle(txt, func);
else this.logger.warn('ActionButton已存在');
globVars.actionList.push({
txt,
func
});
}
private handle(txt, func): void {
@ -25,7 +29,7 @@ export default class ActionButtonUtils {
btn.style.color = '#4CAF50';
btn.innerHTML = txt;
btn.addEventListener('click', func);
ZhongIcon.ZhongNode.querySelector('button').after(btn);
// ZhongIcon.ZhongNode.querySelector('button').after(btn);
this.hasAdded = true;
this.logger.info('ActionButton已添加', { txt, func, btn });
}

View File

@ -1,7 +1,10 @@
import Popup from "../../class/utils/Popup";
import { Container } from "../../container/Container";
import Logger from "../../class/Logger";
// 传单助手
export default function adHelper() {
Container.factory(Logger).error('adHelper')
let popup = new Popup('', '传单助手').getElement();
document.querySelector('#chatRoot').classList.remove('wh-hide');
let info = document.createElement('p');

View File

@ -0,0 +1,33 @@
import { ElMessage } from "element-plus";
const useItem = (itemId: string) => {
fetch(window.addRFC("https://www.torn.com/item.php"), {
"headers": {
"accept": "*/*",
"content-type": "application/x-www-form-urlencoded;charset=UTF-8",
"sec-ch-ua-mobile": "?0",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"x-requested-with": "XMLHttpRequest"
},
"referrer": "https://www.torn.com/item.php",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": `step=useItem&id=${ itemId }&itemID=${ itemId }`,
"method": "POST",
"mode": "cors",
"credentials": "include"
})
.then(res => res.json())
.then(res => ElMessage({
message: res.text,
type: res.success ? 'success' : 'error',
dangerouslyUseHTMLString: true
}))
.catch(e => ElMessage({
message: e.toString,
type: 'error'
}));
};
export default useItem;

View File

@ -1,22 +1,14 @@
import Popup from "./class/utils/Popup";
// export default {
// // 监听到的fetch数据
// WH_NET_LOG: [],
// map: {},
// responseHandlers: [],
// version: '$$WUHU_DEV_VERSION$$',
// } 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)[],
// version: string,
// }
type ResponseHandlers = ((url: string, responseBody: { json: unknown, text: string, isModified: boolean }, opt: { method: string, requestBody: unknown }) => void)[];
type ResponseHandlers = ((url: string, responseBody: {
json: unknown,
text: string,
isModified: boolean
}, opt: {
method: string,
requestBody: unknown
}) => void)[];
/**
*
@ -28,6 +20,11 @@ class GlobVars {
responseHandlers: ResponseHandlers = [];
version = '$$WUHU_DEV_VERSION$$';
popup_node: MyHTMLElement | Popup = null;
actionList: {
txt: string,
func: (ev: Event) => void
}[] = [];
loadTime: number = 0;
}
export default new GlobVars();

View File

@ -6,37 +6,47 @@
<MoonNight/>
</el-icon>
</el-button>
<el-button circle @click="showDrawer">
<el-button v-for="item in _globVars.actionList" @click="item.func">{{ item.txt }}</el-button>
<el-button v-if="editableTabs.length > 0" circle @click="showDrawer">
<el-badge :value="editableTabs.length" type="primary">
<el-icon>
<CopyDocument/>
</el-icon>
</el-badge>
</el-button>
</el-button-group>
<el-dialog v-model="drawer" :destroy-on-close="false" :fullscreen="isMobilePhone" :lock-scroll="true"
:title="drawerTitle" style="padding: 0"
width="65%">
<el-tabs
v-model="editableTabsValue"
closable type="card"
@tab-remove="removeTab"
@tab-click="tabClick"
>
<el-tab-pane
v-for="item in editableTabs"
:key="item.name"
:label="item.title"
:name="item.name"
>
:title="editableTabsValue" width="65%">
<el-tabs v-model="editableTabsValue" closable type="card" @tab-remove="removeTab">
<el-tab-pane v-for="item in editableTabs" :key="item.name" :label="item.title" :name="item.name">
<component :is="item.content"/>
</el-tab-pane>
</el-tabs>
</el-dialog>
<el-drawer v-model="expanded" :size="isMobilePhone ? '85%' : '30%'" direction="rtl">
<template #header>
<p>便捷菜单</p>
<el-button link>芜湖助手 {{ globVars.version.startsWith('$') ? 'dev' : 'v' + globVars.version }}</el-button>
<el-drawer v-model="expanded" :show-close="false" :size="isMobilePhone ? '85%' : '30%'" direction="rtl">
<template #header="{ close, titleId, titleClass }">
<div :id="titleId" :class="titleClass">
<el-tooltip content="更新?" placement="bottom-start">
<el-button link @click="menuClick({ title: '更新', template: UpdateDate })">芜湖助手</el-button>
</el-tooltip>
<el-row>
<el-tag size="small" type="info">{{
globVars.version.startsWith('$') ? 'dev' : 'v' + globVars.version
}}
</el-tag>
</el-row>
<el-row v-if="_globVars.loadTime">
<el-text size="small">{{ _globVars.loadTime }}ms</el-text>
</el-row>
</div>
<el-button type="danger" @click="close">
<el-icon>
<CircleCloseFilled/>
</el-icon>
关闭
</el-button>
</template>
<el-menu :unique-opened="true" class="el-menu-vertical-demo">
<el-menu :unique-opened="true">
<el-sub-menu index="1">
<template #title>
<el-icon></el-icon>
@ -76,6 +86,16 @@
<el-icon>{{ item.title.slice(0, 2) }}</el-icon>
<span>{{ item.title.slice(2, item.title.length) }}</span>
</el-menu-item>
<el-sub-menu :index="2 + menuItemList.length + 1 + ''">
<template #title>
<el-icon>🪓</el-icon>
<span>老功能</span>
</template>
<el-menu-item :index="(2 + menuItemList.length + 1) + '-' + 1" @click="_adHelper">📜 传单助手</el-menu-item>
<el-menu-item :index="(2 + menuItemList.length + 1) + '-' + 2" @click="_safeKeeper">🛡 守望者</el-menu-item>
<el-menu-item :index="(2 + menuItemList.length + 1) + '-' + 3" @click="MUZHUANG">🌲 寻找木桩</el-menu-item>
<el-menu-item :index="(2 + menuItemList.length + 1) + '-' + 4" @click="_setting"> 助手设置</el-menu-item>
</el-sub-menu>
</el-menu>
</el-drawer>
</el-config-provider>
@ -83,59 +103,35 @@
<script lang="ts" setup>
import { CopyDocument, MoonNight } from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox, TabsPaneContext } from "element-plus";
import { CircleCloseFilled, CopyDocument, MoonNight } from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Component, inject, onMounted, ref, shallowRef, triggerRef } from 'vue';
import { LoggerKey } from "../ts/class/Logger";
import { QuickGymTrainKey } from "../ts/class/action/QuickGymTrain";
import { ChangeLogHandler } from "../ts/class/handler/ChangeLogHandler";
import { QuickFlyBtnHandlerKey } from "../ts/class/handler/QuickFlyBtnHandler";
import SettingsHandler from "../ts/class/handler/SettingsHandler";
import { BATTLE_STAT } from "../ts/class/utils/NetHighLvlWrapper";
import { Container } from "../ts/container/Container";
import adHelper from "../ts/func/module/adHelper";
import safeKeeper from "../ts/func/module/safeKeeper";
import useItem from "../ts/func/utils/useItem";
import globVars from "../ts/globVars";
import AutoLoginForm from "./AutoLoginForm.vue";
import CityUItems from "./CityUItems.vue";
import Config from "./Config.vue";
import CompanyWithdraw from "./CompanyWithdraw.vue";
import EventsViewer from "./EventsViewer.vue";
import ForeignStock from "./ForeignStock.vue";
import MarketHelper from "./MarketHelper.vue";
import PTMarketView from "./PTMarketView.vue";
import QuickCrime from "./QuickCrime.vue";
import UpdateDate from "./UpdateScript.vue";
import VirusProgramming from "./VirusProgramming.vue";
import CompanyWithdraw from "./CompanyWithdraw.vue";
import globVars from "../ts/globVars";
const logger = inject(LoggerKey);
const quickGymTrain = inject(QuickGymTrainKey);
const quickFlyBtnHandler = inject(QuickFlyBtnHandlerKey);
const useItem = (itemId: string) => {
fetch(window.addRFC("https://www.torn.com/item.php"), {
"headers": {
"accept": "*/*",
"content-type": "application/x-www-form-urlencoded;charset=UTF-8",
"sec-ch-ua-mobile": "?0",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"x-requested-with": "XMLHttpRequest"
},
"referrer": "https://www.torn.com/item.php",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": `step=useItem&id=${ itemId }&itemID=${ itemId }`,
"method": "POST",
"mode": "cors",
"credentials": "include"
})
.then(res => res.json())
.then(res => ElMessage({
message: res.text,
type: res.success ? 'success' : 'error',
dangerouslyUseHTMLString: true
}))
.catch(e => ElMessage({
message: e.toString,
type: 'error'
}));
};
type MenuItem = { title: string, template?: Component, handler?: Function };
const menuItemList: MenuItem[] = [
{
@ -213,16 +209,23 @@ const menuItemList: MenuItem[] = [
handler: () => bazaarControl.method(),
},
{
title: '⚙️ 插件配置',
template: Config,
title: '🚀 更新历史',
handler: () => {
expanded.value = false
Container.factory(ChangeLogHandler).show()
},
},
// {
// title: ' ',
// template: Config,
// },
];
const drawer = ref(false);
const drawerTitle = ref('');
const drawerContent = shallowRef(null);
const isMobilePhone = ref(false);
const documentHeight = ref(0);
const expanded = ref(false);
const _globVars = ref(globVars);
logger.info({ _globVars })
// tabs
const editableTabsValue = ref('');
const editableTabs = shallowRef([]);
@ -242,12 +245,26 @@ const travelData = [
{ cName: "南非", index: 10 },
];
const MUZHUANG = () => window.location.replace('https://www.torn.com/item.php?temp=4#xunzhaomuzhuang');
const _adHelper = () => {
expanded.value = false;
adHelper();
}
const _safeKeeper = () => {
expanded.value = false;
safeKeeper();
}
const _setting = () => {
expanded.value = false;
SettingsHandler.clickFunc();
}
const menuClick = (menuItem: MenuItem) => {
if (menuItem.handler) {
menuItem.handler();
} else if (menuItem.template) {
drawer.value = true;
drawerTitle.value = menuItem.title;
// drawerTitle.value = menuItem.title;
// drawerContent.value = menuItem.template;
addTab(menuItem);
}
@ -255,17 +272,18 @@ const menuClick = (menuItem: MenuItem) => {
const showDrawer = () => {
if (editableTabs.value.length < 1) {
ElMessage.warning('页面还没有打开任何功能标签');
} else {
drawer.value = true;
logger.error('页面还没有打开任何功能标签');
throw new Error('页面还没有打开任何功能标签');
}
drawer.value = true;
};
const addTab = (menuItem: MenuItem) => {
for (let i = 0; i < editableTabs.value.length; i++) {
if (editableTabs.value[i].name === menuItem.title) {
editableTabsValue.value = menuItem.title;
drawerTitle.value = menuItem.title;
// drawerTitle.value = menuItem.title;
return;
}
}
@ -281,6 +299,10 @@ const addTab = (menuItem: MenuItem) => {
const removeTab = (targetName: string) => {
const tabs = editableTabs.value
let activeName = editableTabsValue.value
logger.info({
activeName,
targetName
})
if (activeName === targetName) {
tabs.forEach((tab, index) => {
if (tab.name === targetName) {
@ -294,15 +316,19 @@ const removeTab = (targetName: string) => {
editableTabsValue.value = activeName
editableTabs.value = tabs.filter((tab) => tab.name !== targetName)
logger.info({
activeName,
targetName
})
if (editableTabs.value.length < 1) {
drawer.value = false;
}
};
const tabClick = (pane: TabsPaneContext) => {
drawerTitle.value = <string>pane.paneName;
}
// const tabClick = (pane: TabsPaneContext) => {
// drawerTitle.value = <string>pane.paneName;
// }
const travelConfirm = (destIndex: number, typeIndex: number) => {
const destName = travelData[destIndex].cName;

View File

@ -5,12 +5,6 @@
<el-skeleton v-if="loading" :rows="3" animated/>
</template>
<script lang="ts">
export default {
name: "QuickCrime"
}
</script>
<script lang="ts" setup>
import { inject, ref } from 'vue';
import { ElMessage } from "element-plus";
@ -44,6 +38,16 @@ const doCrime = async (nerve, crime: "hackbank" | "warehouse") => {
logger.error(e.stack);
results.value = e.message;
}
let err;
try {
err = JSON.parse(results.value).error;
} catch (e) {
}
if (err) {
results.value = '出错了';
ElMessage.error('错误: ' + err);
logger.error(err);
}
loading.value = false;
};
</script>

83
src/vue/UpdateScript.vue Normal file
View File

@ -0,0 +1,83 @@
<script lang="ts" setup>
import { ElMessage } from "element-plus";
import { inject, ref } from "vue";
import { LoggerKey } from "../ts/class/Logger";
import CommonUtils from "../ts/class/utils/CommonUtils";
const logger = inject(LoggerKey)
const loading = ref(false)
const now = performance.now()
const loadAndCopy = async () => {
loading.value = true
let latest: string
try {
latest = await CommonUtils.COFetch(`https://jjins.github.io/fyfuzhi/release.min.user.js?${ performance.now() }`)
} catch (e) {
logger.error(e.stack)
ElMessage.error(e.message)
loading.value = false
throw e
}
if (navigator.clipboard) {
await navigator.clipboard.writeText(latest)
ElMessage.success('脚本已复制,请前往粘贴')
} else {
ElMessage.error('浏览器不支持复制指令')
}
loading.value = false
}
</script>
<template>
<el-space direction="vertical" style="width: 100%">
<el-row>
<el-text>最新版本:
<el-image :src="'https://jjins.github.io/t2i/version.png?' + now" alt="latest"
style="width: 80px;height: 16px"/>
</el-text>
</el-row>
<el-row>
<el-text size="large">电脑</el-text>
</el-row>
<el-text>浏览器运行油猴等用户脚本扩展
<el-image alt="tm.png" src="//jjins.github.io/tm.png"/>
<el-image alt="vm.png"
src="//jjins.github.io/vm.png"/>
时可以使用链接安装自动更新:
<el-link
href="//gitlab.com/JJins/wuhu-torn-helper/-/raw/dev/release.min.user.js" target="_blank"
type="primary">点此安装
</el-link>
</el-text>
<el-divider/>
<el-col>
<el-text size="large">手机</el-text>
</el-col>
<el-text>安卓 ( KIWI) 等可以用油猴脚本的浏览器也可以点上面的链接安装</el-text>
<el-text>Torn PDA app Alook 用户可打开
<el-link href="//jjins.github.io/fyfuzhi/" target="_blank"
type="primary">此页面
</el-link>
快捷复制粘贴
</el-text>
<el-text>Torn PDA Injection time 请选择 Start 达到最好效果</el-text>
<el-divider/>
<el-col>
<el-text size="large">直接复制</el-text>
</el-col>
<el-text>加载脚本后复制粘贴到用户脚本处</el-text>
<el-button :loading="loading" @click="loadAndCopy">加载</el-button>
</el-space>
</template>
<style scoped>
.el-image {
width: 20px;
}
</style>