From 38a23ca6d734d02f63309633e164d04ab8055a2f Mon Sep 17 00:00:00 2001 From: Art_Sakura <1754798088@qq.com> Date: Mon, 7 Apr 2025 18:52:27 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=E7=8E=B0=E5=9C=A8=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E6=AD=A3=E5=B8=B8=E5=BC=80=E5=9E=A6=E4=BA=86(?= =?UTF-8?q?=E4=BD=86=E6=98=AF=E5=BC=80=E5=9E=A6=E6=95=B0=E6=8D=AE=E6=9C=89?= =?UTF-8?q?=E5=BE=85=E5=A1=AB=E5=86=99=20=E2=9A=A1=EF=B8=8F=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81=20=F0=9F=90=9B=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=A0=E6=B3=95=E5=81=B7=E8=8F=9C=E7=9A=84?= =?UTF-8?q?BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- command.py | 171 +++++++++++++++++------------- config.py | 16 +-- config/level.json | 50 +++------ database.py | 139 +++++++++++++++++------- farm/farm.py | 265 +++++++++++++++++++++++++++++----------------- farm/shop.py | 27 ++--- 6 files changed, 400 insertions(+), 268 deletions(-) diff --git a/command.py b/command.py index 7491521..550dd44 100644 --- a/command.py +++ b/command.py @@ -1,8 +1,11 @@ +from nonebot.adapters import Event, MessageTemplate from nonebot.rule import to_me -from nonebot_plugin_alconna import (Alconna, AlconnaQuery, Args, At, Match, - MultiVar, Option, Query, Subcommand, +from nonebot.typing import T_State +from nonebot_plugin_alconna import (Alconna, AlconnaQuery, Args, Arparma, At, + Match, MultiVar, Option, Query, Subcommand, on_alconna, store_true) from nonebot_plugin_uninfo import Uninfo +from nonebot_plugin_waiter import waiter from zhenxun.services.log import logger from zhenxun.utils.message import MessageUtils @@ -11,6 +14,17 @@ from .database import g_pSqlManager from .farm.farm import g_pFarmManager from .farm.shop import g_pShopManager + +async def isRegisteredByUid(uid: str) -> bool: + point = await g_pSqlManager.getUserPointByUid(uid) + + if point < 0: + await MessageUtils.build_message("尚未开通农场,快at我发送 开通农场 开通吧").send() + return False + + return True + + diuse_register = on_alconna( Alconna("开通农场"), priority=5, @@ -43,6 +57,7 @@ diuse_farm = on_alconna( Subcommand("harvest", help_text="收获"), Subcommand("eradicate", help_text="铲除"), Subcommand("my-plant", help_text="我的作物"), + # Subcommand("reclamation", Args["isBool?", str], help_text="开垦"), Subcommand("sell-plant", Args["name?", str]["num?", int], help_text="出售作物"), Subcommand("stealing", Args["target?", At], help_text="偷菜"), Subcommand("buy-point", Args["num?", int], help_text="购买农场币"), @@ -55,11 +70,9 @@ diuse_farm = on_alconna( @diuse_farm.assign("$main") async def _(session: Uninfo): uid = str(session.user.id) - point = await g_pSqlManager.getUserPointByUid(uid) - if point < 0: - await MessageUtils.build_message("尚未开通农场").send() - return None + if await isRegisteredByUid(uid) == False: + return image = await g_pFarmManager.drawFarmByUid(uid) await MessageUtils.build_message(image).send(reply_to=True) @@ -77,8 +90,8 @@ async def _(session: Uninfo): point = await g_pSqlManager.getUserPointByUid(uid) if point < 0: - await MessageUtils.build_message("尚未开通农场").send() - return None + await MessageUtils.build_message("尚未开通农场,快at我发送 开通农场 开通吧").send() + return False await MessageUtils.build_message(f"你的当前农场币为: {point}").send(reply_to=True) @@ -92,11 +105,9 @@ diuse_farm.shortcut( @diuse_farm.assign("seed-shop") async def _(session: Uninfo): uid = str(session.user.id) - point = await g_pSqlManager.getUserPointByUid(uid) - if point < 0: - await MessageUtils.build_message("尚未开通农场").send() - return None + if await isRegisteredByUid(uid) == False: + return image = await g_pShopManager.getSeedShopImage() await MessageUtils.build_message(image).send() @@ -116,11 +127,9 @@ async def _(session: Uninfo, name: Match[str], num: Query[int] = AlconnaQuery("n ).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 + if await isRegisteredByUid(uid) == False: + return result = await g_pShopManager.buySeed(uid, name.result, num.result) await MessageUtils.build_message(result).send(reply_to=True) @@ -135,11 +144,9 @@ diuse_farm.shortcut( @diuse_farm.assign("my-seed") async def _(session: Uninfo): uid = str(session.user.id) - point = await g_pSqlManager.getUserPointByUid(uid) - if point < 0: - await MessageUtils.build_message("尚未开通农场").send() - return None + if await isRegisteredByUid(uid) == False: + return result = await g_pFarmManager.getUserSeedByUid(uid) await MessageUtils.build_message(result).send(reply_to=True) @@ -159,11 +166,9 @@ async def _(session: Uninfo, name: Match[str], num: Query[int] = AlconnaQuery("n ).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 + if await isRegisteredByUid(uid) == False: + return result = await g_pFarmManager.sowing(uid, name.result, num.result) await MessageUtils.build_message(result).send(reply_to=True) @@ -179,11 +184,9 @@ diuse_farm.shortcut( @diuse_farm.assign("harvest") async def _(session: Uninfo): uid = str(session.user.id) - point = await g_pSqlManager.getUserPointByUid(uid) - if point < 0: - await MessageUtils.build_message("尚未开通农场").send() - return None + if await isRegisteredByUid(uid) == False: + return result = await g_pFarmManager.harvest(uid) await MessageUtils.build_message(result).send(reply_to=True) @@ -198,11 +201,9 @@ diuse_farm.shortcut( @diuse_farm.assign("eradicate") async def _(session: Uninfo): uid = str(session.user.id) - point = await g_pSqlManager.getUserPointByUid(uid) - if point < 0: - await MessageUtils.build_message("尚未开通农场").send() - return None + if await isRegisteredByUid(uid) == False: + return result = await g_pFarmManager.eradicate(uid) await MessageUtils.build_message(result).send(reply_to=True) @@ -218,15 +219,45 @@ diuse_farm.shortcut( @diuse_farm.assign("my-plant") async def _(session: Uninfo): uid = str(session.user.id) - point = await g_pSqlManager.getUserPointByUid(uid) - if point < 0: - await MessageUtils.build_message("尚未开通农场").send() - return None + if await isRegisteredByUid(uid) == False: + return result = await g_pFarmManager.getUserPlantByUid(uid) await MessageUtils.build_message(result).send(reply_to=True) + +reclamation = on_alconna( + Alconna("开垦"), + priority=5, + block=True, +) + +@reclamation.handle() +async def _(session: Uninfo): + uid = str(session.user.id) + + if await isRegisteredByUid(uid) == False: + return + + condition = await g_pFarmManager.reclamationCondition(uid) + condition += "\n 回复是将执行开垦" + await MessageUtils.build_message(condition).send(reply_to=True) + + @waiter(waits=["message"], keep_session=True) + async def check(event: Event): + return event.get_plaintext() + + resp = await check.wait(timeout=60) + if resp is None: + await MessageUtils.build_message("等待超时").send(reply_to=True) + return + if not resp == "是": + return + + res = await g_pFarmManager.reclamation(uid) + await MessageUtils.build_message(res).send(reply_to=True) + diuse_farm.shortcut( "出售作物(?P.*?)", command="我的农场", @@ -242,15 +273,40 @@ async def _(session: Uninfo, name: Match[str], num: Query[int] = AlconnaQuery("n ).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 + if await isRegisteredByUid(uid) == False: + return result = await g_pShopManager.sellPlantByUid(uid, name.result, num.result) await MessageUtils.build_message(result).send(reply_to=True) +diuse_farm.shortcut( + "偷菜", + command="我的农场", + arguments=["stealing"], + prefix=True, +) + +@diuse_farm.assign("stealing") +async def _(session: Uninfo, target: Match[At]): + uid = str(session.user.id) + + if await isRegisteredByUid(uid) == False: + return + + if not target.available: + await MessageUtils.build_message("请在指令后跟需要at的人").finish(reply_to=True) + + tar = target.result + point = await g_pSqlManager.getUserPointByUid(tar.target) + + if point < 0: + await MessageUtils.build_message("目标尚未开通农场,快邀请ta开通吧").send() + return None + + result = await g_pFarmManager.stealing(uid, tar.target) + await MessageUtils.build_message(result).send(reply_to=True) + diuse_farm.shortcut( "购买农场币(.*?)", command="我的农场", @@ -266,40 +322,9 @@ async def _(session: Uninfo, num: Query[int] = AlconnaQuery("num", 0)): ).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 + if await isRegisteredByUid(uid) == False: + return result = await g_pFarmManager.buyPointByUid(uid, num.result) await MessageUtils.build_message(result).send(reply_to=True) - -diuse_farm.shortcut( - "偷菜", - command="我的农场", - arguments=["stealing"], - prefix=True, -) - -@diuse_farm.assign("stealing") -async def _(session: Uninfo, target: Match[At]): - uid = str(session.user.id) - point = await g_pSqlManager.getUserPointByUid(uid) - - if point < 0: - await MessageUtils.build_message("尚未开通农场").send() - return None - - if not target.available: - await MessageUtils.build_message("请在指令后跟需要at的人").finish(reply_to=True) - - tar = target.result - point = await g_pSqlManager.getUserPointByUid(tar.target) - - if point < 0: - await MessageUtils.build_message("尚未开通农场").send() - return None - - result = await g_pFarmManager.stealing(uid, tar.target) - await MessageUtils.build_message(result).send(reply_to=True) diff --git a/config.py b/config.py index 5bc2813..a1eb232 100644 --- a/config.py +++ b/config.py @@ -11,10 +11,10 @@ g_sResourcePath = Path(__file__).resolve().parent / "resource" class CJsonManager: def __init__(self): - self.m_pItem = None - self.m_pPlant = None - self.m_pLevel = None - self.m_pSoil = None + self.m_pItem = {} + self.m_pPlant = {} + self.m_pLevel = {} + self.m_pSoil = {} async def init(self) -> bool: if not await self.initItem(): @@ -79,10 +79,10 @@ class CJsonManager: return True except FileNotFoundError: - logger.warning("plant.json 打开失败") + logger.warning("level.json 打开失败") return False except json.JSONDecodeError as e: - logger.warning(f"plant.json JSON格式错误: {e}") + logger.warning(f"level.json JSON格式错误: {e}") return False async def initSoil(self) -> bool: @@ -97,10 +97,10 @@ class CJsonManager: return True except FileNotFoundError: - logger.warning("plant.json 打开失败") + logger.warning("soil.json 打开失败") return False except json.JSONDecodeError as e: - logger.warning(f"plant.json JSON格式错误: {e}") + logger.warning(f"soil.json JSON格式错误: {e}") return False g_pJsonManager = CJsonManager() diff --git a/config/level.json b/config/level.json index 50166c8..6fb4d88 100644 --- a/config/level.json +++ b/config/level.json @@ -1,25 +1,7 @@ { - "level": - { - "1": 0, - "2": 50, - "3": 75, - "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, 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 + "soil":[1, 1, 1, 2, 3, 5, 7, 9, 11, 13, + 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, + 36, 39, 42, 45, 48, 51, 54, 57, 60, 70 ], "reclamation": { @@ -27,79 +9,79 @@ { "level": 3, "point": 800, - "item": "" + "item": [] }, "5": { "level": 5, "point": 1300, - "item": "" + "item": [] }, "6": { "level": 7, "point": 3200, - "item": "" + "item": [] }, "7": { "level": 9, "point": 5500, - "item": "" + "item": [] }, "8": { "level": 12, "point": 12000, - "item": "" + "item": [] }, "9": { "level": 15, "point": 19800, - "item": "" + "item": [] }, "10": { "level":3, "point": 3000, - "item": "" + "item": [] }, "11": { "level":3, "point": 3000, - "item": "" + "item": [] }, "12": { "level":3, "point": 3000, - "item": "" + "item": [] }, "13": { "level":3, "point": 3000, - "item": "" + "item": [] }, "14": { "level":3, "point": 3000, - "item": "" + "item": [] }, "15": { "level":3, "point": 3000, - "item": "" + "item": [] }, "16": { "level":3, "point": 3000, - "item": "" + "item": [] } } } diff --git a/database.py b/database.py index d6b2e8c..269b047 100644 --- a/database.py +++ b/database.py @@ -1,3 +1,4 @@ +import math import os from datetime import date, datetime, timedelta from io import StringIO @@ -144,7 +145,7 @@ class CSqlManager: if not await cls.executeDB(userSoilInfo): return False - return True + return "开通农场成功" @classmethod async def getUserInfoByUid(cls, uid: str) -> dict: @@ -193,9 +194,7 @@ class CSqlManager: return -1 try: - async with cls.m_pDB.execute( - f"SELECT point FROM user WHERE uid = {uid}" - ) as cursor: + async with cls.m_pDB.execute(f"SELECT point FROM user WHERE uid = {uid}") as cursor: async for row in cursor: return int(row[0]) @@ -221,21 +220,14 @@ class CSqlManager: return -1 try: - async with cls.m_pDB.execute( - """UPDATE user - SET point = ? - WHERE uid = ? - RETURNING point""", - (point, uid) - ) as cursor: + async with cls.m_pDB.execute(f"UPDATE user SET point = {point} WHERE uid = {uid}") as cursor: async for row in cursor: return int(row[0]) logger.info(f"未找到用户或未修改数据: uid={uid}") return -1 except Exception as e: - # 记录详细错误日志(建议记录堆栈) - logger.error(f"更新失败: {e}") + logger.error(f"金币更新失败: {e}") return -1 @classmethod @@ -252,7 +244,7 @@ class CSqlManager: return -1 try: - async with cls.m_pDB.execute(f"SELECT exp FROM user WHERE uid = '{uid}'") as cursor: + async with cls.m_pDB.execute(f"SELECT exp FROM user WHERE uid = {uid}") as cursor: async for row in cursor: return int(row[0]) @@ -274,40 +266,43 @@ class CSqlManager: if len(uid) <= 0: return False - sql = f"UPDATE user SET exp = '{exp}' WHERE uid = '{uid}'" + sql = f"UPDATE user SET exp = '{exp}' WHERE uid = {uid}" return await cls.executeDB(sql) @classmethod - async def getUserLevelByUid(cls, uid: str) -> int: + async def getUserLevelByUid(cls, uid: str) -> tuple[int, int, int]: """根据用户Uid获取用户等级 Args: uid (str): 用户Uid Returns: - int: 用户等级` + tuple[int, int, int]: (当前等级, 下级所需经验, 当前等级剩余经验) """ if len(uid) <= 0: - return -1 + return -1, -1, -1 try: - async with cls.m_pDB.execute(f"SELECT exp FROM user WHERE uid = '{uid}'") as cursor: + async with cls.m_pDB.execute(f"SELECT exp FROM user WHERE uid = {uid}") as cursor: async for row in cursor: exp = int(row[0]) - #获取等级列表 - levelDict = g_pJsonManager.m_pLevel['level'] # type: ignore + #计算当前等级(向下取整) + level = math.floor((math.sqrt(1 + 4 * exp / 100) - 1) / 2) - sorted_keys = sorted(levelDict.keys(), key=lambda x: int(x), reverse=True) - for key in sorted_keys: - if exp >= levelDict[key]: - return int(key) + #计算下级所需经验 下级所需经验为:200 + 当前等级 * 200 + nextLevelExp = 200 * (level + 1) + currentLevelExp = 100 * level * (level + 1) - return -1 + remainingExp = exp - currentLevelExp + + return level, nextLevelExp, remainingExp + + return -1, -1, -1 except Exception as e: logger.warning(f"getUserLevelByUid查询失败: {e}") - return -1 + return -1, -1, -1 @classmethod async def getUserSoilByUid(cls, uid: str) -> int: @@ -322,9 +317,9 @@ class CSqlManager: if len(uid) <= 0: return 0 - async with cls.m_pDB.execute(f"SELECT soil FROM user WHERE uid = '{uid}'") as cursor: + async with cls.m_pDB.execute(f"SELECT soil FROM user WHERE uid = {uid}") as cursor: async for row in cursor: - if row[0] == None or len(row[0]) <= 0: + if not row[0]: return 0 else: return int(row[0]) @@ -345,7 +340,7 @@ class CSqlManager: if len(uid) <= 0: return False, "" - async with cls.m_pDB.execute(f"SELECT {soil} FROM soil WHERE uid = '{uid}'") as cursor: + 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 or len(row[0]) <= 0: return True, "" @@ -381,12 +376,12 @@ class CSqlManager: plantInfo = g_pJsonManager.m_pPlant['plant'][plant] # type: ignore currentTime = datetime.now() - newTime = currentTime + timedelta(minutes=int(plantInfo['time'])) + newTime = currentTime + timedelta(hours=int(plantInfo['time'])) #种子名称,种下时间,预计成熟时间,地状态:0:无 1:长草 2:生虫 3:缺水 4:枯萎,是否被偷 示例:QQ号-偷取数量|QQ号-偷取数量 s = f"{plant},{int(currentTime.timestamp())},{int(newTime.timestamp())},{status}," - sql = f"UPDATE soil SET {soil} = '{s}' WHERE uid = '{uid}'" + sql = f"UPDATE soil SET {soil} = '{s}' WHERE uid = {uid}" return await cls.executeDB(sql) @@ -405,7 +400,7 @@ class CSqlManager: return "" try: - async with cls.m_pDB.execute(f"SELECT seed FROM storehouse WHERE uid = '{uid}'") as cursor: + async with cls.m_pDB.execute(f"SELECT seed FROM storehouse WHERE uid = {uid}") as cursor: async for row in cursor: return row[0] @@ -429,7 +424,43 @@ class CSqlManager: if len(uid) <= 0: return False - sql = f"UPDATE storehouse SET seed = '{seed}' WHERE uid = '{uid}'" + sql = f"UPDATE storehouse SET seed = '{seed}' WHERE uid = {uid}" + + return await cls.executeDB(sql) + + @classmethod + async def addUserSeedByPlant(cls, uid: str, seed: str, num: int) -> bool: + """添加作物信息至仓库 + + Args: + uid (str): 用户Uid + seed (str): 种子名称 + num(str): 种子数量 + + Returns: + bool: + """ + + if len(uid) <= 0: + return False + + seedsDict = {} + currentSeeds = await cls.getUserSeedByUid(uid) + + if currentSeeds: + for item in currentSeeds.split(','): + if item.strip(): + name, count = item.split('|') + seedsDict[name.strip()] = int(count.strip()) + + if seed in seedsDict: + seedsDict[seed] += num + else: + seedsDict[seed] = num + + updatedSeeds = ','.join([f"{name}|{count}" for name, count in seedsDict.items()]) + + sql = f"UPDATE storehouse SET seed = '{updatedSeeds}' WHERE uid = {uid}" return await cls.executeDB(sql) @@ -448,7 +479,7 @@ class CSqlManager: return "" try: - async with cls.m_pDB.execute(f"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] @@ -472,7 +503,43 @@ class CSqlManager: if len(uid) <= 0: return False - sql = f"UPDATE storehouse SET plant = '{plant}' WHERE uid = '{uid}'" + sql = f"UPDATE storehouse SET plant = '{plant}' WHERE uid = {uid}" + + return await cls.executeDB(sql) + + @classmethod + async def addUserPlantByPlant(cls, uid: str, plant: str, num: int) -> bool: + """添加作物信息至仓库 + + Args: + uid (str): 用户Uid + plant (str): 作物名称 + num(str): 作物数量 + + Returns: + bool: + """ + + if len(uid) <= 0: + return False + + plantsDict = {} + currentPlants = await cls.getUserPlantByUid(uid) + + if currentPlants: + for item in currentPlants.split(','): + if item.strip(): + name, count = item.split('|') + plantsDict[name.strip()] = int(count.strip()) + + if plant in plantsDict: + plantsDict[plant] += num + else: + plantsDict[plant] = num + + updatedPlants = ','.join([f"{name}|{count}" for name, count in plantsDict.items()]) + + sql = f"UPDATE storehouse SET plant = '{updatedPlants}' WHERE uid = {uid}" return await cls.executeDB(sql) diff --git a/farm/farm.py b/farm/farm.py index ec6c339..5106b0f 100644 --- a/farm/farm.py +++ b/farm/farm.py @@ -4,7 +4,6 @@ from datetime import date, datetime from io import StringIO from typing import Dict, List, Tuple -from Python311.Lib.PIL.ImImagePlugin import number from zhenxun.models.user_console import UserConsole from zhenxun.services.log import logger from zhenxun.utils._build_image import BuildImage @@ -46,11 +45,9 @@ class CFarmManager: Returns: bytes: 返回绘制结果 """ - soilNumber = await g_pSqlManager.getUserLevelByUid(uid) - img = BuildImage(background = g_sResourcePath / "background/background.jpg") - soilSize = g_pJsonManager.m_pSoil['size'] # type: ignore + soilSize = g_pJsonManager.m_pSoil['size'] #TODO 缺少判断用户土地资源状况 soil = BuildImage(background = g_sResourcePath / "soil/普通土地.png") @@ -59,7 +56,7 @@ class CFarmManager: grass = BuildImage(background = g_sResourcePath / "soil/草土地.png") await grass.resize(0, soilSize[0], soilSize[1]) - soilPos = g_pJsonManager.m_pSoil['soil'] # type: ignore + soilPos = g_pJsonManager.m_pSoil['soil'] soilUnlock = await g_pSqlManager.getUserSoilByUid(uid) x = 0 @@ -72,7 +69,7 @@ class CFarmManager: y = soilPos[str(index + 1)]['y'] #如果土地已经到达对应等级 - if index > soilUnlock: + if index < soilUnlock: await img.paste(soil, (x, y)) isPlant, plant, isRipe= await cls.drawSoilPlant(uid, f"soil{str(index + 1)}") @@ -101,6 +98,7 @@ class CFarmManager: await img.paste(expansion, (x + soilSize[0] // 2 - expansion.width // 2, y + soilSize[1] // 2 - expansion.height)) + #左上角绘制用户信息 await img.resize(0.6) return img.pic2bytes() @@ -129,7 +127,7 @@ class CFarmManager: await plant.resize(0, 150, 212) return True, plant, False - plantInfo = g_pJsonManager.m_pPlant['plant'][soilInfo[0]] # type: ignore + plantInfo = g_pJsonManager.m_pPlant['plant'][soilInfo[0]] currentTime = datetime.now() matureTime = datetime.fromtimestamp(int(soilInfo[2])) @@ -195,9 +193,9 @@ class CFarmManager: sell = "" for item in seed.split(','): if '|' in item: - seedName, count = item.split('|', 1) # 分割一次,避免多竖线问题 + seedName, count = item.split('|', 1) #分割一次,避免多竖线问题 try: - plantInfo = g_pJsonManager.m_pPlant['plant'][seedName] # type: ignore + plantInfo = g_pJsonManager.m_pPlant['plant'][seedName] icon = "" icon_path = g_sResourcePath / f"plant/{seedName}/icon.png" @@ -249,7 +247,7 @@ class CFarmManager: """ plant = await g_pSqlManager.getUserSeedByUid(uid) - if plant == None: + if plant == None or len(plant) == 0: return "你的种子仓库是空的,快去买点吧!" plantDict = {} @@ -270,24 +268,26 @@ class CFarmManager: soilName = f"soil{i}" success, message = await g_pSqlManager.getUserSoilStatusBySoilID(uid, soilName) if success: - # 更新种子数量 + #更新种子数量 num -= 1 plantDict[name] -= 1 - if plantDict[name] == 0: - del plantDict[name] - # 更新数据库 + #更新数据库 await g_pSqlManager.updateUserSoilStatusByPlantName(uid, soilName, name) + str = "" + + if num > 0: + str = f"播种数量超出开垦土地数量,已将可播种土地成功播种{name}!仓库还剩下{plantDict[name]}个种子" + else: + str = f"播种{name}成功!仓库还剩下{plantDict[name]}个种子" + await g_pSqlManager.updateUserSeedByUid( uid, - ','.join([f"{k}|{v}" for k, v in plantDict.items()]) + ','.join([f"{k}|{v}" for k, v in plantDict.items() if v != 0]) ) - if num > 0: - return f"播种数量超出开垦土地数量,已将可播种土地成功播种{name}!仓库还剩下{plantDict[name]}个种子" - else: - return f"播种{name}成功!仓库还剩下{plantDict[name]}个种子" + return str @classmethod async def harvest(cls, uid: str) -> str: @@ -300,60 +300,59 @@ class CFarmManager: str: 返回 """ + isStealingPlant = 0 soilUnlock = await g_pSqlManager.getUserSoilByUid(uid) - plant = {} - - soilNames = [f"soil{i}" for i in range(soilUnlock)] + soilNames = [f"soil{i + 1}" for i in range(soilUnlock)] soilStatuses = await asyncio.gather(*[ g_pSqlManager.getUserSoilStatusBySoilID(uid, name) for name in soilNames ]) - plant: Dict[str, int] = {} harvestRecords: List[str] = [] experience = 0 for (soil_name, (status, info)) in zip(soilNames, soilStatuses): - if not status: - soilInfo = info.split(',') - plantId = soilInfo[0] - plantInfo = g_pJsonManager.m_pPlant['plant'][plantId] # type: ignore + if len(info) <= 0: + continue - currentTime = datetime.now() - matureTime = datetime.fromtimestamp(int(soilInfo[2])) + soilInfo = info.split(',') + if int(soilInfo[3]) == 4: + continue - if currentTime >= matureTime: - number = plantInfo['harvest'] + plantId = soilInfo[0] + plantInfo = g_pJsonManager.m_pPlant['plant'][plantId] - #判断该土地作物是否被透过 - if len(soilInfo[4]) > 0: - stealingStatus = soilInfo[4].split('|') - for isUser in stealingStatus: - user = isUser.split('-') - number -= user[1] + currentTime = datetime.now() + matureTime = datetime.fromtimestamp(int(soilInfo[2])) - plant[plantId] = plant.get(plantId, 0) + number - experience += plantInfo['experience'] - harvestRecords.append(f"收获作物:{plantId},数量为:{number},经验为:{plantInfo['experience']}") + if currentTime >= matureTime: + number = plantInfo['harvest'] - #批量更新数据库操作 - await g_pSqlManager.updateUserSoilStatusByPlantName(uid, soil_name, "", 4) + #判断该土地作物是否被透过 + if len(soilInfo[4]) > 0: + stealingStatus = soilInfo[4].split('|') + for isUser in stealingStatus: + user = isUser.split('-') + number -= int(user[1]) + + isStealingPlant += 1 + + experience += plantInfo['experience'] + harvestRecords.append(f"收获作物:{plantId},数量为:{number},经验为:{plantInfo['experience']}") + + #更新数据库操作 + await g_pSqlManager.addUserPlantByPlant(uid, plantId, number) + await g_pSqlManager.updateUserSoilStatusByPlantName(uid, soil_name, "", 4) if experience > 0: harvestRecords.append(f"\t累计获得经验:{experience}") exp = await g_pSqlManager.getUserExpByUid(uid) await g_pSqlManager.UpdateUserExpByUid(uid, exp + experience) - if not plant: - return "可收获作物为0哦~ 不要试图拔苗助长" + if isStealingPlant <= 0: + return "没有可收获的作物哦~ 不要试图拔苗助长" else: - # 批量更新用户作物数据 - await g_pSqlManager.updateUserPlantByUid( - uid, - ','.join([f"{k}|{v}" for k, v in plant.items()]) - ) - return "\n".join(harvestRecords) @classmethod @@ -369,7 +368,7 @@ class CFarmManager: soilUnlock = await g_pSqlManager.getUserSoilByUid(uid) - soilNames = [f"soil{i}" for i in range(soilUnlock)] + soilNames = [f"soil{i + 1}" for i in range(soilUnlock)] soilStatuses = await asyncio.gather(*[ g_pSqlManager.getUserSoilStatusBySoilID(uid, name) for name in soilNames @@ -377,12 +376,12 @@ class CFarmManager: experience = 0 for (soil_name, (status, info)) in zip(soilNames, soilStatuses): - if not status: + if info: soilInfo = info.split(',') if int(soilInfo[3]) == 4: experience += 3 - # 批量更新数据库操作 + #批量更新数据库操作 await g_pSqlManager.updateUserSoilStatusByPlantName(uid, soil_name, "", 0) if experience > 0: @@ -429,9 +428,9 @@ class CFarmManager: sell = "" for item in plant.split(','): if '|' in item: - plantName, count = item.split('|', 1) # 分割一次,避免多竖线问题 + plantName, count = item.split('|', 1) #分割一次,避免多竖线问题 try: - plantInfo = g_pJsonManager.m_pPlant['plant'][plantName] # type: ignore + plantInfo = g_pJsonManager.m_pPlant['plant'][plantName] icon = "" icon_path = g_sResourcePath / f"plant/{plantName}/icon.png" @@ -443,7 +442,7 @@ class CFarmManager: else: sell = "不可以" - number = count * int(plantInfo['price']) + number = int(count) * plantInfo['price'] data_list.append( [ @@ -485,90 +484,164 @@ class CFarmManager: #用户可偷次数 userStealing = userInfo["stealing"].split('|') - if date.fromisoformat(userStealing[0]) != date.today(): - userStealing[0] = date.today() + if userStealing[0] == '': + userStealing[0] = date.today().strftime('%Y-%m-%d') + userStealing.append(5) + elif date.fromisoformat(userStealing[0]) != date.today(): + userStealing[0] = date.today().strftime('%Y-%m-%d') userStealing[1] = 5 if int(userStealing[1]) <= 0: return "你今天可偷次数到达上限啦,手下留情吧" - #获取用户 - soilUnlock = int(userInfo["soil"]) - + #获取用户解锁地块数量 + soilUnlockNum = int(userInfo["soil"]) plant = {} #根据解锁土地,获取每块土地状态信息 - soilNames = [f"soil{i}" for i in range(soilUnlock)] + soilNames = [f"soil{i + 1}" for i in range(soilUnlockNum)] soilStatuses = await asyncio.gather(*[ g_pSqlManager.getUserSoilStatusBySoilID(target, name) for name in soilNames ]) - plant: Dict[str, int] = {} - harvestRecords: List[str] = [] - isStealing = False - for(soilName, (status, info)) in zip(soilNames, soilStatuses): + harvestRecords: List[str] = [] + isStealingNumber = 0 + isStealingPlant = 0 + + for (soilName, (status, info)) in zip(soilNames, soilStatuses): isStealing = False - if not status: - soilInfo = info.split(',') - plantId = soilInfo[0] - plantInfo = g_pJsonManager.m_pPlant['plant'][plantId] # type: ignore + if not info: + continue - currentTime = datetime.now() - matureTime = datetime.fromtimestamp(int(soilInfo[2])) + soilInfo = info.split(',') + if int(soilInfo[3]) == 4: + continue - stealingNumber = 0 + #作物ID + plantId = soilInfo[0] + #作物信息 + plantInfo = g_pJsonManager.m_pPlant['plant'][plantId] - if currentTime >= matureTime: + currentTime = datetime.now() + matureTime = datetime.fromtimestamp(int(soilInfo[2])) + + #偷窃状态 + stealingStatus: list[str] = [] + #偷窃数量 + stealingNumber = 0 + if currentTime >= matureTime: + if soilInfo[4]: #先获取用户是否偷过该土地 stealingStatus = soilInfo[4].split('|') + for isUser in stealingStatus: user = isUser.split('-') if user[0] == uid: isStealing = True + isStealingNumber += 1 break - stealingNumber += int(user[1]) + stealingNumber -= int(user[1]) - #如果偷过,则跳过该土地 - if isStealing: - continue + #如果偷过,则跳过该土地 + if isStealing: + continue - stealingNumber -= plantInfo['harvest'] - randomNumber = random.choice([1, 2]) - randomNumber = min(randomNumber, stealingNumber) + stealingNumber += plantInfo['harvest'] + randomNumber = random.choice([1, 2]) + randomNumber = min(randomNumber, stealingNumber) - if randomNumber > 0: - plant[plantId] = plant.get(plantId, 0) + randomNumber - harvestRecords.append(f"成功偷到作物:{plantId},数量为:{randomNumber}") + logger.info(f"{randomNumber}") - stealingStatus += f"|{uid}-{randomNumber}" + if randomNumber > 0: + await g_pSqlManager.addUserPlantByPlant(uid, plantId, randomNumber) - #如果将作物偷完,就直接更新状态 并记录用户偷取过 - if plantInfo['harvest'] - randomNumber + stealingNumber == 0: - sql = f"UPDATE soil SET {soilName} = ',,,4,{stealingStatus}' WHERE uid = '{target}'" - else: - sql = f"UPDATE soil SET {soilName} = '{soilInfo[0]},{soilInfo[1]},{soilInfo[2]},{soilInfo[3]},{stealingStatus}' WHERE uid = '{target}'" + harvestRecords.append(f"成功偷到作物:{plantId},数量为:{randomNumber}") + stealingStatus.append(f"{uid}-{randomNumber}") - await g_pSqlManager.executeDB(sql) + isStealingPlant += 1 - if not plant: + #如果将作物偷完,就直接更新状态 并记录用户偷取过 + if plantInfo['harvest'] - randomNumber + stealingNumber == 0: + sql = f"UPDATE soil SET {soilName} = ',,,4,{'|'.join(stealingStatus)}' WHERE uid = '{target}'" + else: + sql = f"UPDATE soil SET {soilName} = '{soilInfo[0]},{soilInfo[1]},{soilInfo[2]},{soilInfo[3]},{'|'.join(stealingStatus)}' WHERE uid = '{target}'" + + await g_pSqlManager.executeDB(sql) + + if isStealingPlant <= 0 and isStealingNumber <= 0: return "目标没有作物可以被偷" + elif isStealingPlant <= 0 and isStealingNumber > 0: + return "你已经偷过目标啦,请手下留情" else: - # 批量更新用户作物仓库数据 - await g_pSqlManager.updateUserPlantByUid(target, ','.join([f"{k}|{v}" for k, v in plant.items()])) - userStealing[1] = int(userStealing[1]) - 1 - sql = f"UPDATE user SET stealing = {'|'.join(userStealing)} WHERE uid = {uid}" + sql = f"UPDATE user SET stealing = '{userStealing[0]}|{userStealing[1]}' WHERE uid = {uid}" #更新用户每日偷取次数 await g_pSqlManager.executeDB(sql) return "\n".join(harvestRecords) + @classmethod + async def reclamationCondition(cls, uid: str) -> str: + userInfo = await g_pSqlManager.getUserInfoByUid(uid) + rec = g_pJsonManager.m_pLevel["reclamation"] + + try: + if userInfo['soil'] >= 30: + return "你已经开垦了全部土地" + + rec = rec[f"{userInfo['soil'] + 1}"] + + level = rec['level'] + point = rec['point'] + item = rec['item'] + + str = "" + if len(item) == 0: + str = f"下次升级所需条件:等级:{level},农场币:{point}" + else: + str = f"下次升级所需条件:等级:{level},农场币:{point},物品:{item}" + + return str + except Exception as e: + return "获取升级土地条件失败!" + + @classmethod + async def reclamation(cls, uid: str) -> str: + userInfo = await g_pSqlManager.getUserInfoByUid(uid) + level = await g_pSqlManager.getUserLevelByUid(uid) + + rec = g_pJsonManager.m_pLevel["reclamation"] + + try: + if userInfo['soil'] >= 30: + return "你已经开垦了全部土地" + + rec = rec[f"{userInfo['soil'] + 1}"] + + levelFileter = rec['level'] + point = rec['point'] + item = rec['item'] + + if level[0] < levelFileter: + return f"当前用户等级不足,升级所需等级为{levelFileter}" + + if userInfo['point'] < point: + return f"当前用户农场币不足,升级所需农场币为{point}" + + #TODO 缺少判断需要的Item + sql = f"UPDATE user SET point = '{userInfo['point'] - point}', soil = '{userInfo['soil'] + 1}' WHERE uid = {uid}" + + await g_pSqlManager.executeDB(sql) + + return "开垦土地成功!" + except Exception as e: + return "执行开垦失败!" g_pFarmManager = CFarmManager() diff --git a/farm/shop.py b/farm/shop.py index de156d9..cd53b07 100644 --- a/farm/shop.py +++ b/farm/shop.py @@ -93,13 +93,11 @@ class CShopManager: return "购买出错!请检查需购买的种子名称!" - level = g_pSqlManager.getUserLevelByUid(uid) + level = await g_pSqlManager.getUserLevelByUid(uid) - if level < plantInfo['level']: + if level[0] < int(plantInfo['level']): return "你的等级不够哦,努努力吧" - userPlants = {} - point = await g_pSqlManager.getUserPointByUid(uid) total = int(plantInfo['price']) * num @@ -108,25 +106,12 @@ class CShopManager: if point < total: return "你的农场币不够哦~ 快速速氪金吧!" else: - p = await g_pSqlManager.getUserSeedByUid(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 - - plantList = [f"{k}|{v}" for k, v in userPlants.items()] - await g_pSqlManager.updateUserPointByUid(uid, point - total) - await g_pSqlManager.updateUserSeedByUid(uid, ','.join(plantList)) - return f"成功购买{name},当前仓库数量为:{userPlants[name]},花费{total}农场币, 剩余{point - total}农场币" + if await g_pSqlManager.addUserSeedByPlant(uid, name, num) == False: + return "购买失败,执行数据库错误!" + + return f"成功购买{name},花费{total}农场币, 剩余{point - total}农场币" @classmethod async def sellPlantByUid(cls, uid: str, name: str = "", num: int = 1) -> str: