现在可以正常开垦了(但是开垦数据有待填写

️ 优化部分代码
🐛 修复无法偷菜的BUG
This commit is contained in:
Art_Sakura 2025-04-07 18:52:27 +08:00
parent 98ae76560b
commit 38a23ca6d7
6 changed files with 400 additions and 268 deletions

View File

@ -1,8 +1,11 @@
from nonebot.adapters import Event, MessageTemplate
from nonebot.rule import to_me from nonebot.rule import to_me
from nonebot_plugin_alconna import (Alconna, AlconnaQuery, Args, At, Match, from nonebot.typing import T_State
MultiVar, Option, Query, Subcommand, from nonebot_plugin_alconna import (Alconna, AlconnaQuery, Args, Arparma, At,
Match, MultiVar, Option, Query, Subcommand,
on_alconna, store_true) on_alconna, store_true)
from nonebot_plugin_uninfo import Uninfo from nonebot_plugin_uninfo import Uninfo
from nonebot_plugin_waiter import waiter
from zhenxun.services.log import logger from zhenxun.services.log import logger
from zhenxun.utils.message import MessageUtils from zhenxun.utils.message import MessageUtils
@ -11,6 +14,17 @@ from .database import g_pSqlManager
from .farm.farm import g_pFarmManager from .farm.farm import g_pFarmManager
from .farm.shop import g_pShopManager 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( diuse_register = on_alconna(
Alconna("开通农场"), Alconna("开通农场"),
priority=5, priority=5,
@ -43,6 +57,7 @@ diuse_farm = on_alconna(
Subcommand("harvest", help_text="收获"), Subcommand("harvest", help_text="收获"),
Subcommand("eradicate", help_text="铲除"), Subcommand("eradicate", help_text="铲除"),
Subcommand("my-plant", 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("sell-plant", Args["name?", str]["num?", int], help_text="出售作物"),
Subcommand("stealing", Args["target?", At], help_text="偷菜"), Subcommand("stealing", Args["target?", At], help_text="偷菜"),
Subcommand("buy-point", Args["num?", int], help_text="购买农场币"), Subcommand("buy-point", Args["num?", int], help_text="购买农场币"),
@ -55,11 +70,9 @@ 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)
if point < 0: if await isRegisteredByUid(uid) == False:
await MessageUtils.build_message("尚未开通农场").send() return
return None
image = await g_pFarmManager.drawFarmByUid(uid) image = await g_pFarmManager.drawFarmByUid(uid)
await MessageUtils.build_message(image).send(reply_to=True) await MessageUtils.build_message(image).send(reply_to=True)
@ -77,8 +90,8 @@ async def _(session: Uninfo):
point = await g_pSqlManager.getUserPointByUid(uid) point = await g_pSqlManager.getUserPointByUid(uid)
if point < 0: if point < 0:
await MessageUtils.build_message("尚未开通农场").send() await MessageUtils.build_message("尚未开通农场快at我发送 开通农场 开通吧").send()
return None return False
await MessageUtils.build_message(f"你的当前农场币为: {point}").send(reply_to=True) await MessageUtils.build_message(f"你的当前农场币为: {point}").send(reply_to=True)
@ -92,11 +105,9 @@ diuse_farm.shortcut(
@diuse_farm.assign("seed-shop") @diuse_farm.assign("seed-shop")
async def _(session: Uninfo): async def _(session: Uninfo):
uid = str(session.user.id) uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid)
if point < 0: if await isRegisteredByUid(uid) == False:
await MessageUtils.build_message("尚未开通农场").send() return
return None
image = await g_pShopManager.getSeedShopImage() image = await g_pShopManager.getSeedShopImage()
await MessageUtils.build_message(image).send() 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) ).finish(reply_to=True)
uid = str(session.user.id) uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid)
if point < 0: if await isRegisteredByUid(uid) == False:
await MessageUtils.build_message("尚未开通农场").send() return
return None
result = await g_pShopManager.buySeed(uid, name.result, num.result) result = await g_pShopManager.buySeed(uid, name.result, num.result)
await MessageUtils.build_message(result).send(reply_to=True) await MessageUtils.build_message(result).send(reply_to=True)
@ -135,11 +144,9 @@ diuse_farm.shortcut(
@diuse_farm.assign("my-seed") @diuse_farm.assign("my-seed")
async def _(session: Uninfo): async def _(session: Uninfo):
uid = str(session.user.id) uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid)
if point < 0: if await isRegisteredByUid(uid) == False:
await MessageUtils.build_message("尚未开通农场").send() return
return None
result = await g_pFarmManager.getUserSeedByUid(uid) result = await g_pFarmManager.getUserSeedByUid(uid)
await MessageUtils.build_message(result).send(reply_to=True) 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) ).finish(reply_to=True)
uid = str(session.user.id) uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid)
if point < 0: if await isRegisteredByUid(uid) == False:
await MessageUtils.build_message("尚未开通农场").send() return
return None
result = await g_pFarmManager.sowing(uid, name.result, num.result) result = await g_pFarmManager.sowing(uid, name.result, num.result)
await MessageUtils.build_message(result).send(reply_to=True) await MessageUtils.build_message(result).send(reply_to=True)
@ -179,11 +184,9 @@ diuse_farm.shortcut(
@diuse_farm.assign("harvest") @diuse_farm.assign("harvest")
async def _(session: Uninfo): async def _(session: Uninfo):
uid = str(session.user.id) uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid)
if point < 0: if await isRegisteredByUid(uid) == False:
await MessageUtils.build_message("尚未开通农场").send() return
return None
result = await g_pFarmManager.harvest(uid) result = await g_pFarmManager.harvest(uid)
await MessageUtils.build_message(result).send(reply_to=True) await MessageUtils.build_message(result).send(reply_to=True)
@ -198,11 +201,9 @@ diuse_farm.shortcut(
@diuse_farm.assign("eradicate") @diuse_farm.assign("eradicate")
async def _(session: Uninfo): async def _(session: Uninfo):
uid = str(session.user.id) uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid)
if point < 0: if await isRegisteredByUid(uid) == False:
await MessageUtils.build_message("尚未开通农场").send() return
return None
result = await g_pFarmManager.eradicate(uid) result = await g_pFarmManager.eradicate(uid)
await MessageUtils.build_message(result).send(reply_to=True) await MessageUtils.build_message(result).send(reply_to=True)
@ -218,15 +219,45 @@ diuse_farm.shortcut(
@diuse_farm.assign("my-plant") @diuse_farm.assign("my-plant")
async def _(session: Uninfo): async def _(session: Uninfo):
uid = str(session.user.id) uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid)
if point < 0: if await isRegisteredByUid(uid) == False:
await MessageUtils.build_message("尚未开通农场").send() return
return None
result = await g_pFarmManager.getUserPlantByUid(uid) result = await g_pFarmManager.getUserPlantByUid(uid)
await MessageUtils.build_message(result).send(reply_to=True) 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( diuse_farm.shortcut(
"出售作物(?P<name>.*?)", "出售作物(?P<name>.*?)",
command="我的农场", command="我的农场",
@ -242,15 +273,40 @@ async def _(session: Uninfo, name: Match[str], num: Query[int] = AlconnaQuery("n
).finish(reply_to=True) ).finish(reply_to=True)
uid = str(session.user.id) uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid)
if point < 0: if await isRegisteredByUid(uid) == False:
await MessageUtils.build_message("尚未开通农场").send() return
return None
result = await g_pShopManager.sellPlantByUid(uid, name.result, num.result) result = await g_pShopManager.sellPlantByUid(uid, name.result, num.result)
await MessageUtils.build_message(result).send(reply_to=True) 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( diuse_farm.shortcut(
"购买农场币(.*?)", "购买农场币(.*?)",
command="我的农场", command="我的农场",
@ -266,40 +322,9 @@ async def _(session: Uninfo, num: Query[int] = AlconnaQuery("num", 0)):
).finish(reply_to=True) ).finish(reply_to=True)
uid = str(session.user.id) uid = str(session.user.id)
point = await g_pSqlManager.getUserPointByUid(uid)
if point < 0: if await isRegisteredByUid(uid) == False:
await MessageUtils.build_message("尚未开通农场").send() return
return None
result = await g_pFarmManager.buyPointByUid(uid, num.result) result = await g_pFarmManager.buyPointByUid(uid, num.result)
await MessageUtils.build_message(result).send(reply_to=True) 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)

