koishi-plugin-bns-rate 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,10 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npm install *)",
5
+ "Read(//c/Program Files/**)",
6
+ "Bash(cmd //c \"where npm\")",
7
+ "WebFetch(domain:registry.npmjs.org)"
8
+ ]
9
+ }
10
+ }
@@ -0,0 +1,18 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: actions/setup-node@v4
13
+ with:
14
+ node-version: '22'
15
+ registry-url: 'https://registry.npmjs.org'
16
+ - run: npm publish
17
+ env:
18
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/index.js ADDED
@@ -0,0 +1,94 @@
1
+ const { Schema } = require('koishi')
2
+
3
+ const DEFAULT_URL = 'https://www.dd373.com/s-d5gqt8-0-0-0-0-0-0-0-0-0-0-0-1-0-5-0.html'
4
+
5
+ const FORWARD_RE = /1元\s*=\s*(\d+\.?\d*)神石/g
6
+ const REVERSE_RE = /1神石\s*=\s*(\d+\.?\d*)元/g
7
+
8
+ const Config = Schema.object({
9
+ url: Schema.string()
10
+ .default(DEFAULT_URL)
11
+ .description('dd373 page URL for the target game server'),
12
+ cacheSeconds: Schema.number()
13
+ .default(60)
14
+ .min(10)
15
+ .max(300)
16
+ .description('Cache TTL in seconds'),
17
+ })
18
+
19
+ async function fetchRate(ctx, url) {
20
+ const response = await ctx.http.get(url, {
21
+ responseType: 'text',
22
+ headers: {
23
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
24
+ 'Accept': 'text/html,application/xhtml+xml',
25
+ 'Accept-Language': 'zh-CN,zh;q=0.9',
26
+ },
27
+ })
28
+
29
+ const html = typeof response === 'string' ? response : response.data
30
+
31
+ const forwardMatches = [...html.matchAll(FORWARD_RE)]
32
+ if (forwardMatches.length < 2) {
33
+ throw new Error('无法解析页面汇率数据,页面结构可能已变更')
34
+ }
35
+
36
+ // match[0] = 平台极速收货回收价, match[1] = 最低卖家挂单价
37
+ const forward = parseFloat(forwardMatches[1][1])
38
+
39
+ const reverseMatches = [...html.matchAll(REVERSE_RE)]
40
+ if (reverseMatches.length < 2) {
41
+ throw new Error('无法解析页面反向汇率数据')
42
+ }
43
+
44
+ const reverse = parseFloat(reverseMatches[1][1])
45
+
46
+ if (forward < 100 || forward > 200 || reverse < 0.001 || reverse > 0.02) {
47
+ throw new Error(`解析的汇率超出合理范围: forward=${forward}, reverse=${reverse}`)
48
+ }
49
+
50
+ return { forward, reverse }
51
+ }
52
+
53
+ function formatMessage(forward, reverse, timestamp) {
54
+ const time = new Date(timestamp).toLocaleString('zh-CN', {
55
+ timeZone: 'Asia/Shanghai',
56
+ })
57
+ return [
58
+ `1元 = ${forward}神石`,
59
+ `1神石 = ${reverse}元`,
60
+ `查询时间: ${time}`,
61
+ ].join('\n')
62
+ }
63
+
64
+ function apply(ctx, config) {
65
+ let cache = null
66
+
67
+ ctx.command('bnsrate', '查询剑灵怀旧服神石汇率')
68
+ .alias('神石')
69
+ .alias('shenshi')
70
+ .action(async () => {
71
+ const ttl = config.cacheSeconds * 1000
72
+
73
+ if (cache && Date.now() - cache.timestamp < ttl) {
74
+ return formatMessage(cache.forwardRate, cache.reverseRate, cache.timestamp)
75
+ }
76
+
77
+ try {
78
+ const { forward, reverse } = await fetchRate(ctx, config.url)
79
+ cache = { forwardRate: forward, reverseRate: reverse, timestamp: Date.now() }
80
+ return formatMessage(forward, reverse, cache.timestamp)
81
+ } catch (e) {
82
+ const message = e instanceof Error ? e.message : String(e)
83
+
84
+ if (cache) {
85
+ return formatMessage(cache.forwardRate, cache.reverseRate, cache.timestamp)
86
+ + '\n[警告] 汇率数据已过期,刷新失败: ' + message
87
+ }
88
+
89
+ return '获取汇率失败: ' + message
90
+ }
91
+ })
92
+ }
93
+
94
+ module.exports = { Config, apply }
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "koishi-plugin-bns-rate",
3
+ "version": "1.0.0",
4
+ "description": "Fetch BNS Classic Divine Stone exchange rate from dd373.com",
5
+ "main": "index.js",
6
+ "license": "MIT",
7
+ "keywords": ["koishi", "koishi-plugin", "bns", "dd373", "exchange-rate", "神石", "剑灵"],
8
+ "peerDependencies": {
9
+ "koishi": "^4.18.0"
10
+ },
11
+ "devDependencies": {
12
+ "koishi": "^4.18.0"
13
+ },
14
+ "service": {
15
+ "required": ["http"]
16
+ },
17
+ "koishi": {
18
+ "description": {
19
+ "zh": "从 dd373.com 获取剑灵怀旧服神石实时汇率,输入命令即可查询最低比例。支持 神石/bnsrate/shenshi 命令。",
20
+ "en": "Fetch BNS Classic Divine Stone exchange rate from dd373.com"
21
+ }
22
+ }
23
+ }