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.
@@ -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,30 @@ 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())
198
- session = get_session()
199
- 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
207
-
208
-
209
230
  async def check_achievement(user_id: str) -> str | None:
210
231
  session = get_session()
211
232
  async with session.begin():
212
- record = await session.scalar(select(FishingRecord).where(FishingRecord.user_id == user_id))
233
+ record = await session.scalar(
234
+ select(FishingRecord).where(FishingRecord.user_id == user_id)
235
+ )
213
236
  if not record:
214
237
  return None
215
238
  fishing_frequency = record.frequency
216
239
  user_fishes = json.loads(record.fishes)
217
- achievements = config.fishing_achievement
240
+ achievements = config_achievements
218
241
  result_list = []
219
242
  for achievement in achievements:
220
- achievement_name = achievement["name"]
243
+ achievement_name = achievement.name
221
244
  if await is_exists_achievement(user_id, achievement_name):
222
245
  continue
223
- if (achievement["type"] == "fishing_frequency" and achievement["data"] <= fishing_frequency) or \
224
- (achievement["type"] == "fish_type" and achievement["data"] in user_fishes):
246
+ if (
247
+ achievement.type == "fishing_frequency"
248
+ and achievement.data <= fishing_frequency
249
+ ) or (achievement.type == "fish_type" and achievement.data in user_fishes):
225
250
  await save_achievement(user_id, achievement_name)
226
- result_list.append(f"""达成成就: {achievement_name}\n{achievement["description"]}""")
251
+ result_list.append(
252
+ f"""达成成就: {achievement_name}\n{achievement.description}"""
253
+ )
227
254
  return result_list if result_list != [] else None
228
255
 
229
256
 
@@ -248,10 +275,10 @@ async def save_achievement(user_id: str, achievement_name: str):
248
275
  loads_achievements = json.loads(record.achievements)
249
276
  loads_achievements.append(achievement_name)
250
277
  dump_achievements = json.dumps(loads_achievements)
251
- user_update = update(FishingRecord).where(
252
- FishingRecord.user_id == user_id
253
- ).values(
254
- achievements=dump_achievements
278
+ user_update = (
279
+ update(FishingRecord)
280
+ .where(FishingRecord.user_id == user_id)
281
+ .values(achievements=dump_achievements)
255
282
  )
256
283
  await session.execute(user_update)
257
284
  await session.commit()
@@ -265,16 +292,18 @@ async def save_achievement(user_id: str, achievement_name: str):
265
292
  fishes="{}",
266
293
  special_fishes="{}",
267
294
  coin=0,
268
- achievements=dump_achievements
295
+ achievements=dump_achievements,
269
296
  )
270
297
  session.add(new_record)
271
298
  await session.commit()
272
299
 
273
300
 
274
301
  async def save_fish(user_id: str, fish_name: str) -> None:
275
- """向数据库写入鱼以持久化保存"""
276
302
  time_now = int(time.time())
277
- fishing_limit = config.fishing_limit
303
+ fishing_cooldown = random.randint(
304
+ config.fishing_cooldown_time_min, config.fishing_cooldown_time_max
305
+ )
306
+ amount = get_fish_by_name(fish_name).amount
278
307
  session = get_session()
279
308
  async with session.begin():
280
309
  select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
@@ -282,48 +311,43 @@ async def save_fish(user_id: str, fish_name: str) -> None:
282
311
  if record:
283
312
  loads_fishes = json.loads(record.fishes)
284
313
  try:
285
- loads_fishes[fish_name] += 1
314
+ loads_fishes[fish_name] += amount
286
315
  except KeyError:
287
- loads_fishes[fish_name] = 1
316
+ loads_fishes[fish_name] = amount
288
317
  dump_fishes = json.dumps(loads_fishes)
289
318
  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
319
+ user_update = (
320
+ update(FishingRecord)
321
+ .where(FishingRecord.user_id == user_id)
322
+ .values(
323
+ time=time_now + fishing_cooldown,
324
+ frequency=new_frequency,
325
+ fishes=dump_fishes,
326
+ )
296
327
  )
297
328
  await session.execute(user_update)
298
329
  await session.commit()
299
330
  return
300
- data = {
301
- fish_name: 1
302
- }
331
+ data = {fish_name: amount}
303
332
  dump_fishes = json.dumps(data)
304
333
  new_record = FishingRecord(
305
334
  user_id=user_id,
306
- time=time_now + fishing_limit,
335
+ time=time_now + fishing_cooldown,
307
336
  frequency=1,
308
337
  fishes=dump_fishes,
309
338
  special_fishes="{}",
310
339
  coin=0,
311
- achievements="[]"
340
+ achievements="[]",
312
341
  )
313
342
  session.add(new_record)
314
343
  await session.commit()
315
344
 
316
345
 
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
346
  async def save_special_fish(user_id: str, fish_name: str) -> None:
325
347
  time_now = int(time.time())
326
- fishing_limit = config.fishing_limit
348
+ fishing_cooldown = random.randint(
349
+ config.fishing_cooldown_time_min, config.fishing_cooldown_time_max
350
+ )
327
351
  session = get_session()
328
352
  async with session.begin():
329
353
  select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
@@ -335,32 +359,35 @@ async def save_special_fish(user_id: str, fish_name: str) -> None:
335
359
  except KeyError:
336
360
  loads_fishes[fish_name] = 1
337
361
  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
362
+ user_update = (
363
+ update(FishingRecord)
364
+ .where(FishingRecord.user_id == user_id)
365
+ .values(
366
+ time=time_now + fishing_cooldown,
367
+ frequency=record.frequency + 1,
368
+ special_fishes=dump_fishes,
369
+ )
344
370
  )
345
371
  await session.execute(user_update)
346
372
  else:
347
- data = {
348
- fish_name: 1
349
- }
373
+ data = {fish_name: 1}
350
374
  dump_fishes = json.dumps(data)
351
375
  new_record = FishingRecord(
352
376
  user_id=user_id,
353
- time=time_now + fishing_limit,
377
+ time=time_now + fishing_cooldown,
354
378
  frequency=1,
355
379
  fishes="{}",
356
380
  special_fishes=dump_fishes,
357
381
  coin=0,
358
- achievements=[]
382
+ achievements=[],
359
383
  )
360
384
  session.add(new_record)
361
- select_fish = select(SpecialFishes).where(
362
- SpecialFishes.fish == fish_name
363
- ).order_by(SpecialFishes.id).limit(1)
385
+ select_fish = (
386
+ select(SpecialFishes)
387
+ .where(SpecialFishes.fish == fish_name)
388
+ .order_by(SpecialFishes.id)
389
+ .limit(1)
390
+ )
364
391
  record = await session.scalar(select_fish)
365
392
  fish_id = record.id
366
393
  delete_fishes = delete(SpecialFishes).where(SpecialFishes.id == fish_id)
@@ -368,65 +395,9 @@ async def save_special_fish(user_id: str, fish_name: str) -> None:
368
395
  await session.commit()
369
396
 
370
397
 
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
398
  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
399
  if quantity <= 0:
427
400
  return "你在卖什么 w(゚Д゚)w"
428
- if fish_name not in can_sell_fishes:
429
- return f"这个 {fish_name} 不可以卖哦~"
430
401
  session = get_session()
431
402
  async with session.begin():
432
403
  select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
@@ -435,23 +406,29 @@ async def sell_fish(user_id: str, fish_name: str, quantity: int = 1) -> str:
435
406
  loads_fishes = json.loads(fishes_record.fishes)
436
407
  spec_fishes = json.loads(fishes_record.special_fishes)
437
408
  if fish_name in loads_fishes and loads_fishes[fish_name] > 0:
438
- fish_price = get_price(fish_name)
409
+ if fish_name not in can_sell_fishes:
410
+ return f"这个 {fish_name} 不可以卖哦~"
439
411
  if loads_fishes[fish_name] < quantity:
440
412
  return f"你没有那么多 {fish_name}"
413
+ fish_price = get_fish_by_name(fish_name).price
441
414
  loads_fishes[fish_name] -= quantity
442
415
  if loads_fishes[fish_name] == 0:
443
416
  del loads_fishes[fish_name]
444
417
  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
418
+ user_update = (
419
+ update(FishingRecord)
420
+ .where(FishingRecord.user_id == user_id)
421
+ .values(
422
+ coin=fishes_record.coin + fish_price * quantity,
423
+ fishes=dump_fishes,
424
+ )
450
425
  )
451
426
  await session.execute(user_update)
452
427
  await session.commit()
453
- return (f"你以 {fish_price} {fishing_coin_name} / 条的价格卖出了 {quantity} 条 {fish_name}, "
454
- f"你获得了 {fish_price * quantity} {fishing_coin_name}")
428
+ return (
429
+ f"你以 {fish_price} {fishing_coin_name} / 条的价格卖出了 {quantity} {fish_name}, "
430
+ f"你获得了 {fish_price * quantity} {fishing_coin_name}"
431
+ )
455
432
  elif fish_name in spec_fishes and spec_fishes[fish_name] > 0:
456
433
  fish_price = config.special_fish_price
457
434
  if spec_fishes[fish_name] < quantity:
@@ -460,35 +437,35 @@ async def sell_fish(user_id: str, fish_name: str, quantity: int = 1) -> str:
460
437
  if spec_fishes[fish_name] == 0:
461
438
  del spec_fishes[fish_name]
462
439
  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
440
+ user_update = (
441
+ update(FishingRecord)
442
+ .where(FishingRecord.user_id == user_id)
443
+ .values(
444
+ coin=fishes_record.coin + fish_price * quantity,
445
+ special_fishes=dump_fishes,
446
+ )
468
447
  )
469
448
  await session.execute(user_update)
470
449
  await session.commit()
471
- return (f"你以 {fish_price} {fishing_coin_name} / 条的价格卖出了 {quantity} 条 {fish_name}, "
472
- f"获得了 {fish_price * quantity} {fishing_coin_name}")
473
- else:
450
+ return (
451
+ f"你以 {fish_price} {fishing_coin_name} / 条的价格卖出了 {quantity} {fish_name}, "
452
+ f"获得了 {fish_price * quantity} {fishing_coin_name}"
453
+ )
454
+ else:
474
455
  return "查无此鱼"
475
456
  else:
476
457
  return "还没钓鱼就想卖鱼?"
477
-
458
+
478
459
 
479
460
  async def buy_fish(user_id: str, fish_name: str, quantity: int = 1) -> str:
480
461
  if quantity <= 0:
481
462
  return "别在渔具店老板面前炫耀自己的鱼 (..-˘ ˘-.#)"
482
463
  if fish_name not in can_buy_fishes:
483
464
  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
-
465
+
466
+ fish = get_fish_by_name(fish_name)
467
+ total_price = int(fish.buy_price * fish.amount * quantity)
468
+
492
469
  session = get_session()
493
470
  async with session.begin():
494
471
  select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
@@ -501,34 +478,22 @@ async def buy_fish(user_id: str, fish_name: str, quantity: int = 1) -> str:
501
478
  return f"你没有足够的 {fishing_coin_name}, 还需 {coin_less} {fishing_coin_name}"
502
479
  user_coin -= total_price
503
480
  try:
504
- loads_fishes[fish_name] += amount * quantity
481
+ loads_fishes[fish_name] += fish.amount * quantity
505
482
  except KeyError:
506
- loads_fishes[fish_name] = amount * quantity
483
+ loads_fishes[fish_name] = fish.amount * quantity
507
484
  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
485
+ user_update = (
486
+ update(FishingRecord)
487
+ .where(FishingRecord.user_id == user_id)
488
+ .values(coin=user_coin, fishes=dump_fishes)
513
489
  )
514
490
  await session.execute(user_update)
515
491
  await session.commit()
516
- return (f"你用 {total_price} {fishing_coin_name} 买入了 {quantity * amount} {fish_name}")
492
+ return f"你用 {total_price} {fishing_coin_name} 买入了 {quantity} {fish_name}"
517
493
  else:
518
494
  return "不想钓鱼的人就别在渔具店逛了~"
519
495
 
520
496
 
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
497
  async def free_fish(user_id: str, fish_name: str) -> str:
533
498
  session = get_session()
534
499
  async with session.begin():
@@ -541,16 +506,13 @@ async def free_fish(user_id: str, fish_name: str) -> str:
541
506
  spec_fishes[fish_name] -= 1
542
507
  if spec_fishes[fish_name] == 0:
543
508
  del spec_fishes[fish_name]
544
- new_record = SpecialFishes(
545
- user_id=user_id,
546
- fish=fish_name
547
- )
509
+ new_record = SpecialFishes(user_id=user_id, fish=fish_name)
548
510
  session.add(new_record)
549
511
  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
512
+ user_update = (
513
+ update(FishingRecord)
514
+ .where(FishingRecord.user_id == user_id)
515
+ .values(special_fishes=dump_fishes)
554
516
  )
555
517
  await session.execute(user_update)
556
518
  await session.commit()
@@ -558,24 +520,23 @@ async def free_fish(user_id: str, fish_name: str) -> str:
558
520
  else:
559
521
  if fish_name in fish_list:
560
522
  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)
523
+
524
+ if user_coin < config.special_fish_free_price:
525
+ special_fish_coin_less = str(
526
+ config.special_fish_free_price - fishes_record.coin
527
+ )
564
528
  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
- )
529
+ user_coin -= config.special_fish_free_price
530
+ new_record = SpecialFishes(user_id=user_id, fish=fish_name)
570
531
  session.add(new_record)
571
- user_update = update(FishingRecord).where(
572
- FishingRecord.user_id == user_id
573
- ).values(
574
- coin=user_coin
532
+ user_update = (
533
+ update(FishingRecord)
534
+ .where(FishingRecord.user_id == user_id)
535
+ .values(coin=user_coin)
575
536
  )
576
537
  await session.execute(user_update)
577
538
  await session.commit()
578
- return f"你花费 {config.special_fish_price // 2} {fishing_coin_name} 放生了 {fish_name}, 未来或许会被有缘人钓到呢"
539
+ return f"你花费 {config.special_fish_free_price} {fishing_coin_name} 放生了 {fish_name}, 未来或许会被有缘人钓到呢"
579
540
  return "你甚至还没钓过鱼"
580
541
 
581
542
 
@@ -583,7 +544,9 @@ async def lottery(user_id: str) -> str:
583
544
  """算法来自于 https://github.com/fossifer/minesweeperbot/blob/master/cards.py"""
584
545
  session = get_session()
585
546
  time_now = int(time.time())
586
- fishing_limit = config.fishing_limit
547
+ fishing_cooldown = random.randint(
548
+ config.fishing_cooldown_time_min, config.fishing_cooldown_time_max
549
+ )
587
550
  async with session.begin():
588
551
  select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
589
552
  fishes_record = await session.scalar(select_user)
@@ -591,24 +554,28 @@ async def lottery(user_id: str) -> str:
591
554
  user_coin = fishes_record.coin
592
555
  if user_coin <= 30:
593
556
  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,
557
+ user_update = (
558
+ update(FishingRecord)
559
+ .where(FishingRecord.user_id == user_id)
560
+ .values(
561
+ time=time_now + fishing_cooldown,
562
+ coin=fishes_record.coin + new_coin,
563
+ )
599
564
  )
600
565
  await session.execute(user_update)
601
- await session.commit()
566
+ await session.commit()
602
567
  return f"你穷得连河神都看不下去了,给了你 {new_coin} {fishing_coin_name} w(゚Д゚)w"
603
568
  new_coin = abs(user_coin) / 3
604
569
  new_coin = random.randrange(5000, 15000) / 10000 * new_coin
605
570
  new_coin = int(new_coin) if new_coin > 1 else 1
606
571
  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,
572
+ user_update = (
573
+ update(FishingRecord)
574
+ .where(FishingRecord.user_id == user_id)
575
+ .values(
576
+ time=time_now + fishing_cooldown,
577
+ coin=fishes_record.coin + new_coin,
578
+ )
612
579
  )
613
580
  await session.execute(user_update)
614
581
  await session.commit()
@@ -623,15 +590,17 @@ async def give(user_id: str, fish_name: str, quantity: int = 1) -> str:
623
590
  select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
624
591
  record = await session.scalar(select_user)
625
592
  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,
593
+ if fish_name == "coin" or fish_name == fishing_coin_name:
594
+ user_update = (
595
+ update(FishingRecord)
596
+ .where(FishingRecord.user_id == user_id)
597
+ .values(
598
+ coin=record.coin + quantity,
599
+ )
631
600
  )
632
601
  await session.execute(user_update)
633
602
  await session.commit()
634
- return f"使用滥权之力成功为 {user_id} {"增加" if quantity >= 0 else "减少"} {abs(quantity)} {fishing_coin_name} ヾ(≧▽≦*)o"
603
+ return f"使用滥权之力成功为 {user_id} {"增加" if quantity >= 0 else "减少"} {abs(quantity)} {fishing_coin_name} ヾ(≧▽≦*)o"
635
604
  loads_fishes = json.loads(record.fishes)
636
605
  spec_fishes = json.loads(record.special_fishes)
637
606
  if fish_name in fish_list:
@@ -640,10 +609,10 @@ async def give(user_id: str, fish_name: str, quantity: int = 1) -> str:
640
609
  except KeyError:
641
610
  loads_fishes[fish_name] = quantity
642
611
  dump_fishes = json.dumps(loads_fishes)
643
- user_update = update(FishingRecord).where(
644
- FishingRecord.user_id == user_id
645
- ).values(
646
- fishes=dump_fishes
612
+ user_update = (
613
+ update(FishingRecord)
614
+ .where(FishingRecord.user_id == user_id)
615
+ .values(fishes=dump_fishes)
647
616
  )
648
617
  await session.execute(user_update)
649
618
  await session.commit()
@@ -653,17 +622,115 @@ async def give(user_id: str, fish_name: str, quantity: int = 1) -> str:
653
622
  except KeyError:
654
623
  spec_fishes[fish_name] = quantity
655
624
  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
625
+ user_update = (
626
+ update(FishingRecord)
627
+ .where(FishingRecord.user_id == user_id)
628
+ .values(special_fishes=dump_fishes)
660
629
  )
661
630
  await session.execute(user_update)
662
631
  await session.commit()
663
- return f"使用滥权之力成功将 {fish_name} 添加到 {user_id} 的背包之中 ヾ(≧▽≦*)o"
632
+ return (
633
+ f"使用滥权之力成功将 {fish_name} 添加到 {user_id} 的背包之中 ヾ(≧▽≦*)o"
634
+ )
664
635
  return "未查找到用户信息, 无法执行滥权操作 w(゚Д゚)w"
665
636
 
666
637
 
638
+ async def get_all_special_fish() -> list[str]:
639
+ session = get_session()
640
+ async with session.begin():
641
+ random_select = select(SpecialFishes.fish).order_by(SpecialFishes.fish.asc())
642
+ data = await session.scalars(random_select)
643
+ result = data.all()
644
+ return result
645
+
646
+
647
+ async def get_pool() -> list[MessageSegment]:
648
+
649
+ messages: list[MessageSegment] = []
650
+ pool = await get_all_special_fish()
651
+ messages.append(MessageSegment.text(f"现在鱼池里面有 {len(pool)} 条鱼。"))
652
+
653
+ result = dict()
654
+ for fish in pool:
655
+ try:
656
+ result[fish] += 1
657
+ except KeyError:
658
+ result[fish] = 1
659
+
660
+ msg = "鱼池列表:\n"
661
+ for fish, num in result.items():
662
+ if len(msg) > 300:
663
+ msg += f"{fish} x {num}"
664
+ messages.append(MessageSegment.text(msg))
665
+ msg = ""
666
+ else:
667
+ msg += f"{fish} x {num}\n"
668
+ else:
669
+ messages.append(MessageSegment.text(msg))
670
+
671
+ return messages
672
+
673
+
674
+ async def get_stats(user_id: str) -> str:
675
+ session = get_session()
676
+ async with session.begin():
677
+ select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
678
+ fishing_record = await session.scalar(select_user)
679
+ if fishing_record:
680
+ return f"🐟你钓上了 {fishing_record.frequency} 条鱼"
681
+ return "🐟你还没有钓过鱼,快去钓鱼吧"
682
+
683
+
684
+ async def get_balance(user_id: str) -> str:
685
+ session = get_session()
686
+ async with session.begin():
687
+ select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
688
+ fishes_record = await session.scalar(select_user)
689
+ if fishes_record:
690
+ return f"🪙你有 {fishes_record.coin} {fishing_coin_name}"
691
+ return "🪙你什么也没有 :)"
692
+
693
+
694
+ async def get_backpack(user_id: str) -> list[str]:
695
+ session = get_session()
696
+ async with session.begin():
697
+ select_user = select(FishingRecord).where(FishingRecord.user_id == user_id)
698
+ fishes_record = await session.scalar(select_user)
699
+ if fishes_record:
700
+ load_fishes = json.loads(fishes_record.fishes)
701
+ sorted_fishes = {
702
+ key: load_fishes[key] for key in fish_list if key in load_fishes
703
+ }
704
+ load_special_fishes = json.loads(fishes_record.special_fishes)
705
+ if load_special_fishes:
706
+ sorted_special_fishes = {
707
+ key: load_special_fishes[key] for key in sorted(load_special_fishes)
708
+ }
709
+ return print_backpack(sorted_fishes, sorted_special_fishes)
710
+ return (
711
+ ["🎒你的背包里空无一物"]
712
+ if sorted_fishes == {}
713
+ else print_backpack(sorted_fishes)
714
+ )
715
+ return ["🎒你的背包里空无一物"]
716
+
717
+
718
+ def print_backpack(backpack: dict, special_backpack=None) -> list[str]:
719
+ result = [
720
+ f"{fish_name}×{str(quantity)}" for fish_name, quantity in backpack.items()
721
+ ]
722
+ if special_backpack:
723
+ special_result = [
724
+ f"{fish_name}×{str(quantity)}"
725
+ for fish_name, quantity in special_backpack.items()
726
+ ]
727
+ return [
728
+ "🎒普通鱼:\n" + "\n".join(result),
729
+ "🎒特殊鱼:\n" + "\n".join(special_result),
730
+ ]
731
+ return ["🎒普通鱼:\n" + "\n".join(result)]
732
+
733
+
667
734
  async def get_achievements(user_id: str) -> str:
668
735
  session = get_session()
669
736
  async with session.begin():
@@ -674,10 +741,13 @@ async def get_achievements(user_id: str) -> str:
674
741
  return "已完成成就:\n" + "\n".join(achievements)
675
742
  return "你甚至还没钓过鱼 (╬▔皿▔)╯"
676
743
 
677
- async def get_board() -> list:
744
+
745
+ async def get_board() -> list[tuple]:
678
746
  session = get_session()
679
747
  async with session.begin():
680
- select_users = select(FishingRecord).order_by(FishingRecord.coin.desc()).limit(10)
748
+ select_users = (
749
+ select(FishingRecord).order_by(FishingRecord.coin.desc()).limit(10)
750
+ )
681
751
  record = await session.scalars(select_users)
682
752
  if record:
683
753
  top_users_list = []
@@ -687,67 +757,20 @@ async def get_board() -> list:
687
757
  return top_users_list
688
758
  return []
689
759
 
760
+
690
761
  def get_shop() -> list[MessageSegment]:
691
762
  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
-
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}既不是工具也不是鱼饵!"
713
763
 
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
764
+ messages.append(MessageSegment.text("===== 钓鱼用具店 ====="))
731
765
 
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
766
+ for fish in config_fishes:
767
+ if fish.can_buy:
768
+ total_price = int(fish.buy_price * fish.amount)
769
+ messages.append(
770
+ MessageSegment.text(
771
+ f"商品名:{fish.name} \n单份数量:{fish.amount}\n单价:{fish.buy_price} {fishing_coin_name}\n"
772
+ f"单份总价:{total_price} {fishing_coin_name}\n描述:{fish.description}"
773
+ )
748
774
  )
749
- await session.execute(user_update)
750
- await session.commit()
751
- else:
752
- pass
753
- # raise ValueError("?你的 Check 是怎么通过的?")
775
+
776
+ return messages