✨ 添加签到功能
🐛 修复默认使用格林威治时间而不是北京时间的BUG
This commit is contained in:
parent
c131692b19
commit
afa2259ad8
@ -1,7 +1,16 @@
|
|||||||
|
<div align="center">
|
||||||
|
|
||||||
# 真寻农场(zhenxun_plugin_farm)
|
# 真寻农场(zhenxun_plugin_farm)
|
||||||
|
<p align="center">
|
||||||
|
<a href="./LICENSE">
|
||||||
|
<img src="https://img.shields.io/badge/license-GPL3.0-FE7D37" alt="license">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
你是说可以种地对吧🤔?
|
你是说可以种地对吧🤔?
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 如何安装
|
## 如何安装
|
||||||
|
|||||||
@ -82,8 +82,6 @@ async def start():
|
|||||||
|
|
||||||
await g_pDBService.init()
|
await g_pDBService.init()
|
||||||
|
|
||||||
# await g_pRequestManager.initSignInFile()
|
|
||||||
|
|
||||||
# 析构函数
|
# 析构函数
|
||||||
@driver.on_shutdown
|
@driver.on_shutdown
|
||||||
async def shutdown():
|
async def shutdown():
|
||||||
|
|||||||
54
command.py
54
command.py
@ -1,5 +1,3 @@
|
|||||||
from datetime import date, datetime, timedelta
|
|
||||||
|
|
||||||
from nonebot.adapters import Event, MessageTemplate
|
from nonebot.adapters import Event, MessageTemplate
|
||||||
from nonebot.rule import to_me
|
from nonebot.rule import to_me
|
||||||
from nonebot_plugin_alconna import (Alconna, AlconnaMatch, AlconnaQuery, Args,
|
from nonebot_plugin_alconna import (Alconna, AlconnaMatch, AlconnaQuery, Args,
|
||||||
@ -12,9 +10,12 @@ from zhenxun.configs.config import BotConfig
|
|||||||
from zhenxun.services.log import logger
|
from zhenxun.services.log import logger
|
||||||
from zhenxun.utils.message import MessageUtils
|
from zhenxun.utils.message import MessageUtils
|
||||||
|
|
||||||
|
from .config import g_bSignStatus
|
||||||
from .dbService import g_pDBService
|
from .dbService import g_pDBService
|
||||||
from .farm.farm import g_pFarmManager
|
from .farm.farm import g_pFarmManager
|
||||||
from .farm.shop import g_pShopManager
|
from .farm.shop import g_pShopManager
|
||||||
|
from .json import g_pJsonManager
|
||||||
|
from .tool import g_pToolManager
|
||||||
|
|
||||||
|
|
||||||
async def isRegisteredByUid(uid: str) -> bool:
|
async def isRegisteredByUid(uid: str) -> bool:
|
||||||
@ -136,7 +137,7 @@ diuse_farm = on_alconna(
|
|||||||
Subcommand("buy-point", Args["num?", int], help_text="购买农场币"),
|
Subcommand("buy-point", Args["num?", int], help_text="购买农场币"),
|
||||||
#Subcommand("sell-point", Args["num?", int], help_text="转换金币")
|
#Subcommand("sell-point", Args["num?", int], help_text="转换金币")
|
||||||
Subcommand("change-name", Args["name?", str], help_text="更改农场名"),
|
Subcommand("change-name", Args["name?", str], help_text="更改农场名"),
|
||||||
Subcommand("sing-in", help_text="农场签到"),
|
Subcommand("sign-in", help_text="农场签到"),
|
||||||
),
|
),
|
||||||
priority=5,
|
priority=5,
|
||||||
block=True,
|
block=True,
|
||||||
@ -168,7 +169,7 @@ async def _(session: Uninfo):
|
|||||||
|
|
||||||
info = await g_pFarmManager.drawDetailFarmByUid(uid)
|
info = await g_pFarmManager.drawDetailFarmByUid(uid)
|
||||||
|
|
||||||
await MessageUtils.alc_forward_msg([info], session.self_id, BotConfig.self_nickname).send(reply_to=True)
|
await MessageUtils.alc_forward_msg([info], session.self_id, BotConfig.self_nickname).send()
|
||||||
|
|
||||||
diuse_farm.shortcut(
|
diuse_farm.shortcut(
|
||||||
"我的农场币",
|
"我的农场币",
|
||||||
@ -446,30 +447,55 @@ async def _(session: Uninfo, name: Match[str]):
|
|||||||
else:
|
else:
|
||||||
await MessageUtils.build_message("更新用户名失败!").send(reply_to=True)
|
await MessageUtils.build_message("更新用户名失败!").send(reply_to=True)
|
||||||
|
|
||||||
reclamation = on_alconna(
|
diuse_farm.shortcut(
|
||||||
Alconna("农场签到"),
|
"农场签到",
|
||||||
priority=5,
|
command="我的农场",
|
||||||
block=True,
|
arguments=["sign-in"],
|
||||||
|
prefix=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@reclamation.handle()
|
@diuse_farm.assign("sign-in")
|
||||||
async def _(session: Uninfo):
|
async def _(session: Uninfo):
|
||||||
uid = str(session.user.id)
|
uid = str(session.user.id)
|
||||||
|
|
||||||
if await isRegisteredByUid(uid) == False:
|
if await isRegisteredByUid(uid) == False:
|
||||||
return
|
return
|
||||||
|
|
||||||
toDay = date.today()
|
#判断签到是否正常加载
|
||||||
|
if g_bSignStatus == False:
|
||||||
|
await MessageUtils.build_message("签到功能异常!").send()
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
toDay = g_pToolManager.dateTime().date().today()
|
||||||
message = ""
|
message = ""
|
||||||
status = await g_pDBService.userSign.sign(uid, toDay.strftime("%Y-%m-%d"))
|
status = await g_pDBService.userSign.sign(uid, toDay.strftime("%Y-%m-%d"))
|
||||||
|
|
||||||
if status == True:
|
#如果完成签到
|
||||||
message = "签到成功"
|
if status == 1 or status == 2:
|
||||||
|
#获取签到总天数
|
||||||
|
signDay = await g_pDBService.userSign.getUserSignCountByDate(uid, toDay.strftime("%Y-%m"))
|
||||||
|
|
||||||
|
exp, point = await g_pDBService.userSign.getUserSignRewardByDate(uid, toDay.strftime("%Y-%m-%d"))
|
||||||
|
|
||||||
img = await g_pDBService.userSign.drawSignCalendarImage(uid, toDay.year, toDay.month)
|
message += f"签到成功!累计签到天数:{signDay}\n获得经验{exp},获得金币{point}"
|
||||||
|
|
||||||
await MessageUtils.build_message(img).send()
|
reward = g_pJsonManager.m_pSign['continuou'].get(f"{signDay}", None)
|
||||||
|
|
||||||
|
if reward:
|
||||||
|
extraPoint = reward.get('point', 0)
|
||||||
|
extraExp = reward.get('exp', 0)
|
||||||
|
|
||||||
|
plant = reward.get('plant', {})
|
||||||
|
|
||||||
|
message += f"\n\n成功领取累计签到奖励:\n额外获得经验{extraExp},额外获得金币{extraPoint}"
|
||||||
|
|
||||||
|
if plant:
|
||||||
|
for key, value in plant.items():
|
||||||
|
message += f"\n获得{key}种子 * {value}"
|
||||||
|
else:
|
||||||
|
message = "签到失败!未知错误"
|
||||||
|
|
||||||
|
await MessageUtils.build_message(message).send()
|
||||||
|
|
||||||
# await MessageUtils.alc_forward_msg([info], session.self_id, BotConfig.self_nickname).send(reply_to=True)
|
# await MessageUtils.alc_forward_msg([info], session.self_id, BotConfig.self_nickname).send(reply_to=True)
|
||||||
|
|||||||
@ -10,3 +10,5 @@ g_sPlantPath = g_sResourcePath / "db/plant.db"
|
|||||||
|
|
||||||
g_sConfigPath = Path(__file__).resolve().parent / "config"
|
g_sConfigPath = Path(__file__).resolve().parent / "config"
|
||||||
g_sSignInPath = g_sConfigPath / "sign_in.json"
|
g_sSignInPath = g_sConfigPath / "sign_in.json"
|
||||||
|
|
||||||
|
g_bSignStatus = True
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import math
|
import math
|
||||||
from datetime import date, datetime, timedelta
|
|
||||||
from typing import List, Union
|
from typing import List, Union
|
||||||
|
|
||||||
from zhenxun.services.log import logger
|
from zhenxun.services.log import logger
|
||||||
|
|
||||||
from .database import CSqlManager
|
from .database import CSqlManager
|
||||||
|
from ..tool import g_pToolManager
|
||||||
|
|
||||||
|
|
||||||
class CUserDB(CSqlManager):
|
class CUserDB(CSqlManager):
|
||||||
@ -35,7 +35,7 @@ class CUserDB(CSqlManager):
|
|||||||
Returns:
|
Returns:
|
||||||
Union[bool, str]: False 表示失败,字符串表示成功信息
|
Union[bool, str]: False 表示失败,字符串表示成功信息
|
||||||
"""
|
"""
|
||||||
nowStr = date.today().strftime('%Y-%m-%d')
|
nowStr = g_pToolManager.dateTime().date().today().strftime('%Y-%m-%d')
|
||||||
sql = (
|
sql = (
|
||||||
f"INSERT INTO user (uid, name, exp, point, soil, stealTime, stealCount) "
|
f"INSERT INTO user (uid, name, exp, point, soil, stealTime, stealCount) "
|
||||||
f"VALUES ({uid}, '{name}', {exp}, {point}, 3, '{nowStr}', 5)"
|
f"VALUES ({uid}, '{name}', {exp}, {point}, 3, '{nowStr}', 5)"
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import calendar
|
import calendar
|
||||||
|
import random
|
||||||
from datetime import date, datetime, timedelta
|
from datetime import date, datetime, timedelta
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
@ -8,6 +9,7 @@ from zhenxun.utils._build_image import BuildImage
|
|||||||
from ..dbService import g_pDBService
|
from ..dbService import g_pDBService
|
||||||
from ..json import g_pJsonManager
|
from ..json import g_pJsonManager
|
||||||
from .database import CSqlManager
|
from .database import CSqlManager
|
||||||
|
from ..tool import g_pToolManager
|
||||||
|
|
||||||
|
|
||||||
class CUserSignDB(CSqlManager):
|
class CUserSignDB(CSqlManager):
|
||||||
@ -18,8 +20,9 @@ class CUserSignDB(CSqlManager):
|
|||||||
"uid": "TEXT NOT NULL", #用户ID
|
"uid": "TEXT NOT NULL", #用户ID
|
||||||
"signDate": "DATE NOT NULL", #签到日期
|
"signDate": "DATE NOT NULL", #签到日期
|
||||||
"isSupplement": "TINYINT NOT NULL DEFAULT 0", #是否补签
|
"isSupplement": "TINYINT NOT NULL DEFAULT 0", #是否补签
|
||||||
"rewardType": "VARCHAR(20) DEFAULT ''", #奖励类型
|
"exp": "INT NOT NULL DEFAULT 0", #当天签到经验
|
||||||
"createdAt": "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP", #创建时间
|
"point": "INT NOT NULL DEFAULT 0", #当天签到金币
|
||||||
|
"createdAt": "DATETIME NOT NULL DEFAULT (datetime(CURRENT_TIMESTAMP, 'localtime')",#创建时间
|
||||||
"PRIMARY KEY": "(uid, signDate)"
|
"PRIMARY KEY": "(uid, signDate)"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,22 +35,52 @@ class CUserSignDB(CSqlManager):
|
|||||||
"lastSignDate": "DATE DEFAULT NULL", #上次签到日期
|
"lastSignDate": "DATE DEFAULT NULL", #上次签到日期
|
||||||
"continuousDays": "INT NOT NULL DEFAULT 0", #连续签到天数
|
"continuousDays": "INT NOT NULL DEFAULT 0", #连续签到天数
|
||||||
"supplementCount": "INT NOT NULL DEFAULT 0", #补签次数
|
"supplementCount": "INT NOT NULL DEFAULT 0", #补签次数
|
||||||
"updatedAt": "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP", #更新时间
|
"updatedAt": "DATETIME NOT NULL DEFAULT (datetime(CURRENT_TIMESTAMP, 'localtime')"#更新时间
|
||||||
}
|
}
|
||||||
|
|
||||||
await cls.ensureTableSchema("userSignLog", userSignLog)
|
await cls.ensureTableSchema("userSignLog", userSignLog)
|
||||||
await cls.ensureTableSchema("userSignSummary", userSignSummary)
|
await cls.ensureTableSchema("userSignSummary", userSignSummary)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def getUserSignCountByDate(cls, uid: str, monthStr: str) -> int:
|
async def getUserSignRewardByDate(cls, uid: str, date: str) -> tuple[int, int]:
|
||||||
|
"""根据指定日期获取用户签到随机奖励
|
||||||
|
|
||||||
|
Args:
|
||||||
|
uid (str): 用户Uid
|
||||||
|
date (str): 用户签到日期 示例:2025-05-27
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple[int, int]: 经验、金币
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
|
async with cls._transaction():
|
||||||
|
async with cls.m_pDB.execute(
|
||||||
|
"SELECT exp, point FROM userSignLog WHERE uid=? AND signDate=?",
|
||||||
|
(uid, date)
|
||||||
|
) as cursor:
|
||||||
|
row = await cursor.fetchone()
|
||||||
|
|
||||||
|
if row is None:
|
||||||
|
return 0, 0
|
||||||
|
|
||||||
|
exp = row['exp']
|
||||||
|
point = row['point']
|
||||||
|
|
||||||
|
return exp, point
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning("获取用户签到数据失败", e=e)
|
||||||
|
return 0, 0
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def getUserSignCountByDate(cls, uid: str, monthStr: str) -> int:
|
||||||
|
"""根据日期查询用户签到总天数
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
uid (str): 用户Uid
|
uid (str): 用户Uid
|
||||||
monthStr (str): 需要查询的日期 示例: 2025-05
|
monthStr (str): 需要查询的日期 示例: 2025-05
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
int: _description_
|
int: 查询月总签到天数
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
sql = "SELECT COUNT(*) FROM userSignLog WHERE uid=? AND signDate LIKE ?"
|
sql = "SELECT COUNT(*) FROM userSignLog WHERE uid=? AND signDate LIKE ?"
|
||||||
@ -80,21 +113,43 @@ class CUserSignDB(CSqlManager):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def sign(cls, uid: str, signDate: str = '') -> bool:
|
async def sign(cls, uid: str, signDate: str = '') -> int:
|
||||||
|
"""签到
|
||||||
|
|
||||||
|
Args:
|
||||||
|
uid (int): 用户ID
|
||||||
|
signDate (str): 日期字符串 'YYYY-MM-DD' 不传默认当前系统日期
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: 0: 签到失败 1: 签到成功 2: 重复签到
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
if not signDate:
|
if not signDate:
|
||||||
signDate = date.today().strftime("%Y-%m-%d")
|
signDate = g_pToolManager.dateTime().date().today().strftime("%Y-%m-%d")
|
||||||
|
|
||||||
if await cls.hasSigned(uid, signDate):
|
if await cls.hasSigned(uid, signDate):
|
||||||
return False
|
return 2
|
||||||
|
|
||||||
todayStr = date.today().strftime("%Y-%m-%d")
|
todayStr = g_pToolManager.dateTime().date().today().strftime("%Y-%m-%d")
|
||||||
isSupplement = 0 if signDate == todayStr else 1
|
isSupplement = 0 if signDate == todayStr else 1
|
||||||
|
|
||||||
|
expMax, expMin, pointMax, pointMin = [
|
||||||
|
g_pJsonManager.m_pSign.get(key, default)
|
||||||
|
for key, default in (
|
||||||
|
("exp_max", 50),
|
||||||
|
("exp_min", 5),
|
||||||
|
("point_max", 2000),
|
||||||
|
("point_min", 200),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
exp = random.randint(expMin, expMax)
|
||||||
|
point = random.randint(pointMin, pointMax)
|
||||||
|
|
||||||
async with cls._transaction():
|
async with cls._transaction():
|
||||||
await cls.m_pDB.execute(
|
await cls.m_pDB.execute(
|
||||||
"INSERT INTO userSignLog (uid, signDate, isSupplement, rewardType) VALUES (?, ?, ?, '')",
|
"INSERT INTO userSignLog (uid, signDate, isSupplement, exp, point) VALUES (?, ?, ?, ?, ?)",
|
||||||
(uid, signDate, isSupplement)
|
(uid, signDate, isSupplement, exp, point)
|
||||||
)
|
)
|
||||||
|
|
||||||
cursor = await cls.m_pDB.execute("SELECT * FROM userSignSummary WHERE uid=?", (uid,))
|
cursor = await cls.m_pDB.execute("SELECT * FROM userSignSummary WHERE uid=?", (uid,))
|
||||||
@ -103,8 +158,9 @@ class CUserSignDB(CSqlManager):
|
|||||||
currentMonth = signDate[:7]
|
currentMonth = signDate[:7]
|
||||||
if row:
|
if row:
|
||||||
monthSignDays = row['monthSignDays'] + 1 if row['currentMonth'] == currentMonth else 1
|
monthSignDays = row['monthSignDays'] + 1 if row['currentMonth'] == currentMonth else 1
|
||||||
|
totalSignDays = row['totalSignDays']
|
||||||
lastDate = row['lastSignDate']
|
lastDate = row['lastSignDate']
|
||||||
prevDate = (datetime.strptime(signDate, "%Y-%m-%d") - timedelta(days=1)).strftime("%Y-%m-%d")
|
prevDate = (g_pToolManager.dateTime().strptime(signDate, "%Y-%m-%d") - timedelta(days=1)).strftime("%Y-%m-%d")
|
||||||
continuousDays = row['continuousDays'] + 1 if lastDate == prevDate else 1
|
continuousDays = row['continuousDays'] + 1 if lastDate == prevDate else 1
|
||||||
supplementCount = row['supplementCount'] + 1 if isSupplement else row['supplementCount']
|
supplementCount = row['supplementCount'] + 1 if isSupplement else row['supplementCount']
|
||||||
await cls.m_pDB.execute(
|
await cls.m_pDB.execute(
|
||||||
@ -121,6 +177,7 @@ class CUserSignDB(CSqlManager):
|
|||||||
(currentMonth, monthSignDays, signDate, continuousDays, supplementCount, uid)
|
(currentMonth, monthSignDays, signDate, continuousDays, supplementCount, uid)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
totalSignDays = 1
|
||||||
await cls.m_pDB.execute(
|
await cls.m_pDB.execute(
|
||||||
"""
|
"""
|
||||||
INSERT INTO userSignSummary
|
INSERT INTO userSignSummary
|
||||||
@ -129,10 +186,31 @@ class CUserSignDB(CSqlManager):
|
|||||||
""",
|
""",
|
||||||
(uid, 1, currentMonth, 1, signDate, 1, 1 if isSupplement else 0)
|
(uid, 1, currentMonth, 1, signDate, 1, 1 if isSupplement else 0)
|
||||||
)
|
)
|
||||||
return True
|
|
||||||
|
#计算累签奖励
|
||||||
|
reward = g_pJsonManager.m_pSign['continuou'].get(f"{totalSignDays + 1}", None)
|
||||||
|
|
||||||
|
if reward:
|
||||||
|
point += reward.get('point', 0)
|
||||||
|
exp += reward.get('exp', 0)
|
||||||
|
|
||||||
|
plant = reward.get('plant', {})
|
||||||
|
|
||||||
|
if plant:
|
||||||
|
for key, value in plant.items():
|
||||||
|
await g_pDBService.userSeed.addUserSeedByUid(uid, key, value)
|
||||||
|
|
||||||
|
#向数据库更新
|
||||||
|
currentExp = await g_pDBService.user.getUserExpByUid(uid)
|
||||||
|
await g_pDBService.user.updateUserExpByUid(uid, currentExp + exp)
|
||||||
|
|
||||||
|
currentPoint = await g_pDBService.user.getUserPointByUid(uid)
|
||||||
|
await g_pDBService.user.updateUserPointByUid(uid, currentPoint + point)
|
||||||
|
|
||||||
|
return 1
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning("执行签到失败", e=e)
|
logger.warning("执行签到失败", e=e)
|
||||||
return False
|
return 0
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def drawSignCalendarImage(cls, uid: str, year: int, month: int):
|
async def drawSignCalendarImage(cls, uid: str, year: int, month: int):
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
from datetime import date, datetime, timedelta
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from zhenxun.services.log import logger
|
from zhenxun.services.log import logger
|
||||||
@ -6,6 +5,7 @@ from zhenxun.services.log import logger
|
|||||||
from ..dbService import g_pDBService
|
from ..dbService import g_pDBService
|
||||||
from ..json import g_pJsonManager
|
from ..json import g_pJsonManager
|
||||||
from .database import CSqlManager
|
from .database import CSqlManager
|
||||||
|
from ..tool import g_pToolManager
|
||||||
|
|
||||||
|
|
||||||
class CUserSoilDB(CSqlManager):
|
class CUserSoilDB(CSqlManager):
|
||||||
@ -312,7 +312,7 @@ class CUserSoilDB(CSqlManager):
|
|||||||
logger.error(f"未知植物: {plantName}")
|
logger.error(f"未知植物: {plantName}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
nowTs = int(datetime.now().timestamp())
|
nowTs = int(g_pToolManager.dateTime().now().timestamp())
|
||||||
matureTs = nowTs + int(plantCfg.get("time", 0)) * 3600
|
matureTs = nowTs + int(plantCfg.get("time", 0)) * 3600
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
28
farm/farm.py
28
farm/farm.py
@ -1,7 +1,6 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import math
|
import math
|
||||||
import random
|
import random
|
||||||
from datetime import date, datetime
|
|
||||||
from typing import Dict, List, Tuple
|
from typing import Dict, List, Tuple
|
||||||
|
|
||||||
from zhenxun.configs.config import Config
|
from zhenxun.configs.config import Config
|
||||||
@ -16,6 +15,7 @@ from ..config import g_sResourcePath
|
|||||||
from ..dbService import g_pDBService
|
from ..dbService import g_pDBService
|
||||||
from ..event.event import g_pEventManager
|
from ..event.event import g_pEventManager
|
||||||
from ..json import g_pJsonManager
|
from ..json import g_pJsonManager
|
||||||
|
from ..tool import g_pToolManager
|
||||||
|
|
||||||
|
|
||||||
class CFarmManager:
|
class CFarmManager:
|
||||||
@ -211,7 +211,7 @@ class CFarmManager:
|
|||||||
soilStatus = "-"
|
soilStatus = "-"
|
||||||
plantNumber = "-"
|
plantNumber = "-"
|
||||||
else:
|
else:
|
||||||
matureTime = datetime.fromtimestamp(int(soilInfo.get("matureTime", 0))).strftime("%Y-%m-%d %H:%M:%S.%f")
|
matureTime = g_pToolManager.dateTime().fromtimestamp(int(soilInfo.get("matureTime", 0))).strftime("%Y-%m-%d %H:%M:%S.%f")
|
||||||
soilStatus = await g_pDBService.userSoil.getUserSoilStatus(uid, i)
|
soilStatus = await g_pDBService.userSoil.getUserSoilStatus(uid, i)
|
||||||
|
|
||||||
num = await g_pDBService.userSteal.getTotalStolenCount(uid, i)
|
num = await g_pDBService.userSteal.getTotalStolenCount(uid, i)
|
||||||
@ -286,8 +286,8 @@ class CFarmManager:
|
|||||||
logger.error(f"绘制植物资源失败: {soilInfo['plantName']}")
|
logger.error(f"绘制植物资源失败: {soilInfo['plantName']}")
|
||||||
return False, None, False #type: ignore
|
return False, None, False #type: ignore
|
||||||
|
|
||||||
currentTime = datetime.now()
|
currentTime = g_pToolManager.dateTime().now()
|
||||||
matureTime = datetime.fromtimestamp(int(soilInfo['matureTime']))
|
matureTime = g_pToolManager.dateTime().fromtimestamp(int(soilInfo['matureTime']))
|
||||||
|
|
||||||
#如果当前时间大于成熟时间 说明作物成熟
|
#如果当前时间大于成熟时间 说明作物成熟
|
||||||
if currentTime >= matureTime:
|
if currentTime >= matureTime:
|
||||||
@ -303,7 +303,7 @@ class CFarmManager:
|
|||||||
return True, plant, False
|
return True, plant, False
|
||||||
|
|
||||||
#如果没有成熟 则根据当前阶段进行绘制
|
#如果没有成熟 则根据当前阶段进行绘制
|
||||||
plantedTime = datetime.fromtimestamp(int(soilInfo['plantTime']))
|
plantedTime = g_pToolManager.dateTime().fromtimestamp(int(soilInfo['plantTime']))
|
||||||
|
|
||||||
elapsedTime = currentTime - plantedTime
|
elapsedTime = currentTime - plantedTime
|
||||||
elapsedHour = elapsedTime.total_seconds() / 3600
|
elapsedHour = elapsedTime.total_seconds() / 3600
|
||||||
@ -484,8 +484,8 @@ class CFarmManager:
|
|||||||
if not plantInfo:
|
if not plantInfo:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
currentTime = datetime.now()
|
currentTime = g_pToolManager.dateTime().now()
|
||||||
matureTime = datetime.fromtimestamp(int(soilInfo['matureTime']))
|
matureTime = g_pToolManager.dateTime().fromtimestamp(int(soilInfo['matureTime']))
|
||||||
|
|
||||||
if currentTime >= matureTime:
|
if currentTime >= matureTime:
|
||||||
number = plantInfo['harvest']
|
number = plantInfo['harvest']
|
||||||
@ -664,10 +664,10 @@ class CFarmManager:
|
|||||||
stealCount = int(userInfo['stealCount'])
|
stealCount = int(userInfo['stealCount'])
|
||||||
|
|
||||||
if stealTime == '':
|
if stealTime == '':
|
||||||
stealTime = date.today().strftime('%Y-%m-%d')
|
stealTime = g_pToolManager.dateTime().date().today().strftime('%Y-%m-%d')
|
||||||
stealCount = 5
|
stealCount = 5
|
||||||
elif date.fromisoformat(stealTime) != date.today():
|
elif g_pToolManager.dateTime().date().fromisoformat(stealTime) != g_pToolManager.dateTime().date().today():
|
||||||
stealTime = date.today().strftime('%Y-%m-%d')
|
stealTime = g_pToolManager.dateTime().date().today().strftime('%Y-%m-%d')
|
||||||
stealCount = 5
|
stealCount = 5
|
||||||
|
|
||||||
if stealCount <= 0:
|
if stealCount <= 0:
|
||||||
@ -697,8 +697,8 @@ class CFarmManager:
|
|||||||
if not plantInfo:
|
if not plantInfo:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
currentTime = datetime.now()
|
currentTime = g_pToolManager.dateTime().now()
|
||||||
matureTime = datetime.fromtimestamp(int(soilInfo['matureTime']))
|
matureTime = g_pToolManager.dateTime().fromtimestamp(int(soilInfo['matureTime']))
|
||||||
|
|
||||||
if currentTime >= matureTime:
|
if currentTime >= matureTime:
|
||||||
#如果偷过,则跳过该土地
|
#如果偷过,则跳过该土地
|
||||||
@ -728,10 +728,10 @@ class CFarmManager:
|
|||||||
await g_pDBService.userSoil.updateUserSoil(uid, i, "lastResetTime", int(currentTime.timestamp()))
|
await g_pDBService.userSoil.updateUserSoil(uid, i, "lastResetTime", int(currentTime.timestamp()))
|
||||||
await g_pDBService.userSoil.updateUserSoil(uid, i, "matureTime", matureTs)
|
await g_pDBService.userSoil.updateUserSoil(uid, i, "matureTime", matureTs)
|
||||||
|
|
||||||
await g_pDBService.userSteal.addStealRecord(target, i, uid, randomNumber, int(datetime.now().timestamp()))
|
await g_pDBService.userSteal.addStealRecord(target, i, uid, randomNumber, int(g_pToolManager.dateTime().now().timestamp()))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
await g_pDBService.userSteal.addStealRecord(target, i, uid, randomNumber, int(datetime.now().timestamp()))
|
await g_pDBService.userSteal.addStealRecord(target, i, uid, randomNumber, int(g_pToolManager.dateTime().now().timestamp()))
|
||||||
|
|
||||||
if isStealingPlant <= 0 and isStealingNumber <= 0:
|
if isStealingPlant <= 0 and isStealingNumber <= 0:
|
||||||
return "目标没有作物可以被偷"
|
return "目标没有作物可以被偷"
|
||||||
|
|||||||
39
json.py
39
json.py
@ -3,12 +3,16 @@ from pathlib import Path
|
|||||||
|
|
||||||
from zhenxun.services.log import logger
|
from zhenxun.services.log import logger
|
||||||
|
|
||||||
|
from . import config
|
||||||
|
from .request import g_pRequestManager
|
||||||
|
|
||||||
|
|
||||||
class CJsonManager:
|
class CJsonManager:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.m_pItem = {}
|
self.m_pItem = {}
|
||||||
self.m_pLevel = {}
|
self.m_pLevel = {}
|
||||||
self.m_pSoil = {}
|
self.m_pSoil = {}
|
||||||
|
self.m_pSign = {}
|
||||||
|
|
||||||
async def init(self) -> bool:
|
async def init(self) -> bool:
|
||||||
if not await self.initItem():
|
if not await self.initItem():
|
||||||
@ -20,14 +24,17 @@ class CJsonManager:
|
|||||||
if not await self.initSoil():
|
if not await self.initSoil():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
if not await g_pRequestManager.initSignInFile():
|
||||||
|
config.g_bSignStatus = False
|
||||||
|
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return await self.initSign()
|
||||||
|
|
||||||
async def initItem(self) -> bool:
|
async def initItem(self) -> bool:
|
||||||
current_file_path = Path(__file__)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(
|
with open(
|
||||||
current_file_path.resolve().parent / "config/item.json",
|
config.g_sConfigPath / "item.json",
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
) as file:
|
) as file:
|
||||||
self.m_pItem = json.load(file)
|
self.m_pItem = json.load(file)
|
||||||
@ -41,11 +48,9 @@ class CJsonManager:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
async def initLevel(self) -> bool:
|
async def initLevel(self) -> bool:
|
||||||
current_file_path = Path(__file__)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(
|
with open(
|
||||||
current_file_path.resolve().parent / "config/level.json",
|
config.g_sConfigPath / "level.json",
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
) as file:
|
) as file:
|
||||||
self.m_pLevel = json.load(file)
|
self.m_pLevel = json.load(file)
|
||||||
@ -59,11 +64,9 @@ class CJsonManager:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
async def initSoil(self) -> bool:
|
async def initSoil(self) -> bool:
|
||||||
current_file_path = Path(__file__)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(
|
with open(
|
||||||
current_file_path.resolve().parent / "config/soil.json",
|
config.g_sConfigPath / "soil.json",
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
) as file:
|
) as file:
|
||||||
self.m_pSoil = json.load(file)
|
self.m_pSoil = json.load(file)
|
||||||
@ -76,4 +79,20 @@ class CJsonManager:
|
|||||||
logger.warning(f"soil.json JSON格式错误: {e}")
|
logger.warning(f"soil.json JSON格式错误: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
async def initSign(self) -> bool:
|
||||||
|
try:
|
||||||
|
with open(
|
||||||
|
config.g_sSignInPath,
|
||||||
|
encoding="utf-8",
|
||||||
|
) as file:
|
||||||
|
self.m_pSign = json.load(file)
|
||||||
|
|
||||||
|
return True
|
||||||
|
except FileNotFoundError:
|
||||||
|
logger.warning("sign_in.json 打开失败")
|
||||||
|
return False
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
logger.warning(f"sign_in.json JSON格式错误: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
g_pJsonManager = CJsonManager()
|
g_pJsonManager = CJsonManager()
|
||||||
|
|||||||
41
request.py
41
request.py
@ -36,7 +36,6 @@ class CRequestManager:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
async with httpx.AsyncClient(timeout=10.0) as client:
|
||||||
# 动态组装请求参数
|
|
||||||
requestArgs: dict = {"headers": headers}
|
requestArgs: dict = {"headers": headers}
|
||||||
if params:
|
if params:
|
||||||
requestArgs["params"] = params
|
requestArgs["params"] = params
|
||||||
@ -60,7 +59,7 @@ class CRequestManager:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def post(cls, endpoint: str, name: str = "", jsonData: dict = None) -> dict:
|
async def post(cls, endpoint: str, name: str = "", jsonData: dict = {}) -> dict:
|
||||||
"""发送POST请求到指定接口,统一调用,仅支持JSON格式数据
|
"""发送POST请求到指定接口,统一调用,仅支持JSON格式数据
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -74,9 +73,6 @@ class CRequestManager:
|
|||||||
Returns:
|
Returns:
|
||||||
dict: 返回请求结果的JSON数据
|
dict: 返回请求结果的JSON数据
|
||||||
"""
|
"""
|
||||||
if jsonData is None:
|
|
||||||
raise ValueError("post请求必须提供jsonData")
|
|
||||||
|
|
||||||
baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
|
baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
|
||||||
url = f"{baseUrl.rstrip('/')}/{endpoint.lstrip('/')}"
|
url = f"{baseUrl.rstrip('/')}/{endpoint.lstrip('/')}"
|
||||||
headers = {"token": cls.m_sTokens}
|
headers = {"token": cls.m_sTokens}
|
||||||
@ -129,43 +125,44 @@ class CRequestManager:
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def initSignInFile(cls):
|
async def initSignInFile(cls) -> bool:
|
||||||
if os.path.exists(g_sSignInPath):
|
if os.path.exists(g_sSignInPath):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(g_sSignInPath, "r", encoding="utf-8") as f:
|
with open(g_sSignInPath, "r", encoding="utf-8") as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
sign = json.loads(content)
|
sign = json.loads(content)
|
||||||
|
|
||||||
date = sign.get("date", "")
|
date = sign.get("date", "")
|
||||||
yearMonth = datetime.now().strftime("%Y%m")
|
yearMonth = g_pToolManager.dateTime().now().strftime("%Y%m")
|
||||||
|
|
||||||
if date == yearMonth:
|
if date == yearMonth:
|
||||||
logger.debug("真寻农场签到文件检查完毕")
|
logger.debug("真寻农场签到文件检查完毕")
|
||||||
|
return True
|
||||||
else:
|
else:
|
||||||
logger.warning("真寻农场签到文件检查失败, 即将下载")
|
logger.warning("真寻农场签到文件检查失败, 即将下载")
|
||||||
await cls.downloadSignInFile()
|
return await cls.downloadSignInFile()
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
logger.warning(f"真寻农场签到文件格式错误, 即将下载")
|
logger.warning(f"真寻农场签到文件格式错误, 即将下载")
|
||||||
await cls.downloadSignInFile()
|
return await cls.downloadSignInFile()
|
||||||
else:
|
else:
|
||||||
await cls.downloadSignInFile()
|
return await cls.downloadSignInFile()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def downloadSignInFile(cls):
|
async def downloadSignInFile(cls) -> bool:
|
||||||
baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
|
try:
|
||||||
|
baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
|
||||||
|
|
||||||
url = f"{baseUrl.rstrip('/')}/sign_in"
|
url = f"{baseUrl.rstrip('/')}:8998/sign_in"
|
||||||
url = f"http://127.0.0.1:8998/sign_in"
|
path = str(g_sSignInPath.parent.resolve(strict=False))
|
||||||
|
yearMonth = g_pToolManager.dateTime().now().strftime("%Y%m")
|
||||||
|
|
||||||
path = str(g_sSignInPath.parent.resolve(strict=False))
|
await cls.download(url, path, "signTemp.json", jsonData={'date':yearMonth})
|
||||||
yearMonth = datetime.now().strftime("%Y%m")
|
g_pToolManager.renameFile(f"{path}/signTemp.json", "sign_in.json")
|
||||||
|
|
||||||
logger.info(f"{yearMonth}")
|
return True
|
||||||
yearMonth = "202506"
|
except Exception as e:
|
||||||
|
logger.error("下载签到文件失败", e=e)
|
||||||
await cls.download(url, path, "signTemp.json", jsonData={'date':yearMonth})
|
return False
|
||||||
g_pToolManager.renameFile(f"{path}/signTemp.json", "sign_in.json")
|
|
||||||
|
|
||||||
|
|
||||||
g_pRequestManager = CRequestManager()
|
g_pRequestManager = CRequestManager()
|
||||||
|
|||||||
7
tool.py
7
tool.py
@ -1,4 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
|
from datetime import datetime
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
from zhenxun.services.log import logger
|
from zhenxun.services.log import logger
|
||||||
|
|
||||||
@ -29,4 +31,9 @@ class CToolManager:
|
|||||||
logger.warning(f"文件重命名失败: {e}")
|
logger.warning(f"文件重命名失败: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def dateTime(cls) -> datetime:
|
||||||
|
tz = ZoneInfo("Asia/Shanghai")
|
||||||
|
return datetime.now(tz)
|
||||||
|
|
||||||
g_pToolManager = CToolManager()
|
g_pToolManager = CToolManager()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user