feat: 新增种子商店功能

feat:移除过多的py文件
fix🐛: 对部分json文件进行修正
This commit is contained in:
Art_Sakura 2025-03-19 18:00:50 +08:00
parent ca6eb3343f
commit 13ddcf2a58
10 changed files with 405 additions and 172 deletions

View File

@ -2,12 +2,13 @@ from nonebot import get_driver
from nonebot.plugin import PluginMetadata from nonebot.plugin import PluginMetadata
from zhenxun.configs.utils import PluginExtraData from zhenxun.configs.utils import PluginExtraData
from zhenxun.services.log import logger
from zhenxun.utils.message import MessageUtils from zhenxun.utils.message import MessageUtils
from .command import diuse_farm, diuse_register from .command import diuse_farm, diuse_register
from .config import g_pJsonManager from .config import g_pJsonManager
from .database import g_pSqlManager from .database import g_pSqlManager
from .drawImage import g_pDrawImage from .farm.shop import g_pShopManager
# from .globalClass import g_pDrawImage, g_pJsonManager, g_pSqlManager # from .globalClass import g_pDrawImage, g_pJsonManager, g_pSqlManager

View File

@ -3,10 +3,12 @@ from nonebot_plugin_alconna import (Alconna, AlconnaQuery, Args, Match, Option,
Query, Subcommand, on_alconna, store_true) Query, Subcommand, on_alconna, store_true)
from nonebot_plugin_uninfo import Uninfo from nonebot_plugin_uninfo import Uninfo
from zhenxun.services.log import logger
from zhenxun.utils.message import MessageUtils from zhenxun.utils.message import MessageUtils
from .database import g_pSqlManager from .database import g_pSqlManager
from .drawImage import g_pDrawImage from .farm.farm import g_pFarmManager
from .farm.shop import g_pShopManager
diuse_register = on_alconna( diuse_register = on_alconna(
Alconna("开通农场"), Alconna("开通农场"),
@ -24,9 +26,7 @@ async def _(session: Uninfo):
if user: if user:
await MessageUtils.build_message("你已经有啦").send(reply_to=True) await MessageUtils.build_message("你已经有啦").send(reply_to=True)
else: else:
info = {"uid": uid, "name": "测试", "exp": 0, "point": 100} aaa = await g_pSqlManager.initUserInfoByUid(uid, str(session.user.name), 0, 100)
aaa = await g_pSqlManager.appendUserByUserInfo(info)
await MessageUtils.build_message(str(aaa)).send(reply_to=True) await MessageUtils.build_message(str(aaa)).send(reply_to=True)
@ -51,16 +51,14 @@ diuse_farm = on_alconna(
@diuse_farm.assign("$main") @diuse_farm.assign("$main")
async def _(session: Uninfo): async def _(session: Uninfo):
uid = str(session.user.id) uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid)
level = await g_pSqlManager.getUserLevelByUid(uid) if point < 0:
if level <= 0:
await MessageUtils.build_message("尚未开通农场").send() await MessageUtils.build_message("尚未开通农场").send()
return None return None
image = await g_pDrawImage.drawMyFarm(uid) image = await g_pFarmManager.drawFarmByUid(uid)
await MessageUtils.build_message(image).send(reply_to=True)
await MessageUtils.build_message(image).send()
diuse_farm.shortcut( diuse_farm.shortcut(
"我的农场币", "我的农场币",
@ -74,6 +72,10 @@ async def _(session: Uninfo):
uid = str(session.user.id) uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid) point = await g_pSqlManager.getUserPointByUid(uid)
if point < 0:
await MessageUtils.build_message("尚未开通农场").send()
return None
await MessageUtils.build_message(f"你的当前农场币为: {point}").send(reply_to=True) await MessageUtils.build_message(f"你的当前农场币为: {point}").send(reply_to=True)
diuse_farm.shortcut( diuse_farm.shortcut(
@ -88,7 +90,12 @@ async def _(session: Uninfo):
uid = str(session.user.id) uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid) point = await g_pSqlManager.getUserPointByUid(uid)
await MessageUtils.build_message(f"你的当前农场币为: {point}").send(reply_to=True) if point < 0:
await MessageUtils.build_message("尚未开通农场").send()
return None
image = await g_pShopManager.getPlantShopImage()
await MessageUtils.build_message(image).send()
diuse_farm.shortcut( diuse_farm.shortcut(
"购买种子(?P<name>.*?)", "购买种子(?P<name>.*?)",
@ -104,19 +111,20 @@ async def _(session: Uninfo, name: Match[str], num: Query[int] = AlconnaQuery("n
"请在指令后跟需要购买的种子名称" "请在指令后跟需要购买的种子名称"
).finish(reply_to=True) ).finish(reply_to=True)
# result = await ShopManage.buy_prop(session.user.id, name.result, num.result)
uid = str(session.user.id) uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid) point = await g_pSqlManager.getUserPointByUid(uid)
await MessageUtils.build_message(f"你的当前农场币为: {point}").send(reply_to=True) if point < 0:
await MessageUtils.build_message("尚未开通农场").send()
return None
result = await g_pShopManager.buyPlant(uid, name.result, num.result)
await MessageUtils.build_message(result).send(reply_to=True)
diuse_farm.shortcut( diuse_farm.shortcut(
"种子商店", "我的种子",
command="我的农场", command="我的农场",
arguments=["plant-shop"], arguments=["my-plant"],
prefix=True, prefix=True,
) )
@ -125,4 +133,9 @@ async def _(session: Uninfo):
uid = str(session.user.id) uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid) point = await g_pSqlManager.getUserPointByUid(uid)
await MessageUtils.build_message(f"你的当前农场币为: {point}").send(reply_to=True) if point < 0:
await MessageUtils.build_message("尚未开通农场").send()
return None
result = await g_pFarmManager.getUserPlantByUid(uid)
await MessageUtils.build_message(result).send(reply_to=True)

View File

@ -2,10 +2,24 @@
"level": "level":
{ {
"1": 0, "1": 0,
"2": 500, "2": 50,
"3": 1250, "3": 75,
"4": 3000 "4": 125,
"5": 185,
"6": 200,
"7": 275,
"8": 350,
"9": 500,
"10": 850,
"11": 1250,
"12": 2250,
"13": 3500,
"14": 4500,
"15": 5800
}, },
"soil":[1, 1, 1, 5, 10, 15, 25], "soil":[1, 1, 1, 2, 3, 5, 7, 9, 12, 15,
18, 21, 25, 29, 33, 38, 43, 48, 54, 60,
66, 72, 78, 85, 92, 99, 106, 114, 120, 130],
"point":[0, 2000, 5000, 10000, 30000, 50000] "point":[0, 2000, 5000, 10000, 30000, 50000]
} }

View File

@ -1,7 +1,6 @@
{ {
"zhuShi": "zhuShi":
[ [
"name: 名称",
"level: 解锁等级", "level: 解锁等级",
"limit: 限制等级 0普通土地 1红土地 2黄土地 3黑土地", "limit: 限制等级 0普通土地 1红土地 2黄土地 3黑土地",
"experience: 收获经验", "experience: 收获经验",
@ -16,9 +15,8 @@
], ],
"plant": "plant":
{ {
"daBaiCai": "大白菜":
{ {
"name": "大白菜",
"level": 0, "level": 0,
"limit": 0, "limit": 0,
"experience": 5, "experience": 5,
@ -31,9 +29,8 @@
"general": true, "general": true,
"sell": false "sell": false
}, },
"baiLuoBo": "白萝卜":
{ {
"name": "白萝卜",
"level": 0, "level": 0,
"limit": 0, "limit": 0,
"experience": 5, "experience": 5,
@ -46,9 +43,106 @@
"general": true, "general": true,
"sell": false "sell": false
}, },
"huLuoBo": "胡萝卜":
{
"level": 0,
"limit": 0,
"experience": 5,
"harvest": 30,
"price": 5,
"time": 5,
"crop": 1,
"again": 0,
"phase": 5,
"general": true,
"sell": false
},
"牧草":
{
"level": 0,
"limit": 0,
"experience": 5,
"harvest": 30,
"price": 5,
"time": 5,
"crop": 1,
"again": 0,
"phase": 5,
"general": true,
"sell": false
},
"大蒜":
{
"level": 0,
"limit": 0,
"experience": 5,
"harvest": 30,
"price": 5,
"time": 5,
"crop": 1,
"again": 0,
"phase": 5,
"general": true,
"sell": false
},
"水稻":
{
"level": 0,
"limit": 0,
"experience": 5,
"harvest": 30,
"price": 5,
"time": 5,
"crop": 1,
"again": 0,
"phase": 5,
"general": true,
"sell": false
},
"小麦":
{
"level": 0,
"limit": 0,
"experience": 5,
"harvest": 30,
"price": 5,
"time": 5,
"crop": 1,
"again": 0,
"phase": 5,
"general": true,
"sell": false
},
"玉米":
{
"level": 0,
"limit": 0,
"experience": 5,
"harvest": 30,
"price": 5,
"time": 5,
"crop": 1,
"again": 0,
"phase": 5,
"general": true,
"sell": false
},
"油菜":
{
"level": 0,
"limit": 0,
"experience": 5,
"harvest": 30,
"price": 5,
"time": 5,
"crop": 1,
"again": 0,
"phase": 5,
"general": true,
"sell": false
},
"生菜":
{ {
"name": "胡萝卜",
"level": 0, "level": 0,
"limit": 0, "limit": 0,
"experience": 5, "experience": 5,

View File

@ -1,5 +1,5 @@
{ {
"size":[234.378, 156.252], "size":[234, 156],
"soil": "soil":
{ {
"1": "1":

View File

@ -127,6 +127,34 @@ class CSqlManager:
logger.error(f"数据库执行失败: {e}") logger.error(f"数据库执行失败: {e}")
return None return None
@classmethod
async def initUserInfoByUid(cls,
uid: str, name: str = "", exp: int = 0, point: int = 100):
#用户信息
userInfo = f"""
INSERT INTO user (uid, name, exp, point) VALUES ({uid}, '{name}', {str(exp)}, {str(point)})
"""
#用户仓库
userStorehouse = f"""
INSERT INTO storehouse (uid) VALUES ({uid});
"""
userSoilInfo = f"""
INSERT INTO soil (uid) VALUES ({uid});
"""
if not await cls.executeDB(userInfo):
return False
if not await cls.executeDB(userStorehouse):
return False
if not await cls.executeDB(userSoilInfo):
return False
return True
@classmethod @classmethod
async def getUserInfoByUid(cls, uid: str) -> list[dict]: async def getUserInfoByUid(cls, uid: str) -> list[dict]:
"""根据用户Uid获取用户信息 """根据用户Uid获取用户信息
@ -157,7 +185,7 @@ class CSqlManager:
return results return results
except Exception as e: except Exception as e:
logger.warning(f"查询失败: {e}") logger.warning(f"getUserInfoByUid查询失败: {e}")
return [] return []
@classmethod @classmethod
@ -175,12 +203,14 @@ class CSqlManager:
try: try:
async with cls.m_pDB.execute( async with cls.m_pDB.execute(
"SELECT point FROM user WHERE uid = ?", (uid,) f"SELECT point FROM user WHERE uid = {uid}"
) as cursor: ) as cursor:
async for row in cursor: async for row in cursor:
return int(row[0]) return int(row[0])
return -1
except Exception as e: except Exception as e:
logger.warning(f"查询失败: {e}") logger.warning(f"getUserPointByUid查询失败: {e}")
return -1 return -1
@classmethod @classmethod
@ -231,14 +261,12 @@ class CSqlManager:
return -1 return -1
try: try:
async with cls.m_pDB.execute( async with cls.m_pDB.execute(f"SELECT exp FROM user WHERE uid = '{uid}'") as cursor:
"SELECT exp FROM user WHERE uid = ?", (uid,)
) as cursor:
async for row in cursor: async for row in cursor:
exp = int(row[0]) exp = int(row[0])
#获取等级列表 #获取等级列表
levelDict = g_pJsonManager.m_pLevel['level'] levelDict = g_pJsonManager.m_pLevel['level'] # type: ignore
sorted_keys = sorted(levelDict.keys(), key=lambda x: int(x), reverse=True) sorted_keys = sorted(levelDict.keys(), key=lambda x: int(x), reverse=True)
for key in sorted_keys: for key in sorted_keys:
@ -247,7 +275,7 @@ class CSqlManager:
return -1 return -1
except Exception as e: except Exception as e:
logger.warning(f"查询失败: {e}") logger.warning(f"getUserLevelByUid查询失败: {e}")
return -1 return -1
@classmethod @classmethod
@ -275,79 +303,47 @@ class CSqlManager:
return soilNumber return soilNumber
@classmethod @classmethod
async def appendUserByUserInfo(cls, info: list[dict]) -> bool: async def getUserPlantByUid(cls, uid: str) -> str:
"""添加用户信息 """获取用户仓库种子信息
Args: Args:
info (list[dict]): 用户信息 info (list[dict]): 用户信息
Returns:
str: 仓库种子信息
"""
if len(uid) <= 0:
return ""
try:
async with cls.m_pDB.execute(
"SELECT plant FROM storehouse WHERE uid = ?", (uid,)
) as cursor:
async for row in cursor:
return row[0]
return ""
except Exception as e:
logger.warning(f"getUserPlantByUid查询失败: {e}")
return ""
@classmethod
async def updateUserPlantByUid(cls, uid: str, plant: str) -> bool:
"""添加用户仓库种子信息
Args:
info (list[dict]): 种子信息
Returns: Returns:
bool: 是否添加成功 bool: 是否添加成功
""" """
try: if len(uid) <= 0:
await cls.m_pDB.execute(
"""
INSERT INTO user (uid, name, exp, point) VALUES (?, ?, ?, ?)
""",
(info["uid"], info["name"], info["exp"], info["point"]),
)
await cls.m_pDB.commit()
return True
except Exception as e:
logger.warning(f"添加失败: {e}")
return False return False
# @classmethod sql = f"UPDATE storehouse SET plant = '{plant}' WHERE uid = '{uid}'"
# async def getUserStorehousePlant(cls, info: list[dict]) -> str:
# """获取用户仓库种子信息
# Args:
# info (list[dict]): 用户信息
# Returns:
# str: 仓库种子信息
# """
# try:
# await cls.m_pDB.execute(
# """
# INSERT INTO user (uid, name, exp, point) VALUES (?, ?, ?, ?)
# """,
# (info["uid"], info["name"], info["exp"], info["point"]),
# )
# await cls.m_pDB.commit()
# return True
# except Exception as e:
# logger.warning(f"添加失败: {e}")
# return False
# @classmethod
# async def appendUserByUserInfo(cls, info: list[dict]) -> bool:
# """添加用户信息
# Args:
# info (list[dict]): 用户信息
# Returns:
# bool: 是否添加成功
# """
# try:
# await cls.m_pDB.execute(
# """
# INSERT INTO user (uid, name, exp, point) VALUES (?, ?, ?, ?)
# """,
# (info["uid"], info["name"], info["exp"], info["point"]),
# )
# await cls.m_pDB.commit()
# return True
# except Exception as e:
# logger.warning(f"添加失败: {e}")
# return False
return await cls.executeDB(sql)
g_pSqlManager = CSqlManager() g_pSqlManager = CSqlManager()

View File

@ -1,43 +0,0 @@
from zhenxun.services.log import logger
from zhenxun.utils._build_image import BuildImage
from .config import g_pJsonManager, g_sResourcePath
from .database import g_pSqlManager
class CDrawImageManager:
@classmethod
async def drawMyFarm(cls, uid: str) -> bytes:
"""绘制我的农场
Args:
uid (str): 用户UID
Returns:
bytes: 返回绘制结果
"""
soilNumber = await g_pSqlManager.getUserLevelByUid(uid)
img = BuildImage(background=g_sResourcePath / "background/background.jpg")
soilSize = g_pJsonManager.m_pSoil['size'] # type: ignore
#TODO 缺少判断用户土地资源状况
soil = BuildImage(background=g_sResourcePath / "soil/普通土地.png")
await soil.resize(0, soilSize[0], soilSize[1])
grass = BuildImage(background=g_sResourcePath / "soil/草土地.png")
await grass.resize(0, soilSize[0], soilSize[1])
soilPos = g_pJsonManager.m_pSoil['soil'] # type: ignore
for key, value in soilPos.items():
if soilNumber >= int(key):
await img.paste(soil, (value['x'], value['y']))
else:
await img.paste(grass, (value['x'], value['y']))
return img.pic2bytes()
g_pDrawImage = CDrawImageManager()

View File

@ -1,5 +1,6 @@
from zhenxun.services.log import logger from zhenxun.services.log import logger
from zhenxun.utils._build_image import BuildImage from zhenxun.utils._build_image import BuildImage
from zhenxun.utils.image_utils import ImageTemplate
from ..config import g_pJsonManager, g_sResourcePath from ..config import g_pJsonManager, g_sResourcePath
from ..database import g_pSqlManager from ..database import g_pSqlManager
@ -8,8 +9,8 @@ from ..database import g_pSqlManager
class CFarmManager: class CFarmManager:
@classmethod @classmethod
async def drawFarm(cls, uid: str) -> bytes: async def drawFarmByUid(cls, uid: str) -> bytes:
"""绘制农场 """绘制用户农场
Args: Args:
uid (str): 用户UID uid (str): 用户UID
@ -31,11 +32,95 @@ class CFarmManager:
await grass.resize(0, soilSize[0], soilSize[1]) await grass.resize(0, soilSize[0], soilSize[1])
soilPos = g_pJsonManager.m_pSoil['soil'] # type: ignore soilPos = g_pJsonManager.m_pSoil['soil'] # type: ignore
soilUnlock = g_pJsonManager.m_pLevel['soil'] # type: ignore
for key, value in soilPos.items(): x = 0
if soilNumber >= int(key): y = 0
await img.paste(soil, (value['x'], value['y'])) for index, level in enumerate(soilUnlock):
x = soilPos[str(index + 1)]['x']
y = soilPos[str(index + 1)]['y']
if soilNumber >= int(level):
await img.paste(soil, (x, y))
#缺少判断土地上是否有农作物
plant = BuildImage(background=g_sResourcePath / "plant/basic/0.png")
await plant.resize(0, 35, 58)
await img.paste(plant, (x + 3, y + 3))
else: else:
await img.paste(grass, (value['x'], value['y'])) await img.paste(grass, (x, y))
return img.pic2bytes() return img.pic2bytes()
@classmethod
async def getUserPlantByUid(cls, uid: str) -> bytes:
data_list = []
column_name = [
"-",
"种子名称",
"数量"
"收获经验",
"收获数量",
"成熟时间(分钟)",
"收获次数",
"再次成熟时间(分钟)",
"是否可以上架交易行"
]
plant = await g_pSqlManager.getUserPlantByUid(uid)
if plant == None:
result = await ImageTemplate.table_page(
"种子仓库",
"播种示例:@小真寻 播种 大白菜",
column_name,
data_list,
)
return result.pic2bytes()
sell = ""
for item in plant.split(','):
if '|' in item:
plant_name, count = item.split('|', 1) # 分割一次,避免多竖线问题
try:
plantInfo = g_pJsonManager.m_pPlant['plant'][plant_name] # type: ignore
icon = ""
icon_path = g_sResourcePath / f"plant/{plant_name}/icon.png"
if icon_path.exists():
icon = (icon_path, 33, 33)
if plantInfo['again'] == True:
sell = "可以"
else:
sell = "不可以"
data_list.append(
[
icon,
plant_name,
count,
plantInfo['experience'],
plantInfo['harvest'],
plantInfo['time'],
plantInfo['crop'],
plantInfo['again'],
sell
]
)
except Exception as e:
continue
result = await ImageTemplate.table_page(
"种子商店",
"购买示例:@小真寻 购买种子 大白菜 5",
column_name,
data_list,
)
return result.pic2bytes()
g_pFarmManager = CFarmManager()

View File

@ -1,5 +1,6 @@
from zhenxun.services.log import logger from zhenxun.services.log import logger
from zhenxun.utils._build_image import BuildImage from zhenxun.utils._build_image import BuildImage
from zhenxun.utils.image_utils import ImageTemplate
from ..config import g_pJsonManager, g_sResourcePath from ..config import g_pJsonManager, g_sResourcePath
from ..database import g_pSqlManager from ..database import g_pSqlManager
@ -9,23 +10,104 @@ class CShopManager:
@classmethod @classmethod
async def getPlantShopImage(cls) -> bytes: async def getPlantShopImage(cls) -> bytes:
return bytes() """by ATTomato
Returns:
bytes: _description_
"""
data_list = []
column_name = [
"-",
"种子名称",
"解锁等级",
"种子单价",
"收获经验",
"收获数量",
"成熟时间(分钟)",
"收获次数",
"再次成熟时间(分钟)",
"是否可以上架交易行"
]
sell = ""
plants = g_pJsonManager.m_pPlant['plant'] # type: ignore
for key, plant in plants.items():
icon = ""
icon_path = g_sResourcePath / f"plant/{key}/icon.png"
if icon_path.exists():
icon = (icon_path, 33, 33)
if plant['again'] == True:
sell = "可以"
else:
sell = "不可以"
data_list.append(
[
icon,
key,
plant['level'],
plant['price'],
plant['experience'],
plant['harvest'],
plant['time'],
plant['crop'],
plant['again'],
sell
]
)
result = await ImageTemplate.table_page(
"种子商店",
"购买示例:@小真寻 购买种子 大白菜 5",
column_name,
data_list,
)
return result.pic2bytes()
@classmethod @classmethod
async def buyPlant(cls, uid: str, name: str, num: int = 1) -> str: async def buyPlant(cls, uid: str, name: str, num: int = 1) -> str:
if num <= 0: if num <= 0:
return "请输入购买数量!" return "请输入购买数量!"
plants = g_pJsonManager.m_pPlant['plant'] # type: ignore plantInfo = None
for key, plant in plants.items(): try:
if plant['name'] == name: plantInfo = g_pJsonManager.m_pPlant['plant'][name] # type: ignore
point = g_pSqlManager.getUserPointByUid(uid) except Exception as e:
total = int(plant['price']) * num return "购买出错!请检查需购买的种子名称!"
if point < total userPlants = {}
return "你的农场币不够哦~ 快速速氪金吧!"
else:
await g_pSqlManager.updateUserPointByUid(uid, point - total)
pass point = await g_pSqlManager.getUserPointByUid(uid)
total = int(plantInfo['price']) * num
logger.debug(f"用户:{uid}购买{name},数量为{num}。用户农场币为{point},购买需要{total}")
if point < total:
return "你的农场币不够哦~ 快速速氪金吧!"
else:
p = await g_pSqlManager.getUserPlantByUid(uid)
if not p == None:
for item in p.split(','):
if '|' in item:
plant_name, count = item.split('|', 1) # 分割一次,避免多竖线问题
userPlants[plant_name] = int(count)
if name in userPlants:
userPlants[name] += num
else:
userPlants[name] = num
plant_list = [f"{k}|{v}" for k, v in userPlants.items()]
await g_pSqlManager.updateUserPointByUid(uid, point - total)
await g_pSqlManager.updateUserPlantByUid(uid, ','.join(plant_list))
return f"成功购买{name},当前仓库数量为:{userPlants[name]},花费{total}农场币, 剩余{point - total}农场币"
g_pShopManager = CShopManager()

View File

@ -1,9 +0,0 @@
# from .config import CJsonManager
# from .database import CSqlManager
# from .drawImage import CDrawImageManager
# g_pJsonManager = CJsonManager()
# g_pSqlManager = CSqlManager()
# g_pDrawImage = CDrawImageManager(g_pJsonManager, g_pSqlManager)