View File

@ -11,10 +11,10 @@ g_sResourcePath = Path(__file__).resolve().parent / "resource"
class CJsonManager: class CJsonManager:
def __init__(self): def __init__(self):
self.m_pItem = None self.m_pItem = {}
self.m_pPlant = None self.m_pPlant = {}
self.m_pLevel = None self.m_pLevel = {}
self.m_pSoil = None self.m_pSoil = {}
async def init(self) -> bool: async def init(self) -> bool:
if not await self.initItem(): if not await self.initItem():
@ -79,10 +79,10 @@ class CJsonManager:
return True return True
except FileNotFoundError: except FileNotFoundError:
logger.warning("plant.json 打开失败") logger.warning("level.json 打开失败")
return False return False
except json.JSONDecodeError as e: except json.JSONDecodeError as e:
logger.warning(f"plant.json JSON格式错误: {e}") logger.warning(f"level.json JSON格式错误: {e}")
return False return False
async def initSoil(self) -> bool: async def initSoil(self) -> bool:
@ -97,10 +97,10 @@ class CJsonManager:
return True return True
except FileNotFoundError: except FileNotFoundError:
logger.warning("plant.json 打开失败") logger.warning("soil.json 打开失败")
return False return False
except json.JSONDecodeError as e: except json.JSONDecodeError as e:
logger.warning(f"plant.json JSON格式错误: {e}") logger.warning(f"soil.json JSON格式错误: {e}")
return False return False
g_pJsonManager = CJsonManager() g_pJsonManager = CJsonManager()

