napgram-plugin-slave-market 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.
- package/README.md +248 -0
- package/dist/commands/admin.commands.d.ts +11 -0
- package/dist/commands/admin.commands.d.ts.map +1 -0
- package/dist/commands/admin.commands.js +268 -0
- package/dist/commands/bank.commands.d.ts +13 -0
- package/dist/commands/bank.commands.d.ts.map +1 -0
- package/dist/commands/bank.commands.js +211 -0
- package/dist/commands/base.commands.d.ts +12 -0
- package/dist/commands/base.commands.d.ts.map +1 -0
- package/dist/commands/base.commands.js +149 -0
- package/dist/commands/economy.commands.d.ts +13 -0
- package/dist/commands/economy.commands.d.ts.map +1 -0
- package/dist/commands/economy.commands.js +221 -0
- package/dist/commands/gameplay.commands.d.ts +15 -0
- package/dist/commands/gameplay.commands.d.ts.map +1 -0
- package/dist/commands/gameplay.commands.js +461 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +47 -0
- package/dist/commands/social.commands.d.ts +13 -0
- package/dist/commands/social.commands.d.ts.map +1 -0
- package/dist/commands/social.commands.js +305 -0
- package/dist/config.d.ts +37 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +35 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.mjs +57 -0
- package/dist/models/index.d.ts +10 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +40 -0
- package/dist/services/admin.service.d.ts +59 -0
- package/dist/services/admin.service.d.ts.map +1 -0
- package/dist/services/admin.service.js +164 -0
- package/dist/services/bank.service.d.ts +74 -0
- package/dist/services/bank.service.d.ts.map +1 -0
- package/dist/services/bank.service.js +354 -0
- package/dist/services/bodyguard.service.d.ts +36 -0
- package/dist/services/bodyguard.service.d.ts.map +1 -0
- package/dist/services/bodyguard.service.js +102 -0
- package/dist/services/cooldown.service.d.ts +33 -0
- package/dist/services/cooldown.service.d.ts.map +1 -0
- package/dist/services/cooldown.service.js +104 -0
- package/dist/services/farm.service.d.ts +61 -0
- package/dist/services/farm.service.d.ts.map +1 -0
- package/dist/services/farm.service.js +255 -0
- package/dist/services/index.d.ts +16 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +15 -0
- package/dist/services/market.service.d.ts +58 -0
- package/dist/services/market.service.d.ts.map +1 -0
- package/dist/services/market.service.js +286 -0
- package/dist/services/player.service.d.ts +56 -0
- package/dist/services/player.service.d.ts.map +1 -0
- package/dist/services/player.service.js +201 -0
- package/dist/services/ranking.service.d.ts +28 -0
- package/dist/services/ranking.service.d.ts.map +1 -0
- package/dist/services/ranking.service.js +71 -0
- package/dist/services/redpacket.service.d.ts +63 -0
- package/dist/services/redpacket.service.d.ts.map +1 -0
- package/dist/services/redpacket.service.js +207 -0
- package/dist/services/transaction.service.d.ts +48 -0
- package/dist/services/transaction.service.d.ts.map +1 -0
- package/dist/services/transaction.service.js +102 -0
- package/dist/services/vip.service.d.ts +41 -0
- package/dist/services/vip.service.d.ts.map +1 -0
- package/dist/services/vip.service.js +167 -0
- package/dist/services/work.service.d.ts +49 -0
- package/dist/services/work.service.d.ts.map +1 -0
- package/dist/services/work.service.js +258 -0
- package/dist/types/index.d.ts +62 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/utils/helpers.d.ts +40 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +88 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/napgram-plugin.json +15 -0
- package/package.json +56 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 社交功能命令 - VIP、红包、排行榜
|
|
3
|
+
*/
|
|
4
|
+
import { createCommand, makeText } from '@napgram/sdk';
|
|
5
|
+
export function registerSocialCommands(ctx, config, services) {
|
|
6
|
+
const { playerService, vipService, redPacketService, rankingService } = services;
|
|
7
|
+
// ========== VIP系统 ==========
|
|
8
|
+
// 生成VIP卡命令(仅管理员)
|
|
9
|
+
ctx.command(createCommand({
|
|
10
|
+
name: '生成vip卡',
|
|
11
|
+
description: '生成VIP卡密(管理员)',
|
|
12
|
+
handler: async (event, args) => {
|
|
13
|
+
try {
|
|
14
|
+
const userId = event.sender.userId;
|
|
15
|
+
const player = await playerService.getPlayer(userId);
|
|
16
|
+
if (player?.commandBanned) {
|
|
17
|
+
await event.reply([makeText('❌ 你的命令权限已被禁用')]);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const isAdmin = await playerService.isAdmin(userId);
|
|
21
|
+
if (!isAdmin) {
|
|
22
|
+
await event.reply([makeText('❌ 只有管理员可以生成VIP卡')]);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const type = args[0];
|
|
26
|
+
const count = Number(args[1]);
|
|
27
|
+
const hours = args[2] ? Number(args[2]) : undefined;
|
|
28
|
+
if (!type || isNaN(count) || count <= 0 || count > 100) {
|
|
29
|
+
await event.reply([makeText('❌ 用法:生成vip卡 <类型> <数量> [小时]\n类型:日卡、周卡、月卡、小时卡\n数量:1-100')]);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
let cardType;
|
|
33
|
+
switch (type) {
|
|
34
|
+
case '日卡':
|
|
35
|
+
cardType = '日卡';
|
|
36
|
+
break;
|
|
37
|
+
case '周卡':
|
|
38
|
+
cardType = '周卡';
|
|
39
|
+
break;
|
|
40
|
+
case '月卡':
|
|
41
|
+
cardType = '月卡';
|
|
42
|
+
break;
|
|
43
|
+
case '小时卡':
|
|
44
|
+
if (!hours || hours <= 0) {
|
|
45
|
+
await event.reply([makeText('❌ 小时卡需要指定时长')]);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
cardType = '小时卡';
|
|
49
|
+
break;
|
|
50
|
+
default:
|
|
51
|
+
await event.reply([makeText('❌ 卡类型错误,支持:日卡、周卡、月卡、小时卡')]);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const cards = await vipService.generateVipCards(userId, cardType, count, hours);
|
|
55
|
+
let message = `✅ 生成成功!\n\n`;
|
|
56
|
+
message += `🎫 卡类型: ${cardType}\n`;
|
|
57
|
+
message += `📦 数量: ${count}\n\n`;
|
|
58
|
+
message += `卡密列表:\n`;
|
|
59
|
+
for (let i = 0; i < cards.length; i++) {
|
|
60
|
+
message += `${i + 1}. ${cards[i]}\n`;
|
|
61
|
+
}
|
|
62
|
+
await event.reply([makeText(message)]);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
await event.reply([makeText(`❌ 生成失败:${error.message}`)]);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}));
|
|
69
|
+
// VIP兑换命令
|
|
70
|
+
ctx.command(createCommand({
|
|
71
|
+
name: 'vip兑换',
|
|
72
|
+
description: '兑换VIP卡密',
|
|
73
|
+
handler: async (event, args) => {
|
|
74
|
+
try {
|
|
75
|
+
const userId = event.sender.userId;
|
|
76
|
+
const player = await playerService.getPlayer(userId);
|
|
77
|
+
if (!player) {
|
|
78
|
+
await event.reply([makeText('❌ 你还未注册')]);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (player.commandBanned) {
|
|
82
|
+
await event.reply([makeText('❌ 你的命令权限已被禁用')]);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const code = args[0];
|
|
86
|
+
if (!code) {
|
|
87
|
+
await event.reply([makeText('❌ 请输入卡密')]);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const result = await vipService.redeemVipCard(userId, code.toUpperCase());
|
|
91
|
+
await event.reply([makeText(`✅ 兑换成功!\n\n🎫 卡类型: ${result.cardType}\n⏰ 时长: ${result.duration} 小时\n📅 到期时间: ${new Date(result.newEndTime).toLocaleString('zh-CN')}\n\n👑 VIP特权已激活!`)]);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
await event.reply([makeText(`❌ 兑换失败:${error.message}`)]);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}));
|
|
98
|
+
// VIP状态命令
|
|
99
|
+
ctx.command(createCommand({
|
|
100
|
+
name: 'vip状态',
|
|
101
|
+
aliases: ['vip'],
|
|
102
|
+
description: '查看VIP状态',
|
|
103
|
+
handler: async (event) => {
|
|
104
|
+
try {
|
|
105
|
+
const userId = event.sender.userId;
|
|
106
|
+
const player = await playerService.getPlayer(userId);
|
|
107
|
+
if (player?.commandBanned) {
|
|
108
|
+
await event.reply([makeText('❌ 你的命令权限已被禁用')]);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const status = await vipService.checkVipStatus(userId);
|
|
112
|
+
if (!status.isVip) {
|
|
113
|
+
await event.reply([makeText(`👑 VIP状态\n\n当前未激活VIP\n\n💡 使用"vip兑换 <卡密>"激活VIP`)]);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (status.isPermanent) {
|
|
117
|
+
await event.reply([makeText(`👑 VIP状态\n\n状态: ✅ 永久VIP(管理员)\n\n🎁 特权:\n - 转账免手续费\n - 购买/抢牛马免花费\n - 开地/种地/雇佣保镖免消耗\n - 无冷却限制`)]);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const days = Math.floor(status.remaining / 24);
|
|
121
|
+
const hours = status.remaining % 24;
|
|
122
|
+
await event.reply([makeText(`👑 VIP状态\n\n状态: ✅ 已激活\n⏰ 剩余: ${days}天 ${hours}小时\n\n🎁 特权:\n - 转账免手续费\n - 专属福利`)]);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
await event.reply([makeText(`❌ 查询失败:${error.message}`)]);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}));
|
|
129
|
+
// ========== 红包系统 ==========
|
|
130
|
+
// 发红包命令
|
|
131
|
+
ctx.command(createCommand({
|
|
132
|
+
name: '发红包',
|
|
133
|
+
description: '发送红包',
|
|
134
|
+
handler: async (event, args) => {
|
|
135
|
+
try {
|
|
136
|
+
const userId = event.sender.userId;
|
|
137
|
+
const player = await playerService.getPlayer(userId);
|
|
138
|
+
if (!player) {
|
|
139
|
+
await event.reply([makeText('❌ 你还未注册')]);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (player.commandBanned) {
|
|
143
|
+
await event.reply([makeText('❌ 你的命令权限已被禁用')]);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const userName = event.sender.userName || '匿名';
|
|
147
|
+
const scopeKey = event.channelType === 'group' ? event.channelId : userId;
|
|
148
|
+
const amount = Number(args[0]);
|
|
149
|
+
const count = Number(args[1]);
|
|
150
|
+
if (isNaN(amount) || isNaN(count) || amount <= 0 || count <= 0) {
|
|
151
|
+
await event.reply([makeText('❌ 用法:发红包 <总金额> <份数>')]);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const isAdmin = await playerService.isAdmin(userId);
|
|
155
|
+
const result = await redPacketService.sendRedPacket(userId, userName, amount, count, scopeKey, isAdmin);
|
|
156
|
+
let message = `✅ 红包已发出!\n\n`;
|
|
157
|
+
message += `🧧 红包ID: ${result.packetId}\n`;
|
|
158
|
+
message += `💰 总金额: ${amount}\n`;
|
|
159
|
+
message += `📦 份数: ${count}\n`;
|
|
160
|
+
if (result.fee > 0) {
|
|
161
|
+
message += `💳 手续费: ${result.fee}\n`;
|
|
162
|
+
}
|
|
163
|
+
message += `💵 剩余余额: ${result.newBalance}\n\n`;
|
|
164
|
+
message += `💡 使用"抢红包 ${result.packetId}"抢红包`;
|
|
165
|
+
await event.reply([makeText(message)]);
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
await event.reply([makeText(`❌ 发红包失败:${error.message}`)]);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}));
|
|
172
|
+
// 抢红包命令
|
|
173
|
+
ctx.command(createCommand({
|
|
174
|
+
name: '抢红包',
|
|
175
|
+
aliases: ['抢', 'grab'],
|
|
176
|
+
description: '抢红包',
|
|
177
|
+
handler: async (event, args) => {
|
|
178
|
+
try {
|
|
179
|
+
const userId = event.sender.userId;
|
|
180
|
+
const player = await playerService.getPlayer(userId);
|
|
181
|
+
if (!player) {
|
|
182
|
+
await event.reply([makeText('❌ 你还未注册')]);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (player.commandBanned) {
|
|
186
|
+
await event.reply([makeText('❌ 你的命令权限已被禁用')]);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const userName = event.sender.userName || '匿名';
|
|
190
|
+
const packetId = args[0];
|
|
191
|
+
const scopeKey = event.channelType === 'group' ? event.channelId : userId;
|
|
192
|
+
if (!packetId) {
|
|
193
|
+
await event.reply([makeText('❌ 请输入红包ID')]);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const result = await redPacketService.grabRedPacket(userId, userName, packetId, scopeKey);
|
|
197
|
+
let message = `✅ 抢红包成功!\n\n`;
|
|
198
|
+
message += `💰 金额: ${result.amount}\n`;
|
|
199
|
+
message += `💵 当前余额: ${result.newBalance}\n`;
|
|
200
|
+
message += `📦 剩余: ${result.remaining} 个\n`;
|
|
201
|
+
if (result.lucky) {
|
|
202
|
+
message += `\n🎉 恭喜!你是手气最佳!`;
|
|
203
|
+
}
|
|
204
|
+
await event.reply([makeText(message)]);
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
await event.reply([makeText(`❌ 抢红包失败:${error.message}`)]);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}));
|
|
211
|
+
// ========== 排行榜系统 ==========
|
|
212
|
+
// 身价排行榜
|
|
213
|
+
ctx.command(createCommand({
|
|
214
|
+
name: '身价排行',
|
|
215
|
+
aliases: ['worth'],
|
|
216
|
+
description: '查看身价排行榜',
|
|
217
|
+
handler: async (event) => {
|
|
218
|
+
try {
|
|
219
|
+
const userId = event.sender.userId;
|
|
220
|
+
const player = await playerService.getPlayer(userId);
|
|
221
|
+
if (player?.commandBanned) {
|
|
222
|
+
await event.reply([makeText('❌ 你的命令权限已被禁用')]);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const ranking = await rankingService.getWorthRanking(10);
|
|
226
|
+
if (ranking.length === 0) {
|
|
227
|
+
await event.reply([makeText('排行榜暂无数据')]);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
let message = '💎 身价排行榜\n\n';
|
|
231
|
+
for (const item of ranking) {
|
|
232
|
+
const medal = item.rank === 1 ? '🥇' : item.rank === 2 ? '🥈' : item.rank === 3 ? '🥉' : ' ';
|
|
233
|
+
message += `${medal} ${item.rank}. ${item.player.nickname}\n`;
|
|
234
|
+
message += ` 身价: ${item.value}\n\n`;
|
|
235
|
+
}
|
|
236
|
+
await event.reply([makeText(message)]);
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
await event.reply([makeText(`❌ 查询失败:${error.message}`)]);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}));
|
|
243
|
+
// 资产排行榜
|
|
244
|
+
ctx.command(createCommand({
|
|
245
|
+
name: '资金排行',
|
|
246
|
+
aliases: ['asset'],
|
|
247
|
+
description: '查看资产排行榜',
|
|
248
|
+
handler: async (event) => {
|
|
249
|
+
try {
|
|
250
|
+
const userId = event.sender.userId;
|
|
251
|
+
const player = await playerService.getPlayer(userId);
|
|
252
|
+
if (player?.commandBanned) {
|
|
253
|
+
await event.reply([makeText('❌ 你的命令权限已被禁用')]);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const ranking = await rankingService.getAssetRanking(10);
|
|
257
|
+
if (ranking.length === 0) {
|
|
258
|
+
await event.reply([makeText('排行榜暂无数据')]);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
let message = '💰 资产排行榜(余额+存款)\n\n';
|
|
262
|
+
for (const item of ranking) {
|
|
263
|
+
const medal = item.rank === 1 ? '🥇' : item.rank === 2 ? '🥈' : item.rank === 3 ? '🥉' : ' ';
|
|
264
|
+
message += `${medal} ${item.rank}. ${item.player.nickname}\n`;
|
|
265
|
+
message += ` 资产: ${item.value}\n\n`;
|
|
266
|
+
}
|
|
267
|
+
await event.reply([makeText(message)]);
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
await event.reply([makeText(`❌ 查询失败:${error.message}`)]);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}));
|
|
274
|
+
// 牛马排行榜
|
|
275
|
+
ctx.command(createCommand({
|
|
276
|
+
name: '牛马排行',
|
|
277
|
+
aliases: ['slaves'],
|
|
278
|
+
description: '查看牛马数量排行榜',
|
|
279
|
+
handler: async (event) => {
|
|
280
|
+
try {
|
|
281
|
+
const userId = event.sender.userId;
|
|
282
|
+
const player = await playerService.getPlayer(userId);
|
|
283
|
+
if (player?.commandBanned) {
|
|
284
|
+
await event.reply([makeText('❌ 你的命令权限已被禁用')]);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
const ranking = await rankingService.getSlaveCountRanking(10);
|
|
288
|
+
if (ranking.length === 0) {
|
|
289
|
+
await event.reply([makeText('排行榜暂无数据')]);
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
let message = '🐂 牛马排行榜\n\n';
|
|
293
|
+
for (const item of ranking) {
|
|
294
|
+
const medal = item.rank === 1 ? '🥇' : item.rank === 2 ? '🥈' : item.rank === 3 ? '🥉' : ' ';
|
|
295
|
+
message += `${medal} ${item.rank}. ${item.player.nickname}\n`;
|
|
296
|
+
message += ` 牛马数: ${item.value} 个\n\n`;
|
|
297
|
+
}
|
|
298
|
+
await event.reply([makeText(message)]);
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
await event.reply([makeText(`❌ 查询失败:${error.message}`)]);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}));
|
|
305
|
+
}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 插件配置定义
|
|
3
|
+
*/
|
|
4
|
+
export interface SlaveMarketConfig {
|
|
5
|
+
初始余额: number;
|
|
6
|
+
初始身价: number;
|
|
7
|
+
初始存款上限: number;
|
|
8
|
+
管理员列表: string[];
|
|
9
|
+
打工收益比例: number;
|
|
10
|
+
抢劫收益比例: number;
|
|
11
|
+
存款利率: number;
|
|
12
|
+
转账手续费: number;
|
|
13
|
+
贷款系统: {
|
|
14
|
+
基础额度: number;
|
|
15
|
+
等级加成: number;
|
|
16
|
+
利率: number;
|
|
17
|
+
};
|
|
18
|
+
冷却时间: {
|
|
19
|
+
打工: number;
|
|
20
|
+
抢劫: number;
|
|
21
|
+
转账: number;
|
|
22
|
+
购买: number;
|
|
23
|
+
种地: number;
|
|
24
|
+
收获: number;
|
|
25
|
+
};
|
|
26
|
+
种地系统: {
|
|
27
|
+
地块价格: number[];
|
|
28
|
+
最大地块数: number;
|
|
29
|
+
};
|
|
30
|
+
VIP配置: {
|
|
31
|
+
启用: boolean;
|
|
32
|
+
管理员永久VIP: boolean;
|
|
33
|
+
};
|
|
34
|
+
调试日志: boolean;
|
|
35
|
+
}
|
|
36
|
+
export declare const defaultConfig: SlaveMarketConfig;
|
|
37
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,iBAAiB;IAE9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;IAGhB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IAGd,IAAI,EAAE;QACF,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;KACd,CAAC;IAGF,IAAI,EAAE;QACF,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;KACd,CAAC;IAGF,IAAI,EAAE;QACF,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC;IAGF,KAAK,EAAE;QACH,EAAE,EAAE,OAAO,CAAC;QACZ,QAAQ,EAAE,OAAO,CAAC;KACrB,CAAC;IAGF,IAAI,EAAE,OAAO,CAAC;CACjB;AAED,eAAO,MAAM,aAAa,EAAE,iBAqC3B,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 插件配置定义
|
|
3
|
+
*/
|
|
4
|
+
export const defaultConfig = {
|
|
5
|
+
初始余额: 0,
|
|
6
|
+
初始身价: 100,
|
|
7
|
+
初始存款上限: 1000,
|
|
8
|
+
管理员列表: [],
|
|
9
|
+
打工收益比例: 0.1,
|
|
10
|
+
抢劫收益比例: 0.3,
|
|
11
|
+
存款利率: 0.01,
|
|
12
|
+
转账手续费: 0.05,
|
|
13
|
+
贷款系统: {
|
|
14
|
+
基础额度: 1000,
|
|
15
|
+
等级加成: 500,
|
|
16
|
+
利率: 0.02,
|
|
17
|
+
},
|
|
18
|
+
冷却时间: {
|
|
19
|
+
打工: 120000, // 2分钟
|
|
20
|
+
抢劫: 60000, // 1分钟
|
|
21
|
+
转账: 120000, // 2分钟
|
|
22
|
+
购买: 300000, // 5分钟
|
|
23
|
+
种地: 30000, // 30秒
|
|
24
|
+
收获: 10000, // 10秒
|
|
25
|
+
},
|
|
26
|
+
种地系统: {
|
|
27
|
+
地块价格: [10000, 50000, 100000, 200000, 400000, 800000, 1600000, 3200000, 6400000, 12800000],
|
|
28
|
+
最大地块数: 10,
|
|
29
|
+
},
|
|
30
|
+
VIP配置: {
|
|
31
|
+
启用: true,
|
|
32
|
+
管理员永久VIP: true,
|
|
33
|
+
},
|
|
34
|
+
调试日志: false,
|
|
35
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 大牛马时代 - NapGram Plugin
|
|
3
|
+
* 群聊经济养成游戏
|
|
4
|
+
*/
|
|
5
|
+
import type { PluginContext } from '@napgram/sdk';
|
|
6
|
+
/**
|
|
7
|
+
* 大牛马时代插件
|
|
8
|
+
*/
|
|
9
|
+
declare const plugin: {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
version: string;
|
|
13
|
+
author: string;
|
|
14
|
+
description: string;
|
|
15
|
+
permissions: {
|
|
16
|
+
instances: number[];
|
|
17
|
+
};
|
|
18
|
+
install(ctx: PluginContext): Promise<void>;
|
|
19
|
+
};
|
|
20
|
+
export default plugin;
|
|
21
|
+
export { SlaveMarketConfig } from './config';
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,cAAc,CAAC;AAMhE;;GAEG;AACH,QAAA,MAAM,MAAM;;;;;;;;;iBAWW,aAAa;CAyClC,CAAC;AAEH,eAAe,MAAM,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 大牛马时代 - NapGram Plugin
|
|
3
|
+
* 群聊经济养成游戏
|
|
4
|
+
*/
|
|
5
|
+
import { definePlugin } from '@napgram/sdk';
|
|
6
|
+
import { registerCommands } from './commands';
|
|
7
|
+
import { initializeDatabase, closeDatabase } from './models';
|
|
8
|
+
import { defaultConfig } from './config';
|
|
9
|
+
import { PlayerService } from './services';
|
|
10
|
+
/**
|
|
11
|
+
* 大牛马时代插件
|
|
12
|
+
*/
|
|
13
|
+
const plugin = definePlugin({
|
|
14
|
+
id: 'slave-market',
|
|
15
|
+
name: '大牛马时代',
|
|
16
|
+
version: '1.0.0',
|
|
17
|
+
author: 'NapGram Team',
|
|
18
|
+
description: '群聊经济养成游戏插件',
|
|
19
|
+
permissions: {
|
|
20
|
+
instances: [0],
|
|
21
|
+
},
|
|
22
|
+
async install(ctx) {
|
|
23
|
+
const config = {
|
|
24
|
+
...defaultConfig,
|
|
25
|
+
...ctx.config
|
|
26
|
+
};
|
|
27
|
+
ctx.logger.info('[slave-market] Plugin activating...');
|
|
28
|
+
// 初始化数据库
|
|
29
|
+
initializeDatabase(ctx);
|
|
30
|
+
// 注册命令
|
|
31
|
+
registerCommands(ctx, config);
|
|
32
|
+
// 创建玩家服务用于自动注册
|
|
33
|
+
const playerService = new PlayerService(ctx, config);
|
|
34
|
+
// 自动注册中间件
|
|
35
|
+
ctx.on('message', async (event) => {
|
|
36
|
+
try {
|
|
37
|
+
const userId = event.sender.userId;
|
|
38
|
+
const nickname = event.sender.userName || event.sender.userId;
|
|
39
|
+
const groupId = event.channelType === 'group' ? event.channelId : undefined;
|
|
40
|
+
// 静默自动注册(不影响消息流)
|
|
41
|
+
await playerService.getOrCreatePlayer(userId, nickname, groupId);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
// 自动注册失败不影响其他功能
|
|
45
|
+
ctx.logger.debug('[slave-market] Auto register failed:', error.message);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
// 注册卸载钩子
|
|
49
|
+
ctx.onUnload(() => {
|
|
50
|
+
ctx.logger.info('[slave-market] Plugin deactivating...');
|
|
51
|
+
closeDatabase();
|
|
52
|
+
ctx.logger.info('[slave-market] Plugin deactivated');
|
|
53
|
+
});
|
|
54
|
+
ctx.logger.info('[slave-market] Plugin activated successfully');
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
export default plugin;
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 大牛马时代 - NapGram Plugin
|
|
3
|
+
* 群聊经济养成游戏
|
|
4
|
+
*/
|
|
5
|
+
import { definePlugin } from '@napgram/sdk';
|
|
6
|
+
import { registerCommands } from './commands';
|
|
7
|
+
import { initializeDatabase, closeDatabase } from './models';
|
|
8
|
+
import { defaultConfig } from './config';
|
|
9
|
+
import { PlayerService } from './services';
|
|
10
|
+
/**
|
|
11
|
+
* 大牛马时代插件
|
|
12
|
+
*/
|
|
13
|
+
const plugin = definePlugin({
|
|
14
|
+
id: 'slave-market',
|
|
15
|
+
name: '大牛马时代',
|
|
16
|
+
version: '1.0.0',
|
|
17
|
+
author: 'NapGram Team',
|
|
18
|
+
description: '群聊经济养成游戏插件',
|
|
19
|
+
permissions: {
|
|
20
|
+
instances: [0],
|
|
21
|
+
},
|
|
22
|
+
async install(ctx) {
|
|
23
|
+
const config = {
|
|
24
|
+
...defaultConfig,
|
|
25
|
+
...ctx.config
|
|
26
|
+
};
|
|
27
|
+
ctx.logger.info('[slave-market] Plugin activating...');
|
|
28
|
+
// 初始化数据库
|
|
29
|
+
initializeDatabase(ctx);
|
|
30
|
+
// 注册命令
|
|
31
|
+
registerCommands(ctx, config);
|
|
32
|
+
// 创建玩家服务用于自动注册
|
|
33
|
+
const playerService = new PlayerService(ctx, config);
|
|
34
|
+
// 自动注册中间件
|
|
35
|
+
ctx.on('message', async (event) => {
|
|
36
|
+
try {
|
|
37
|
+
const userId = event.sender.userId;
|
|
38
|
+
const nickname = event.sender.userName || event.sender.userId;
|
|
39
|
+
const groupId = event.channelType === 'group' ? event.channelId : undefined;
|
|
40
|
+
// 静默自动注册(不影响消息流)
|
|
41
|
+
await playerService.getOrCreatePlayer(userId, nickname, groupId);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
// 自动注册失败不影响其他功能
|
|
45
|
+
ctx.logger.debug('[slave-market] Auto register failed:', error.message);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
// 注册卸载钩子
|
|
49
|
+
ctx.onUnload(() => {
|
|
50
|
+
ctx.logger.info('[slave-market] Plugin deactivating...');
|
|
51
|
+
closeDatabase();
|
|
52
|
+
ctx.logger.info('[slave-market] Plugin deactivated');
|
|
53
|
+
});
|
|
54
|
+
ctx.logger.info('[slave-market] Plugin activated successfully');
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
export default plugin;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 数据库模型初始化
|
|
3
|
+
*/
|
|
4
|
+
import type { PluginContext } from '@napgram/sdk';
|
|
5
|
+
import { PrismaClient } from '@prisma/client';
|
|
6
|
+
export declare function initializeDatabase(ctx: PluginContext): PrismaClient;
|
|
7
|
+
export declare function getDatabase(): PrismaClient;
|
|
8
|
+
export declare function closeDatabase(): Promise<void>;
|
|
9
|
+
export type { SlaveMarketPlayer, SlaveMarketTransaction, SlaveMarketFarmLand, SlaveMarketAppearance, SlaveMarketRedPacket, SlaveMarketRedPacketGrab, SlaveMarketVipCard, SlaveMarketSystem, SlaveMarketAdmin, } from '@prisma/client';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAO9C,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,CAmBnE;AAED,wBAAgB,WAAW,IAAI,YAAY,CAK1C;AAED,wBAAsB,aAAa,kBAUlC;AAGD,YAAY,EACR,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,GACnB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 数据库模型初始化
|
|
3
|
+
*/
|
|
4
|
+
import { PrismaClient } from '@prisma/client';
|
|
5
|
+
import { PrismaPg } from '@prisma/adapter-pg';
|
|
6
|
+
import { Pool } from 'pg';
|
|
7
|
+
let prisma = null;
|
|
8
|
+
let pool = null;
|
|
9
|
+
export function initializeDatabase(ctx) {
|
|
10
|
+
if (!prisma) {
|
|
11
|
+
const connectionString = process.env.DATABASE_URL;
|
|
12
|
+
if (!connectionString) {
|
|
13
|
+
throw new Error('DATABASE_URL is not set');
|
|
14
|
+
}
|
|
15
|
+
pool = new Pool({ connectionString });
|
|
16
|
+
const adapter = new PrismaPg(pool);
|
|
17
|
+
prisma = new PrismaClient({
|
|
18
|
+
adapter,
|
|
19
|
+
log: ctx.config.调试日志 ? ['query', 'error', 'warn'] : ['error'],
|
|
20
|
+
});
|
|
21
|
+
ctx.logger.info('[slave-market] Database initialized');
|
|
22
|
+
}
|
|
23
|
+
return prisma;
|
|
24
|
+
}
|
|
25
|
+
export function getDatabase() {
|
|
26
|
+
if (!prisma) {
|
|
27
|
+
throw new Error('Database not initialized. Call initializeDatabase first.');
|
|
28
|
+
}
|
|
29
|
+
return prisma;
|
|
30
|
+
}
|
|
31
|
+
export async function closeDatabase() {
|
|
32
|
+
if (prisma) {
|
|
33
|
+
await prisma.$disconnect();
|
|
34
|
+
prisma = null;
|
|
35
|
+
}
|
|
36
|
+
if (pool) {
|
|
37
|
+
await pool.end();
|
|
38
|
+
pool = null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 管理员服务 - 系统管理、数据维护
|
|
3
|
+
*/
|
|
4
|
+
import type { PluginContext } from '@napgram/sdk';
|
|
5
|
+
import type { SlaveMarketConfig } from '../config';
|
|
6
|
+
export declare class AdminService {
|
|
7
|
+
private ctx;
|
|
8
|
+
private config;
|
|
9
|
+
constructor(ctx: PluginContext, config: SlaveMarketConfig);
|
|
10
|
+
/**
|
|
11
|
+
* 添加管理员
|
|
12
|
+
*/
|
|
13
|
+
addAdmin(adminId: string, targetId: string, targetName: string): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* 移除管理员
|
|
16
|
+
*/
|
|
17
|
+
removeAdmin(targetId: string): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* 重置游戏数据
|
|
20
|
+
*/
|
|
21
|
+
resetGame(): Promise<{
|
|
22
|
+
players: number;
|
|
23
|
+
transactions: number;
|
|
24
|
+
farmLands: number;
|
|
25
|
+
redPackets: number;
|
|
26
|
+
redPacketGrabs: number;
|
|
27
|
+
appearances: number;
|
|
28
|
+
vipCards: number;
|
|
29
|
+
admins: number;
|
|
30
|
+
systemConfigs: number;
|
|
31
|
+
}>;
|
|
32
|
+
/**
|
|
33
|
+
* 获取系统统计
|
|
34
|
+
*/
|
|
35
|
+
getSystemStats(): Promise<{
|
|
36
|
+
totalPlayers: number;
|
|
37
|
+
totalTransactions: number;
|
|
38
|
+
totalBalance: number;
|
|
39
|
+
totalDeposit: number;
|
|
40
|
+
activeVips: number;
|
|
41
|
+
activePlayers24h: number;
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* 禁用/启用玩家命令
|
|
45
|
+
*/
|
|
46
|
+
togglePlayerBan(targetId: string, banned: boolean): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* 清理过期数据
|
|
49
|
+
*/
|
|
50
|
+
cleanupExpiredData(): Promise<{
|
|
51
|
+
redPackets: number;
|
|
52
|
+
vipCards: number;
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* 给玩家加钱
|
|
56
|
+
*/
|
|
57
|
+
giveBalance(targetId: string, amount: number): Promise<number>;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=admin.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.service.d.ts","sourceRoot":"","sources":["../../src/services/admin.service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnD,qBAAa,YAAY;IAEjB,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,MAAM;gBADN,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,iBAAiB;IAGrC;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCpF;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBlD;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,EAAE,MAAM,CAAC;KACzB,CAAC;IAwCF;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC;QAC5B,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;KAC5B,CAAC;IA4BF;;OAEG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IASvE;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC;QAChC,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KACpB,CAAC;IA2BF;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAYvE"}
|