From b1788f42c2f016a50bb95102a839f928ecd7d562 Mon Sep 17 00:00:00 2001 From: Art_Sakura <1754798088@qq.com> Date: Thu, 20 Mar 2025 00:45:05 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=E6=96=B0=E5=A2=9E=E6=88=91?= =?UTF-8?q?=E7=9A=84=E7=A7=8D=E5=AD=90=E6=8C=87=E4=BB=A4=20=E2=9C=A8=20?= =?UTF-8?q?=E5=AF=B9=E9=83=A8=E5=88=86=E8=B5=84=E6=BA=90=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E8=A1=A5=E5=85=85=20=E2=9C=A8=20=E6=96=B0=E5=A2=9E=E6=92=AD?= =?UTF-8?q?=E7=A7=8D=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __init__.py | 6 ++- command.py | 28 ++++++++++- database.py | 46 ++++++++++++++++-- farm/farm.py | 75 ++++++++++++++++++++++++++---- resource/background/expansion.png | Bin 0 -> 8697 bytes resource/background/gains.png | Bin 0 -> 5354 bytes 6 files changed, 141 insertions(+), 14 deletions(-) create mode 100644 resource/background/expansion.png create mode 100644 resource/background/gains.png diff --git a/__init__.py b/__init__.py index 5ddc680..2025009 100644 --- a/__init__.py +++ b/__init__.py @@ -8,10 +8,9 @@ from zhenxun.utils.message import MessageUtils from .command import diuse_farm, diuse_register from .config import g_pJsonManager from .database import g_pSqlManager +from .farm.farm import g_pFarmManager from .farm.shop import g_pShopManager -# from .globalClass import g_pDrawImage, g_pJsonManager, g_pSqlManager - __plugin_meta = PluginMetadata( name="真寻的农场", description="快乐的农场时光", @@ -37,6 +36,9 @@ async def start(): # 初始化读取Json await g_pJsonManager.init() + aaa = await g_pFarmManager.sowing("1754798088", "胡萝卜", 1) + logger.info(aaa) + # 析构函数 @driver.on_shutdown async def shutdown(): diff --git a/command.py b/command.py index e5640ad..3f74d7b 100644 --- a/command.py +++ b/command.py @@ -39,6 +39,7 @@ diuse_farm = on_alconna( Subcommand("buy-plant", Args["name?", str]["num?", int], help_text="购买种子"), Subcommand("my-plant", help_text="我的种子"), Subcommand("my-props", help_text="我的农场道具"), + Subcommand("sowing", Args["name?", str]["num?", int], help_text="播种"), Subcommand("buy", Args["name?", str]["num?", int], help_text="购买道具"), Subcommand("use", Args["name?", str]["num?", int], help_text="使用道具"), Subcommand("gold-list", Args["num?", int], help_text="金币排行"), @@ -128,7 +129,7 @@ diuse_farm.shortcut( prefix=True, ) -@diuse_farm.assign("plant-shop") +@diuse_farm.assign("my-plant") async def _(session: Uninfo): uid = str(session.user.id) point = await g_pSqlManager.getUserPointByUid(uid) @@ -139,3 +140,28 @@ async def _(session: Uninfo): result = await g_pFarmManager.getUserPlantByUid(uid) await MessageUtils.build_message(result).send(reply_to=True) + +diuse_farm.shortcut( + "播种(?P.*?)", + command="我的农场", + arguments=["sowing", "{name}"], + prefix=True, +) + +async def _(session: Uninfo, name: Match[str], num: Query[int] = AlconnaQuery("num", 1),): + if not name.available: + await MessageUtils.build_message( + "请在指令后跟需要播种的种子名称" + ).finish(reply_to=True) + + uid = str(session.user.id) + point = await g_pSqlManager.getUserPointByUid(uid) + + if point < 0: + await MessageUtils.build_message("尚未开通农场").send() + return None + + return None + + # result = await g_pShopManager.buyPlant(uid, name.result, num.result) + # await MessageUtils.build_message(result).send(reply_to=True) diff --git a/database.py b/database.py index 82525f6..ab3a0dc 100644 --- a/database.py +++ b/database.py @@ -1,4 +1,5 @@ import os +from datetime import datetime, timedelta from io import StringIO from typing import Any, List, Optional @@ -302,6 +303,47 @@ class CSqlManager: return soilNumber + @classmethod + async def getUserSoilStatusBySoilID(cls, uid: str, soil: str) -> bool: + """根据土地块获取用户土地状态 + + Args: + uid (str): 用户Uid + soil (str): 土地块 + + Returns: + bool: 是否可以播种 + """ + if len(uid) <= 0: + return False + + async with cls.m_pDB.execute(f"SELECT {soil} FROM soil WHERE uid = '{uid}'") as cursor: + async for row in cursor: + if row[0] == None: + return True + + return False + + @classmethod + async def updateUserSoilStatusBySowing(cls, uid: str, soil: str, plant: str) -> bool: + + if len(uid) <= 0: + return False + + #获取种子信息 这里能崩我吃 + plantInfo = g_pJsonManager.m_pPlant['plant'][plant] # type: ignore + + + currentTime = datetime.now() + newTime = currentTime + timedelta(minutes=int(plantInfo['time'])) + + #种子名称,当前阶段,预计长大/预计下个阶段,地状态:0:无 1:长草 2:生虫 3:缺水 4:枯萎状态 + status = f"{plant},1,{int(newTime.timestamp())},0" + + sql = f"UPDATE soil SET {soil} = '{status}' WHERE uid = '{uid}'" + + return await cls.executeDB(sql) + @classmethod async def getUserPlantByUid(cls, uid: str) -> str: """获取用户仓库种子信息 @@ -317,9 +359,7 @@ class CSqlManager: return "" try: - async with cls.m_pDB.execute( - "SELECT plant FROM storehouse WHERE uid = ?", (uid,) - ) as cursor: + async with cls.m_pDB.execute(f"SELECT plant FROM storehouse WHERE uid = '{uid}'") as cursor: async for row in cursor: return row[0] diff --git a/farm/farm.py b/farm/farm.py index 3ee1cf9..ca01ac3 100644 --- a/farm/farm.py +++ b/farm/farm.py @@ -1,3 +1,5 @@ +from numpy import arange + from zhenxun.services.log import logger from zhenxun.utils._build_image import BuildImage from zhenxun.utils.image_utils import ImageTemplate @@ -36,29 +38,48 @@ class CFarmManager: x = 0 y = 0 + isFirst = True 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)) - #缺少判断土地上是否有农作物 + #TODO 缺少判断土地上是否有农作物 plant = BuildImage(background=g_sResourcePath / "plant/basic/0.png") await plant.resize(0, 35, 58) - await img.paste(plant, (x + 3, y + 3)) + await img.paste(plant, (x + 100, y + 50)) else: await img.paste(grass, (x, y)) + if isFirst: + isFirst = False + + #首次添加扩建图片 + expansion = BuildImage(background=g_sResourcePath / "background/expansion.png") + await expansion.resize(0, 69, 69) + await img.paste(expansion, (x + 85, y + 20)) + return img.pic2bytes() @classmethod async def getUserPlantByUid(cls, uid: str) -> bytes: + """获取用户种子仓库 + + Args: + uid (str): 用户Uid + + Returns: + bytes: 返回图片 + """ + data_list = [] column_name = [ "-", "种子名称", - "数量" + "数量", "收获经验", "收获数量", "成熟时间(分钟)", @@ -80,15 +101,14 @@ class CFarmManager: return result.pic2bytes() sell = "" - for item in plant.split(','): if '|' in item: - plant_name, count = item.split('|', 1) # 分割一次,避免多竖线问题 + plantName, count = item.split('|', 1) # 分割一次,避免多竖线问题 try: - plantInfo = g_pJsonManager.m_pPlant['plant'][plant_name] # type: ignore + plantInfo = g_pJsonManager.m_pPlant['plant'][plantName] # type: ignore icon = "" - icon_path = g_sResourcePath / f"plant/{plant_name}/icon.png" + icon_path = g_sResourcePath / f"plant/{plantName}/icon.png" if icon_path.exists(): icon = (icon_path, 33, 33) @@ -100,7 +120,7 @@ class CFarmManager: data_list.append( [ icon, - plant_name, + plantName, count, plantInfo['experience'], plantInfo['harvest'], @@ -123,4 +143,43 @@ class CFarmManager: return result.pic2bytes() + @classmethod + async def sowing(cls, uid: str, name: str, num: int = 1) -> str: + """播种 + + Args: + uid (str): 用户Uid + name (str): 播种种子名称 + num (int, optional): 播种数量 + + Returns: + str: + """ + plant = await g_pSqlManager.getUserPlantByUid(uid) + + if plant == None: + return "你的种子仓库是空的,快去买点吧!" + + for item in plant.split(','): + if '|' in item: + plantName, count = item.split('|', 1) # 分割一次,避免多竖线问题 + + #判断仓库是否有当前播种种子 + if plantName == name: + count = int(count) + + #获取用户解锁多少块地 + soilName = "" + soilNumber = await g_pSqlManager.getUserSoilByUid(uid) + #遍历地块,查看地块是否可以播种 + for i in arange(1, soilNumber + 1): + if count > 0: + soilName = f"soil{str(i)}" + #如果可以播种 + if await g_pSqlManager.getUserSoilStatusBySoilID(uid, soilName): + count -= 1 + await g_pSqlManager.updateUserSoilStatusBySowing(uid, soilName, plantName) + return f"播种{plantName}成功!" + return "播种失败" + g_pFarmManager = CFarmManager() diff --git a/resource/background/expansion.png b/resource/background/expansion.png new file mode 100644 index 0000000000000000000000000000000000000000..f05660638ba43d1cf1b26659708bf7274f4dc657 GIT binary patch literal 8697 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 Nvb=^| literal 0 HcmV?d00001 diff --git a/resource/background/gains.png b/resource/background/gains.png new file mode 100644 index 0000000000000000000000000000000000000000..4f5b5db66c2160f074d0c2ba42e0c7cffe89fa69 GIT binary patch literal 5354 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