View File

@ -1,25 +1,7 @@
{ {
"level": "soil":[1, 1, 1, 2, 3, 5, 7, 9, 11, 13,
{ 15, 17, 19, 21, 23, 25, 27, 29, 31, 33,
"1": 0, 36, 39, 42, 45, 48, 51, 54, 57, 60, 70
"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
], ],
"reclamation": "reclamation":
{ {
@ -27,79 +9,79 @@
{ {
"level": 3, "level": 3,
"point": 800, "point": 800,
"item": "" "item": []
}, },
"5": "5":
{ {
"level": 5, "level": 5,
"point": 1300, "point": 1300,
"item": "" "item": []
}, },
"6": "6":
{ {
"level": 7, "level": 7,
"point": 3200, "point": 3200,
"item": "" "item": []
}, },
"7": "7":
{ {
"level": 9, "level": 9,
"point": 5500, "point": 5500,
"item": "" "item": []
}, },
"8": "8":
{ {
"level": 12, "level": 12,
"point": 12000, "point": 12000,
"item": "" "item": []
}, },
"9": "9":
{ {
"level": 15, "level": 15,
"point": 19800, "point": 19800,
"item": "" "item": []
}, },
"10": "10":
{ {
"level":3, "level":3,
"point": 3000, "point": 3000,
"item": "" "item": []
}, },
"11": "11":
{ {
"level":3, "level":3,
"point": 3000, "point": 3000,
"item": "" "item": []
}, },
"12": "12":
{ {
"level":3, "level":3,
"point": 3000, "point": 3000,
"item": "" "item": []
}, },
"13": "13":
{ {
"level":3, "level":3,
"point": 3000, "point": 3000,
"item": "" "item": []
}, },
"14": "14":
{ {
"level":3, "level":3,
"point": 3000, "point": 3000,
"item": "" "item": []
}, },
"15": "15":
{ {
"level":3, "level":3,
"point": 3000, "point": 3000,
"item": "" "item": []
}, },
"16": "16":
{ {
"level":3, "level":3,
"point": 3000, "point": 3000,
"item": "" "item": []
} }
} }
} }

View File

