nonebot-plugin-fishing2 0.0.3__py3-none-any.whl → 0.0.4__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.
@@ -12,78 +12,145 @@ from nonebot_plugin_orm import get_session
12
12
 
13
13
  from .config import config
14
14
  from .model import FishingRecord, SpecialFishes
15
+ from .fish_helper import *
15
16
 
16
- fishing_coin_name = config.fishing_coin_name
17
- fish_list = [fish["name"] for fish in config.fishes]
18
- can_catch_fishes = {fish["name"]: fish["weight"] for fish in config.fishes if fish["can_catch"]}
19
- can_buy_fishes = [fish["name"] for fish in config.fishes if fish["can_buy"]]
20
- can_sell_fishes = [fish["name"] for fish in config.fishes if fish["can_sell"]]
21
-
22
- def get_info(fish_name: str) -> list[MessageSegment]:
23
- message = []
24
- for fish in config.fishes:
25
- if fish.get("name") == fish_name:
26
- message1 = ""
27
- message1 += f'▶ 名称:{fish_name}\n'
28
- message1 += f'▶ 基准价格:{fish["price"]} {fishing_coin_name}\n'
29
- message1 += f'▶ 描述:{fish["description"]}\n'
30
- message1 += f'▶ {"可钓鱼获取" if fish["can_catch"] else "不可钓鱼获取"},'
31
- message1 += f'{"可购买" if fish["can_buy"] else "不可购买"},'
32
- message1 += f'{"可出售" if fish["can_sell"] else "不可出售"}'
33
- message.append(MessageSegment.text(message1))
34
- if fish["can_catch"]:
35
- message2 = ""
36
- message2 += f'▶ 钓鱼信息:\n'
37
- message2 += f' ▷ 基础权重:{fish["weight"]},'
38
- message2 += f'上钩时间:{fish["frequency"]}s'
39
- message.append(MessageSegment.text(message2))
40
- if fish["can_buy"]:
41
- message3 = ""
42
- message3 += f'▶ 商店信息:\n'
43
- message3 += f' ▷ 出售价格:{fish["price"] * 2},'
44
- message3 += f'单份数量:{fish.get("amount") if fish.get("amount") else 1}'
45
- message.append(MessageSegment.text(message3))
46
- if fish.get("props") and fish["props"] != []:
47
- message4 = ""
48
- message4 += f'▶ 道具信息:\n'
49
- message4 += f' ▷ 道具类型:{"鱼饵" if fish["type"] == "fish" else "道具"}\n'
50
- message4 += print_props(fish["props"])
51
- message.append(MessageSegment.text(message4))
52
- return message
53
-
54
- def adjusted_choice(adjusts: list[dict[str, Union[str, int]]] = None) -> str:
55
17
 
18
+ async def can_fishing(user_id: str) -> bool:
19
+ time_now = int(time.time())
20
+ session = get_session()
21
+ async with session.begin():
22
+ select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
23
+ record = await session.scalar(select_user)
24
+ return True if not record else record.time < time_now
25
+
26
+
27
+ async def can_catch_special_fish(probability_add: int):
28
+ session = get_session()
29
+ async with session.begin():
30
+ records = await session.execute(select(SpecialFishes))
31
+ return (
32
+ len(records.all()) != 0
33
+ and random.random() <= config.special_fish_probability + probability_add
34
+ )
35
+
36
+
37
+ async def check_tools(
38
+ user_id: str, tools: list[str] = None, check_have: bool = True
39
+ ) -> str | None:
40
+ if not tools or tools == []:
41
+ return None
42
+
43
+ # 这是工具吗?
44
+ for tool in tools:
45
+ fish = get_fish_by_name(tool)
46
+ if not fish:
47
+ return f"你在用什么钓鱼……?{tool}?"
48
+
49
+ props = fish.props
50
+ if not props or props == []:
51
+ return f"搞啥嘞!{tool}既不是工具也不是鱼饵!"
52
+
53
+ # 如果有两个工具,是一个工具一个鱼饵吗?
54
+ if len(tools) == 2:
55
+ if get_fish_by_name(tools[0]).type == get_fish_by_name(tools[1]).type:
56
+ return "你为啥要用两个类型一样的东西?"
57
+
58
+ # 有吗?有吗?
59
+ if check_have:
60
+ session = get_session()
61
+ async with session.begin():
62
+ select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
63
+ fishes_record = await session.scalar(select_user)
64
+ if fishes_record:
65
+ loads_fishes = json.loads(fishes_record.fishes)
66
+ for tool in tools:
67
+ if tool not in loads_fishes:
68
+ return f"你哪来的{tool}?"
69
+
70
+ return None
71
+
72
+
73
+ async def remove_tools(user_id: str, tools: list[str] = None) -> None:
74
+ if not tools or tools == []:
75
+ return None
76
+
77
+ session = get_session()
78
+ async with session.begin():
79
+ select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
80
+ fishes_record = await session.scalar(select_user)
81
+ if fishes_record:
82
+ loads_fishes = json.loads(fishes_record.fishes)
83
+ for tool_name in tools:
84
+ loads_fishes[tool_name] -= 1
85
+ if loads_fishes[tool_name] == 0:
86
+ del loads_fishes[tool_name]
87
+ dump_fishes = json.dumps(loads_fishes)
88
+ user_update = (
89
+ update(FishingRecord)
90
+ .where(FishingRecord.user_id == user_id)
91
+ .values(fishes=dump_fishes)
92
+ )
93
+ await session.execute(user_update)
94
+ await session.commit()
95
+ else:
96
+ pass
97
+ # raise ValueError("?你的 Check 是怎么通过的?")
98
+
99
+
100
+ def get_adjusts_from_tools(tools: list = None) -> list:
101
+ no_add = 0
102
+ sp_add = 0
103
+ adjusts: list[Property] = []
104
+
105
+ if tools:
106
+ for tool in tools:
107
+ adjusts += get_fish_by_name(tool).props
108
+
109
+ for adjust in adjusts:
110
+ if adjust.type == "special_fish":
111
+ sp_add += adjust.value
112
+ if adjust.type == "no_fish":
113
+ no_add += adjust.value
114
+
115
+ return adjusts, no_add, sp_add
116
+
117
+
118
+ def adjusted(adjusts: list[Property] = None) -> tuple:
56
119
  adjusted_fishes = copy.deepcopy(can_catch_fishes)
57
-
58
- if adjusts:
59
- for adjust in adjusts:
60
- if adjust.get("key") and adjust["key"] not in adjusted_fishes:
61
- continue
62
- match adjust["type"]:
63
- case "normal_fish":
64
- for key, weight in can_catch_fishes.items():
65
- if weight >= 500 and key in adjusted_fishes:
66
- adjusted_fishes[key] += adjust["value"]
67
- case "rare_fish":
68
- for key, weight in can_catch_fishes.items():
69
- if weight < 500 and key in adjusted_fishes:
70
- adjusted_fishes[key] += adjust["value"]
71
- case "fish":
72
- adjusted_fishes[adjust["key"]] += adjust["value"]
73
- case "rm_fish":
74
- adjusted_fishes.pop(adjust["key"])
75
- case "special_fish":
76
- pass
77
- case _:
78
- pass
79
-
120
+
121
+ for adjust in adjusts:
122
+ if adjust.key and adjust.key not in adjusted_fishes:
123
+ continue
124
+ match adjust.type:
125
+ case "normal_fish":
126
+ for key, weight in can_catch_fishes.items():
127
+ if weight >= config.rare_fish_weight and key in adjusted_fishes:
128
+ adjusted_fishes[key] += adjust.value
129
+ case "rare_fish":
130
+ for key, weight in can_catch_fishes.items():
131
+ if weight < config.rare_fish_weight and key in adjusted_fishes:
132
+ adjusted_fishes[key] += adjust.value
133
+ case "fish":
134
+ adjusted_fishes[adjust.key] += adjust.value
135
+ case "rm_fish":
136
+ adjusted_fishes.pop(adjust.key)
137
+ case "special_fish" | "no_fish":
138
+ pass
139
+ case _:
140
+ pass
141
+
80
142
  adjusted_fishes_list = list(adjusted_fishes.keys())
81
143
  adjusted_weights = list(adjusted_fishes.values())
82
-
144
+
83
145
  for i in range(len(adjusted_weights)):
84
146
  if adjusted_weights[i] < 0:
85
147
  adjusted_weights[i] = 0
86
-
148
+
149
+ return adjusted_fishes_list, adjusted_weights
150
+
151
+
152
+ def choice(adjusts: list[Property] = None) -> str:
153
+ adjusted_fishes_list, adjusted_weights = adjusted(adjusts)
87
154
  choices = random.choices(
88
155
  adjusted_fishes_list,
89
156
  weights=adjusted_weights,
@@ -92,99 +159,67 @@ def adjusted_choice(adjusts: list[dict[str, Union[str, int]]] = None) -> str:
92
159
 
93
160
 
94
161
  async def get_fish(user_id: int, tools: list = None) -> str:
95
- probability_add = 0
96
- adjusts: list[dict[str, Union[str, int]]] = []
97
-
98
- if tools:
99
- for tool in tools:
100
- adjusts += get_props(tool)
162
+ adjusts, no_add, sp_add = get_adjusts_from_tools(tools)
101
163
 
102
- for adjust in adjusts:
103
- if adjust["type"] == "special_fish":
104
- probability_add += adjust["value"]
105
-
106
- if await can_catch_special_fish(probability_add):
164
+ if random.random() < config.no_fish_probability + no_add:
165
+ await asyncio.sleep(random.randint(10, 20))
166
+ return "QAQ你空军了,什么都没钓到"
167
+
168
+ if await can_catch_special_fish(sp_add):
107
169
  special_fish_name = await random_get_a_special_fish()
170
+ await asyncio.sleep(random.randint(10, 20))
108
171
  await save_special_fish(user_id, special_fish_name)
109
172
  result = f"你钓到了别人放生的 {special_fish_name}"
110
173
  return result
111
- fish = adjusted_choice(adjusts)
112
- sleep_time = get_frequency(fish)
174
+
175
+ fish = choice(adjusts)
176
+ sleep_time = get_fish_by_name(fish).sleep_time
113
177
  result = f"钓到了一条{fish}, 你把它收进了背包里"
114
178
  await asyncio.sleep(sleep_time)
115
179
  await save_fish(user_id, fish)
116
180
  return result
117
181
 
118
182
 
119
- def get_type(fish_name: str) -> list:
120
- """获取鱼的类型"""
121
- config_fishes = config.fishes
122
- return next(
123
- (
124
- fish["type"]
125
- for fish in config_fishes
126
- if fish["name"] == fish_name
127
- ),
128
- "fish"
129
- )
183
+ def predict(tools: list = None) -> str:
184
+ no = config.no_fish_probability
185
+ sp = config.special_fish_probability
186
+ sp_price = config.special_fish_price
187
+ result = ""
130
188
 
131
- def get_props(fish_name: str) -> list:
132
- """获取鱼的属性"""
133
- config_fishes = config.fishes
134
- return next(
135
- (
136
- fish["props"]
137
- for fish in config_fishes
138
- if fish["name"] == fish_name
139
- ),
140
- []
141
- )
142
- def get_price(fish_name: str) -> int:
143
- """获取鱼的价格"""
144
- config_fishes = config.fishes
145
- return next(
146
- (
147
- fish["price"]
148
- for fish in config_fishes
149
- if fish["name"] == fish_name
150
- ),
151
- 0
152
- )
153
-
154
- def get_frequency(fish_name: str) -> int:
155
- """获取鱼的冷却"""
156
- config_fishes = config.fishes
157
- return next(
158
- (
159
- fish["frequency"]
160
- for fish in config_fishes
161
- if fish["name"] == fish_name
162
- ),
163
- 60
164
- )
189
+ adjusts, no_add, sp_add = get_adjusts_from_tools(tools)
190
+ sp_t = min(max(sp + sp_add, 0), 1)
191
+ no_t = min(max(no + no_add, 0), 1)
192
+
193
+ # 拉取矫正权重
194
+ adjusted_fishes_list, adjusted_weights = adjusted(adjusts)
195
+
196
+ adjusted_fishes_value = []
197
+ for fish_name in adjusted_fishes_list:
198
+ fish = get_fish_by_name(fish_name)
199
+ adjusted_fishes_value.append(int(fish.price * fish.amount))
200
+
201
+ # 归一化
202
+ total_weight = sum(adjusted_weights)
203
+ probabilities = [w / total_weight for w in adjusted_weights]
204
+ expected_value = sum(v * p for v, p in zip(adjusted_fishes_value, probabilities))
205
+
206
+ result += f"鱼列表:[{', '.join(adjusted_fishes_list)}]\n"
207
+ result += f"概率列表: [{', '.join([str(round(w * 100, 2)) + "%" for w in probabilities])}]\n"
208
+ result += f"特殊鱼概率:{round(sp_t * (1 - no_t), 6)}\n"
209
+ result += f"空军概率:{round(no_t, 6)}\n"
210
+
211
+ # 无特殊鱼
212
+ expected_value = expected_value * (1 - no_t)
213
+ result += f"无特殊鱼时期望为:{expected_value:.3f}\n"
214
+
215
+ # 有特殊鱼
216
+ expected_value = expected_value * (1 - sp_t) + sp_price * sp_t * (1 - no_t)
217
+ result += f"有特殊鱼期望为:{expected_value:.3f}"
165
218
 
166
- def print_props(props: list) -> str:
167
- """打印鱼的属性"""
168
- result = " ▷ 道具效果:\n"
169
- for i in range(len(props)):
170
- prop = props[i]
171
- match prop["type"]:
172
- case "normal_fish":
173
- result += f" {i + 1}. 普通鱼权重{'增加' if prop['value'] > 0 else '减少'}{prop['value']}\n"
174
- case "rare_fish":
175
- result += f" {i + 1}. 稀有鱼权重{'增加' if prop['value'] > 0 else '减少'}{prop['value']}\n"
176
- case "fish":
177
- result += f" {i + 1}. {prop['key']}权重{'增加' if prop['value'] > 0 else '减少'}{prop['value']}\n"
178
- case "rm_fish":
179
- result += f" {i + 1}. 不会钓到{prop['key']}\n"
180
- case "special_fish":
181
- result += f" {i + 1}. 特殊鱼概率{'增加' if prop['value'] > 0 else '减少'}{prop['value']}\n"
182
- case _:
183
- pass
184
219
  return result
185
220
 
221
+
186
222
  async def random_get_a_special_fish() -> str:
187
- """随机返回一条别人放生的鱼"""
188
223
  session = get_session()
189
224
  async with session.begin():
190
225
  random_select = select(SpecialFishes).order_by(func.random())
@@ -192,38 +227,39 @@ async def random_get_a_special_fish() -> str:
192
227
  return data.fish
193
228
 
194
229
 
195
- async def can_fishing(user_id: str) -> bool:
196
- """判断是否可以钓鱼"""
197
- time_now = int(time.time())
230
+ async def get_all_special_fish() -> list[str]:
198
231
  session = get_session()
199
232
  async with session.begin():
200
- select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
201
- record = await session.scalar(select_user)
202
- return True if not record else record.time < time_now
203
-
204
-
205
- def can_free_fish() -> bool:
206
- return config.special_fish_enabled
233
+ random_select = select(SpecialFishes.fish).order_by(SpecialFishes.fish.asc())
234
+ data = await session.scalars(random_select)
235
+ result = data.all()
236
+ return result
207
237
 
208
238
 
209
239
  async def check_achievement(user_id: str) -> str | None:
210
240
  session = get_session()
211
241
  async with session.begin():
212
- record = await session.scalar(select(FishingRecord).where(FishingRecord.user_id == user_id))
242
+ record = await session.scalar(
243
+ select(FishingRecord).where(FishingRecord.user_id == user_id)
244
+ )
213
245
  if not record:
214
246
  return None
215
247
  fishing_frequency = record.frequency
216
248
  user_fishes = json.loads(record.fishes)
217
- achievements = config.fishing_achievement
249
+ achievements = config_achievements
218
250
  result_list = []
219
251
  for achievement in achievements:
220
- achievement_name = achievement["name"]
252
+ achievement_name = achievement.name
221
253
  if await is_exists_achievement(user_id, achievement_name):
222
254
  continue
223
- if (achievement["type"] == "fishing_frequency" and achievement["data"] <= fishing_frequency) or \
224
- (achievement["type"] == "fish_type" and achievement["data"] in user_fishes):
255
+ if (
256
+ achievement.type == "fishing_frequency"
257
+ and achievement.data <= fishing_frequency
258
+ ) or (achievement.type == "fish_type" and achievement.data in user_fishes):
225
259
  await save_achievement(user_id, achievement_name)
226
- result_list.append(f"""达成成就: {achievement_name}\n{achievement["description"]}""")
260
+ result_list.append(
261
+ f"""达成成就: {achievement_name}\n{achievement.description}"""
262
+ )
227
263
  return result_list if result_list != [] else None
228
264
 
229
265
 
@@ -248,10 +284,10 @@ async def save_achievement(user_id: str, achievement_name: str):
248
284
  loads_achievements = json.loads(record.achievements)
249
285
  loads_achievements.append(achievement_name)
250
286
  dump_achievements = json.dumps(loads_achievements)
251
- user_update = update(FishingRecord).where(
252
- FishingRecord.user_id == user_id
253
- ).values(
254
- achievements=dump_achievements
287
+ user_update = (
288
+ update(FishingRecord)
289
+ .where(FishingRecord.user_id == user_id)
290
+ .values(achievements=dump_achievements)
255
291
  )
256
292
  await session.execute(user_update)
257
293
  await session.commit()
@@ -265,16 +301,16 @@ async def save_achievement(user_id: str, achievement_name: str):
265
301
  fishes="{}",
266
302
  special_fishes="{}",
267
303
  coin=0,
268
- achievements=dump_achievements
304
+ achievements=dump_achievements,
269
305
  )
270
306
  session.add(new_record)
271
307
  await session.commit()
272
308
 
273
309
 
274
310
  async def save_fish(user_id: str, fish_name: str) -> None:
275
- """向数据库写入鱼以持久化保存"""
276
311
  time_now = int(time.time())
277
312
  fishing_limit = config.fishing_limit
313
+ amount = get_fish_by_name(fish_name).amount
278
314
  session = get_session()
279
315
  async with session.begin():
280
316
  select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
@@ -282,24 +318,24 @@ async def save_fish(user_id: str, fish_name: str) -> None:
282
318
  if record:
283
319
  loads_fishes = json.loads(record.fishes)
284
320
  try:
285
- loads_fishes[fish_name] += 1
321
+ loads_fishes[fish_name] += amount
286
322
  except KeyError:
287
- loads_fishes[fish_name] = 1
323
+ loads_fishes[fish_name] = amount
288
324
  dump_fishes = json.dumps(loads_fishes)
289
325
  new_frequency = record.frequency + 1
290
- user_update = update(FishingRecord).where(
291
- FishingRecord.user_id == user_id
292
- ).values(
293
- time=time_now + fishing_limit,
294
- frequency=new_frequency,
295
- fishes=dump_fishes
326
+ user_update = (
327
+ update(FishingRecord)
328
+ .where(FishingRecord.user_id == user_id)
329
+ .values(
330
+ time=time_now + fishing_limit,
331
+ frequency=new_frequency,
332
+ fishes=dump_fishes,
333
+ )
296
334
  )
297
335
  await session.execute(user_update)
298
336
  await session.commit()
299
337
  return
300
- data = {
301
- fish_name: 1
302
- }
338
+ data = {fish_name: amount}
303
339
  dump_fishes = json.dumps(data)
304
340
  new_record = FishingRecord(
305
341
  user_id=user_id,
@@ -308,19 +344,12 @@ async def save_fish(user_id: str, fish_name: str) -> None:
308
344
  fishes=dump_fishes,
309
345
  special_fishes="{}",
310
346
  coin=0,
311
- achievements="[]"
347
+ achievements="[]",
312
348
  )
313
349
  session.add(new_record)
314
350
  await session.commit()
315
351
 
316
352
 
317
- async def can_catch_special_fish(probability_add: int):
318
- session = get_session()
319
- async with session.begin():
320
- records = await session.execute(select(SpecialFishes))
321
- return len(records.all()) != 0 and random.random() <= config.special_fish_probability + probability_add
322
-
323
-
324
353
  async def save_special_fish(user_id: str, fish_name: str) -> None:
325
354
  time_now = int(time.time())
326
355
  fishing_limit = config.fishing_limit
@@ -335,18 +364,18 @@ async def save_special_fish(user_id: str, fish_name: str) -> None:
335
364
  except KeyError:
336
365
  loads_fishes[fish_name] = 1
337
366
  dump_fishes = json.dumps(loads_fishes)
338
- user_update = update(FishingRecord).where(
339
- FishingRecord.user_id == user_id
340
- ).values(
341
- time=time_now + fishing_limit,
342
- frequency=record.frequency + 1,
343
- special_fishes=dump_fishes
367
+ user_update = (
368
+ update(FishingRecord)
369
+ .where(FishingRecord.user_id == user_id)
370
+ .values(
371
+ time=time_now + fishing_limit,
372
+ frequency=record.frequency + 1,
373
+ special_fishes=dump_fishes,
374
+ )
344
375
  )
345
376
  await session.execute(user_update)
346
377
  else:
347
- data = {
348
- fish_name: 1
349
- }
378
+ data = {fish_name: 1}
350
379
  dump_fishes = json.dumps(data)
351
380
  new_record = FishingRecord(
352
381
  user_id=user_id,
@@ -355,12 +384,15 @@ async def save_special_fish(user_id: str, fish_name: str) -> None:
355
384
  fishes="{}",
356
385
  special_fishes=dump_fishes,
357
386
  coin=0,
358
- achievements=[]
387
+ achievements=[],
359
388
  )
360
389
  session.add(new_record)
361
- select_fish = select(SpecialFishes).where(
362
- SpecialFishes.fish == fish_name
363
- ).order_by(SpecialFishes.id).limit(1)
390
+ select_fish = (
391
+ select(SpecialFishes)
392
+ .where(SpecialFishes.fish == fish_name)
393
+ .order_by(SpecialFishes.id)
394
+ .limit(1)
395
+ )
364
396
  record = await session.scalar(select_fish)
365
397
  fish_id = record.id
366
398
  delete_fishes = delete(SpecialFishes).where(SpecialFishes.id == fish_id)
@@ -368,65 +400,9 @@ async def save_special_fish(user_id: str, fish_name: str) -> None:
368
400
  await session.commit()
369
401
 
370
402
 
371
- async def get_stats(user_id: str) -> str:
372
- """获取钓鱼统计信息"""
373
- session = get_session()
374
- async with session.begin():
375
- select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
376
- fishing_record = await session.scalar(select_user)
377
- if fishing_record:
378
- return f"🐟你钓鱼了 {fishing_record.frequency} 次"
379
- return "🐟你还没有钓过鱼,快去钓鱼吧"
380
-
381
-
382
- def print_backpack(backpack: dict, special_backpack=None) -> str:
383
- """输出背包内容"""
384
- result = [
385
- f"{fish_name}×{str(quantity)}"
386
- for fish_name, quantity in backpack.items()
387
- ]
388
- if special_backpack:
389
- special_result = [
390
- f"{fish_name}×{str(quantity)}"
391
- for fish_name, quantity in special_backpack.items()
392
- ]
393
- return "🎒背包:\n" + "\n".join(result) + "\n\n特殊鱼:\n" + "\n".join(special_result)
394
- return "🎒背包:\n" + "\n".join(result)
395
-
396
-
397
- async def get_backpack(user_id: str) -> str:
398
- """从数据库查询背包内容"""
399
- session = get_session()
400
- async with session.begin():
401
- select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
402
- fishes_record = await session.scalar(select_user)
403
- if fishes_record:
404
- load_fishes = json.loads(fishes_record.fishes)
405
- sorted_fishes = {key: load_fishes[key] for key in fish_list if key in load_fishes}
406
- load_special_fishes = json.loads(fishes_record.special_fishes)
407
- if load_special_fishes:
408
- sorted_special_fishes = {key: load_special_fishes[key] for key in sorted(load_special_fishes)}
409
- return print_backpack(sorted_fishes, sorted_special_fishes)
410
- return "🎒你的背包里空无一物" if sorted_fishes == {} else print_backpack(sorted_fishes)
411
- return "🎒你的背包里空无一物"
412
-
413
-
414
403
  async def sell_fish(user_id: str, fish_name: str, quantity: int = 1) -> str:
415
- """
416
- 卖鱼
417
-
418
- 参数:
419
- - user_id: 用户标识符
420
- - fish_name: 将要卖鱼的鱼名称
421
- - quantity: 卖出鱼的数量
422
-
423
- 返回:
424
- - (str): 回复的文本
425
- """
426
404
  if quantity <= 0:
427
405
  return "你在卖什么 w(゚Д゚)w"
428
- if fish_name not in can_sell_fishes:
429
- return f"这个 {fish_name} 不可以卖哦~"
430
406
  session = get_session()
431
407
  async with session.begin():
432
408
  select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
@@ -435,23 +411,29 @@ async def sell_fish(user_id: str, fish_name: str, quantity: int = 1) -> str:
435
411
  loads_fishes = json.loads(fishes_record.fishes)
436
412
  spec_fishes = json.loads(fishes_record.special_fishes)
437
413
  if fish_name in loads_fishes and loads_fishes[fish_name] > 0:
438
- fish_price = get_price(fish_name)
414
+ if fish_name not in can_sell_fishes:
415
+ return f"这个 {fish_name} 不可以卖哦~"
439
416
  if loads_fishes[fish_name] < quantity:
440
417
  return f"你没有那么多 {fish_name}"
418
+ fish_price = get_fish_by_name(fish_name).price
441
419
  loads_fishes[fish_name] -= quantity
442
420
  if loads_fishes[fish_name] == 0:
443
421
  del loads_fishes[fish_name]
444
422
  dump_fishes = json.dumps(loads_fishes)
445
- user_update = update(FishingRecord).where(
446
- FishingRecord.user_id == user_id
447
- ).values(
448
- coin=fishes_record.coin + fish_price * quantity,
449
- fishes=dump_fishes
423
+ user_update = (
424
+ update(FishingRecord)
425
+ .where(FishingRecord.user_id == user_id)
426
+ .values(
427
+ coin=fishes_record.coin + fish_price * quantity,
428
+ fishes=dump_fishes,
429
+ )
450
430
  )
451
431
  await session.execute(user_update)
452
432
  await session.commit()
453
- return (f"你以 {fish_price} {fishing_coin_name} / 条的价格卖出了 {quantity} 条 {fish_name}, "
454
- f"你获得了 {fish_price * quantity} {fishing_coin_name}")
433
+ return (
434
+ f"你以 {fish_price} {fishing_coin_name} / 条的价格卖出了 {quantity} {fish_name}, "
435
+ f"你获得了 {fish_price * quantity} {fishing_coin_name}"
436
+ )
455
437
  elif fish_name in spec_fishes and spec_fishes[fish_name] > 0:
456
438
  fish_price = config.special_fish_price
457
439
  if spec_fishes[fish_name] < quantity:
@@ -460,35 +442,35 @@ async def sell_fish(user_id: str, fish_name: str, quantity: int = 1) -> str:
460
442
  if spec_fishes[fish_name] == 0:
461
443
  del spec_fishes[fish_name]
462
444
  dump_fishes = json.dumps(spec_fishes)
463
- user_update = update(FishingRecord).where(
464
- FishingRecord.user_id == user_id
465
- ).values(
466
- coin=fishes_record.coin + fish_price * quantity,
467
- special_fishes=dump_fishes
445
+ user_update = (
446
+ update(FishingRecord)
447
+ .where(FishingRecord.user_id == user_id)
448
+ .values(
449
+ coin=fishes_record.coin + fish_price * quantity,
450
+ special_fishes=dump_fishes,
451
+ )
468
452
  )
469
453
  await session.execute(user_update)
470
454
  await session.commit()
471
- return (f"你以 {fish_price} {fishing_coin_name} / 条的价格卖出了 {quantity} 条 {fish_name}, "
472
- f"获得了 {fish_price * quantity} {fishing_coin_name}")
473
- else:
455
+ return (
456
+ f"你以 {fish_price} {fishing_coin_name} / 条的价格卖出了 {quantity} {fish_name}, "
457
+ f"获得了 {fish_price * quantity} {fishing_coin_name}"
458
+ )
459
+ else:
474
460
  return "查无此鱼"
475
461
  else:
476
462
  return "还没钓鱼就想卖鱼?"
477
-
463
+
478
464
 
479
465
  async def buy_fish(user_id: str, fish_name: str, quantity: int = 1) -> str:
480
466
  if quantity <= 0:
481
467
  return "别在渔具店老板面前炫耀自己的鱼 (..-˘ ˘-.#)"
482
468
  if fish_name not in can_buy_fishes:
483
469
  return "商店不卖这个!"
484
-
485
- for fish in config.fishes:
486
- if fish["name"] == fish_name:
487
- price = fish["price"] * 2
488
- amount = fish["amount"] if fish.get("amount") else 1
489
- total_price = price * amount * quantity
490
- break
491
-
470
+
471
+ fish = get_fish_by_name(fish_name)
472
+ total_price = int(fish.buy_price * fish.amount * quantity)
473
+
492
474
  session = get_session()
493
475
  async with session.begin():
494
476
  select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
@@ -501,34 +483,22 @@ async def buy_fish(user_id: str, fish_name: str, quantity: int = 1) -> str:
501
483
  return f"你没有足够的 {fishing_coin_name}, 还需 {coin_less} {fishing_coin_name}"
502
484
  user_coin -= total_price
503
485
  try:
504
- loads_fishes[fish_name] += amount * quantity
486
+ loads_fishes[fish_name] += fish.amount * quantity
505
487
  except KeyError:
506
- loads_fishes[fish_name] = amount * quantity
488
+ loads_fishes[fish_name] = fish.amount * quantity
507
489
  dump_fishes = json.dumps(loads_fishes)
508
- user_update = update(FishingRecord).where(
509
- FishingRecord.user_id == user_id
510
- ).values(
511
- coin=user_coin,
512
- fishes=dump_fishes
490
+ user_update = (
491
+ update(FishingRecord)
492
+ .where(FishingRecord.user_id == user_id)
493
+ .values(coin=user_coin, fishes=dump_fishes)
513
494
  )
514
495
  await session.execute(user_update)
515
496
  await session.commit()
516
- return (f"你用 {total_price} {fishing_coin_name} 买入了 {quantity * amount} {fish_name}")
497
+ return f"你用 {total_price} {fishing_coin_name} 买入了 {quantity} {fish_name}"
517
498
  else:
518
499
  return "不想钓鱼的人就别在渔具店逛了~"
519
500
 
520
501
 
521
- async def get_balance(user_id: str) -> str:
522
- """获取余额"""
523
- session = get_session()
524
- async with session.begin():
525
- select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
526
- fishes_record = await session.scalar(select_user)
527
- if fishes_record:
528
- return f"🪙你有 {fishes_record.coin} {fishing_coin_name}"
529
- return "🪙你什么也没有 :)"
530
-
531
-
532
502
  async def free_fish(user_id: str, fish_name: str) -> str:
533
503
  session = get_session()
534
504
  async with session.begin():
@@ -541,16 +511,13 @@ async def free_fish(user_id: str, fish_name: str) -> str:
541
511
  spec_fishes[fish_name] -= 1
542
512
  if spec_fishes[fish_name] == 0:
543
513
  del spec_fishes[fish_name]
544
- new_record = SpecialFishes(
545
- user_id=user_id,
546
- fish=fish_name
547
- )
514
+ new_record = SpecialFishes(user_id=user_id, fish=fish_name)
548
515
  session.add(new_record)
549
516
  dump_fishes = json.dumps(spec_fishes)
550
- user_update = update(FishingRecord).where(
551
- FishingRecord.user_id == user_id
552
- ).values(
553
- special_fishes=dump_fishes
517
+ user_update = (
518
+ update(FishingRecord)
519
+ .where(FishingRecord.user_id == user_id)
520
+ .values(special_fishes=dump_fishes)
554
521
  )
555
522
  await session.execute(user_update)
556
523
  await session.commit()
@@ -558,24 +525,23 @@ async def free_fish(user_id: str, fish_name: str) -> str:
558
525
  else:
559
526
  if fish_name in fish_list:
560
527
  return "普通鱼不能放生哦~"
561
-
562
- if user_coin < config.special_fish_price // 2:
563
- special_fish_coin_less = str(config.special_fish_price // 2 - fishes_record.coin)
528
+
529
+ if user_coin < config.special_fish_free_price:
530
+ special_fish_coin_less = str(
531
+ config.special_fish_free_price - fishes_record.coin
532
+ )
564
533
  return f"你没有足够的 {fishing_coin_name}, 还需 {special_fish_coin_less} {fishing_coin_name}"
565
- user_coin -= config.special_fish_price // 2
566
- new_record = SpecialFishes(
567
- user_id=user_id,
568
- fish=fish_name
569
- )
534
+ user_coin -= config.special_fish_free_price
535
+ new_record = SpecialFishes(user_id=user_id, fish=fish_name)
570
536
  session.add(new_record)
571
- user_update = update(FishingRecord).where(
572
- FishingRecord.user_id == user_id
573
- ).values(
574
- coin=user_coin
537
+ user_update = (
538
+ update(FishingRecord)
539
+ .where(FishingRecord.user_id == user_id)
540
+ .values(coin=user_coin)
575
541
  )
576
542
  await session.execute(user_update)
577
543
  await session.commit()
578
- return f"你花费 {config.special_fish_price // 2} {fishing_coin_name} 放生了 {fish_name}, 未来或许会被有缘人钓到呢"
544
+ return f"你花费 {config.special_fish_free_price} {fishing_coin_name} 放生了 {fish_name}, 未来或许会被有缘人钓到呢"
579
545
  return "你甚至还没钓过鱼"
580
546
 
581
547
 
@@ -591,24 +557,28 @@ async def lottery(user_id: str) -> str:
591
557
  user_coin = fishes_record.coin
592
558
  if user_coin <= 30:
593
559
  new_coin = random.randrange(1, 50)
594
- user_update = update(FishingRecord).where(
595
- FishingRecord.user_id == user_id
596
- ).values(
597
- time=time_now + fishing_limit,
598
- coin=fishes_record.coin + new_coin,
560
+ user_update = (
561
+ update(FishingRecord)
562
+ .where(FishingRecord.user_id == user_id)
563
+ .values(
564
+ time=time_now + fishing_limit,
565
+ coin=fishes_record.coin + new_coin,
566
+ )
599
567
  )
600
568
  await session.execute(user_update)
601
- await session.commit()
569
+ await session.commit()
602
570
  return f"你穷得连河神都看不下去了,给了你 {new_coin} {fishing_coin_name} w(゚Д゚)w"
603
571
  new_coin = abs(user_coin) / 3
604
572
  new_coin = random.randrange(5000, 15000) / 10000 * new_coin
605
573
  new_coin = int(new_coin) if new_coin > 1 else 1
606
574
  new_coin *= random.randrange(-1, 2, 2)
607
- user_update = update(FishingRecord).where(
608
- FishingRecord.user_id == user_id
609
- ).values(
610
- time=time_now + fishing_limit,
611
- coin=fishes_record.coin + new_coin,
575
+ user_update = (
576
+ update(FishingRecord)
577
+ .where(FishingRecord.user_id == user_id)
578
+ .values(
579
+ time=time_now + fishing_limit,
580
+ coin=fishes_record.coin + new_coin,
581
+ )
612
582
  )
613
583
  await session.execute(user_update)
614
584
  await session.commit()
@@ -623,15 +593,17 @@ async def give(user_id: str, fish_name: str, quantity: int = 1) -> str:
623
593
  select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
624
594
  record = await session.scalar(select_user)
625
595
  if record:
626
- if fish_name == 'coin' or fish_name == fishing_coin_name:
627
- user_update = update(FishingRecord).where(
628
- FishingRecord.user_id == user_id
629
- ).values(
630
- coin=record.coin + quantity,
596
+ if fish_name == "coin" or fish_name == fishing_coin_name:
597
+ user_update = (
598
+ update(FishingRecord)
599
+ .where(FishingRecord.user_id == user_id)
600
+ .values(
601
+ coin=record.coin + quantity,
602
+ )
631
603
  )
632
604
  await session.execute(user_update)
633
605
  await session.commit()
634
- return f"使用滥权之力成功为 {user_id} {"增加" if quantity >= 0 else "减少"} {abs(quantity)} {fishing_coin_name} ヾ(≧▽≦*)o"
606
+ return f"使用滥权之力成功为 {user_id} {"增加" if quantity >= 0 else "减少"} {abs(quantity)} {fishing_coin_name} ヾ(≧▽≦*)o"
635
607
  loads_fishes = json.loads(record.fishes)
636
608
  spec_fishes = json.loads(record.special_fishes)
637
609
  if fish_name in fish_list:
@@ -640,10 +612,10 @@ async def give(user_id: str, fish_name: str, quantity: int = 1) -> str:
640
612
  except KeyError:
641
613
  loads_fishes[fish_name] = quantity
642
614
  dump_fishes = json.dumps(loads_fishes)
643
- user_update = update(FishingRecord).where(
644
- FishingRecord.user_id == user_id
645
- ).values(
646
- fishes=dump_fishes
615
+ user_update = (
616
+ update(FishingRecord)
617
+ .where(FishingRecord.user_id == user_id)
618
+ .values(fishes=dump_fishes)
647
619
  )
648
620
  await session.execute(user_update)
649
621
  await session.commit()
@@ -653,17 +625,79 @@ async def give(user_id: str, fish_name: str, quantity: int = 1) -> str:
653
625
  except KeyError:
654
626
  spec_fishes[fish_name] = quantity
655
627
  dump_fishes = json.dumps(spec_fishes)
656
- user_update = update(FishingRecord).where(
657
- FishingRecord.user_id == user_id
658
- ).values(
659
- special_fishes=dump_fishes
628
+ user_update = (
629
+ update(FishingRecord)
630
+ .where(FishingRecord.user_id == user_id)
631
+ .values(special_fishes=dump_fishes)
660
632
  )
661
633
  await session.execute(user_update)
662
634
  await session.commit()
663
- return f"使用滥权之力成功将 {fish_name} 添加到 {user_id} 的背包之中 ヾ(≧▽≦*)o"
635
+ return (
636
+ f"使用滥权之力成功将 {fish_name} 添加到 {user_id} 的背包之中 ヾ(≧▽≦*)o"
637
+ )
664
638
  return "未查找到用户信息, 无法执行滥权操作 w(゚Д゚)w"
665
639
 
666
640
 
641
+ async def get_stats(user_id: str) -> str:
642
+ session = get_session()
643
+ async with session.begin():
644
+ select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
645
+ fishing_record = await session.scalar(select_user)
646
+ if fishing_record:
647
+ return f"🐟你钓上了 {fishing_record.frequency} 条鱼"
648
+ return "🐟你还没有钓过鱼,快去钓鱼吧"
649
+
650
+
651
+ async def get_balance(user_id: str) -> str:
652
+ session = get_session()
653
+ async with session.begin():
654
+ select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
655
+ fishes_record = await session.scalar(select_user)
656
+ if fishes_record:
657
+ return f"🪙你有 {fishes_record.coin} {fishing_coin_name}"
658
+ return "🪙你什么也没有 :)"
659
+
660
+
661
+ async def get_backpack(user_id: str) -> list[str]:
662
+ session = get_session()
663
+ async with session.begin():
664
+ select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
665
+ fishes_record = await session.scalar(select_user)
666
+ if fishes_record:
667
+ load_fishes = json.loads(fishes_record.fishes)
668
+ sorted_fishes = {
669
+ key: load_fishes[key] for key in fish_list if key in load_fishes
670
+ }
671
+ load_special_fishes = json.loads(fishes_record.special_fishes)
672
+ if load_special_fishes:
673
+ sorted_special_fishes = {
674
+ key: load_special_fishes[key] for key in sorted(load_special_fishes)
675
+ }
676
+ return print_backpack(sorted_fishes, sorted_special_fishes)
677
+ return (
678
+ ["🎒你的背包里空无一物"]
679
+ if sorted_fishes == {}
680
+ else print_backpack(sorted_fishes)
681
+ )
682
+ return ["🎒你的背包里空无一物"]
683
+
684
+
685
+ def print_backpack(backpack: dict, special_backpack=None) -> list[str]:
686
+ result = [
687
+ f"{fish_name}×{str(quantity)}" for fish_name, quantity in backpack.items()
688
+ ]
689
+ if special_backpack:
690
+ special_result = [
691
+ f"{fish_name}×{str(quantity)}"
692
+ for fish_name, quantity in special_backpack.items()
693
+ ]
694
+ return [
695
+ "🎒普通鱼:\n" + "\n".join(result),
696
+ "🎒特殊鱼:\n" + "\n".join(special_result),
697
+ ]
698
+ return ["🎒普通鱼:\n" + "\n".join(result)]
699
+
700
+
667
701
  async def get_achievements(user_id: str) -> str:
668
702
  session = get_session()
669
703
  async with session.begin():
@@ -674,10 +708,13 @@ async def get_achievements(user_id: str) -> str:
674
708
  return "已完成成就:\n" + "\n".join(achievements)
675
709
  return "你甚至还没钓过鱼 (╬▔皿▔)╯"
676
710
 
677
- async def get_board() -> list:
711
+
712
+ async def get_board() -> list[tuple]:
678
713
  session = get_session()
679
714
  async with session.begin():
680
- select_users = select(FishingRecord).order_by(FishingRecord.coin.desc()).limit(10)
715
+ select_users = (
716
+ select(FishingRecord).order_by(FishingRecord.coin.desc()).limit(10)
717
+ )
681
718
  record = await session.scalars(select_users)
682
719
  if record:
683
720
  top_users_list = []
@@ -687,67 +724,20 @@ async def get_board() -> list:
687
724
  return top_users_list
688
725
  return []
689
726
 
727
+
690
728
  def get_shop() -> list[MessageSegment]:
691
729
  messages: list[MessageSegment] = []
692
-
693
- messages.append(MessageSegment.text("===== 渔具店 ====="))
694
-
695
- for fish in config.fishes:
696
- if fish.get("can_buy"):
697
- name = fish["name"]
698
- price = fish["price"] * 2
699
- amount = fish["amount"] if fish.get("amount") else 1
700
- total_price = price * amount
701
- desc = fish["description"] if fish.get("description") else ""
702
- messages.append(MessageSegment.text(f"商品名:{name} \n单份数量:{amount}\n单价:{price} {fishing_coin_name}\n单份总价:{total_price} {fishing_coin_name}\n描述:{desc}"))
703
-
704
- return messages
705
-
706
730
 
707
- async def check_tools(user_id: str, tools: list) -> str | None:
708
- # 这是工具吗?
709
- for tool in tools:
710
- props = get_props(tool)
711
- if not props or props == []:
712
- return f"搞啥嘞!{tool}既不是工具也不是鱼饵!"
731
+ messages.append(MessageSegment.text("===== 钓鱼用具店 ====="))
713
732
 
714
- # 如果有两个工具,是一个工具一个鱼饵吗?
715
- if len(tools) == 2:
716
- if get_type(tools[0]) == get_type(tools[1]):
717
- return "你为啥要用两个类型一样的东西?"
718
-
719
- # 有吗?有吗?
720
- session = get_session()
721
- async with session.begin():
722
- select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
723
- fishes_record = await session.scalar(select_user)
724
- if fishes_record:
725
- loads_fishes = json.loads(fishes_record.fishes)
726
- for tool in tools:
727
- if tool not in loads_fishes:
728
- return f"你哪来的 {tool}?"
729
-
730
- return None
731
-
732
- async def remove_tools(user_id: str, tools: list[str]) -> None:
733
- session = get_session()
734
- async with session.begin():
735
- select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
736
- fishes_record = await session.scalar(select_user)
737
- if fishes_record:
738
- loads_fishes = json.loads(fishes_record.fishes)
739
- for tool in tools:
740
- loads_fishes[tool] -= 1
741
- if loads_fishes[tool] == 0:
742
- del loads_fishes[tool]
743
- dump_fishes = json.dumps(loads_fishes)
744
- user_update = update(FishingRecord).where(
745
- FishingRecord.user_id == user_id
746
- ).values(
747
- fishes=dump_fishes
733
+ for fish in config_fishes:
734
+ if fish.can_buy:
735
+ total_price = int(fish.buy_price * fish.amount)
736
+ messages.append(
737
+ MessageSegment.text(
738
+ f"商品名:{fish.name} \n单份数量:{fish.amount}\n单价:{fish.buy_price} {fishing_coin_name}\n"
739
+ f"单份总价:{total_price} {fishing_coin_name}\n描述:{fish.description}"
740
+ )
748
741
  )
749
- await session.execute(user_update)
750
- await session.commit()
751
- else:
752
- pass
753
- # raise ValueError("?你的 Check 是怎么通过的?")
742
+
743
+ return messages