nonebot-plugin-fishing2 0.0.3__py3-none-any.whl → 0.1.0__py3-none-any.whl

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.
@@ -1,26 +1,28 @@
1
- from nonebot import on_command, require
1
+ from nonebot import require
2
2
 
3
3
  require("nonebot_plugin_orm") # noqa
4
4
 
5
- from nonebot import logger
5
+ import shlex
6
+ from typing import Union
7
+
8
+ from nonebot import on_command, logger
6
9
  from nonebot.plugin import PluginMetadata
7
10
  from nonebot.adapters import Event, Message
8
11
  from nonebot.params import CommandArg
9
- from nonebot.permission import SUPERUSER
10
12
  from nonebot.matcher import Matcher
11
13
 
12
- from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, PrivateMessageEvent, Message, MessageSegment, ActionFailed
13
-
14
- import asyncio
15
-
16
- from typing import Union
14
+ from nonebot.adapters.onebot.v11 import (
15
+ Bot,
16
+ GroupMessageEvent,
17
+ PrivateMessageEvent,
18
+ Message,
19
+ MessageSegment,
20
+ ActionFailed,
21
+ )
17
22
 
18
23
  from .config import Config, config
19
24
  from .data_source import (
20
- fish_list,
21
- get_info,
22
25
  can_fishing,
23
- can_free_fish,
24
26
  get_fish,
25
27
  get_stats,
26
28
  get_backpack,
@@ -35,108 +37,136 @@ from .data_source import (
35
37
  check_tools,
36
38
  remove_tools,
37
39
  get_shop,
38
- buy_fish
40
+ buy_fish,
41
+ predict,
42
+ get_pool,
39
43
  )
44
+ from .fish_helper import fish_list, get_fish_by_name
40
45
 
41
46
  fishing_coin_name = config.fishing_coin_name
47
+ cool_down = (
48
+ f"{config.fishing_cooldown_time_min}s~{config.fishing_cooldown_time_max}s"
49
+ if config.fishing_cooldown_time_min != config.fishing_cooldown_time_max
50
+ else f"{config.fishing_cooldown_time_min}s"
51
+ ) # 浮动 CD 法力无边,有效遏制频繁钓鱼
42
52
 
43
53
  __plugin_meta__ = PluginMetadata(
44
54
  name="更好的电子钓鱼",
45
55
  description="赛博钓鱼……但是加强版本",
46
- usage=f'''钓鱼帮助
47
- ▶ 查询 [物品]:查询某个物品的信息
56
+ usage=f"""▶ 查询 [物品]:查询某个物品的信息
48
57
  ▶ 钓鱼 [鱼竿] [鱼饵]:
49
- {config.fishing_limit}s 的冷却,时间随上一条鱼稀有度而增加
58
+ 钓鱼后有 {cool_down} 的冷却,频繁钓鱼会触怒河神
59
+ ▷ {config.no_fish_probability} 概率空军,{config.special_fish_probability} 概率钓到特殊鱼
50
60
  ▷ 加参数可以使用鱼饵或鱼竿,同类物品同时只能使用一种
51
- ▷ 频繁钓鱼会触怒河神
52
61
  ▶ 出售 <物品> <数量>:出售物品获得{fishing_coin_name}
62
+ ▷ 如果卖不出去,尝试用英文双引号框住鱼名
53
63
  ▶ 购买 <物品> <份数>:购买渔具店的物品
54
64
  ▶ 放生 <鱼名>:给一条鱼取名并放生
65
+ ▷ 不要放生奇怪名字的鱼
55
66
  ▶ 商店:看看渔具店都有些啥
56
67
  ▶ 祈愿:向神祈愿,随机获取/损失{fishing_coin_name}
57
68
  ▶ 背包:查看背包中的{fishing_coin_name}与物品
58
69
  ▶ 成就:查看拥有的成就
59
70
  ▶ 钓鱼排行榜:查看{fishing_coin_name}排行榜
60
- ''',
71
+ """,
61
72
  type="application",
62
73
  homepage="https://github.com/FDCraft/nonebot-plugin-fishing2",
63
74
  config=Config,
64
- supported_adapters=None,
65
- extra={
66
- 'author': 'Polaris_Light',
67
- 'version': '0.0.3',
68
- 'priority': 5
69
- }
75
+ supported_adapters={"~onebot.v11"},
76
+ extra={"author": "Polaris_Light", "version": "0.1.0", "priority": 5},
70
77
  )
71
78
 
72
79
 
73
-
74
80
  block_user_list = []
75
81
  punish_user_dict = {}
76
82
 
77
- fishing_help = on_command("fishing_help", aliases={"钓鱼帮助"}, priority=3,block=True)
78
- fishing_lookup = on_command("fishing_lookup", aliases={"查看", "查询"}, priority=3,block=True)
79
- fishing = on_command("fishing", aliases={"钓鱼"}, priority=5)
80
- backpack = on_command("backpack", aliases={"背包", "钓鱼背包"}, priority=5)
81
- shop = on_command("shop", aliases={"商店"}, priority=5)
82
- buy = on_command("buy", aliases={"购买"}, priority=5)
83
- sell = on_command("sell", aliases={"卖鱼", "出售", "售卖"}, priority=5)
84
- free_fish_cmd = on_command("free_fish", aliases={"放生", "钓鱼放生"}, priority=5)
85
- lottery_cmd = on_command("lottery", aliases={"祈愿"}, priority=5)
86
- achievement_cmd = on_command("achievement", aliases={"成就", "钓鱼成就"}, priority=5)
87
- give_cmd = on_command("give", aliases={"赐予"}, permission=SUPERUSER, priority=5)
88
- board_cmd = on_command("board", aliases={"排行榜", "钓鱼排行榜"}, priority=5)
83
+ # fmt:off
84
+ fishing_help = on_command("fishing_help", aliases={"钓鱼帮助"}, force_whitespace=True, priority=3, block=True)
85
+ fishing_lookup = on_command("fishing_lookup",aliases={"查看", "查询"},force_whitespace=True,priority=3,block=True,)
86
+ fishing = on_command("fishing", aliases={"钓鱼"}, force_whitespace=True, priority=5)
87
+ backpack = on_command("backpack", aliases={"背包", "钓鱼背包"}, force_whitespace=True, priority=5)
88
+ shop = on_command("shop", aliases={"商店"}, force_whitespace=True, priority=5)
89
+ buy = on_command("buy", aliases={"购买"}, force_whitespace=True, priority=5)
90
+ sell = on_command("sell", aliases={"卖鱼", "出售", "售卖"}, force_whitespace=True, priority=5)
91
+ free_fish_cmd = on_command("free_fish", aliases={"放生", "钓鱼放生"}, force_whitespace=True, priority=5)
92
+ lottery_cmd = on_command("lottery", aliases={"祈愿"}, force_whitespace=True, priority=5)
93
+ achievement_cmd = on_command("achievement", aliases={"成就", "钓鱼成就"}, force_whitespace=True, priority=5)
94
+ give_cmd = on_command("give", aliases={"赐予"}, force_whitespace=True, priority=5)
95
+ board_cmd = on_command("board", aliases={"排行榜", "钓鱼排行榜"}, force_whitespace=True, priority=5)
96
+
97
+ # hidden cmd
98
+ predict_cmd = on_command("predict", aliases={"钓鱼预测"}, force_whitespace=True, priority=5)
99
+ pool_cmd = on_command("pool", aliases={"鱼池"}, force_whitespace=True, priority=5)
100
+ # fmt:on
89
101
 
90
102
 
91
103
  @fishing_help.handle()
92
104
  async def _():
93
105
  await fishing_help.finish(__plugin_meta__.usage)
94
106
 
107
+
95
108
  @shop.handle()
96
109
  async def _(bot: Bot, event: Union[GroupMessageEvent, PrivateMessageEvent]):
97
110
  messages = get_shop()
98
111
  await forward_send(bot, event, messages)
99
112
  return None
100
-
113
+
114
+
101
115
  @fishing_lookup.handle()
102
- async def _(bot: Bot, event: Union[GroupMessageEvent, PrivateMessageEvent], arg: Message = CommandArg()):
116
+ async def _(
117
+ bot: Bot,
118
+ event: Union[GroupMessageEvent, PrivateMessageEvent],
119
+ arg: Message = CommandArg(),
120
+ ):
121
+ user_id = event.get_user_id()
103
122
  arg = arg.extract_plain_text()
104
123
  if not arg or arg == "":
105
- await fishing_lookup.finish("请输入要查询的物品\n可查询物品:" + "、".join(fish_list))
106
- await forward_send(bot, event, get_info(arg))
124
+ await fishing_lookup.finish(
125
+ "请输入要查询的物品\n可查询物品:" + "、".join(fish_list)
126
+ )
127
+ if arg == "空军":
128
+ await fishing_lookup.finish(
129
+ MessageSegment.at(user_id)
130
+ + " 在钓鱼活动中,空军指钓鱼者一无所获,没有钓到任何鱼,空手而归。"
131
+ )
132
+ elif arg not in fish_list:
133
+ await fishing_lookup.finish(MessageSegment.at(user_id) + " 查无此鱼。")
134
+
135
+ messages = get_fish_by_name(arg).print_info()
136
+ await forward_send(bot, event, messages)
107
137
  return None
108
138
 
109
139
 
110
140
  @fishing.handle()
111
- async def _(bot:Bot, event: Event, matcher: Matcher, arg: Message = CommandArg()):
141
+ async def _(bot: Bot, event: Event, matcher: Matcher, arg: Message = CommandArg()):
112
142
  user_id = event.get_user_id()
113
143
  if user_id in block_user_list:
114
144
  await fishing.finish()
115
-
116
- use_tools = False
117
- tools = arg.extract_plain_text().split()[:2]
118
- logger.debug(f"PLDEBUG0: {tools}")
119
- if tools and tools != [] and tools != [""]:
120
- use_tools = True
121
- check_result = await check_tools(user_id, tools)
122
- if check_result:
123
- await fishing.finish(MessageSegment.at(user_id) + " " + check_result)
124
-
145
+
146
+ tools = shlex.split((arg.extract_plain_text()))[:2]
147
+
148
+ logger.debug(f"Fishing: {user_id} try to use {tools}")
149
+
150
+ check_result = await check_tools(user_id, tools)
151
+ if check_result:
152
+ await fishing.finish(MessageSegment.at(user_id) + " " + check_result)
153
+
125
154
  await punish(bot, event, matcher, user_id)
126
155
  block_user_list.append(user_id)
127
156
  try:
128
- if use_tools:
129
- await remove_tools(user_id, tools)
130
- await fishing.send(MessageSegment.at(user_id) + "\n你使用了" + "、".join(tools) + "\n正在钓鱼…")
131
- result = await get_fish(user_id, tools)
132
- else:
133
- await fishing.send(MessageSegment.at(user_id) + " 正在钓鱼…")
134
- result = await get_fish(user_id)
157
+ await remove_tools(user_id, tools)
158
+ await fishing.send(
159
+ MessageSegment.at(user_id) + f'\n你使用了{"、".join(tools)}\n'
160
+ if tools != []
161
+ else "" + "正在钓鱼…"
162
+ )
163
+ result = await get_fish(user_id, tools)
135
164
  achievements = await check_achievement(user_id)
136
165
  if achievements is not None:
137
166
  for achievement in achievements:
138
167
  await fishing.send(achievement)
139
168
  except Exception as e:
169
+ result = "河神睡着了……"
140
170
  logger.error(e)
141
171
  finally:
142
172
  block_user_list.remove(user_id)
@@ -144,21 +174,84 @@ async def _(bot:Bot, event: Event, matcher: Matcher, arg: Message = CommandArg()
144
174
  await fishing.finish(MessageSegment.at(user_id) + " " + result)
145
175
 
146
176
 
177
+ @predict_cmd.handle()
178
+ async def _(
179
+ bot: Bot,
180
+ event: Union[GroupMessageEvent, PrivateMessageEvent],
181
+ arg: Message = CommandArg(),
182
+ ):
183
+ user_id = event.get_user_id()
184
+
185
+ is_superuser = str(user_id) in bot.config.superusers
186
+ is_self = event.self_id == user_id
187
+ if not is_superuser and not is_self:
188
+ return None
189
+
190
+ tools = shlex.split(arg.extract_plain_text())[:2]
191
+
192
+ tools = [x for x in tools if x != ""]
193
+
194
+ check_result = await check_tools(user_id, tools, check_have=False)
195
+ if check_result:
196
+ await predict_cmd.finish(MessageSegment.at(user_id) + " " + check_result)
197
+ result = predict(tools)
198
+ await predict_cmd.finish(result)
199
+
200
+
201
+ @pool_cmd.handle()
202
+ async def _(bot: Bot, event: Union[GroupMessageEvent, PrivateMessageEvent]):
203
+ user_id = event.get_user_id()
204
+ is_superuser = str(user_id) in bot.config.superusers
205
+ is_self = event.self_id == user_id
206
+ if not is_superuser and not is_self:
207
+ return None
208
+
209
+ messages: list[MessageSegment] = await get_pool()
210
+
211
+ await forward_send(bot, event, messages)
212
+ return None
213
+
214
+
147
215
  @backpack.handle()
148
- async def _(event: Event):
216
+ async def _(bot: Bot, event: Union[GroupMessageEvent, PrivateMessageEvent]):
149
217
  user_id = event.get_user_id()
150
- await backpack.finish(MessageSegment.at(user_id) + " \n" + await get_stats(user_id) + "\n" + await get_balance(user_id) + "\n" + await get_backpack(user_id))
218
+ if not config.backpack_forward:
219
+ await backpack.finish(
220
+ MessageSegment.at(user_id)
221
+ + " \n"
222
+ + await get_stats(user_id)
223
+ + "\n"
224
+ + await get_balance(user_id)
225
+ + "\n"
226
+ + "\n\n".join(await get_backpack(user_id))
227
+ )
228
+ else:
229
+ messages: list[MessageSegment] = []
230
+ messages.append(MessageSegment.at(user_id))
231
+ messages.append(await get_stats(user_id))
232
+ messages.append(await get_balance(user_id))
233
+ backpacks = await get_backpack(user_id)
234
+ messages += [MessageSegment.text(msg) for msg in backpacks]
235
+ await forward_send(bot, event, messages)
236
+
151
237
 
152
238
  @buy.handle()
153
239
  async def _(event: Event, arg: Message = CommandArg()):
154
- fish_info = arg.extract_plain_text()
240
+ args = arg.extract_plain_text().split(" ")
241
+ args = [x for x in args if x != ""]
242
+
155
243
  user_id = event.get_user_id()
156
- if fish_info == "":
157
- await buy.finish(MessageSegment.at(user_id) + " " + "请输入要买入物品的名字和份数 (份数为1时可省略), 如 /购买 钛金鱼竿 1")
158
- if len(fish_info.split()) == 1:
159
- result = await buy_fish(user_id, fish_info)
244
+ if args == []:
245
+ await buy.finish(
246
+ MessageSegment.at(user_id)
247
+ + " "
248
+ + "请输入要买入物品的名字和份数 (份数为1时可省略), 如 /购买 钛金鱼竿 1"
249
+ )
250
+ if len(args) == 1:
251
+ fish_name = args[0]
252
+ result = await buy_fish(user_id, fish_name)
160
253
  else:
161
- fish_name, fish_quantity = fish_info.split()
254
+ fish_name, fish_quantity = args[0], args[1]
162
255
  result = await buy_fish(user_id, fish_name, int(fish_quantity))
163
256
  achievements = await check_achievement(user_id)
164
257
  if achievements is not None:
@@ -169,26 +262,55 @@ async def _(event: Event, arg: Message = CommandArg()):
169
262
 
170
263
  @sell.handle()
171
264
  async def _(event: Event, arg: Message = CommandArg()):
172
- fish_info = arg.extract_plain_text()
265
+ args = shlex.split(arg.extract_plain_text())
266
+
173
267
  user_id = event.get_user_id()
174
- if fish_info == "":
175
- await sell.finish(MessageSegment.at(user_id) + " " + "请输入要卖出的鱼的名字和数量 (数量为1时可省略), 如 /卖鱼 小鱼 1")
176
- if len(fish_info.split()) == 1:
177
- await sell.finish(MessageSegment.at(user_id) + " " + await sell_fish(user_id, fish_info))
268
+ if args == []:
269
+ await sell.finish(
270
+ MessageSegment.at(user_id)
271
+ + " "
272
+ + "请输入要卖出的鱼的名字和数量 (数量为1时可省略), 如 /卖鱼 小鱼 1"
273
+ )
274
+ if len(args) == 1:
275
+ fish_name = args[0]
276
+ await sell.finish(
277
+ MessageSegment.at(user_id) + " " + await sell_fish(user_id, fish_name)
278
+ )
178
279
  else:
179
- fish_name, fish_quantity = fish_info.split()
180
- await sell.finish(MessageSegment.at(user_id) + " " + await sell_fish(user_id, fish_name, int(fish_quantity)))
280
+ fish_name, fish_quantity = args[0], args[1]
281
+ result = await sell_fish(user_id, fish_name, int(fish_quantity))
282
+ await sell.finish(MessageSegment.at(user_id) + " " + result)
181
283
 
182
284
 
183
285
  @free_fish_cmd.handle()
184
- async def _(event: Event, arg: Message = CommandArg()):
185
- if not can_free_fish():
286
+ async def _(bot: Bot, event: Event, arg: Message = CommandArg()):
287
+ if not config.special_fish_enabled:
186
288
  await free_fish_cmd.finish("未开启此功能, 请联系机器人管理员")
289
+
187
290
  fish_name = arg.extract_plain_text()
188
291
  user_id = event.get_user_id()
292
+
293
+ if (
294
+ "\u200b" in fish_name
295
+ or "\u200c" in fish_name
296
+ or "\u200d" in fish_name
297
+ or "\u2060" in fish_name
298
+ or "\ufeff" in fish_name
299
+ ):
300
+ if isinstance(event, GroupMessageEvent):
301
+ group_id = event.group_id
302
+ await bot.set_group_ban(group_id=group_id, user_id=user_id, duration=1800)
303
+ await free_fish_cmd.finish(
304
+ MessageSegment.at(user_id) + " " + "你 TM 在放生什么?滚滚滚"
305
+ )
306
+
189
307
  if fish_name == "":
190
- await free_fish_cmd.finish(MessageSegment.at(user_id) + " " + "请输入要放生的鱼的名字, 如 /放生 测试鱼")
191
- await free_fish_cmd.finish(MessageSegment.at(user_id) + " " + await free_fish(user_id, fish_name))
308
+ await free_fish_cmd.finish(
309
+ MessageSegment.at(user_id) + " " + "请输入要放生的鱼的名字, /放生 测试鱼"
310
+ )
311
+ await free_fish_cmd.finish(
312
+ MessageSegment.at(user_id) + " " + await free_fish(user_id, fish_name)
313
+ )
192
314
 
193
315
 
194
316
  @lottery_cmd.handle()
@@ -198,7 +320,7 @@ async def _(bot: Bot, event: Event, matcher: Matcher):
198
320
  await punish(bot, event, matcher, user_id)
199
321
  result = await lottery(user_id)
200
322
  except:
201
- pass
323
+ result = "河神睡着了……"
202
324
  finally:
203
325
  punish_user_dict.pop(user_id, None)
204
326
  await lottery_cmd.finish(MessageSegment.at(user_id) + " " + result)
@@ -207,83 +329,117 @@ async def _(bot: Bot, event: Event, matcher: Matcher):
207
329
  @achievement_cmd.handle()
208
330
  async def _(event: Event):
209
331
  user_id = event.get_user_id()
210
- await achievement_cmd.finish(MessageSegment.at(user_id) + " " + await get_achievements(user_id))
332
+ await achievement_cmd.finish(
333
+ MessageSegment.at(user_id) + " " + await get_achievements(user_id)
334
+ )
211
335
 
212
336
 
213
337
  @give_cmd.handle()
214
- async def _(arg: Message = CommandArg()):
215
- args = arg.extract_plain_text().split()
338
+ async def _(
339
+ bot: Bot,
340
+ event: Union[GroupMessageEvent, PrivateMessageEvent],
341
+ arg: Message = CommandArg(),
342
+ ):
343
+ is_superuser = str(event.user_id) in bot.config.superusers
344
+ is_self = event.self_id == event.user_id
345
+ if not is_superuser and not is_self:
346
+ return None
347
+
348
+ target = await get_at(event)
349
+ args = shlex.split(arg.extract_plain_text())
350
+ if target:
351
+ args.insert(0, target)
216
352
  if len(args) < 2 or len(args) > 3:
217
- await give_cmd.finish("请输入用户的 id 和鱼的名字和数量 (数量为1时可省略), 如 /give 114514 开发鱼 1")
353
+ await give_cmd.finish(
354
+ "请输入用户的 id 和鱼的名字和数量 (数量为1时可省略), 如 /give 114514 开发鱼 1"
355
+ )
218
356
  else:
219
- print(f"PLDEBUG1: {args}")
220
357
  quantity = int(args[2]) if len(args) == 3 else 1
221
358
  result = await give(args[0], args[1], quantity)
222
359
  achievements = await check_achievement(args[0])
223
360
  if achievements is not None:
224
361
  for achievement in achievements:
225
- await fishing.send(achievement)
362
+ await fishing.send(achievement)
226
363
  await give_cmd.finish(result)
227
364
 
228
365
 
229
366
  @board_cmd.handle()
230
- async def _(bot: Bot, event: GroupMessageEvent):
231
- group_id = event.group_id
367
+ async def _(bot: Bot, event: Union[GroupMessageEvent, PrivateMessageEvent]):
232
368
  top_users_list = await get_board()
233
- msg = '钓鱼富豪排行榜:'
369
+ msg = "钓鱼富豪排行榜:"
234
370
  for index, user in enumerate(top_users_list):
235
371
  try:
236
- user_info = await bot.get_group_member_info(group_id=group_id, user_id=user[0])
237
- username = user_info['card'] if user_info['card'] is not None and user_info['card'] != '' else user_info['nickname']
372
+ if isinstance(event, GroupMessageEvent):
373
+ group_id = event.group_id
374
+ user_info = await bot.get_group_member_info(
375
+ group_id=group_id, user_id=user[0]
376
+ )
377
+ username = (
378
+ user_info["card"]
379
+ if user_info["card"] is not None and user_info["card"] != ""
380
+ else user_info["nickname"]
381
+ )
382
+ elif isinstance(event, PrivateMessageEvent):
383
+ user_info = await bot.get_stranger_info(user_id=user[0])
384
+ username = user_info["nickname"]
238
385
  except ActionFailed:
239
386
  username = "[神秘富豪]"
240
387
 
241
- msg += f'\n{index + 1}. {username}: {user[1]} {fishing_coin_name}'
242
-
388
+ msg += f"\n{index + 1}. {username}: {user[1]} {fishing_coin_name}"
389
+
243
390
  await board_cmd.finish(msg)
244
-
245
-
391
+
246
392
 
247
393
  async def punish(bot: Bot, event: Event, matcher: Matcher, user_id: int):
248
394
  global punish_user_dict
249
-
395
+
250
396
  if not await can_fishing(user_id):
251
397
  try:
252
398
  punish_user_dict[user_id] += 1
253
399
  except KeyError:
254
400
  punish_user_dict[user_id] = 1
255
401
 
256
- if punish_user_dict[user_id] < config.punish_limit - 1 :
257
- await matcher.finish(MessageSegment.at(user_id) + " " + "河累了,休息一下吧")
402
+ if punish_user_dict[user_id] < config.punish_limit - 1:
403
+ await matcher.finish(
404
+ MessageSegment.at(user_id) + " " + "河累了,休息一下吧"
405
+ )
258
406
  elif punish_user_dict[user_id] == config.punish_limit - 1:
259
407
  await matcher.finish(MessageSegment.at(user_id) + " " + "河神快要不耐烦了")
260
408
  elif punish_user_dict[user_id] == config.punish_limit:
261
409
  groud_id = event.group_id if isinstance(event, GroupMessageEvent) else None
262
410
  try:
263
- await bot.set_group_ban(group_id=groud_id, user_id=user_id, duration=1800)
411
+ await bot.set_group_ban(
412
+ group_id=groud_id, user_id=user_id, duration=1800
413
+ )
264
414
  except ActionFailed:
265
415
  pass
266
- await matcher.finish(MessageSegment.at(user_id) + " " + "河神生气了,降下了惩罚")
416
+ await matcher.finish(
417
+ MessageSegment.at(user_id) + " " + "河神生气了,降下了惩罚"
418
+ )
267
419
  else:
268
420
  await matcher.finish()
269
421
 
270
422
 
271
- async def forward_send(bot: Bot, event: Union[GroupMessageEvent, PrivateMessageEvent], messages: list[MessageSegment]) -> None:
423
+ async def forward_send(
424
+ bot: Bot,
425
+ event: Union[GroupMessageEvent, PrivateMessageEvent],
426
+ messages: list[MessageSegment],
427
+ ) -> None:
272
428
  if isinstance(event, GroupMessageEvent):
273
429
  await bot.send_group_forward_msg(
274
430
  group_id=event.group_id,
275
- messages=[
276
- {
277
- "type": "node",
278
- "data": {
279
- "name": "花花",
280
- "uin": bot.self_id,
281
- "content": msg,
282
- },
283
- }
284
- for msg in messages
285
- ],
286
- )
431
+ messages=[
432
+ {
433
+ "type": "node",
434
+ "data": {
435
+ "name": "花花",
436
+ "uin": bot.self_id,
437
+ "content": msg,
438
+ },
439
+ }
440
+ for msg in messages
441
+ ],
442
+ )
287
443
  else:
288
444
  await bot.send_private_forward_msg(
289
445
  user_id=event.user_id,
@@ -299,4 +455,12 @@ async def forward_send(bot: Bot, event: Union[GroupMessageEvent, PrivateMessageE
299
455
  for msg in messages
300
456
  ],
301
457
  )
302
-
458
+
459
+
460
+ async def get_at(event: Union[GroupMessageEvent, PrivateMessageEvent]) -> int:
461
+ if isinstance(event, GroupMessageEvent):
462
+ msg = event.get_message()
463
+ for msg_seg in msg:
464
+ if msg_seg.type == "at":
465
+ return msg_seg.data["qq"]
466
+ return None