2025-04-28 19:27:16 +08:00
|
|
|
|
from zhenxun.services.log import logger
|
|
|
|
|
|
|
2025-05-29 18:20:03 +08:00
|
|
|
|
from ..config import g_bIsDebug
|
2025-04-28 19:27:16 +08:00
|
|
|
|
from ..dbService import g_pDBService
|
2025-05-27 18:15:11 +08:00
|
|
|
|
from ..tool import g_pToolManager
|
2025-05-28 19:48:12 +08:00
|
|
|
|
from .database import CSqlManager
|
2025-04-28 19:27:16 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CUserSoilDB(CSqlManager):
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def initDB(cls):
|
|
|
|
|
|
userSoil = {
|
|
|
|
|
|
"uid": "TEXT NOT NULL",
|
2025-06-06 10:56:22 +08:00
|
|
|
|
"soilIndex": "INTEGER NOT NULL", # 地块索引从1开始
|
|
|
|
|
|
"plantName": "TEXT DEFAULT ''", # 作物名称
|
|
|
|
|
|
"plantTime": "INTEGER DEFAULT 0", # 播种时间
|
|
|
|
|
|
"matureTime": "INTEGER DEFAULT 0", # 成熟时间
|
|
|
|
|
|
"soilLevel": "INTEGER DEFAULT 0", # 土地等级 0=普通地,1=红土地,2=黑土地,3=金土地
|
|
|
|
|
|
"wiltStatus": "INTEGER DEFAULT 0", # 枯萎状态 0=未枯萎,1=枯萎
|
|
|
|
|
|
"fertilizerStatus": "INTEGER DEFAULT 0", # 施肥状态 0=未施肥,1=施肥 2=增肥
|
|
|
|
|
|
"bugStatus": "INTEGER DEFAULT 0", # 虫害状态 0=无虫害,1=有虫害
|
|
|
|
|
|
"weedStatus": "INTEGER DEFAULT 0", # 杂草状态 0=无杂草,1=有杂草
|
|
|
|
|
|
"waterStatus": "INTEGER DEFAULT 0", # 缺水状态 0=不缺水,1=缺水
|
|
|
|
|
|
"harvestCount": "INTEGER DEFAULT 0", # 收获次数
|
2025-04-29 18:11:09 +08:00
|
|
|
|
"PRIMARY KEY": "(uid, soilIndex)",
|
2025-04-28 19:27:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await cls.ensureTableSchema("userSoil", userSoil)
|
|
|
|
|
|
|
2025-05-29 18:20:03 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def nextPhase(cls, uid: str, soilIndex: int):
|
|
|
|
|
|
"""将指定地块的作物进入下个阶段
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
soilIndex (int): 地块索引 从1开始
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not g_bIsDebug:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
soilInfo = await cls.getUserSoil(uid, soilIndex)
|
|
|
|
|
|
|
|
|
|
|
|
if not soilInfo:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
2025-06-06 10:56:22 +08:00
|
|
|
|
plantInfo = await g_pDBService.plant.getPlantByName(soilInfo["plantName"])
|
2025-05-29 18:20:03 +08:00
|
|
|
|
|
|
|
|
|
|
if not plantInfo:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
2025-05-30 11:22:32 +08:00
|
|
|
|
currentTime = g_pToolManager.dateTime().now().timestamp()
|
2025-06-06 10:56:22 +08:00
|
|
|
|
phaseList = await g_pDBService.plant.getPlantPhaseByName(soilInfo["plantName"])
|
2025-05-29 18:20:03 +08:00
|
|
|
|
|
2025-06-06 10:56:22 +08:00
|
|
|
|
if currentTime >= soilInfo["matureTime"]:
|
2025-05-29 18:20:03 +08:00
|
|
|
|
return
|
|
|
|
|
|
|
2025-06-06 10:56:22 +08:00
|
|
|
|
elapsedTime = currentTime - soilInfo["plantTime"]
|
2025-05-30 16:07:34 +08:00
|
|
|
|
currentStage = currentStage = sum(1 for thr in phaseList if elapsedTime >= thr)
|
2025-05-29 18:20:03 +08:00
|
|
|
|
|
2025-06-06 10:56:22 +08:00
|
|
|
|
t = int(soilInfo["plantTime"]) - phaseList[currentStage]
|
|
|
|
|
|
s = int(soilInfo["matureTime"]) - phaseList[currentStage]
|
2025-05-30 11:22:32 +08:00
|
|
|
|
|
2025-06-06 10:56:22 +08:00
|
|
|
|
await cls.updateUserSoilFields(
|
|
|
|
|
|
uid, soilIndex, {"plantTime": t, "matureTime": s}
|
|
|
|
|
|
)
|
2025-05-29 18:20:03 +08:00
|
|
|
|
|
2025-06-06 10:56:22 +08:00
|
|
|
|
logger.debug(
|
|
|
|
|
|
f"当前阶段{currentStage}, 阶段时间{phaseList[currentStage]}, 播种时间{t}, 收获时间{s}"
|
|
|
|
|
|
)
|
2025-05-29 18:20:03 +08:00
|
|
|
|
|
2025-06-29 01:45:24 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def matureNow(cls, uid: str, soilIndex: int):
|
|
|
|
|
|
"""将指定地块的作物直接成熟
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户ID
|
|
|
|
|
|
soilIndex (int): 地块索引(从1开始)
|
|
|
|
|
|
"""
|
|
|
|
|
|
# 与 nextPhase 不同:无需调试模式检查,允许在任何模式下调用
|
|
|
|
|
|
soilInfo = await cls.getUserSoil(uid, soilIndex)
|
|
|
|
|
|
if not soilInfo:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
plantName = soilInfo.get("plantName")
|
|
|
|
|
|
if not plantName:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
plantInfo = await g_pDBService.plant.getPlantByName(plantName)
|
|
|
|
|
|
if not plantInfo:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
currentTime = g_pToolManager.dateTime().now().timestamp()
|
|
|
|
|
|
# 如果当前时间已经超过或等于成熟时间,则作物已成熟或可收获
|
|
|
|
|
|
if currentTime >= soilInfo["matureTime"]:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
# 将作物成熟时间直接更新为当前时间,实现立即成熟
|
|
|
|
|
|
await cls.updateUserSoilFields(uid, soilIndex, {"matureTime": currentTime})
|
|
|
|
|
|
|
2025-04-28 19:27:16 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def getUserFarmByUid(cls, uid: str) -> dict:
|
|
|
|
|
|
"""获取指定用户的旧农场数据
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户ID
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
dict: 包含字段名-值的字典; 若无数据则返回空字典
|
|
|
|
|
|
"""
|
|
|
|
|
|
cursor = await cls.m_pDB.execute("SELECT * FROM soil WHERE uid = ?", (uid,))
|
|
|
|
|
|
row = await cursor.fetchone()
|
2025-04-29 18:11:09 +08:00
|
|
|
|
|
2025-04-28 19:27:16 +08:00
|
|
|
|
if not row:
|
|
|
|
|
|
return {}
|
|
|
|
|
|
columns = [description[0] for description in cursor.description]
|
|
|
|
|
|
return dict(zip(columns, row))
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2025-04-29 18:11:09 +08:00
|
|
|
|
async def migrateOldFarmData(cls) -> bool:
|
2025-04-28 19:27:16 +08:00
|
|
|
|
"""迁移旧土地数据到新表 userSoil 并删除旧表
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
2025-04-29 18:11:09 +08:00
|
|
|
|
bool: 如果旧表不存在则返回 False,否则迁移并删除后返回 True
|
2025-04-28 19:27:16 +08:00
|
|
|
|
"""
|
2025-06-06 10:56:22 +08:00
|
|
|
|
# 检查旧表是否存在
|
2025-04-29 18:11:09 +08:00
|
|
|
|
cursor = await cls.m_pDB.execute(
|
|
|
|
|
|
"SELECT name FROM sqlite_master WHERE type='table' AND name='soil'"
|
|
|
|
|
|
)
|
|
|
|
|
|
if not await cursor.fetchone():
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
2025-04-28 19:27:16 +08:00
|
|
|
|
async with cls._transaction():
|
|
|
|
|
|
users = await g_pDBService.user.getAllUsers()
|
2025-04-29 18:11:09 +08:00
|
|
|
|
|
2025-04-28 19:27:16 +08:00
|
|
|
|
for uid in users:
|
|
|
|
|
|
farmInfo = await cls.getUserFarmByUid(uid)
|
|
|
|
|
|
for i in range(1, 31):
|
2025-04-29 18:11:09 +08:00
|
|
|
|
key = f"soil{i}"
|
|
|
|
|
|
data = farmInfo.get(key)
|
|
|
|
|
|
if not data:
|
2025-04-28 19:27:16 +08:00
|
|
|
|
continue
|
2025-06-03 15:32:14 +08:00
|
|
|
|
|
|
|
|
|
|
if data == ",,,4,":
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
2025-04-29 18:11:09 +08:00
|
|
|
|
parts = data.split(",")
|
|
|
|
|
|
if len(parts) < 3:
|
2025-04-28 19:27:16 +08:00
|
|
|
|
continue
|
2025-06-03 15:32:14 +08:00
|
|
|
|
|
2025-04-29 18:11:09 +08:00
|
|
|
|
name = parts[0]
|
|
|
|
|
|
pt = int(parts[1])
|
|
|
|
|
|
mt = int(parts[2])
|
2025-04-28 19:27:16 +08:00
|
|
|
|
|
2025-04-29 18:11:09 +08:00
|
|
|
|
await cls.m_pDB.execute(
|
2025-05-09 18:20:00 +08:00
|
|
|
|
"""
|
|
|
|
|
|
INSERT INTO userSoil
|
2025-05-26 15:10:12 +08:00
|
|
|
|
(uid,soilIndex,plantName,plantTime,matureTime,harvestCount)
|
2025-05-09 18:20:00 +08:00
|
|
|
|
VALUES (?,?,?,?,?,?)
|
|
|
|
|
|
""",
|
|
|
|
|
|
(uid, i, name, pt, mt, 0),
|
2025-04-29 18:11:09 +08:00
|
|
|
|
)
|
2025-04-28 19:27:16 +08:00
|
|
|
|
|
|
|
|
|
|
await cls.m_pDB.execute("DROP TABLE soil")
|
2025-05-26 15:10:12 +08:00
|
|
|
|
|
|
|
|
|
|
logger.info("数据库迁移完毕!")
|
2025-04-29 18:11:09 +08:00
|
|
|
|
return True
|
2025-04-28 19:27:16 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def insertUserSoil(cls, soilInfo: dict):
|
|
|
|
|
|
"""插入一条新的 userSoil 记录
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
soilInfo (dict): 新土地数据
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
None
|
|
|
|
|
|
"""
|
|
|
|
|
|
async with cls._transaction():
|
|
|
|
|
|
await cls.m_pDB.execute(
|
2025-05-09 18:20:00 +08:00
|
|
|
|
"""
|
|
|
|
|
|
INSERT INTO userSoil
|
|
|
|
|
|
(uid, soilIndex, plantName, plantTime, matureTime,
|
|
|
|
|
|
soilLevel, wiltStatus, fertilizerStatus, bugStatus,
|
|
|
|
|
|
weedStatus, waterStatus, harvestCount)
|
|
|
|
|
|
VALUES (?,?,?,?,?,?,?,?,?,?,?,?)
|
|
|
|
|
|
""",
|
2025-04-28 19:27:16 +08:00
|
|
|
|
(
|
|
|
|
|
|
soilInfo["uid"],
|
|
|
|
|
|
soilInfo["soilIndex"],
|
|
|
|
|
|
soilInfo.get("plantName", ""),
|
|
|
|
|
|
soilInfo.get("plantTime", 0),
|
|
|
|
|
|
soilInfo.get("matureTime", 0),
|
|
|
|
|
|
soilInfo.get("soilLevel", 0),
|
2025-05-09 18:20:00 +08:00
|
|
|
|
soilInfo.get("wiltStatus", 0),
|
2025-04-28 19:27:16 +08:00
|
|
|
|
soilInfo.get("fertilizerStatus", 0),
|
|
|
|
|
|
soilInfo.get("bugStatus", 0),
|
|
|
|
|
|
soilInfo.get("weedStatus", 0),
|
2025-04-29 18:11:09 +08:00
|
|
|
|
soilInfo.get("waterStatus", 0),
|
2025-05-09 18:20:00 +08:00
|
|
|
|
soilInfo.get("harvestCount", 0),
|
2025-04-29 18:11:09 +08:00
|
|
|
|
),
|
2025-04-28 19:27:16 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
2025-04-29 18:11:09 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def _insertUserSoil(cls, soilInfo: dict):
|
|
|
|
|
|
"""插入一条新的 userSoil 记录
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
soilInfo (dict): 新土地数据
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
None
|
|
|
|
|
|
"""
|
|
|
|
|
|
await cls.m_pDB.execute(
|
2025-06-06 10:56:22 +08:00
|
|
|
|
"""
|
2025-05-09 18:20:00 +08:00
|
|
|
|
INSERT INTO userSoil
|
|
|
|
|
|
(uid, soilIndex, plantName, plantTime, matureTime,
|
|
|
|
|
|
soilLevel, wiltStatus, fertilizerStatus, bugStatus,
|
|
|
|
|
|
weedStatus, waterStatus, harvestCount)
|
|
|
|
|
|
VALUES (?,?,?,?,?,?,?,?,?,?,?,?)
|
|
|
|
|
|
""",
|
2025-06-06 10:56:22 +08:00
|
|
|
|
(
|
|
|
|
|
|
soilInfo["uid"],
|
|
|
|
|
|
soilInfo["soilIndex"],
|
|
|
|
|
|
soilInfo.get("plantName", ""),
|
|
|
|
|
|
soilInfo.get("plantTime", 0),
|
|
|
|
|
|
soilInfo.get("matureTime", 0),
|
|
|
|
|
|
soilInfo.get("soilLevel", 0),
|
|
|
|
|
|
soilInfo.get("wiltStatus", 0),
|
|
|
|
|
|
soilInfo.get("fertilizerStatus", 0),
|
|
|
|
|
|
soilInfo.get("bugStatus", 0),
|
|
|
|
|
|
soilInfo.get("weedStatus", 0),
|
|
|
|
|
|
soilInfo.get("waterStatus", 0),
|
|
|
|
|
|
soilInfo.get("harvestCount", 0),
|
|
|
|
|
|
),
|
2025-04-29 18:11:09 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
2025-04-28 19:27:16 +08:00
|
|
|
|
@classmethod
|
2025-06-06 10:56:22 +08:00
|
|
|
|
async def getUserSoil(cls, uid: str, soilIndex: int) -> dict | None:
|
2025-04-28 19:27:16 +08:00
|
|
|
|
"""获取指定用户某块土地的详细信息
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户ID
|
|
|
|
|
|
soilIndex (int): 土地索引
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
Optional[dict]: 记录存在返回字段-值字典,否则返回 None
|
|
|
|
|
|
"""
|
|
|
|
|
|
async with cls._transaction():
|
|
|
|
|
|
cursor = await cls.m_pDB.execute(
|
|
|
|
|
|
"SELECT * FROM userSoil WHERE uid = ? AND soilIndex = ?",
|
2025-04-29 18:11:09 +08:00
|
|
|
|
(uid, soilIndex),
|
2025-04-28 19:27:16 +08:00
|
|
|
|
)
|
|
|
|
|
|
row = await cursor.fetchone()
|
|
|
|
|
|
if not row:
|
|
|
|
|
|
return None
|
|
|
|
|
|
columns = [description[0] for description in cursor.description]
|
|
|
|
|
|
return dict(zip(columns, row))
|
|
|
|
|
|
|
2025-04-29 18:11:09 +08:00
|
|
|
|
@classmethod
|
2025-06-06 10:56:22 +08:00
|
|
|
|
async def _getUserSoil(cls, uid: str, soilIndex: int) -> dict | None:
|
2025-04-29 18:11:09 +08:00
|
|
|
|
"""获取指定用户某块土地的详细信息
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户ID
|
|
|
|
|
|
soilIndex (int): 土地索引
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
Optional[dict]: 记录存在返回字段-值字典,否则返回 None
|
|
|
|
|
|
"""
|
|
|
|
|
|
cursor = await cls.m_pDB.execute(
|
|
|
|
|
|
"SELECT * FROM userSoil WHERE uid = ? AND soilIndex = ?",
|
|
|
|
|
|
(uid, soilIndex),
|
|
|
|
|
|
)
|
|
|
|
|
|
row = await cursor.fetchone()
|
|
|
|
|
|
if not row:
|
|
|
|
|
|
return None
|
|
|
|
|
|
columns = [description[0] for description in cursor.description]
|
|
|
|
|
|
return dict(zip(columns, row))
|
|
|
|
|
|
|
2025-06-29 01:45:24 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def countSoilByLevel(cls, uid: str, soilLevel: int) -> int:
|
|
|
|
|
|
"""统计指定用户在指定土地等级的土地数量
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户ID
|
|
|
|
|
|
soilLevel (int): 土地等级
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
int: 符合条件的土地数量
|
|
|
|
|
|
"""
|
|
|
|
|
|
async with cls._transaction():
|
|
|
|
|
|
cursor = await cls.m_pDB.execute(
|
|
|
|
|
|
"SELECT COUNT(*) FROM userSoil WHERE uid = ? AND soilLevel = ?",
|
|
|
|
|
|
(uid, soilLevel),
|
|
|
|
|
|
)
|
|
|
|
|
|
row = await cursor.fetchone()
|
|
|
|
|
|
return row[0] if row else 0
|
|
|
|
|
|
|
2025-04-28 19:27:16 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def updateUserSoil(cls, uid: str, soilIndex: int, field: str, value):
|
|
|
|
|
|
"""更新指定用户土地的单个字段
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户ID
|
|
|
|
|
|
soilIndex (int): 土地索引
|
|
|
|
|
|
field (str): 需更新的字段名
|
|
|
|
|
|
value: 新值
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
None
|
|
|
|
|
|
"""
|
|
|
|
|
|
async with cls._transaction():
|
|
|
|
|
|
await cls.m_pDB.execute(
|
|
|
|
|
|
f"UPDATE userSoil SET {field} = ? WHERE uid = ? AND soilIndex = ?",
|
2025-04-29 18:11:09 +08:00
|
|
|
|
(value, uid, soilIndex),
|
2025-04-28 19:27:16 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
2025-04-29 18:11:09 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def _updateUserSoil(cls, uid: str, soilIndex: int, field: str, value):
|
|
|
|
|
|
"""更新指定用户土地的单个字段
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户ID
|
|
|
|
|
|
soilIndex (int): 土地索引
|
|
|
|
|
|
field (str): 需更新的字段名
|
|
|
|
|
|
value: 新值
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
None
|
|
|
|
|
|
"""
|
|
|
|
|
|
await cls.m_pDB.execute(
|
|
|
|
|
|
f"UPDATE userSoil SET {field} = ? WHERE uid = ? AND soilIndex = ?",
|
|
|
|
|
|
(value, uid, soilIndex),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2025-05-28 19:48:12 +08:00
|
|
|
|
@classmethod
|
2025-06-06 10:56:22 +08:00
|
|
|
|
async def updateUserSoilFields(
|
|
|
|
|
|
cls, uid: str, soilIndex: int, updates: dict
|
|
|
|
|
|
) -> bool:
|
2025-05-28 19:48:12 +08:00
|
|
|
|
"""批量更新指定用户土地的多个字段
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户ID
|
|
|
|
|
|
soilIndex (int): 土地索引
|
|
|
|
|
|
updates (dict): 字段-新值的字典
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
bool: 如果无可更新字段则返回 False,否则更新成功返回 True
|
|
|
|
|
|
"""
|
2025-06-06 10:56:22 +08:00
|
|
|
|
# 允许更新的列白名单
|
2025-05-28 19:48:12 +08:00
|
|
|
|
allowedFields = {
|
2025-06-06 10:56:22 +08:00
|
|
|
|
"plantName",
|
|
|
|
|
|
"plantTime",
|
|
|
|
|
|
"matureTime",
|
|
|
|
|
|
"soilLevel",
|
|
|
|
|
|
"wiltStatus",
|
|
|
|
|
|
"fertilizerStatus",
|
|
|
|
|
|
"bugStatus",
|
|
|
|
|
|
"weedStatus",
|
|
|
|
|
|
"waterStatus",
|
|
|
|
|
|
"harvestCount",
|
2025-05-28 19:48:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
setClauses = []
|
|
|
|
|
|
values = []
|
|
|
|
|
|
for field, value in updates.items():
|
|
|
|
|
|
if field not in allowedFields:
|
|
|
|
|
|
continue
|
|
|
|
|
|
setClauses.append(f'"{field}" = ?')
|
|
|
|
|
|
values.append(value)
|
|
|
|
|
|
if not setClauses:
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
values.extend([uid, soilIndex])
|
2025-06-06 10:56:22 +08:00
|
|
|
|
sql = f"UPDATE userSoil SET {', '.join(setClauses)} WHERE uid = ? AND soilIndex = ?"
|
2025-05-28 19:48:12 +08:00
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
async with cls._transaction():
|
|
|
|
|
|
await cls.m_pDB.execute(sql, tuple(values))
|
|
|
|
|
|
return True
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"批量更新土地字段失败: {e}")
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
2025-04-28 19:27:16 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def deleteUserSoil(cls, uid: str, soilIndex: int):
|
|
|
|
|
|
"""删除指定用户的土地记录
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户ID
|
|
|
|
|
|
soilIndex (int): 土地索引
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
None
|
|
|
|
|
|
"""
|
|
|
|
|
|
async with cls._transaction():
|
|
|
|
|
|
await cls.m_pDB.execute(
|
2025-04-29 18:11:09 +08:00
|
|
|
|
"DELETE FROM userSoil WHERE uid = ? AND soilIndex = ?", (uid, soilIndex)
|
2025-04-28 19:27:16 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
2025-04-29 18:11:09 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def _deleteUserSoil(cls, uid: str, soilIndex: int):
|
|
|
|
|
|
"""删除指定用户的土地记录
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户ID
|
|
|
|
|
|
soilIndex (int): 土地索引
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
None
|
|
|
|
|
|
"""
|
|
|
|
|
|
await cls.m_pDB.execute(
|
|
|
|
|
|
"DELETE FROM userSoil WHERE uid = ? AND soilIndex = ?", (uid, soilIndex)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2025-04-28 19:27:16 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def isSoilPlanted(cls, uid: str, soilIndex: int) -> bool:
|
|
|
|
|
|
"""判断指定用户的指定土地是否已种植
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户ID
|
|
|
|
|
|
soilIndex (int): 土地索引
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
bool: 如果 plantName 不为空且 plantTime 大于 0,则视为已种植,返回 True;否则 False
|
|
|
|
|
|
"""
|
|
|
|
|
|
soilInfo = await cls.getUserSoil(uid, soilIndex)
|
|
|
|
|
|
if not soilInfo:
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
return bool(soilInfo.get("plantName")) and soilInfo.get("plantTime", 0) > 0
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def sowingByPlantName(cls, uid: str, soilIndex: int, plantName: str) -> bool:
|
|
|
|
|
|
"""播种指定作物到用户土地区
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
uid (str): 用户ID
|
|
|
|
|
|
soilIndex (int): 土地区索引
|
|
|
|
|
|
plantName (str): 植物名
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
bool: 播种成功返回 True,否则返回 False
|
|
|
|
|
|
"""
|
2025-06-06 10:56:22 +08:00
|
|
|
|
# 校验土地区是否已种植
|
2025-06-29 01:45:24 +08:00
|
|
|
|
soilInfo = await cls.getUserSoil(uid, soilIndex)
|
|
|
|
|
|
if not soilInfo:
|
2025-04-28 19:27:16 +08:00
|
|
|
|
return False
|
|
|
|
|
|
|
2025-06-06 10:56:22 +08:00
|
|
|
|
# 获取植物配置
|
2025-05-08 17:56:45 +08:00
|
|
|
|
plantCfg = await g_pDBService.plant.getPlantByName(plantName)
|
2025-04-28 19:27:16 +08:00
|
|
|
|
if not plantCfg:
|
|
|
|
|
|
logger.error(f"未知植物: {plantName}")
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
2025-05-27 18:15:11 +08:00
|
|
|
|
nowTs = int(g_pToolManager.dateTime().now().timestamp())
|
2025-06-29 01:45:24 +08:00
|
|
|
|
|
|
|
|
|
|
time = int(plantCfg.get("time", 0))
|
|
|
|
|
|
percent = await cls.getSoilLevelTime(soilInfo.get("soilLevel", 0))
|
|
|
|
|
|
|
|
|
|
|
|
# 处理土地等级带来的时间缩短
|
|
|
|
|
|
time = time * (100 + percent) // 100
|
|
|
|
|
|
|
|
|
|
|
|
matureTs = nowTs + time * 3600
|
2025-04-28 19:27:16 +08:00
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
async with cls._transaction():
|
2025-06-29 01:45:24 +08:00
|
|
|
|
prev = soilInfo or {}
|
2025-04-29 18:11:09 +08:00
|
|
|
|
await cls._deleteUserSoil(uid, soilIndex)
|
|
|
|
|
|
await cls._insertUserSoil(
|
|
|
|
|
|
{
|
|
|
|
|
|
"uid": uid,
|
|
|
|
|
|
"soilIndex": soilIndex,
|
|
|
|
|
|
"plantName": plantName,
|
|
|
|
|
|
"plantTime": nowTs,
|
|
|
|
|
|
"matureTime": matureTs,
|
|
|
|
|
|
"soilLevel": prev.get("soilLevel", 0),
|
|
|
|
|
|
"wiltStatus": prev.get("wiltStatus", 0),
|
|
|
|
|
|
"fertilizerStatus": prev.get("fertilizerStatus", 0),
|
|
|
|
|
|
"bugStatus": prev.get("bugStatus", 0),
|
|
|
|
|
|
"weedStatus": prev.get("weedStatus", 0),
|
|
|
|
|
|
"waterStatus": prev.get("waterStatus", 0),
|
2025-06-06 10:56:22 +08:00
|
|
|
|
"harvestCount": 0,
|
2025-04-29 18:11:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
)
|
2025-04-28 19:27:16 +08:00
|
|
|
|
return True
|
|
|
|
|
|
except Exception as e:
|
2025-06-06 10:56:22 +08:00
|
|
|
|
logger.error("播种失败!", e=e)
|
2025-04-28 19:27:16 +08:00
|
|
|
|
return False
|
2025-05-12 17:28:33 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def getUserSoilStatus(cls, uid: str, soilIndex: int) -> str:
|
|
|
|
|
|
status = []
|
|
|
|
|
|
soilInfo = await g_pDBService.userSoil.getUserSoil(uid, soilIndex)
|
|
|
|
|
|
|
|
|
|
|
|
if not soilInfo:
|
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
if soilInfo.get("wiltStatus", 0) == 1:
|
|
|
|
|
|
return "枯萎"
|
|
|
|
|
|
|
|
|
|
|
|
if soilInfo.get("fertilizerStatus", 0) == 1:
|
|
|
|
|
|
status.append("施肥")
|
|
|
|
|
|
elif soilInfo.get("fertilizerStatus", 0) == 2:
|
|
|
|
|
|
status.append("增肥")
|
|
|
|
|
|
|
|
|
|
|
|
if soilInfo.get("bugStatus", 0) == 1:
|
|
|
|
|
|
status.append("虫害")
|
|
|
|
|
|
|
|
|
|
|
|
if soilInfo.get("weedStatus", 0) == 1:
|
|
|
|
|
|
status.append("杂草")
|
|
|
|
|
|
|
|
|
|
|
|
if soilInfo.get("waterStatus", 0) == 1:
|
|
|
|
|
|
status.append("缺水")
|
|
|
|
|
|
|
|
|
|
|
|
return ",".join(status)
|
2025-06-29 01:45:24 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def getSoilLevel(cls, level: int) -> str:
|
|
|
|
|
|
"""获取土地等级英文文本
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
level (int): 土地等级
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
str:
|
|
|
|
|
|
"""
|
|
|
|
|
|
if level == 1:
|
|
|
|
|
|
return "red"
|
|
|
|
|
|
elif level == 2:
|
|
|
|
|
|
return "black"
|
|
|
|
|
|
elif level == 3:
|
|
|
|
|
|
return "gold"
|
|
|
|
|
|
|
|
|
|
|
|
return "default"
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def getSoilLevelText(cls, level: int) -> str:
|
|
|
|
|
|
"""获取土地等级中文文本
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
level (int): 土地等级
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
str:
|
|
|
|
|
|
"""
|
|
|
|
|
|
if level == 1:
|
|
|
|
|
|
return "红土地"
|
|
|
|
|
|
elif level == 2:
|
|
|
|
|
|
return "黑土地"
|
|
|
|
|
|
elif level == 3:
|
|
|
|
|
|
return "金土地"
|
|
|
|
|
|
|
|
|
|
|
|
return "草土地"
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def getSoilLevelHarvestNumber(cls, level: int) -> int:
|
|
|
|
|
|
"""获取土地等级收获数量增加比例
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
level (int): 土地等级
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
int:
|
|
|
|
|
|
"""
|
|
|
|
|
|
if level == 2:
|
|
|
|
|
|
return 20
|
|
|
|
|
|
elif level == 3:
|
|
|
|
|
|
return 28
|
|
|
|
|
|
|
|
|
|
|
|
return 10
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def getSoilLevelHarvestExp(cls, level: int) -> int:
|
|
|
|
|
|
"""获取土地等级收获经验增加比例
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
level (int): 土地等级
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
int:
|
|
|
|
|
|
"""
|
|
|
|
|
|
if level == 3:
|
|
|
|
|
|
return 28
|
|
|
|
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def getSoilLevelTime(cls, level: int) -> int:
|
|
|
|
|
|
"""获取土地等级播种减少时间消耗
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
level (int): 土地等级
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
int:
|
|
|
|
|
|
"""
|
|
|
|
|
|
if level == 2:
|
|
|
|
|
|
return 20
|
|
|
|
|
|
elif level == 3:
|
|
|
|
|
|
return 20
|
|
|
|
|
|
|
|
|
|
|
|
return 0
|