Files
main_plugin_farm/core/farm.py
T

892 lines
30 KiB
Python
Raw Normal View History

2025-04-10 18:25:20 +08:00
import math
2025-03-21 18:14:50 +08:00
import random
import re
2025-03-20 00:45:05 +08:00
2025-04-08 19:00:17 +08:00
from zhenxun.configs.config import Config
2025-03-21 00:25:20 +08:00
from zhenxun.models.user_console import UserConsole
from zhenxun.services.log import logger
2025-03-21 00:25:20 +08:00
from zhenxun.utils.enum import GoldHandle
2025-03-19 18:00:50 +08:00
from zhenxun.utils.image_utils import ImageTemplate
2025-10-20 23:24:33 +08:00
from ..core.dbService import g_pDBService
2025-11-30 16:45:13 +08:00
from ..event import g_pEventManager
from ..utils import config, getJsonManager, getToolManager
class CFarmManager:
2025-03-21 00:25:20 +08:00
@classmethod
async def buyPointByUid(cls, uid: str, num: int) -> str:
if num <= 0:
return "你是怎么做到购买不是正数的农场币的"
user = await UserConsole.get_user(uid)
2025-04-10 18:25:20 +08:00
pro = float(Config.get_config("zhenxun_plugin_farm", "兑换倍数"))
tax = float(Config.get_config("zhenxun_plugin_farm", "手续费"))
2025-03-21 00:25:20 +08:00
2025-06-06 10:56:22 +08:00
# 计算手续费
2025-04-10 18:25:20 +08:00
fee = math.floor(num * tax)
2025-06-06 10:56:22 +08:00
# 实际扣费金额
2025-04-10 18:25:20 +08:00
deduction = num + fee
2025-04-08 19:00:17 +08:00
2025-04-10 18:25:20 +08:00
if user.gold < deduction:
return f"你的金币不足或不足承担手续费。当前手续费为{fee}"
2025-04-08 19:00:17 +08:00
2025-06-06 10:56:22 +08:00
await UserConsole.reduce_gold(
2025-10-20 23:24:33 +08:00
uid,
num,
GoldHandle.PLUGIN, # type: ignore
"zhenxun_plugin_farm",
2025-06-29 01:45:24 +08:00
)
2025-06-06 10:56:22 +08:00
await UserConsole.reduce_gold(
2025-10-20 23:24:33 +08:00
uid,
fee,
GoldHandle.PLUGIN, # type: ignore
"zhenxun_plugin_farm",
)
2025-04-10 18:25:20 +08:00
point = num * pro
2025-11-30 16:45:13 +08:00
player = await getToolManager().getPlayerByUid(uid)
2025-10-20 23:24:33 +08:00
if not player:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["basic"]["error"]
2025-03-21 00:25:20 +08:00
await player.addPoint("point", int(point))
2025-03-21 00:25:20 +08:00
return f"充值{point}农场币成功,手续费{tax}金币,当前农场币:{player.user.get('point', 0)}"
2025-03-20 18:06:38 +08:00
@classmethod
async def getUserSeedByUid(cls, uid: str) -> bytes:
2025-04-22 19:42:09 +08:00
"""获取用户种子仓库"""
dataList = []
columnNames = [
2025-03-19 18:00:50 +08:00
"-",
"种子名称",
2025-03-20 00:45:05 +08:00
"数量",
2025-03-19 18:00:50 +08:00
"收获经验",
"收获数量",
2025-03-21 00:25:20 +08:00
"成熟时间(小时)",
2025-03-19 18:00:50 +08:00
"收获次数",
2025-06-06 10:56:22 +08:00
"是否可以上架交易行",
2025-03-19 18:00:50 +08:00
]
2025-06-06 10:56:22 +08:00
# 从数据库获取结构化数据
2025-04-28 19:27:16 +08:00
seedRecords = await g_pDBService.userSeed.getUserSeedByUid(uid) or {}
2025-03-19 18:00:50 +08:00
2025-04-22 19:42:09 +08:00
if not seedRecords:
2025-03-19 18:00:50 +08:00
result = await ImageTemplate.table_page(
"种子仓库",
2025-03-20 18:06:38 +08:00
"播种示例:@小真寻 播种 大白菜 [数量]",
2025-04-22 19:42:09 +08:00
columnNames,
dataList,
2025-03-19 18:00:50 +08:00
)
return result.pic2bytes()
2025-04-22 19:42:09 +08:00
for seedName, count in seedRecords.items():
try:
2025-05-08 17:56:45 +08:00
plantInfo = await g_pDBService.plant.getPlantByName(seedName)
if not plantInfo:
continue
2025-11-30 16:45:13 +08:00
iconPath = config.g_sResourcePath / f"plant/{seedName}/icon.png"
2025-04-22 19:42:09 +08:00
icon = (iconPath, 33, 33) if iconPath.exists() else ""
2025-06-06 10:56:22 +08:00
sellable = "可以" if plantInfo["sell"] else "不可以"
dataList.append(
[
icon,
seedName,
count,
plantInfo["experience"],
plantInfo["harvest"],
plantInfo["time"],
plantInfo["crop"],
sellable,
]
)
2025-04-22 19:42:09 +08:00
except KeyError:
continue
2025-03-19 18:00:50 +08:00
result = await ImageTemplate.table_page(
2025-03-20 18:06:38 +08:00
"种子仓库",
"播种示例:@小真寻 播种 大白菜 [数量]",
2025-04-22 19:42:09 +08:00
columnNames,
dataList,
2025-03-19 18:00:50 +08:00
)
return result.pic2bytes()
2025-03-20 00:45:05 +08:00
@classmethod
2025-03-20 18:06:38 +08:00
async def sowing(cls, uid: str, name: str, num: int = -1) -> str:
2025-03-20 00:45:05 +08:00
"""播种
Args:
uid (str): 用户Uid
name (str): 播种种子名称
num (int, optional): 播种数量
Returns:
2025-04-22 19:42:09 +08:00
str: 返回结果
2025-03-20 00:45:05 +08:00
"""
2025-04-22 19:42:09 +08:00
try:
2025-06-06 10:56:22 +08:00
# 获取用户的种子数量
2025-04-28 19:27:16 +08:00
count = await g_pDBService.userSeed.getUserSeedByName(uid, name)
2025-04-22 19:42:09 +08:00
if count is None:
2025-06-06 10:56:22 +08:00
count = 0 # 如果返回 None,则视为没有种子
2025-04-22 19:42:09 +08:00
if count <= 0:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["sowing"]["noSeed"].format(name=name)
2025-04-22 19:42:09 +08:00
2025-06-06 10:56:22 +08:00
# 如果播种数量超过仓库种子数量
2025-04-22 19:42:09 +08:00
if count < num and num != -1:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["sowing"]["noNum"].format(
name=name, num=count
)
2025-04-22 19:42:09 +08:00
2025-06-06 10:56:22 +08:00
# 获取用户土地数量
2025-11-30 16:45:13 +08:00
player = await getToolManager().getPlayerByUid(uid)
2025-10-20 23:24:33 +08:00
if not player:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["basic"]["error"]
2025-10-20 23:24:33 +08:00
soilNumber = player.user.get("soil", 3)
2025-04-22 19:42:09 +08:00
2025-06-06 10:56:22 +08:00
# 如果播种数量为 -1,表示播种所有可播种的土地
2025-04-22 19:42:09 +08:00
if num == -1:
num = count
2025-06-06 10:56:22 +08:00
# 发送播种前信号
2025-06-29 01:45:24 +08:00
await g_pEventManager.m_beforePlant.emit(uid=uid, name=name, num=num) # type: ignore
2025-04-28 19:27:16 +08:00
2025-06-06 10:56:22 +08:00
# 记录是否成功播种
2025-04-22 19:42:09 +08:00
successCount = 0
for i in range(1, soilNumber + 1):
if count > 0 and num > 0:
2025-06-06 10:56:22 +08:00
success = await g_pDBService.userSoil.sowingByPlantName(
uid, i, name
)
2025-03-20 18:06:38 +08:00
if success:
2025-06-06 10:56:22 +08:00
# 更新种子数量
2025-03-20 18:06:38 +08:00
num -= 1
2025-04-10 18:25:20 +08:00
count -= 1
2025-06-06 10:56:22 +08:00
# 记录种子消耗数量
2025-04-22 19:42:09 +08:00
successCount += 1
2025-03-20 18:06:38 +08:00
2025-06-06 10:56:22 +08:00
# 发送播种后信号
2025-06-29 01:45:24 +08:00
await g_pEventManager.m_afterPlant.emit( # type: ignore
2025-06-06 10:56:22 +08:00
uid=uid, name=name, soilIndex=i
)
2025-03-20 18:06:38 +08:00
2025-06-06 10:56:22 +08:00
# 确保用户仓库数量更新
2025-04-22 19:42:09 +08:00
if successCount > 0:
2025-04-28 19:27:16 +08:00
await g_pDBService.userSeed.updateUserSeedByName(uid, name, count)
2025-06-06 10:56:22 +08:00
# 根据播种结果给出反馈
2025-04-22 19:42:09 +08:00
if num == 0:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["sowing"]["success"].format(
name=name, num=count
)
2025-04-22 19:42:09 +08:00
else:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["sowing"]["success2"].format(
name=name, num=count
)
2025-03-20 18:06:38 +08:00
2025-04-22 19:42:09 +08:00
except Exception as e:
2025-06-06 10:56:22 +08:00
logger.warning("播种操作失败!", e=e)
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["sowing"]["error"]
2025-03-20 18:06:38 +08:00
@classmethod
async def harvest(cls, uid: str) -> str:
"""收获作物
Args:
uid (str): 用户Uid
Returns:
str: 返回
"""
2025-04-28 19:27:16 +08:00
try:
2025-06-29 01:45:24 +08:00
await g_pEventManager.m_beforeHarvest.emit(uid=uid) # type: ignore
2025-03-20 18:06:38 +08:00
2025-11-30 16:45:13 +08:00
player = await getToolManager().getPlayerByUid(uid)
2025-10-20 23:24:33 +08:00
if not player:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["basic"]["error"]
2025-10-20 23:24:33 +08:00
soilNumber = player.user.get("soil", 3)
2025-03-20 18:06:38 +08:00
2025-06-06 10:56:22 +08:00
harvestRecords = [] # 收获日志记录
experience = 0 # 总经验值
harvestCount = 0 # 成功收获数量
2025-03-20 18:06:38 +08:00
2025-04-28 19:27:16 +08:00
for i in range(1, soilNumber + 1):
soilInfo = await g_pDBService.userSoil.getUserSoil(uid, i)
if not soilInfo:
continue
2025-03-20 18:06:38 +08:00
2025-06-30 03:43:44 +08:00
# 如果没有种植
if soilInfo.get("isSoilPlanted", 1) == 0:
2025-06-30 03:43:44 +08:00
continue
2025-06-29 01:45:24 +08:00
level = soilInfo.get("soilLevel", 0)
2025-06-06 10:56:22 +08:00
# 如果是枯萎状态
2025-04-28 19:27:16 +08:00
if soilInfo.get("wiltStatus", 1) == 1:
continue
2025-03-20 18:06:38 +08:00
2025-06-06 10:56:22 +08:00
plantInfo = await g_pDBService.plant.getPlantByName(
soilInfo["plantName"]
)
2025-05-08 17:56:45 +08:00
if not plantInfo:
continue
2025-11-30 16:45:13 +08:00
currentTime = getToolManager().dateTime().now()
matureTime = (
getToolManager()
.dateTime()
.fromtimestamp(int(soilInfo["matureTime"]))
2025-06-06 10:56:22 +08:00
)
2025-03-21 18:14:50 +08:00
2025-04-28 19:27:16 +08:00
if currentTime >= matureTime:
2025-06-06 10:56:22 +08:00
number = plantInfo["harvest"]
2025-03-21 18:14:50 +08:00
2025-06-06 10:56:22 +08:00
# 处理偷菜扣除数量
2025-04-29 18:11:09 +08:00
stealNum = await g_pDBService.userSteal.getTotalStolenCount(uid, i)
2025-04-28 19:27:16 +08:00
number -= stealNum
2025-06-29 01:45:24 +08:00
# 处理土地等级带来的数量增长 向下取整
percent = await g_pDBService.userSoil.getSoilLevelHarvestNumber(
level
)
2025-06-29 21:31:09 +08:00
number = math.floor(number * (100 + percent) // 100)
2025-06-29 01:45:24 +08:00
2025-04-28 19:27:16 +08:00
if number <= 0:
continue
2025-04-28 19:27:16 +08:00
harvestCount += 1
2025-06-06 10:56:22 +08:00
experience += plantInfo["experience"]
2025-06-29 01:45:24 +08:00
# 处理土地等级带来的经验增长 向下取整
percent = await g_pDBService.userSoil.getSoilLevelHarvestExp(level)
2025-06-29 21:31:09 +08:00
experience = math.floor(experience * (100 + percent) // 100)
2025-06-29 01:45:24 +08:00
2025-06-06 10:56:22 +08:00
harvestRecords.append(
2025-11-30 16:45:13 +08:00
config.g_sTranslation["harvest"]["append"].format(
2025-06-06 10:56:22 +08:00
name=soilInfo["plantName"],
num=number,
2025-06-29 21:31:09 +08:00
exp=plantInfo["experience"],
2025-06-06 10:56:22 +08:00
)
)
2025-03-20 18:06:38 +08:00
2025-06-06 10:56:22 +08:00
await g_pDBService.userPlant.addUserPlantByUid(
uid, soilInfo["plantName"], number
)
2025-05-09 18:20:00 +08:00
# 统计收获次数
try:
# 处理星级前缀(只在前两字为 一星/二星/三星/四星/五星 时去掉前缀)
plant_name = soilInfo["plantName"]
m = re.match(r"^(?:一星|二星|三星|四星|五星)", plant_name)
if m:
plant_name = plant_name[len(m.group(0)) :]
await g_pDBService.userPlantCount.addUserPlantCountByUid(
uid, plant_name
)
except Exception:
# 忽略统计异常,避免影响主流程
pass
2025-06-06 10:56:22 +08:00
# 如果到达收获次数上限
if soilInfo["harvestCount"] + 1 >= plantInfo["crop"]:
await g_pDBService.userSoil.updateUserSoil(
uid, i, "wiltStatus", 1
)
2025-05-09 18:20:00 +08:00
else:
2025-06-06 10:56:22 +08:00
phase = await g_pDBService.plant.getPlantPhaseByName(
soilInfo["plantName"]
)
2025-05-28 19:48:12 +08:00
2025-06-06 10:56:22 +08:00
ts, hc = (
int(currentTime.timestamp()),
soilInfo["harvestCount"] + 1,
)
2025-05-28 19:48:12 +08:00
p1, p2, *rest = phase
2025-05-09 18:20:00 +08:00
2025-06-06 10:56:22 +08:00
await g_pDBService.userSoil.updateUserSoilFields(
uid,
i,
2025-05-28 19:48:12 +08:00
{
"harvestCount": hc,
2025-06-06 10:56:22 +08:00
"plantTime": ts - p1 - p2,
"matureTime": ts + p2 + sum(rest),
},
2025-05-28 19:48:12 +08:00
)
2025-03-21 00:25:20 +08:00
2025-06-29 01:45:24 +08:00
await g_pEventManager.m_afterHarvest.emit( # type: ignore
2025-06-06 10:56:22 +08:00
uid=uid, name=soilInfo["plantName"], num=number, soilIndex=i
)
2025-04-28 19:27:16 +08:00
if experience > 0:
2025-10-20 23:24:33 +08:00
exp = player.user.get("exp", 0)
await player.addExp(exp + experience)
2025-06-06 10:56:22 +08:00
harvestRecords.append(
2025-11-30 16:45:13 +08:00
config.g_sTranslation["harvest"]["exp"].format(
2025-06-06 10:56:22 +08:00
exp=experience,
)
)
2025-04-28 19:27:16 +08:00
if harvestCount <= 0:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["harvest"]["no"]
2025-04-28 19:27:16 +08:00
else:
return "\n".join(harvestRecords)
except Exception as e:
2025-06-06 10:56:22 +08:00
logger.warning("收获操作失败!", e=e)
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["harvest"]["error"]
2025-03-20 18:06:38 +08:00
2025-03-21 00:25:20 +08:00
@classmethod
async def eradicate(cls, uid: str) -> str:
"""铲除作物
TODO 缺少随意铲除作物 目前只能铲除荒废作物
Args:
uid (str): 用户Uid
Returns:
str: 返回
"""
2025-11-30 16:45:13 +08:00
player = await getToolManager().getPlayerByUid(uid)
2025-10-20 23:24:33 +08:00
if not player:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["basic"]["error"]
2025-10-20 23:24:33 +08:00
soilNumber = player.user.get("soil", 3)
2025-03-21 00:25:20 +08:00
2025-06-29 01:45:24 +08:00
await g_pEventManager.m_beforeEradicate.emit(uid=uid) # type: ignore
2025-03-21 00:25:20 +08:00
experience = 0
2025-04-28 19:27:16 +08:00
for i in range(1, soilNumber + 1):
2025-06-06 10:56:22 +08:00
soilInfo = await g_pDBService.userSoil.getUserSoil(uid, i)
if not soilInfo:
continue
2025-03-21 00:25:20 +08:00
2025-06-30 03:43:44 +08:00
# 如果没有种植
if soilInfo.get("isSoilPlanted", 1) == 0:
2025-06-30 03:43:44 +08:00
continue
2025-06-06 10:56:22 +08:00
# 如果不是枯萎状态
if soilInfo.get("wiltStatus", 0) == 0:
continue
2025-04-28 19:27:16 +08:00
2025-06-06 10:56:22 +08:00
experience += 3
2025-04-28 19:27:16 +08:00
2025-11-30 16:45:13 +08:00
if config.g_bIsDebug:
2025-06-06 10:56:22 +08:00
experience += 999
2025-05-29 18:20:03 +08:00
2025-06-29 21:31:09 +08:00
# 更新数据库操作
2025-06-06 10:56:22 +08:00
await g_pDBService.userSoil.deleteUserSoil(uid, i)
2025-04-28 19:27:16 +08:00
2025-06-29 21:31:09 +08:00
await g_pDBService.userSoil.updateUserSoilFields(
uid,
i,
{
"plantName": "",
"plantTime": 0,
"matureTime": 0,
"wiltStatus": 0,
2025-06-30 03:43:44 +08:00
"isSoilPlanted": 0,
2025-06-29 21:31:09 +08:00
},
)
2025-06-06 10:56:22 +08:00
# 铲除作物会将偷菜记录清空
await g_pDBService.userSteal.deleteStealRecord(uid, i)
2025-05-09 18:20:00 +08:00
2025-06-29 01:45:24 +08:00
await g_pEventManager.m_afterEradicate.emit(uid=uid, soilIndex=i) # type: ignore
2025-03-21 00:25:20 +08:00
if experience > 0:
2025-10-20 23:24:33 +08:00
exp = player.user.get("exp", 0)
await player.addExp(exp + experience)
2025-03-21 00:25:20 +08:00
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["eradicate"]["success"].format(exp=experience)
2025-03-21 00:25:20 +08:00
else:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["eradicate"]["error"]
2025-03-21 00:25:20 +08:00
2025-03-20 18:06:38 +08:00
@classmethod
async def getUserPlantByUid(cls, uid: str) -> bytes:
"""获取用户作物仓库
Args:
uid (str): 用户Uid
Returns:
bytes: 返回图片
"""
data_list = []
2025-08-06 17:51:26 +08:00
column_name = [
"-",
"作物名称",
"数量",
"单价",
"总价",
"是否上锁",
"是否可以上架交易行",
]
2025-03-20 18:06:38 +08:00
2025-04-28 19:27:16 +08:00
plant = await g_pDBService.userPlant.getUserPlantByUid(uid)
2025-03-20 18:06:38 +08:00
2025-04-27 10:52:28 +08:00
if plant is None:
2025-03-20 18:06:38 +08:00
result = await ImageTemplate.table_page(
"作物仓库",
2025-04-27 17:00:58 +08:00
"出售示例:@小真寻 出售作物 大白菜 [数量]",
2025-03-20 18:06:38 +08:00
column_name,
data_list,
)
return result.pic2bytes()
sell = ""
2025-04-27 17:00:58 +08:00
for name, count in plant.items():
2025-05-08 17:56:45 +08:00
plantInfo = await g_pDBService.plant.getPlantByName(name)
if not plantInfo:
continue
2025-04-27 10:52:28 +08:00
icon = ""
2025-11-30 16:45:13 +08:00
icon_path = config.g_sResourcePath / f"plant/{name}/icon.png"
2025-04-27 10:52:28 +08:00
if icon_path.exists():
icon = (icon_path, 33, 33)
2025-06-29 01:45:24 +08:00
if plantInfo["sell"]:
2025-04-27 10:52:28 +08:00
sell = "可以"
else:
sell = "不可以"
2025-06-06 10:56:22 +08:00
number = int(count) * plantInfo["price"]
2025-08-06 17:51:26 +08:00
isLock = await g_pDBService.userPlant.checkPlantLockByName(uid, name)
if isLock:
lock = "上锁"
else:
lock = "未上锁"
data_list.append(
[icon, name, count, plantInfo["price"], number, lock, sell]
)
2025-03-20 18:06:38 +08:00
result = await ImageTemplate.table_page(
"作物仓库",
2025-04-27 17:00:58 +08:00
"出售示例:@小真寻 出售作物 大白菜 [数量]",
2025-03-20 18:06:38 +08:00
column_name,
data_list,
)
return result.pic2bytes()
2025-03-20 00:45:05 +08:00
2025-08-06 17:51:26 +08:00
@classmethod
async def lockUserPlantByUid(cls, uid: str, name: str, lock: int) -> str:
"""加/解 锁用户作物
Args:
uid (str): 用户uid
name (str): 作物名称
lock (int): 0=解锁 非0=加锁
Returns:
str: 返回
"""
# 先判断该用户仓库是否有该作物
if not await g_pDBService.userPlant.checkUserPlantByName(uid, name):
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["lockPlant"]["noPlant"]
2025-08-06 17:51:26 +08:00
# 更改加锁状态
if await g_pDBService.userPlant.lockUserPlantByName(uid, name, lock):
if lock == 0:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["lockPlant"]["unlockPlant"].format(
name=name
)
2025-08-06 17:51:26 +08:00
else:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["lockPlant"]["lockPlant"].format(name=name)
2025-08-06 17:51:26 +08:00
else:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["lockPlant"]["error"]
2025-08-06 17:51:26 +08:00
2025-03-21 00:25:20 +08:00
@classmethod
2025-03-21 18:14:50 +08:00
async def stealing(cls, uid: str, target: str) -> str:
"""偷菜
2025-03-21 00:25:20 +08:00
Args:
uid (str): 用户Uid
2025-03-21 18:14:50 +08:00
target (str): 被偷用户Uid
2025-03-21 00:25:20 +08:00
Returns:
2025-03-21 18:14:50 +08:00
str: 返回
2025-03-21 00:25:20 +08:00
"""
2025-06-06 10:56:22 +08:00
# 用户信息
2025-11-30 16:45:13 +08:00
player = await getToolManager().getPlayerByUid(uid)
2025-10-20 23:24:33 +08:00
if not player:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["basic"]["error"]
2025-03-21 18:14:50 +08:00
2025-10-20 23:24:33 +08:00
stealTime = player.user.get("stealTime", "")
stealCount = int(player.user["stealCount"])
2025-03-21 18:14:50 +08:00
2025-05-30 11:22:32 +08:00
if stealTime == "" or not stealTime:
2025-11-30 16:45:13 +08:00
stealTime = getToolManager().dateTime().date().today().strftime("%Y-%m-%d")
2025-04-28 19:27:16 +08:00
stealCount = 5
2025-06-06 10:56:22 +08:00
elif (
2025-11-30 16:45:13 +08:00
getToolManager().dateTime().date().fromisoformat(stealTime)
!= getToolManager().dateTime().date().today()
2025-06-06 10:56:22 +08:00
):
2025-11-30 16:45:13 +08:00
stealTime = getToolManager().dateTime().date().today().strftime("%Y-%m-%d")
2025-04-28 19:27:16 +08:00
stealCount = 5
2025-03-21 18:14:50 +08:00
2025-04-28 19:27:16 +08:00
if stealCount <= 0:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["stealing"]["max"]
2025-04-28 19:27:16 +08:00
2025-06-06 10:56:22 +08:00
# 获取用户解锁地块数量
soilNumber = player.user.get("soil", 3)
2025-06-06 10:56:22 +08:00
harvestRecords: list[str] = []
isStealingNumber = 0
isStealingPlant = 0
2025-03-21 18:14:50 +08:00
2025-04-28 19:27:16 +08:00
for i in range(1, soilNumber + 1):
2025-05-30 11:22:32 +08:00
soilInfo = await g_pDBService.userSoil.getUserSoil(target, i)
2025-04-28 19:27:16 +08:00
if not soilInfo:
continue
2025-03-21 18:14:50 +08:00
2025-06-30 03:43:44 +08:00
# 如果没有种植
if soilInfo.get("isSoilPlanted", 1) == 0:
2025-06-30 03:43:44 +08:00
continue
2025-06-06 10:56:22 +08:00
# 如果是枯萎状态
2025-04-28 19:27:16 +08:00
if soilInfo.get("wiltStatus", 1) == 1:
continue
2025-03-21 18:14:50 +08:00
2025-06-06 10:56:22 +08:00
# 作物信息
plantInfo = await g_pDBService.plant.getPlantByName(soilInfo["plantName"])
2025-05-08 17:56:45 +08:00
if not plantInfo:
continue
2025-11-30 16:45:13 +08:00
currentTime = getToolManager().dateTime().now()
matureTime = (
getToolManager().dateTime().fromtimestamp(int(soilInfo["matureTime"]))
2025-06-06 10:56:22 +08:00
)
if currentTime >= matureTime:
2025-06-06 10:56:22 +08:00
# 如果偷过,则跳过该土地
2025-04-28 19:27:16 +08:00
if await g_pDBService.userSteal.hasStealed(target, i, uid):
2025-06-06 10:56:22 +08:00
isStealingNumber += 1
continue
2025-06-06 10:56:22 +08:00
stealingNumber = plantInfo[
"harvest"
] - await g_pDBService.userSteal.getTotalStolenCount(target, i)
randomNumber = random.choice([1, 2])
randomNumber = min(randomNumber, stealingNumber)
2025-03-21 00:25:20 +08:00
if randomNumber > 0:
2025-06-06 10:56:22 +08:00
await g_pDBService.userPlant.addUserPlantByUid(
uid, soilInfo["plantName"], randomNumber
)
2025-03-21 00:25:20 +08:00
2025-06-06 10:56:22 +08:00
harvestRecords.append(
2025-11-30 16:45:13 +08:00
config.g_sTranslation["stealing"]["info"].format(
2025-06-06 10:56:22 +08:00
name=soilInfo["plantName"], num=randomNumber
)
)
2025-03-21 00:25:20 +08:00
isStealingPlant += 1
2025-06-06 10:56:22 +08:00
# 如果将作物偷完,就直接更新状态 并记录用户偷取过
if plantInfo["harvest"] - randomNumber + stealingNumber == 0:
# 如果作物 是最后一阶段作物且偷完 则直接枯萎
if soilInfo["harvestCount"] + 1 >= plantInfo["crop"]:
await g_pDBService.userSoil.updateUserSoil(
target, i, "wiltStatus", 1
)
2025-05-09 18:20:00 +08:00
else:
2025-06-06 10:56:22 +08:00
phase = await g_pDBService.plant.getPlantPhaseByName(
soilInfo["plantName"]
)
2025-05-28 19:48:12 +08:00
2025-06-06 10:56:22 +08:00
ts, hc = (
int(currentTime.timestamp()),
soilInfo["harvestCount"] + 1,
)
2025-05-28 19:48:12 +08:00
p1, p2, *rest = phase
2025-06-06 10:56:22 +08:00
await g_pDBService.userSoil.updateUserSoilFields(
uid,
i,
2025-05-28 19:48:12 +08:00
{
"harvestCount": hc,
2025-06-06 10:56:22 +08:00
"plantTime": ts - p1 - p2,
"matureTime": ts + p2 + sum(rest),
},
2025-05-28 19:48:12 +08:00
)
2025-05-09 18:20:00 +08:00
2025-06-06 10:56:22 +08:00
await g_pDBService.userSteal.addStealRecord(
target,
i,
uid,
randomNumber,
2025-11-30 16:45:13 +08:00
int(getToolManager().dateTime().now().timestamp()),
2025-06-06 10:56:22 +08:00
)
2025-05-09 18:20:00 +08:00
else:
2025-06-06 10:56:22 +08:00
await g_pDBService.userSteal.addStealRecord(
target,
i,
uid,
randomNumber,
2025-11-30 16:45:13 +08:00
int(getToolManager().dateTime().now().timestamp()),
2025-06-06 10:56:22 +08:00
)
2025-03-21 18:14:50 +08:00
if isStealingPlant <= 0 and isStealingNumber <= 0:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["stealing"]["noPlant"]
elif isStealingPlant <= 0 and isStealingNumber > 0:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["stealing"]["repeat"]
2025-03-21 00:25:20 +08:00
else:
2025-04-28 19:27:16 +08:00
stealCount -= 1
2025-03-21 18:14:50 +08:00
await player.updateStealCountByUid(uid, stealTime, stealCount)
2025-03-21 00:25:20 +08:00
2025-03-21 18:14:50 +08:00
return "\n".join(harvestRecords)
2025-03-21 00:25:20 +08:00
@classmethod
async def reclamationCondition(cls, uid: str) -> str:
2025-06-29 01:45:24 +08:00
"""获取开垦条件
Args:
uid (str): 用户Uid
Returns:
str: 返回条件文本信息
"""
2025-11-30 16:45:13 +08:00
jLevel = await getJsonManager().getLevel()
rec = jLevel["reclamation"]
2025-11-30 16:45:13 +08:00
player = await getToolManager().getPlayerByUid(uid)
if not player:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["basic"]["error"]
try:
if player.user["soil"] >= 30:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["reclamation"]["perfect"]
rec = rec[f"{player.user['soil'] + 1}"]
2025-06-06 10:56:22 +08:00
level = rec["level"]
point = rec["point"]
item = rec["item"]
str = ""
if len(item) == 0:
2025-11-30 16:45:13 +08:00
str = config.g_sTranslation["reclamation"]["next"].format(
2025-06-06 10:56:22 +08:00
level=level, num=point
)
else:
2025-11-30 16:45:13 +08:00
str = config.g_sTranslation["reclamation"]["next2"].format(
2025-06-06 10:56:22 +08:00
level=level, num=point, item=item
)
return str
2025-06-06 10:56:22 +08:00
except Exception:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["reclamation"]["error"]
@classmethod
async def reclamation(cls, uid: str) -> str:
2025-06-29 01:45:24 +08:00
"""开垦
Args:
uid (str): 用户Uid
Returns:
str: _description_
"""
2025-11-30 16:45:13 +08:00
player = await getToolManager().getPlayerByUid(uid)
if not player:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["basic"]["error"]
level = await player.getUserLevel()
2025-11-30 16:45:13 +08:00
jsonLevel = await getJsonManager().getLevel()
rec = jsonLevel["reclamation"]
try:
if player.user["soil"] >= 30:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["reclamation"]["perfect"]
rec = rec[f"{player.user['soil'] + 1}"]
2025-06-06 10:56:22 +08:00
levelFileter = rec["level"]
point = rec["point"]
2025-06-29 01:45:24 +08:00
# item = rec["item"]
if level[0] < levelFileter:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["reclamation"]["nextLevel"].format(
2025-06-06 10:56:22 +08:00
level=level[0], next=levelFileter
)
if player.user["point"] < point:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["reclamation"]["noNum"].format(num=point)
2025-06-06 10:56:22 +08:00
# TODO 缺少判断消耗的item
await player.subPoint("point", point)
await player.updateField("soil", player.user["soil"] + 1)
2025-06-06 10:56:22 +08:00
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["reclamation"]["success"]
2025-06-06 10:56:22 +08:00
except Exception:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["reclamation"]["error1"]
2025-06-29 01:45:24 +08:00
@classmethod
async def soilUpgradeCondition(cls, uid: str, soilIndex: int) -> str:
"""获取土地升级条件
Args:
uid (str): 用户Uid
soilIndex (str): 土地索引
Returns:
str: 返回土地升级条件
"""
soilInfo = await g_pDBService.userSoil.getUserSoil(uid, soilIndex)
if not soilInfo:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["soilInfo"]["error"]
2025-06-29 01:45:24 +08:00
soilLevel = soilInfo.get("soilLevel", 0) + 1
2025-11-30 16:45:13 +08:00
if soilLevel >= config.g_iSoilLevelMax:
return config.g_sTranslation["soilInfo"]["error1"]
2025-06-29 01:45:24 +08:00
# 获取用户当前土地 的下一级土地 数量
countSoil = await g_pDBService.userSoil.countSoilByLevel(uid, soilLevel)
# 获取升级所需
soilLevelText = await g_pDBService.userSoil.getSoilLevel(soilLevel)
2025-11-30 16:45:13 +08:00
jSoil = await getJsonManager().getSoil()
fileter = jSoil["upgrade"][soilLevelText][countSoil]
2025-06-29 01:45:24 +08:00
2025-06-29 21:31:09 +08:00
nextLevel = await g_pDBService.userSoil.getSoilLevelText(soilLevel)
lines = ["将土地升级至:" + nextLevel + "。", "所需:"]
2025-06-29 01:45:24 +08:00
fields = [
("level", "等级"),
("point", "金币"),
("vipPoint", "点券"),
]
for key, label in fields:
value = fileter.get(key, 0)
if value > 0:
lines.append(f"{label}:{value}")
items = fileter.get("item", {})
for name, qty in items.items():
if qty:
lines.append(f"{name}:{qty}")
lines.append("回复“是”将执行升级")
return "\n".join(lines)
@classmethod
async def soilUpgrade(cls, uid: str, soilIndex: int) -> str:
"""土地升级
Args:
uid (str): 用户Uid
soilIndex (int): 土地索引
Returns:
str:
"""
2025-11-30 16:45:13 +08:00
player = await getToolManager().getPlayerByUid(uid)
if not player:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["basic"]["error"]
2025-06-29 01:45:24 +08:00
soilInfo = await g_pDBService.userSoil.getUserSoil(uid, soilIndex)
2025-06-29 01:45:24 +08:00
if not soilInfo:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["soilInfo"]["error"]
2025-06-29 01:45:24 +08:00
soilLevel = soilInfo.get("soilLevel", 0) + 1
2025-11-30 16:45:13 +08:00
if soilLevel >= config.g_iSoilLevelMax:
return config.g_sTranslation["soilInfo"]["error1"]
2025-06-29 01:45:24 +08:00
countSoil = await g_pDBService.userSoil.countSoilByLevel(uid, soilLevel)
soilLevelText = await g_pDBService.userSoil.getSoilLevel(soilLevel)
2025-11-30 16:45:13 +08:00
soil = await getJsonManager().getSoil()
fileter = soil["upgrade"][soilLevelText][countSoil]
2025-06-29 01:45:24 +08:00
getters = {
"level": (await player.getUserLevel())[0],
"point": player.user.get("point", 0),
"vipPoint": player.user.get("vipPoint", 0),
2025-06-29 01:45:24 +08:00
}
requirements = {
"level": "等级",
"point": "金币",
"vipPoint": "点券",
}
for key, val in getters.items():
need = fileter.get(key, 0)
if val < need:
return f"你的{requirements[key]}不够哦~"
# 缺少item判断
# 更新数据库字段
await g_pDBService.userSoil.updateUserSoil(
uid, soilIndex, "soilLevel", soilLevel
)
# 如果有作物的话直接成熟
await g_pDBService.userSoil.matureNow(uid, soilIndex)
# 更新数据库字段
await player.subPoint("point", fileter.get("point", 0))
await player.subPoint("vipPoint", fileter.get("vipPoint", 0))
2025-06-29 01:45:24 +08:00
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["soilInfo"]["success"].format(
2025-06-29 01:45:24 +08:00
name=await g_pDBService.userSoil.getSoilLevelText(soilLevel),
2025-11-30 16:45:13 +08:00
text=config.g_sTranslation["soilInfo"][soilLevelText],
2025-06-29 01:45:24 +08:00
)
@classmethod
async def pointToVipPointByUid(cls, uid: str, num: int) -> str:
"""点券兑换
Args:
uid (str): 用户Uid
num (int): 兑换点券数量
Returns:
str: 返回结果
兑换比例在配置文件中配置
目前配置文件中默认是20倍
100点券需要20000农场币
赠送点券规则:
小于2000点券:0
2000-5000点券:100
5000-50000点券:280
大于50000点券:3000
"""
if num < 100:
return "点券兑换数量必须大于等于100"
pro = int(Config.get_config("zhenxun_plugin_farm", "点券兑换倍数"))
pro *= num
2025-11-30 16:45:13 +08:00
player = await getToolManager().getPlayerByUid(uid)
if not player:
2025-11-30 16:45:13 +08:00
return config.g_sTranslation["basic"]["error"]
point = player.user.get("point", 0)
if point < pro:
return f"你的农场币不足,当前农场币为{point},兑换还需要{pro - point}农场币"
giftPoints: int
if num < 2000:
giftPoints = 0
elif num < 5000:
giftPoints = 100
elif num < 50000:
giftPoints = 280
else:
giftPoints = 3000
number = num + giftPoints
await player.addPoint("vipPoint", number)
await player.subPoint("point", pro)
return f"兑换{num}点券成功,当前点券:{number},赠送点券:{giftPoints},当前农场币:{point}"