diff --git a/README.md b/README.md
index d7e449a..86333e6 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
## 如何安装
-方法一(推荐):在小真寻后台的插件商店下载即可。
+方法一(推荐):在小真寻后台的插件商店下载即可
方法二:下载源码放在小真寻`plugin`目录下
## 使用指令
@@ -22,22 +22,32 @@
| 收获 | 收获成熟作物 | |
| 铲除 | 铲除荒废作物 | |
| 我的作物 | | |
-| 出售作物 [作物名称] [数量] | 从仓库里向系统售卖作物 | 作物不填默认清空仓库 数量不填默认全部 |
+| 出售作物 [作物名称] [数量] | 从仓库里向系统售卖作物 | 不填写作物名将售卖仓库种全部作物 填作物名不填数量将指定作物全部出售 |
| @美波理 偷菜 | 偷别人的菜 | 每人每天只能偷5次 |
| 购买农场币 | 将真寻金币兑换成农场币 | 兑换比例默认为1:2 手续费默认20% |
---
+## 更新日志[详细](./log/log.md):
+- 感谢[quanquan1014](https://github.com/quanquan1014)对农场名称中包含特殊字符的处理。
+- 更正数据库写法,但是会导致V1.0用户的作物和种子丢失
+- 完善我的农场图片资源,现在会在左上角显示经验、等级、金币等详细信息了
+- 完善出售作物逻辑,现在可以空置作物名称来一键出售全部作物了,也可以选择空置数量来一键出售仓库种指定作物
+- 完善播种逻辑,现在可以空置数量来一键播种指定作物了
+- 新增更改农场名指令
+- 改进对土地开垦条件判断
+---
+
## 待办事宜 `Todo` 列表
- [x] 完善我的农场图片,例如左上角显示用户数据
-- [x] 完善升级数据、作物数据、作物图片
-- [x] 签到功能
-- [x] 添加渔场功能
-- [x] 增加活动、交易行功能
-- [x] 增加交易行总行功能
-- [x] 添加其他游戏种子素材
-- [x] 想不到了,想到再说
+- [ ] 完善升级数据、作物数据、作物图片
+- [ ] 签到功能
+- [ ] 添加渔场功能
+- [ ] 增加活动、交易行功能
+- [ ] 增加交易行总行功能
+- [ ] 添加其他游戏种子素材
+- [ ] 想不到了,想到再说
---
diff --git a/__init__.py b/__init__.py
index ca568a8..ba53d5c 100644
--- a/__init__.py
+++ b/__init__.py
@@ -24,18 +24,19 @@ __plugin_meta__ = PluginMetadata(
种子商店 [页数]
购买种子 [作物/种子名称] [数量]
我的种子
- 播种 [作物/种子名称] [数量]
+ 播种 [作物/种子名称] [数量] (数量不填默认将最大可能播种
收获
铲除
我的作物
- 出售作物 [作物/种子名称] [数量] (不填写作物
- 偷菜 at
+ 出售作物 [作物/种子名称] [数量] (不填写作物名将售卖仓库种全部作物 填作物名不填数量将指定作物全部出售
+ 偷菜 at (每人每天只能偷5次
开垦
购买农场币 [数量] 数量为消耗金币的数量
+ 更改农场名 [新农场名]
""".strip(),
extra=PluginExtraData(
author="Art_Sakura",
- version="1.0",
+ version="1.1",
commands=[Command(command="我的农场")],
menu_type="群内小游戏",
configs=[
diff --git a/command.py b/command.py
index cee7761..1d4ae4a 100644
--- a/command.py
+++ b/command.py
@@ -1,9 +1,9 @@
from nonebot.adapters import Event, MessageTemplate
from nonebot.rule import to_me
from nonebot.typing import T_State
-from nonebot_plugin_alconna import (Alconna, AlconnaQuery, Args, Arparma, At,
- Match, MultiVar, Option, Query, Subcommand,
- on_alconna, store_true)
+from nonebot_plugin_alconna import (Alconna, AlconnaMatch, AlconnaQuery, Args,
+ Arparma, At, Match, MultiVar, Option,
+ Query, Subcommand, on_alconna, store_true)
from nonebot_plugin_uninfo import Uninfo
from nonebot_plugin_waiter import waiter
@@ -46,18 +46,18 @@ async def handle_register(session: Uninfo):
# 获取原始用户名并安全处理
raw_name = str(session.user.name)
safe_name = sanitize_username(raw_name)
-
+
# 初始化用户信息
success = await g_pSqlManager.initUserInfoByUid(
uid=uid,
name=safe_name,
exp=0,
- point=100
+ point=500
)
msg = (
- "✅ 农场开通成功!\n💼 初始资金:100农场币"
- if success
+ "✅ 农场开通成功!\n💼 初始资金:500农场币"
+ if success
else "⚠️ 开通失败,请稍后再试"
)
logger.info(f"用户注册 {'成功' if success else '失败'}:{uid}")
@@ -65,9 +65,9 @@ async def handle_register(session: Uninfo):
except Exception as e:
msg = "⚠️ 系统繁忙,请稍后再试"
logger.error(f"注册异常 | UID:{uid} | 错误:{str(e)}")
-
+
await MessageUtils.build_message(msg).send(reply_to=True)
-
+
def sanitize_username(username: str, max_length: int = 15) -> str:
"""
安全处理用户名
@@ -81,14 +81,14 @@ def sanitize_username(username: str, max_length: int = 15) -> str:
# 处理空值
if not username:
return "神秘农夫"
-
+
# 基础清洗
cleaned = username.strip()
-
+
# 允许的字符白名单(可自定义扩展)
safe_chars = {
'_', '-', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
- '+', '=', '.', ',', '~', '·', ' ',
+ '+', '=', '.', ',', '~', '·', ' ',
'a','b','c','d','e','f','g','h','i','j','k','l','m',
'n','o','p','q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M',
@@ -97,24 +97,24 @@ def sanitize_username(username: str, max_length: int = 15) -> str:
}
# 添加常用中文字符(Unicode范围)
safe_chars.update(chr(c) for c in range(0x4E00, 0x9FFF+1))
-
+
# 过滤危险字符
filtered = [
- c if c in safe_chars or 0x4E00 <= ord(c) <= 0x9FFF
- else ''
+ c if c in safe_chars or 0x4E00 <= ord(c) <= 0x9FFF
+ else ''
for c in cleaned
]
-
+
# 合并处理结果
safe_str = ''.join(filtered)
-
+
# 转义单引号(双重保障)
escaped = safe_str.replace("'", "''")
-
+
# 处理空结果
if not escaped:
return "神秘农夫"
-
+
# 长度限制
return escaped[:max_length]
@@ -130,24 +130,24 @@ diuse_farm = on_alconna(
Subcommand("harvest", help_text="收获"),
Subcommand("eradicate", help_text="铲除"),
Subcommand("my-plant", help_text="我的作物"),
- # Subcommand("reclamation", Args["isBool?", str], help_text="开垦"),
Subcommand("sell-plant", Args["name?", str]["num?", int], help_text="出售作物"),
Subcommand("stealing", Args["target?", At], help_text="偷菜"),
Subcommand("buy-point", Args["num?", int], help_text="购买农场币"),
#Subcommand("sell-point", Args["num?", int], help_text="转换金币")
+ Subcommand("change-name", Args["name?", str], help_text="更改农场名")
),
priority=5,
block=True,
)
@diuse_farm.assign("$main")
-async def _(session: Uninfo, nickname: str = UserName()):
+async def _(session: Uninfo):
uid = str(session.user.id)
if await isRegisteredByUid(uid) == False:
return
- image = await g_pFarmManager.drawFarmByUid(uid, nickname)
+ image = await g_pFarmManager.drawFarmByUid(uid)
await MessageUtils.build_message(image).send(reply_to=True)
diuse_farm.shortcut(
@@ -339,12 +339,7 @@ diuse_farm.shortcut(
)
@diuse_farm.assign("sell-plant")
-async def _(session: Uninfo, name: Match[str], num: Query[int] = AlconnaQuery("num", 1),):
- if not name.available:
- await MessageUtils.build_message(
- "请在指令后跟需要出售的作物名称"
- ).finish(reply_to=True)
-
+async def _(session: Uninfo, name: Match[str], num: Query[int] = AlconnaQuery("num", -1),):
uid = str(session.user.id)
if await isRegisteredByUid(uid) == False:
@@ -401,3 +396,32 @@ async def _(session: Uninfo, num: Query[int] = AlconnaQuery("num", 0)):
result = await g_pFarmManager.buyPointByUid(uid, num.result)
await MessageUtils.build_message(result).send(reply_to=True)
+
+
+diuse_farm.shortcut(
+ "更改农场名(?P)",
+ command="我的农场",
+ arguments=["change-name", "{name}"],
+ prefix=True,
+)
+
+@diuse_farm.assign("change-name")
+async def _(session: Uninfo, name: Match[str]):
+ if not name.available:
+ await MessageUtils.build_message(
+ "请在指令后跟需要更改的用户名"
+ ).finish(reply_to=True)
+
+ uid = str(session.user.id)
+
+ if await isRegisteredByUid(uid) == False:
+ return
+
+ safeName = sanitize_username(name.result)
+
+ result = await g_pSqlManager.updateUserNameByUid(uid, safeName)
+
+ if result == True:
+ await MessageUtils.build_message("更新用户名成功!").send(reply_to=True)
+ else:
+ await MessageUtils.build_message("更新用户名失败!").send(reply_to=True)
diff --git a/config/plant.json b/config/plant.json
index 6f4fb86..5c5e523 100644
--- a/config/plant.json
+++ b/config/plant.json
@@ -213,6 +213,21 @@
"sell": false
},
"番茄":
+ {
+ "level": 6,
+ "buy": 251,
+ "limit": 0,
+ "experience": 22,
+ "harvest": 21,
+ "price": 26,
+ "time": 17,
+ "crop": 1,
+ "again": 0,
+ "phase": 6,
+ "general": true,
+ "sell": false
+ },
+ "ATTomato":
{
"level": 6,
"buy": 99999,
diff --git a/config/sign_in.json b/config/sign_in.json
new file mode 100644
index 0000000..4b4e999
--- /dev/null
+++ b/config/sign_in.json
@@ -0,0 +1,4 @@
+{
+ "date": "202505",
+ ""
+}
diff --git a/database.py b/database.py
index a056dad..ba45c4c 100644
--- a/database.py
+++ b/database.py
@@ -143,12 +143,20 @@ class CSqlManager:
"count": "INTEGER NOT NULL DEFAULT 0",
"PRIMARY KEY": "(uid, seed)"
}
+ # 5. 用户道具明细表
+ userItem = {
+ "uid": "INTEGER NOT NULL",
+ "item": "TEXT NOT NULL",
+ "count": "INTEGER NOT NULL DEFAULT 0",
+ "PRIMARY KEY": "(uid, item)"
+ }
#建表(或增列)
await cls.ensureTableSchema("user", userInfo)
await cls.ensureTableSchema("soil", userSoilInfo)
await cls.ensureTableSchema("userPlant", userPlant)
await cls.ensureTableSchema("userSeed", userSeed)
+ await cls.ensureTableSchema("userItem", userItem)
return True
@@ -175,7 +183,7 @@ class CSqlManager:
return False
@classmethod
- async def initUserInfoByUid(cls, uid: str, name: str = "", exp: int = 0, point: int = 100):
+ async def initUserInfoByUid(cls, uid: str, name: str = "", exp: int = 0, point: int = 500):
"""初始化用户信息
Args:
@@ -190,11 +198,6 @@ class CSqlManager:
INSERT INTO user (uid, name, exp, point, soil, stealing) VALUES ({uid}, '{name}', {exp}, {point}, 3, '{date.today()}|5')
"""
- #用户仓库
- userStorehouse = f"""
- INSERT INTO storehouse (uid) VALUES ({uid});
- """
-
#用户土地
userSoilInfo = f"""
INSERT INTO soil (uid) VALUES ({uid});
@@ -203,9 +206,6 @@ class CSqlManager:
if not await cls.executeDB(userInfo):
return False
- if not await cls.executeDB(userStorehouse):
- return False
-
if not await cls.executeDB(userSoilInfo):
return False
@@ -244,6 +244,55 @@ class CSqlManager:
logger.warning(f"getUserInfoByUid查询失败: {e}")
return {}
+ @classmethod
+ async def getUserNameByUid(cls, uid: str) -> str:
+ """根据用户uid查询用户名
+
+ Args:
+ uid (str): 用户uid
+
+ Returns:
+ str: 用户名,如果失败返回空字符串
+ """
+ if not uid:
+ return ""
+
+ try:
+ async with cls.m_pDB.execute(
+ "SELECT name FROM user WHERE uid = ?",
+ (uid,)
+ ) as cursor:
+ row = await cursor.fetchone()
+ return row["name"] if row else ""
+ except Exception as e:
+ logger.warning(f"真寻农场getUserNameByUid查询失败: {e}")
+ return ""
+
+ @classmethod
+ async def updateUserNameByUid(cls, uid: str, name: str) -> bool:
+ """根据用户uid修改用户名
+
+ Args:
+ uid (str): 用户uid
+ name (str): 新用户名
+
+ Returns:
+ bool: 是否更新成功
+ """
+ if not uid or not name:
+ return False
+
+ try:
+ async with cls._transaction():
+ await cls.m_pDB.execute(
+ "UPDATE user SET name = ? WHERE uid = ?",
+ (name, uid)
+ )
+ return True
+ except Exception as e:
+ logger.warning(f"真寻农场updateUserNameByUid失败: {e}")
+ return False
+
@classmethod
async def getUserPointByUid(cls, uid: str) -> int:
"""根据用户Uid获取用户农场币
@@ -709,4 +758,152 @@ class CSqlManager:
logger.warning(f"真寻农场deleteUserPlantByName 失败: {e}")
return False
+
+ @classmethod
+ async def getUserItemByName(cls, uid: str, item: str) -> Optional[int]:
+ """根据道具名称查询某一项数量
+
+ Args:
+ uid (str): 用户uid
+ item (str): 道具名称
+
+ Returns:
+ Optional[int]: 数量(不存在返回None)
+ """
+ if not uid or not item:
+ return None
+ try:
+ async with cls.m_pDB.execute(
+ "SELECT count FROM userItem WHERE uid = ? AND item = ?",
+ (uid, item)
+ ) as cursor:
+ row = await cursor.fetchone()
+ return row[0] if row else None
+ except Exception as e:
+ logger.warning(f"真寻农场getUserItemByName查询失败: {e}")
+ return None
+
+ @classmethod
+ async def getUserItemByUid(cls, uid: str) -> dict:
+ """根据用户Uid获取全部道具信息
+
+ Args:
+ uid (str): 用户uid
+
+ Returns:
+ dict: {itemName: count, ...}
+ """
+ if not uid:
+ return {}
+ try:
+ cursor = await cls.m_pDB.execute(
+ "SELECT item, count FROM userItem WHERE uid = ?",
+ (uid,)
+ )
+ rows = await cursor.fetchall()
+ return {row["item"]: row["count"] for row in rows}
+ except Exception as e:
+ logger.warning(f"真寻农场getUserItemByUid查询失败: {e}")
+ return {}
+
+ @classmethod
+ async def deleteUserItemByName(cls, uid: str, item: str) -> bool:
+ """根据道具名删除道具
+
+ Args:
+ uid (str): 用户uid
+ item (str): 道具名称
+
+ Returns:
+ bool: 是否删除成功
+ """
+ if not uid or not item:
+ return False
+ try:
+ async with cls._transaction():
+ await cls.m_pDB.execute(
+ "DELETE FROM userItem WHERE uid = ? AND item = ?",
+ (uid, item)
+ )
+ return True
+ except Exception as e:
+ logger.warning(f"真寻农场deleteUserItemByName失败: {e}")
+ return False
+
+ @classmethod
+ async def updateUserItemByName(cls, uid: str, item: str, count: int) -> bool:
+ """根据道具名直接更新道具数量
+
+ Args:
+ uid (str): 用户uid
+ item (str): 道具名称
+ count (int): 要更新的新数量
+
+ Returns:
+ bool: 是否更新成功
+ """
+ if not uid or not item:
+ return False
+ try:
+ async with cls._transaction():
+ if count <= 0:
+ await cls.m_pDB.execute(
+ "DELETE FROM userItem WHERE uid = ? AND item = ?",
+ (uid, item)
+ )
+ else:
+ await cls.m_pDB.execute(
+ "UPDATE userItem SET count = ? WHERE uid = ? AND item = ?",
+ (count, uid, item)
+ )
+ return True
+ except Exception as e:
+ logger.warning(f"真寻农场updateUserItemByName失败: {e}")
+ return False
+
+ @classmethod
+ async def addUserItemByUid(cls, uid: str, item: str, count: int = 1) -> bool:
+ """根据用户uid添加道具信息
+
+ Args:
+ uid (str): 用户uid
+ item (str): 道具名称
+ count (int, optional): 数量.Defaults to 1.
+
+ Returns:
+ bool: 是否添加成功
+ """
+ if not uid or not item:
+ return False
+ try:
+ async with cls._transaction():
+ async with cls.m_pDB.execute(
+ "SELECT count FROM userItem WHERE uid = ? AND item = ?",
+ (uid, item)
+ ) as cursor:
+ row = await cursor.fetchone()
+
+ if row:
+ newCount = row[0] + count
+ if newCount <= 0:
+ await cls.m_pDB.execute(
+ "DELETE FROM userItem WHERE uid = ? AND item = ?",
+ (uid, item)
+ )
+ else:
+ await cls.m_pDB.execute(
+ "UPDATE userItem SET count = ? WHERE uid = ? AND item = ?",
+ (newCount, uid, item)
+ )
+ else:
+ if count > 0:
+ await cls.m_pDB.execute(
+ "INSERT INTO userItem (uid, item, count) VALUES (?, ?, ?)",
+ (uid, item, count)
+ )
+ return True
+ except Exception as e:
+ logger.warning(f"真寻农场addUserItemByUid失败: {e}")
+ return False
+
g_pSqlManager = CSqlManager()
diff --git a/farm/farm.py b/farm/farm.py
index 89e458d..ff0870a 100644
--- a/farm/farm.py
+++ b/farm/farm.py
@@ -51,7 +51,7 @@ class CFarmManager:
return f"充值{point}农场币成功,手续费{tax}金币,当前农场币:{number}"
@classmethod
- async def drawFarmByUid(cls, uid: str, name: str) -> bytes:
+ async def drawFarmByUid(cls, uid: str) -> bytes:
"""绘制用户农场
Args:
@@ -72,7 +72,9 @@ class CFarmManager:
await grass.resize(0, soilSize[0], soilSize[1])
soilPos = g_pJsonManager.m_pSoil['soil']
- soilUnlock = await g_pSqlManager.getUserSoilByUid(uid)
+
+ userInfo = await g_pSqlManager.getUserInfoByUid(uid)
+ soilUnlock = int(userInfo['soil'])
x = 0
y = 0
@@ -128,7 +130,7 @@ class CFarmManager:
await img.paste(frame, (75, 44))
#用户名
- nameImg = await BuildImage.build_text_image(name, size = 24, font_color = (77, 35, 4))
+ nameImg = await BuildImage.build_text_image(userInfo['name'], size = 24, font_color = (77, 35, 4))
await img.paste(nameImg, (300, 92))
#经验值
@@ -148,12 +150,10 @@ class CFarmManager:
await img.paste(levelImg, (660, 187))
#金币
- point = await g_pSqlManager.getUserPointByUid(uid)
- pointImg = await BuildImage.build_text_image(str(point), size = 24, font_color = (253, 253, 253))
+ pointImg = await BuildImage.build_text_image(str(userInfo['point']), size = 24, font_color = (253, 253, 253))
await img.paste(pointImg, (330, 255))
- #点券
- bonds = await g_pSqlManager.getUserPointByUid(uid)
+ #点券 TODO
bondsImg = await BuildImage.build_text_image("0", size = 24, font_color = (253, 253, 253))
await img.paste(bondsImg, (570, 255))
@@ -473,14 +473,14 @@ class CFarmManager:
if plant is None:
result = await ImageTemplate.table_page(
"作物仓库",
- "播种示例:@小真寻 出售作物 大白菜 [数量]",
+ "出售示例:@小真寻 出售作物 大白菜 [数量]",
column_name,
data_list,
)
return result.pic2bytes()
sell = ""
- for name, count in plant.items(): # 使用 .items() 来遍历字典
+ for name, count in plant.items():
plantInfo = g_pJsonManager.m_pPlant['plant'][name]
icon = ""
icon_path = g_sResourcePath / f"plant/{name}/icon.png"
@@ -507,7 +507,7 @@ class CFarmManager:
result = await ImageTemplate.table_page(
"作物仓库",
- "播种示例:@小真寻 出售作物 大白菜 [数量]",
+ "出售示例:@小真寻 出售作物 大白菜 [数量]",
column_name,
data_list,
)
diff --git a/farm/shop.py b/farm/shop.py
index 167c91c..c028194 100644
--- a/farm/shop.py
+++ b/farm/shop.py
@@ -23,7 +23,7 @@ class CShopManager:
column_name = [
"-",
"种子名称",
- "种子单价"
+ "种子单价",
"解锁等级",
"果实单价",
"收获经验",
@@ -132,39 +132,39 @@ class CShopManager:
Returns:
str:
"""
- plantDict = await g_pSqlManager.getUserPlantByUid(uid)
- if not plantDict:
+ if not isinstance(name, str) or name.strip() == "":
+ name = ""
+
+ plant = await g_pSqlManager.getUserPlantByUid(uid)
+ if not plant:
return "你仓库没有可以出售的作物"
- totalPoint = 0
+ point = 0
+ totalSold = 0
+ isAll = (num == -1)
- if not name:
- for plantName, count in plantDict.items():
+ if name == "":
+ for plantName, count in plant.items():
plantInfo = g_pJsonManager.m_pPlant['plant'][plantName]
- totalPoint += plantInfo['price'] * count
- await g_pSqlManager.deleteUserPlantByName(uid, plantName)
+ point += plantInfo['price'] * count
+ await g_pSqlManager.updateUserPlantByName(uid, plantName, 0)
else:
- currentCount = plantDict.get(name)
- if currentCount is None:
- return f"出售作物{name}出错:你没有这种作物"
+ if name not in plant:
+ return f"出售作物{name}出错:仓库中不存在该作物"
+ available = plant[name]
+ sellAmount = available if isAll else min(available, num)
+ if sellAmount <= 0:
+ return f"出售作物{name}出错:数量不足"
+ await g_pSqlManager.updateUserPlantByName(uid, name, available - sellAmount)
+ totalSold = sellAmount
- if num == -1:
- sellCount = currentCount
- else:
- if num > currentCount:
- return f"出售作物{name}出错:数量不足"
- sellCount = num
+ totalPoint = point if name == "" else totalSold * g_pJsonManager.m_pPlant['plant'][name]['price']
+ currentPoint = await g_pSqlManager.getUserPointByUid(uid)
+ await g_pSqlManager.updateUserPointByUid(uid, currentPoint + totalPoint)
- plantInfo = g_pJsonManager.m_pPlant['plant'][name]
- totalPoint = plantInfo['price'] * sellCount
- await g_pSqlManager.addUserPlantByUid(uid, name, -sellCount)
-
- point = await g_pSqlManager.getUserPointByUid(uid)
- await g_pSqlManager.updateUserPointByUid(uid, point + totalPoint)
-
- if not name:
- return f"成功出售所有作物,获得农场币:{totalPoint},当前农场币:{point + totalPoint}"
+ if name == "":
+ return f"成功出售所有作物,获得农场币:{totalPoint},当前农场币:{currentPoint + totalPoint}"
else:
- return f"成功出售{name},获得农场币:{totalPoint},当前农场币:{point + totalPoint}"
+ return f"成功出售{name},获得农场币:{totalPoint},当前农场币:{currentPoint + totalPoint}"
g_pShopManager = CShopManager()
diff --git a/log/log.md b/log/log.md
new file mode 100644
index 0000000..590d27c
--- /dev/null
+++ b/log/log.md
@@ -0,0 +1,15 @@
+# 真寻农场更新日志
+
+## V1.1
+
+- 感谢[quanquan1014](https://github.com/quanquan1014)对农场名称中包含特殊字符的处理。
+- 更正数据库写法,但是会导致V1.0用户的作物和种子丢失
+- 完善我的农场图片资源,现在会在左上角显示经验、等级、金币等详细信息了
+- 完善出售作物逻辑,现在可以空置作物名称来一键出售全部作物了,也可以选择空置数量来一键出售仓库种指定作物
+- 完善播种逻辑,现在可以空置数量来一键播种指定作物了
+- 新增更改农场名指令
+- 改进对土地开垦条件判断
+
+## V1.0
+
+世界的起源。
diff --git a/request.py b/request.py
index b3daab8..3031324 100644
--- a/request.py
+++ b/request.py
@@ -1,5 +1,4 @@
-from email.mime import base
-from unittest import result
+import os
import httpx
@@ -11,11 +10,11 @@ class CRequestManager:
@classmethod
async def download(cls, url: str, savePath: str, fileName: str) -> bool:
- """下载文件到指定路径
+ """下载文件到指定路径并覆盖已存在的文件
Args:
url (str): 文件的下载链接
- savePath (str): 保存文件的文件夹路径
+ savePath (str): 保存文件夹路径
fileName (str): 保存后的文件名
Returns:
@@ -25,7 +24,8 @@ class CRequestManager:
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.get(url)
if response.status_code == 200:
- fullPath = savePath.rstrip("/") + "/" + fileName
+ fullPath = os.path.join(savePath, fileName)
+ os.makedirs(os.path.dirname(fullPath), exist_ok=True)
with open(fullPath, "wb") as f:
f.write(response.content)
return True
diff --git a/resource/plant/ATTomato/1.png b/resource/plant/ATTomato/1.png
new file mode 100644
index 0000000..470bbe2
Binary files /dev/null and b/resource/plant/ATTomato/1.png differ
diff --git a/resource/plant/ATTomato/2.png b/resource/plant/ATTomato/2.png
new file mode 100644
index 0000000..1c729bc
Binary files /dev/null and b/resource/plant/ATTomato/2.png differ
diff --git a/resource/plant/ATTomato/3.png b/resource/plant/ATTomato/3.png
new file mode 100644
index 0000000..fa2521a
Binary files /dev/null and b/resource/plant/ATTomato/3.png differ
diff --git a/resource/plant/ATTomato/4.png b/resource/plant/ATTomato/4.png
new file mode 100644
index 0000000..b399ef0
Binary files /dev/null and b/resource/plant/ATTomato/4.png differ
diff --git a/resource/plant/ATTomato/5.png b/resource/plant/ATTomato/5.png
new file mode 100644
index 0000000..3ddc306
Binary files /dev/null and b/resource/plant/ATTomato/5.png differ
diff --git a/resource/plant/ATTomato/icon.png b/resource/plant/ATTomato/icon.png
new file mode 100644
index 0000000..7d09384
Binary files /dev/null and b/resource/plant/ATTomato/icon.png differ