Files
NewWPSBot/Plugins/WPSGardenSystem/garden_plugin_view.py
2025-11-15 17:15:06 +08:00

234 lines
8.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Garden overview and selling plugin."""
from __future__ import annotations
from typing import Optional, Sequence
from PWF.Convention.Runtime.Architecture import Architecture
from Plugins.WPSAPI import GuideEntry
from Plugins.WPSBackpackSystem import WPSBackpackSystem
from Plugins.WPSConfigSystem import WPSConfigAPI
from .garden_plugin_base import WPSGardenBase
class WPSGardenView(WPSGardenBase):
def get_guide_subtitle(self) -> str:
return "查看菜园概览与果实售出"
def collect_command_entries(self) -> Sequence[GuideEntry]:
return (
GuideEntry(
title="菜园 概览",
identifier="菜园",
description="显示当前所有地块状态与剩余果实。",
metadata={"别名": "garden"},
icon="🗺️",
details=[
{
"type": "list",
"items": [
"列出地块序号、作物名称、成熟时间与被偷情况。",
"空地块会提示剩余可用数量。",
],
}
],
),
GuideEntry(
title="菜园 查看",
identifier="菜园 查看 <用户名|用户ID>",
description="查看任意玩家的菜园情况(不显示陷阱信息)。",
metadata={"别名": "garden view"},
icon="🔍",
details=[
{
"type": "steps",
"items": [
"输入目标用户名或用户ID。",
"系统显示该玩家的菜园状态和成熟作物信息。",
"无法看到陷阱信息,保护隐私。",
],
}
],
),
GuideEntry(
title="菜园 售出",
identifier="菜园 售出 <果实> <数量>",
description="售出成熟果实并换取积分。",
metadata={"别名": "garden sell"},
icon="💰",
details=[
{
"type": "steps",
"items": [
"检查背包持有的果实数量。",
"输入欲出售的果实 ID/名称与数量。",
"系统按配置的售价乘以数量发放积分,同时扣除背包库存。",
],
}
],
),
)
def collect_guide_entries(self) -> Sequence[GuideEntry]:
return (
{
"title": "概览视图",
"description": "默认输出地块编号、成熟状态、剩余果实与被偷记录。",
},
{
"title": "查看他人菜园",
"description": "`菜园 查看 <用户名|用户ID>`,查看任意玩家的菜园情况,不显示陷阱信息。",
},
{
"title": "果实售出",
"description": "`菜园 售出 <果实> <数量>`,自动结算积分并扣除背包库存。",
},
)
def wake_up(self) -> None:
super().wake_up()
self.register_plugin("garden")
self.register_plugin("菜园")
async def callback(self, message: str, chat_id: int, user_id: int) -> Optional[str]:
payload = self.parse_message_after_at(message).strip()
if not payload:
return await self._send_overview(chat_id, user_id)
tokens = [token.strip() for token in payload.split() if token.strip()]
if tokens and tokens[0] in {"查看", "view"}:
return await self._handle_view(tokens[1:], chat_id, user_id)
if tokens and tokens[0] in {"售出", "sell"}:
return await self._handle_sell(tokens[1:], chat_id, user_id)
return await self._send_overview(chat_id, user_id)
async def _send_overview(self, chat_id: int, user_id: int) -> Optional[str]:
overview = self.format_garden_overview(user_id)
return await self.send_markdown_message(overview, chat_id, user_id)
def _resolve_target_user(self, identifier: str) -> Optional[int]:
"""解析目标用户名或用户ID
Args:
identifier: 用户名或用户ID字符串
Returns:
用户ID如果解析失败则返回None
"""
text = identifier.strip()
if not text:
return None
# 尝试通过用户名查找
try:
config_api: WPSConfigAPI = Architecture.Get(WPSConfigAPI)
resolved_id = config_api.find_user_id_by_username(text)
if resolved_id is not None:
return resolved_id
except Exception:
pass
# 尝试按用户ID解析
if text.isdigit():
return int(text)
return None
async def _handle_view(self, args: list[str], chat_id: int, user_id: int) -> Optional[str]:
"""处理查看其他用户菜园的指令
Args:
args: 参数列表应包含目标用户名或用户ID
chat_id: 会话ID
user_id: 当前用户ID
Returns:
消息或None
"""
if not args:
return await self.send_markdown_message(
"❌ 指令格式:`菜园 查看 <用户名|用户ID>`",
chat_id,
user_id,
)
target_identifier = " ".join(args)
target_user_id = self._resolve_target_user(target_identifier)
if target_user_id is None:
return await self.send_markdown_message(
"❌ 未找到目标用户请检查用户名或用户ID是否正确",
chat_id,
user_id,
)
# 获取目标用户名
config_api: WPSConfigAPI = Architecture.Get(WPSConfigAPI)
target_username = config_api.get_user_name(target_user_id)
# 格式化显示目标用户的菜园(不显示陷阱)
overview = self.format_garden_overview(target_user_id, show_trap=False)
# 替换标题,显示目标用户信息
overview_with_header = overview.replace("# 🌱 菜园概览", f"# 🌱 {target_username} 的菜园")
return await self.send_markdown_message(overview_with_header, chat_id, user_id)
async def _handle_sell(self, args: list[str], chat_id: int, user_id: int) -> Optional[str]:
if len(args) < 2:
return await self.send_markdown_message(
"❌ 指令格式:`菜园 售出 <果实> <数量>`",
chat_id,
user_id,
)
identifier = args[0]
try:
quantity = int(args[1])
except ValueError:
return await self.send_markdown_message("❌ 数量必须是整数", chat_id, user_id)
if quantity <= 0:
return await self.send_markdown_message("❌ 数量必须大于0", chat_id, user_id)
crop = self.resolve_fruit_id(identifier)
if crop is None:
return await self.send_markdown_message("❌ 未找到对应果实", chat_id, user_id)
backpack: WPSBackpackSystem = Architecture.Get(WPSBackpackSystem)
owned = 0
for item in backpack.get_user_items(user_id):
if item.item_id == crop.fruit_id:
owned = item.quantity
break
if owned < quantity:
return await self.send_markdown_message("❌ 果实数量不足", chat_id, user_id)
total_points, price_per = self.service().sell_fruit(
user_id=user_id,
fruit_id=crop.fruit_id,
quantity=quantity,
)
backpack.set_item_quantity(user_id, crop.fruit_id, owned - quantity)
config_api: WPSConfigAPI = Architecture.Get(WPSConfigAPI)
new_points = await config_api.adjust_user_points(
chat_id,
user_id,
total_points,
reason=f"出售 {crop.display_name} 的果实",
)
message = (
"# 🛒 售出成功\n"
f"- 果实:{crop.display_name} × {quantity}\n"
f"- 单价:{price_per}\n"
f"- 总计:{total_points}\n"
f"- 当前积分:{new_points}"
)
return await self.send_markdown_message(message, chat_id, user_id)
__all__ = ["WPSGardenView"]