@ -1,3 +1,4 @@
import math
import os import os
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
from io import StringIO from io import StringIO
@ -144,7 +145,7 @@ class CSqlManager:
if not await cls.executeDB(userSoilInfo): if not await cls.executeDB(userSoilInfo):
return False return False
return True return "开通农场成功"
@classmethod @classmethod
async def getUserInfoByUid(cls, uid: str) -> dict: async def getUserInfoByUid(cls, uid: str) -> dict:
@ -193,9 +194,7 @@ class CSqlManager:
return -1 return -1
try: try:
async with cls.m_pDB.execute( async with cls.m_pDB.execute(f"SELECT point FROM user WHERE uid = {uid}") as cursor:
f"SELECT point FROM user WHERE uid = {uid}"
) as cursor:
async for row in cursor: async for row in cursor:
return int(row[0]) return int(row[0])
@ -221,21 +220,14 @@ class CSqlManager:
return -1 return -1
try: try:
async with cls.m_pDB.execute( async with cls.m_pDB.execute(f"UPDATE user SET point = {point} WHERE uid = {uid}") as cursor:
"""UPDATE user
SET point = ?
WHERE uid = ?
RETURNING point""",
(point, uid)
) as cursor:
async for row in cursor: async for row in cursor:
return int(row[0]) return int(row[0])
logger.info(f"未找到用户或未修改数据: uid={uid}") logger.info(f"未找到用户或未修改数据: uid={uid}")
return -1 return -1
except Exception as e: except Exception as e:
# 记录详细错误日志(建议记录堆栈) logger.error(f"金币更新失败: {e}")
logger.error(f"更新失败: {e}")
return -1 return -1
@classmethod @classmethod
@ -252,7 +244,7 @@ class CSqlManager:
return -1 return -1
try: 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: async for row in cursor:
return int(row[0]) return int(row[0])
@ -274,40 +266,43 @@ class CSqlManager:
if len(uid) <= 0: if len(uid) <= 0:
return False 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) return await cls.executeDB(sql)
@classmethod @classmethod
async def getUserLevelByUid(cls, uid: str) -> int: async def getUserLevelByUid(cls, uid: str) -> tuple[int, int, int]:
"""根据用户Uid获取用户等级 """根据用户Uid获取用户等级
Args: Args:
uid (str): 用户Uid uid (str): 用户Uid
Returns: Returns:
int: 用户等级` tuple[int, int, int]: (当前等级, 下级所需经验, 当前等级剩余经验)
""" """
if len(uid) <= 0: if len(uid) <= 0:
return -1 return -1, -1, -1
try: 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: async for row in cursor:
exp = int(row[0]) 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) #计算下级所需经验 下级所需经验为200 + 当前等级 * 200
for key in sorted_keys: nextLevelExp = 200 * (level + 1)
if exp >= levelDict[key]: currentLevelExp = 100 * level * (level + 1)
return int(key)
return -1 remainingExp = exp - currentLevelExp
return level, nextLevelExp, remainingExp
return -1, -1, -1
except Exception as e: except Exception as e:
logger.warning(f"getUserLevelByUid查询失败: {e}") logger.warning(f"getUserLevelByUid查询失败: {e}")
return -1 return -1, -1, -1
@classmethod @classmethod
async def getUserSoilByUid(cls, uid: str) -> int: async def getUserSoilByUid(cls, uid: str) -> int:
@ -322,9 +317,9 @@ class CSqlManager:
if len(uid) <= 0: if len(uid) <= 0:
return 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: async for row in cursor:
if row[0] == None or len(row[0]) <= 0: if not row[0]:
return 0 return 0
else: else:
return int(row[0]) return int(row[0])
@ -345,7 +340,7 @@ class CSqlManager:
if len(uid) <= 0: if len(uid) <= 0:
return False, "" 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: async for row in cursor:
if row[0] == None or len(row[0]) <= 0: if row[0] == None or len(row[0]) <= 0:
return True, "" return True, ""
@ -381,12 +376,12 @@ class CSqlManager:
plantInfo = g_pJsonManager.m_pPlant['plant'][plant] # type: ignore plantInfo = g_pJsonManager.m_pPlant['plant'][plant] # type: ignore
currentTime = datetime.now() currentTime = datetime.now()
newTime = currentTime + timedelta(minutes=int(plantInfo['time'])) newTime = currentTime + timedelta(hours=int(plantInfo['time']))
#种子名称种下时间预计成熟时间地状态0无 1长草 2生虫 3缺水 4枯萎是否被偷 示例QQ号-偷取数量|QQ号-偷取数量 #种子名称种下时间预计成熟时间地状态0无 1长草 2生虫 3缺水 4枯萎是否被偷 示例QQ号-偷取数量|QQ号-偷取数量
s = f"{plant},{int(currentTime.timestamp())},{int(newTime.timestamp())},{status}," 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) return await cls.executeDB(sql)
@ -405,7 +400,7 @@ class CSqlManager:
return "" return ""
try: 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: async for row in cursor:
return row[0] return row[0]
@ -429,7 +424,43 @@ class CSqlManager:
if len(uid) <= 0: if len(uid) <= 0:
return False 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) return await cls.executeDB(sql)
@ -448,7 +479,7 @@ class CSqlManager:
return "" return ""
try: 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: async for row in cursor:
return row[0] return row[0]
@ -472,7 +503,43 @@ class CSqlManager:
if len(uid) <= 0: if len(uid) <= 0:
return False 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) return await cls.executeDB(sql)

View File

@ -4,7 +4,6 @@ from datetime import date, datetime
from io import StringIO from io import StringIO
from typing import Dict, List, Tuple from typing import Dict, List, Tuple
from Python311.Lib.PIL.ImImagePlugin import number
from zhenxun.models.user_console import UserConsole from zhenxun.models.user_console import UserConsole
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
@ -46,11 +45,9 @@ class CFarmManager:
Returns: Returns:
bytes: 返回绘制结果 bytes: 返回绘制结果
""" """
soilNumber = await g_pSqlManager.getUserLevelByUid(uid)
img = BuildImage(background = g_sResourcePath / "background/background.jpg") img = BuildImage(background = g_sResourcePath / "background/background.jpg")
soilSize = g_pJsonManager.m_pSoil['size'] # type: ignore soilSize = g_pJsonManager.m_pSoil['size']
#TODO 缺少判断用户土地资源状况 #TODO 缺少判断用户土地资源状况
soil = BuildImage(background = g_sResourcePath / "soil/普通土地.png") soil = BuildImage(background = g_sResourcePath / "soil/普通土地.png")
@ -59,7 +56,7 @@ class CFarmManager:
grass = BuildImage(background = g_sResourcePath / "soil/草土地.png") grass = BuildImage(background = g_sResourcePath / "soil/草土地.png")
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']
soilUnlock = await g_pSqlManager.getUserSoilByUid(uid) soilUnlock = await g_pSqlManager.getUserSoilByUid(uid)
x = 0 x = 0
@ -72,7 +69,7 @@ class CFarmManager:
y = soilPos[str(index + 1)]['y'] y = soilPos[str(index + 1)]['y']
#如果土地已经到达对应等级 #如果土地已经到达对应等级
if index > soilUnlock: if index < soilUnlock:
await img.paste(soil, (x, y)) await img.paste(soil, (x, y))
isPlant, plant, isRipe= await cls.drawSoilPlant(uid, f"soil{str(index + 1)}") 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, await img.paste(expansion, (x + soilSize[0] // 2 - expansion.width // 2,
y + soilSize[1] // 2 - expansion.height)) y + soilSize[1] // 2 - expansion.height))
#左上角绘制用户信息
await img.resize(0.6) await img.resize(0.6)
return img.pic2bytes() return img.pic2bytes()
@ -129,7 +127,7 @@ class CFarmManager:
await plant.resize(0, 150, 212) await plant.resize(0, 150, 212)
return True, plant, False 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() currentTime = datetime.now()
matureTime = datetime.fromtimestamp(int(soilInfo[2])) matureTime = datetime.fromtimestamp(int(soilInfo[2]))
@ -195,9 +193,9 @@ class CFarmManager:
sell = "" sell = ""
for item in seed.split(','): for item in seed.split(','):
if '|' in item: if '|' in item:
seedName, count = item.split('|', 1) # 分割一次,避免多竖线问题 seedName, count = item.split('|', 1) #分割一次,避免多竖线问题
try: try:
plantInfo = g_pJsonManager.m_pPlant['plant'][seedName] # type: ignore plantInfo = g_pJsonManager.m_pPlant['plant'][seedName]
icon = "" icon = ""
icon_path = g_sResourcePath / f"plant/{seedName}/icon.png" icon_path = g_sResourcePath / f"plant/{seedName}/icon.png"
@ -249,7 +247,7 @@ class CFarmManager:
""" """
plant = await g_pSqlManager.getUserSeedByUid(uid) plant = await g_pSqlManager.getUserSeedByUid(uid)
if plant == None: if plant == None or len(plant) == 0:
return "你的种子仓库是空的,快去买点吧!" return "你的种子仓库是空的,快去买点吧!"
plantDict = {} plantDict = {}
@ -270,24 +268,26 @@ class CFarmManager:
soilName = f"soil{i}" soilName = f"soil{i}"
success, message = await g_pSqlManager.getUserSoilStatusBySoilID(uid, soilName) success, message = await g_pSqlManager.getUserSoilStatusBySoilID(uid, soilName)
if success: if success:
# 更新种子数量 #更新种子数量
num -= 1 num -= 1
plantDict[name] -= 1 plantDict[name] -= 1
if plantDict[name] == 0:
del plantDict[name]
# 更新数据库 #更新数据库
await g_pSqlManager.updateUserSoilStatusByPlantName(uid, soilName, 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( await g_pSqlManager.updateUserSeedByUid(
uid, 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 str
return f"播种数量超出开垦土地数量,已将可播种土地成功播种{name}!仓库还剩下{plantDict[name]}个种子"
else:
return f"播种{name}成功!仓库还剩下{plantDict[name]}个种子"
@classmethod @classmethod
async def harvest(cls, uid: str) -> str: async def harvest(cls, uid: str) -> str:
@ -300,60 +300,59 @@ class CFarmManager:
str: 返回 str: 返回
""" """
isStealingPlant = 0
soilUnlock = await g_pSqlManager.getUserSoilByUid(uid) soilUnlock = await g_pSqlManager.getUserSoilByUid(uid)
plant = {} soilNames = [f"soil{i + 1}" for i in range(soilUnlock)]
soilNames = [f"soil{i}" for i in range(soilUnlock)]
soilStatuses = await asyncio.gather(*[ soilStatuses = await asyncio.gather(*[
g_pSqlManager.getUserSoilStatusBySoilID(uid, name) g_pSqlManager.getUserSoilStatusBySoilID(uid, name)
for name in soilNames for name in soilNames
]) ])
plant: Dict[str, int] = {}
harvestRecords: List[str] = [] harvestRecords: List[str] = []
experience = 0 experience = 0
for (soil_name, (status, info)) in zip(soilNames, soilStatuses): for (soil_name, (status, info)) in zip(soilNames, soilStatuses):
if not status: if len(info) <= 0:
soilInfo = info.split(',') continue
plantId = soilInfo[0]
plantInfo = g_pJsonManager.m_pPlant['plant'][plantId] # type: ignore
currentTime = datetime.now() soilInfo = info.split(',')
matureTime = datetime.fromtimestamp(int(soilInfo[2])) if int(soilInfo[3]) == 4:
continue
if currentTime >= matureTime: plantId = soilInfo[0]
number = plantInfo['harvest'] plantInfo = g_pJsonManager.m_pPlant['plant'][plantId]
#判断该土地作物是否被透过 currentTime = datetime.now()
if len(soilInfo[4]) > 0: matureTime = datetime.fromtimestamp(int(soilInfo[2]))
stealingStatus = soilInfo[4].split('|')
for isUser in stealingStatus:
user = isUser.split('-')
number -= user[1]
plant[plantId] = plant.get(plantId, 0) + number if currentTime >= matureTime:
experience += plantInfo['experience'] number = plantInfo['harvest']
harvestRecords.append(f"收获作物:{plantId},数量为:{number},经验为:{plantInfo['experience']}")
#批量更新数据库操作 #判断该土地作物是否被透过
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: if experience > 0:
harvestRecords.append(f"\t累计获得经验:{experience}") harvestRecords.append(f"\t累计获得经验:{experience}")
exp = await g_pSqlManager.getUserExpByUid(uid) exp = await g_pSqlManager.getUserExpByUid(uid)
await g_pSqlManager.UpdateUserExpByUid(uid, exp + experience) await g_pSqlManager.UpdateUserExpByUid(uid, exp + experience)
if not plant: if isStealingPlant <= 0:
return "可收获作物为0哦~ 不要试图拔苗助长" return "没有可收获作物哦~ 不要试图拔苗助长"
else: else:
# 批量更新用户作物数据
await g_pSqlManager.updateUserPlantByUid(
uid,
','.join([f"{k}|{v}" for k, v in plant.items()])
)
return "\n".join(harvestRecords) return "\n".join(harvestRecords)
@classmethod @classmethod
@ -369,7 +368,7 @@ class CFarmManager:
soilUnlock = await g_pSqlManager.getUserSoilByUid(uid) 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(*[ soilStatuses = await asyncio.gather(*[
g_pSqlManager.getUserSoilStatusBySoilID(uid, name) g_pSqlManager.getUserSoilStatusBySoilID(uid, name)
for name in soilNames for name in soilNames
@ -377,12 +376,12 @@ class CFarmManager:
experience = 0 experience = 0
for (soil_name, (status, info)) in zip(soilNames, soilStatuses): for (soil_name, (status, info)) in zip(soilNames, soilStatuses):
if not status: if info:
soilInfo = info.split(',') soilInfo = info.split(',')
if int(soilInfo[3]) == 4: if int(soilInfo[3]) == 4:
experience += 3 experience += 3
# 批量更新数据库操作 #批量更新数据库操作
await g_pSqlManager.updateUserSoilStatusByPlantName(uid, soil_name, "", 0) await g_pSqlManager.updateUserSoilStatusByPlantName(uid, soil_name, "", 0)
if experience > 0: if experience > 0:
@ -429,9 +428,9 @@ class CFarmManager:
sell = "" sell = ""
for item in plant.split(','): for item in plant.split(','):
if '|' in item: if '|' in item:
plantName, count = item.split('|', 1) # 分割一次,避免多竖线问题 plantName, count = item.split('|', 1) #分割一次,避免多竖线问题
try: try:
plantInfo = g_pJsonManager.m_pPlant['plant'][plantName] # type: ignore plantInfo = g_pJsonManager.m_pPlant['plant'][plantName]
icon = "" icon = ""
icon_path = g_sResourcePath / f"plant/{plantName}/icon.png" icon_path = g_sResourcePath / f"plant/{plantName}/icon.png"
@ -443,7 +442,7 @@ class CFarmManager:
else: else:
sell = "不可以" sell = "不可以"
number = count * int(plantInfo['price']) number = int(count) * plantInfo['price']
data_list.append( data_list.append(
[ [
@ -485,90 +484,164 @@ class CFarmManager:
#用户可偷次数 #用户可偷次数
userStealing = userInfo["stealing"].split('|') userStealing = userInfo["stealing"].split('|')
if date.fromisoformat(userStealing[0]) != date.today(): if userStealing[0] == '':
userStealing[0] = date.today() 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 userStealing[1] = 5
if int(userStealing[1]) <= 0: if int(userStealing[1]) <= 0:
return "你今天可偷次数到达上限啦,手下留情吧" return "你今天可偷次数到达上限啦,手下留情吧"
#获取用户 #获取用户解锁地块数量
soilUnlock = int(userInfo["soil"]) soilUnlockNum = int(userInfo["soil"])
plant = {} plant = {}
#根据解锁土地,获取每块土地状态信息 #根据解锁土地,获取每块土地状态信息
soilNames = [f"soil{i}" for i in range(soilUnlock)] soilNames = [f"soil{i + 1}" for i in range(soilUnlockNum)]
soilStatuses = await asyncio.gather(*[ soilStatuses = await asyncio.gather(*[
g_pSqlManager.getUserSoilStatusBySoilID(target, name) g_pSqlManager.getUserSoilStatusBySoilID(target, name)
for name in soilNames for name in soilNames
]) ])
plant: Dict[str, int] = {}
harvestRecords: List[str] = []
isStealing = False 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 isStealing = False
if not status: if not info:
soilInfo = info.split(',') continue
plantId = soilInfo[0]
plantInfo = g_pJsonManager.m_pPlant['plant'][plantId] # type: ignore
currentTime = datetime.now() soilInfo = info.split(',')
matureTime = datetime.fromtimestamp(int(soilInfo[2])) 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('|') stealingStatus = soilInfo[4].split('|')
for isUser in stealingStatus: for isUser in stealingStatus:
user = isUser.split('-') user = isUser.split('-')
if user[0] == uid: if user[0] == uid:
isStealing = True isStealing = True
isStealingNumber += 1
break break
stealingNumber += int(user[1]) stealingNumber -= int(user[1])
#如果偷过,则跳过该土地 #如果偷过,则跳过该土地
if isStealing: if isStealing:
continue continue
stealingNumber -= plantInfo['harvest'] stealingNumber += plantInfo['harvest']
randomNumber = random.choice([1, 2]) randomNumber = random.choice([1, 2])
randomNumber = min(randomNumber, stealingNumber) randomNumber = min(randomNumber, stealingNumber)
if randomNumber > 0: logger.info(f"{randomNumber}")
plant[plantId] = plant.get(plantId, 0) + randomNumber
harvestRecords.append(f"成功偷到作物:{plantId},数量为:{randomNumber}")
stealingStatus += f"|{uid}-{randomNumber}" if randomNumber > 0:
await g_pSqlManager.addUserPlantByPlant(uid, plantId, randomNumber)
#如果将作物偷完,就直接更新状态 并记录用户偷取过 harvestRecords.append(f"成功偷到作物:{plantId},数量为:{randomNumber}")
if plantInfo['harvest'] - randomNumber + stealingNumber == 0: stealingStatus.append(f"{uid}-{randomNumber}")
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}'"
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 "目标没有作物可以被偷" return "目标没有作物可以被偷"
elif isStealingPlant <= 0 and isStealingNumber > 0:
return "你已经偷过目标啦,请手下留情"
else: else:
# 批量更新用户作物仓库数据
await g_pSqlManager.updateUserPlantByUid(target, ','.join([f"{k}|{v}" for k, v in plant.items()]))
userStealing[1] = int(userStealing[1]) - 1 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) await g_pSqlManager.executeDB(sql)
return "\n".join(harvestRecords) 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() g_pFarmManager = CFarmManager()

View File

@ -93,13 +93,11 @@ class CShopManager:
return "购买出错!请检查需购买的种子名称!" return "购买出错!请检查需购买的种子名称!"
level = g_pSqlManager.getUserLevelByUid(uid) level = await g_pSqlManager.getUserLevelByUid(uid)
if level < plantInfo['level']: if level[0] < int(plantInfo['level']):
return "你的等级不够哦,努努力吧" return "你的等级不够哦,努努力吧"
userPlants = {}
point = await g_pSqlManager.getUserPointByUid(uid) point = await g_pSqlManager.getUserPointByUid(uid)
total = int(plantInfo['price']) * num total = int(plantInfo['price']) * num
@ -108,25 +106,12 @@ class CShopManager:
if point < total: if point < total:
return "你的农场币不够哦~ 快速速氪金吧!" return "你的农场币不够哦~ 快速速氪金吧!"
else: 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.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 @classmethod
async def sellPlantByUid(cls, uid: str, name: str = "", num: int = 1) -> str: async def sellPlantByUid(cls, uid: str, name: str = "", num: int = 1) -> str: