✨ 继续完善了我的农场资源图片
🐛 修复当种子或作物为0时还存在的BUG 🐛 修复部分默认值异常BUG
49
README.md
@ -11,42 +11,40 @@
|
||||
|
||||
## 使用指令
|
||||
|
||||
- @小真寻 开通农场
|
||||
- 我的农场币
|
||||
- 种子商店 [页数]
|
||||
- 数量不填默认为1
|
||||
- todo:缺少判断页数溢出
|
||||
- 购买种子 [种子名称] [数量]
|
||||
- 数量不填默认为1
|
||||
- 我的种子
|
||||
- 播种 [种子名称] [数量]
|
||||
- 数量不填默认为1
|
||||
- 收获
|
||||
- 铲除
|
||||
- todo:目前只能铲除枯萎作物
|
||||
- 我的作物
|
||||
- 出售作物 [作物名称] [数量]
|
||||
- todo:有待优化
|
||||
- @美波理 偷菜
|
||||
- 购买农场币 [消耗金币的数量]
|
||||
- 该金币为小真寻的金币 兑换比例默认为1:2 可以配置
|
||||
| 指令 | 描述 | Tip |
|
||||
| --- | --- | --- |
|
||||
| @小真寻 开通农场 | 首次开通农场 | |
|
||||
| 我的农场币 | 查询农场币 | |
|
||||
| 种子商店 [页数] | 查看种子商店 | 数量不填默认为1 |
|
||||
| 购买种子 [种子名称] [数量] | 购买种子 | 数量不填默认为1 |
|
||||
| 我的种子 | 查询仓库种子 | |
|
||||
| 播种 [种子名称] [数量] | 播种种子 | 数量不填默认将最大可能播种 |
|
||||
| 收获 | 收获成熟作物 | |
|
||||
| 铲除 | 铲除荒废作物 | |
|
||||
| 我的作物 | | |
|
||||
| 出售作物 [作物名称] [数量] | 从仓库里向系统售卖作物 | 数量不填默认全部 |
|
||||
| @美波理 偷菜 | 偷别人的菜 | 每人每天只能偷5次 |
|
||||
| 购买农场币 | 将真寻金币兑换成农场币 | 兑换比例默认为1:2 手续费默认20% |
|
||||
|
||||
---
|
||||
|
||||
## 待办事宜 `Todo` 列表
|
||||
|
||||
- [x] 完善我的农场图片,例如左上角显示用户数据;
|
||||
- [x] 完善升级数据、作物数据、作物图片;
|
||||
- [x] 签到功能;
|
||||
- [x] 增加活动、交易行功能;
|
||||
- [x] 增加交易行总行功能;
|
||||
- [x] 添加其他游戏种子素材;
|
||||
- [x] 完善我的农场图片,例如左上角显示用户数据
|
||||
- [x] 完善升级数据、作物数据、作物图片
|
||||
- [x] 签到功能
|
||||
- [x] 添加渔场功能
|
||||
- [x] 增加活动、交易行功能
|
||||
- [x] 增加交易行总行功能
|
||||
- [x] 添加其他游戏种子素材
|
||||
- [x] 想不到了,想到再说
|
||||
|
||||
---
|
||||
|
||||
## 关于
|
||||
|
||||
本人毫无任何Python经验,也从未正式的、系统的、完整的去学习Python。如有看到写的不对的地方,欢迎指出,也欢迎任何人一起来开发、完善农场。
|
||||
|
||||
素材来均源于互联网,侵权请联系我删除
|
||||
|
||||
---
|
||||
@ -58,6 +56,7 @@
|
||||
- [Nonebot2](https://github.com/nonebot/nonebot2) *✨ 跨平台 Python 异步机器人框架 ✨*
|
||||
- [zhenxun_bot](https://github.com/zhenxun-org/zhenxun_bot) *最爱真寻的一集*
|
||||
- [HibiKier](https://github.com/HibiKier) *阿咪为什么是神*
|
||||
- [ATTomato](https://github.com/ATTomatoo) *流泪偷码头.jpg*
|
||||
|
||||
## 许可证
|
||||
|
||||
|
||||
@ -103,7 +103,7 @@ diuse_farm.shortcut(
|
||||
)
|
||||
|
||||
@diuse_farm.assign("seed-shop")
|
||||
async def _(session: Uninfo, num: Query[int] = AlconnaQuery("num", 0)):
|
||||
async def _(session: Uninfo, num: Query[int] = AlconnaQuery("num", 1)):
|
||||
uid = str(session.user.id)
|
||||
|
||||
if await isRegisteredByUid(uid) == False:
|
||||
@ -159,7 +159,7 @@ diuse_farm.shortcut(
|
||||
)
|
||||
|
||||
@diuse_farm.assign("sowing")
|
||||
async def _(session: Uninfo, name: Match[str], num: Query[int] = AlconnaQuery("num", 1),):
|
||||
async def _(session: Uninfo, name: Match[str], num: Query[int] = AlconnaQuery("num", -1),):
|
||||
if not name.available:
|
||||
await MessageUtils.build_message(
|
||||
"请在指令后跟需要播种的种子名称"
|
||||
|
||||
56
database.py
@ -4,7 +4,7 @@ import re
|
||||
from datetime import date, datetime, timedelta
|
||||
from io import StringIO
|
||||
from math import e
|
||||
from typing import Any, List, Optional
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
import aiosqlite
|
||||
|
||||
@ -283,12 +283,7 @@ class CSqlManager:
|
||||
return -1
|
||||
|
||||
try:
|
||||
async with cls.m_pDB.execute(f"UPDATE user SET point = {point} WHERE uid = {uid}") as cursor:
|
||||
async for row in cursor:
|
||||
return int(row[0])
|
||||
|
||||
logger.info(f"未找到用户或未修改数据: uid={uid}")
|
||||
return -1
|
||||
return await cls.executeDB(f"UPDATE user SET point = {point} WHERE uid = {uid}")
|
||||
except Exception as e:
|
||||
logger.error(f"金币更新失败: {e}")
|
||||
return -1
|
||||
@ -351,13 +346,10 @@ class CSqlManager:
|
||||
async for row in cursor:
|
||||
exp = int(row[0])
|
||||
|
||||
#计算当前等级(向下取整)
|
||||
level = math.floor((math.sqrt(1 + 4 * exp / 100) - 1) / 2)
|
||||
|
||||
#计算下级所需经验 下级所需经验为:200 + 当前等级 * 200
|
||||
level = exp // 200
|
||||
nextLevelExp = 200 * (level + 1)
|
||||
currentLevelExp = 100 * level * (level + 1)
|
||||
|
||||
currentLevelExp = level * 200
|
||||
remainingExp = exp - currentLevelExp
|
||||
|
||||
return level, nextLevelExp, remainingExp
|
||||
@ -477,6 +469,43 @@ class CSqlManager:
|
||||
logger.warning(f"getUserSeedByUid查询失败: {e}")
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
async def getUserSeedByName(cls, uid: str, name: str) -> int:
|
||||
"""获取用户仓库种子信息
|
||||
|
||||
Args:
|
||||
uid (str): 用户信息
|
||||
name (str): 种子名称
|
||||
|
||||
Returns:
|
||||
int: 仓库种子信息
|
||||
"""
|
||||
|
||||
if len(uid) <= 0:
|
||||
return -1
|
||||
|
||||
try:
|
||||
async with cls.m_pDB.execute(f"SELECT seed FROM storehouse WHERE uid = {uid}") as cursor:
|
||||
async for row in cursor:
|
||||
if row[0] == None or len(row[0]) == 0:
|
||||
return -1
|
||||
|
||||
plantDict: Dict[str, int] = {}
|
||||
for item in row[0].split(','):
|
||||
if '|' in item:
|
||||
seedName, count = item.split('|', 1)
|
||||
plantDict[seedName] = int(count)
|
||||
|
||||
if name in plantDict:
|
||||
return plantDict[name]
|
||||
else:
|
||||
return -1
|
||||
|
||||
return -1
|
||||
except Exception as e:
|
||||
logger.warning(f"getUserSeedByUid查询失败: {e}")
|
||||
return -1
|
||||
|
||||
@classmethod
|
||||
async def updateUserSeedByUid(cls, uid: str, seed: str) -> bool:
|
||||
"""更新用户种子仓库
|
||||
@ -523,7 +552,10 @@ class CSqlManager:
|
||||
|
||||
if seed in seedsDict:
|
||||
seedsDict[seed] += num
|
||||
if seedsDict[seed] <= 0:
|
||||
del seedsDict[seed]
|
||||
else:
|
||||
if num > 0:
|
||||
seedsDict[seed] = num
|
||||
|
||||
updatedSeeds = ','.join([f"{name}|{count}" for name, count in seedsDict.items()])
|
||||
|
||||
97
farm/farm.py
@ -1,4 +1,5 @@
|
||||
import asyncio
|
||||
import math
|
||||
import random
|
||||
from datetime import date, datetime
|
||||
from io import StringIO
|
||||
@ -25,23 +26,28 @@ class CFarmManager:
|
||||
|
||||
user = await UserConsole.get_user(uid)
|
||||
|
||||
if user.gold < num:
|
||||
return "你的金币不足"
|
||||
pro = float(Config.get_config("zhenxun_plugin_farm", "兑换倍数"))
|
||||
tax = float(Config.get_config("zhenxun_plugin_farm", "手续费"))
|
||||
|
||||
await UserConsole.reduce_gold(uid, num, GoldHandle.BUY , 'zhenxun_plugin_farm')
|
||||
#计算手续费
|
||||
fee = math.floor(num * tax)
|
||||
#实际扣费金额
|
||||
deduction = num + fee
|
||||
|
||||
pro = Config.get_config("zhenxun_plugin_farm", "兑换倍数")
|
||||
tax = Config.get_config("zhenxun_plugin_farm", "手续费")
|
||||
if user.gold < deduction:
|
||||
return f"你的金币不足或不足承担手续费。当前手续费为{fee}"
|
||||
|
||||
exc = num * pro
|
||||
point = exc - (exc * tax)
|
||||
await UserConsole.reduce_gold(uid, num, GoldHandle.PLUGIN , 'zhenxun_plugin_farm')
|
||||
await UserConsole.reduce_gold(uid, fee, GoldHandle.PLUGIN , 'zhenxun_plugin_farm')
|
||||
|
||||
point = num * pro
|
||||
|
||||
p = await g_pSqlManager.getUserPointByUid(uid)
|
||||
number = point + p
|
||||
|
||||
await g_pSqlManager.updateUserPointByUid(uid, number)
|
||||
await g_pSqlManager.updateUserPointByUid(uid, int(number))
|
||||
|
||||
return f"充值{num}农场币成功,当前农场币:{number}"
|
||||
return f"充值{point}农场币成功,手续费{tax}金币,当前农场币:{number}"
|
||||
|
||||
@classmethod
|
||||
async def drawFarmByUid(cls, uid: str) -> bytes:
|
||||
@ -53,7 +59,7 @@ class CFarmManager:
|
||||
Returns:
|
||||
bytes: 返回绘制结果
|
||||
"""
|
||||
img = BuildImage(background = g_sResourcePath / "background/background.jpg")
|
||||
img = BuildImage(background = g_sResourcePath / "background/background.png")
|
||||
|
||||
soilSize = g_pJsonManager.m_pSoil['size']
|
||||
|
||||
@ -86,6 +92,7 @@ class CFarmManager:
|
||||
await img.paste(plant, (x + soilSize[0] // 2 - plant.width // 2,
|
||||
y + soilSize[1] // 2 - plant.height // 2))
|
||||
|
||||
#1700 275
|
||||
#首次添加可收获图片
|
||||
if isRipe and isFirstRipe:
|
||||
ripe = BuildImage(background = g_sResourcePath / "background/ripe.png")
|
||||
@ -106,8 +113,34 @@ class CFarmManager:
|
||||
await img.paste(expansion, (x + soilSize[0] // 2 - expansion.width // 2,
|
||||
y + soilSize[1] // 2 - expansion.height))
|
||||
|
||||
#绘制背景信息
|
||||
#小屋
|
||||
hut = BuildImage(background = g_sResourcePath / "background/hut.png")
|
||||
await hut.resize(0, 600, 661)
|
||||
await img.paste(hut, (1700, 100))
|
||||
|
||||
#犬舍
|
||||
kennel = BuildImage(background = g_sResourcePath / "background/kennel.png")
|
||||
await img.paste(kennel, (300, 750))
|
||||
|
||||
#交易
|
||||
trade = BuildImage(background = g_sResourcePath / "background/trade.png")
|
||||
await img.paste(trade, (555, 510))
|
||||
|
||||
#魔法
|
||||
magic = BuildImage(background = g_sResourcePath / "background/magic.png")
|
||||
await img.paste(magic, (850, 450))
|
||||
|
||||
#信箱
|
||||
mailbox = BuildImage(background = g_sResourcePath / "background/mailbox.png")
|
||||
await img.paste(mailbox, (800, 550))
|
||||
|
||||
#渔场
|
||||
fisheries = BuildImage(background = g_sResourcePath / "background/fisheries.png")
|
||||
await img.paste(fisheries, (1120, 1000))
|
||||
|
||||
#左上角绘制用户信息
|
||||
await img.resize(0.6)
|
||||
await img.resize(0.5)
|
||||
return img.pic2bytes()
|
||||
|
||||
@classmethod
|
||||
@ -253,17 +286,19 @@ class CFarmManager:
|
||||
Returns:
|
||||
str:
|
||||
"""
|
||||
plant = await g_pSqlManager.getUserSeedByUid(uid)
|
||||
|
||||
if plant == None or len(plant) == 0:
|
||||
return "你的种子仓库是空的,快去买点吧!"
|
||||
number = 0
|
||||
count = await g_pSqlManager.getUserSeedByName(uid, name)
|
||||
|
||||
plantDict = {}
|
||||
for item in plant.split(','):
|
||||
if '|' in item:
|
||||
seed_name, count = item.split('|', 1)
|
||||
plantDict[seed_name] = int(count)
|
||||
if count <= 0:
|
||||
return f"没有在你的仓库发现{name}种子,快去买点吧!"
|
||||
|
||||
#如果播种超过仓库种子
|
||||
isMax = False
|
||||
if count < num:
|
||||
isMax = True
|
||||
|
||||
#如果播种全部
|
||||
isAll = False
|
||||
if num == -1:
|
||||
isAll = True
|
||||
@ -271,29 +306,31 @@ class CFarmManager:
|
||||
soilNumber = await g_pSqlManager.getUserSoilByUid(uid)
|
||||
|
||||
for i in range(1, soilNumber + 1):
|
||||
if plantDict[name] > 0:
|
||||
if count > 0:
|
||||
if isAll or num > 0:
|
||||
soilName = f"soil{i}"
|
||||
success, message = await g_pSqlManager.getUserSoilStatusBySoilID(uid, soilName)
|
||||
if success:
|
||||
#更新种子数量
|
||||
num -= 1
|
||||
plantDict[name] -= 1
|
||||
count -= 1
|
||||
|
||||
#记录种子消耗数量
|
||||
number -= 1
|
||||
|
||||
#更新数据库
|
||||
await g_pSqlManager.updateUserSoilStatusByPlantName(uid, soilName, name)
|
||||
|
||||
str = ""
|
||||
|
||||
if num > 0:
|
||||
str = f"播种数量超出开垦土地数量,已将可播种土地成功播种{name}!仓库还剩下{plantDict[name]}个种子"
|
||||
if isMax:
|
||||
str = f"仓库数量不够那么多,已将剩余数量全部播种!"
|
||||
elif num > 0:
|
||||
str = f"播种数量超出开垦土地数量,已将可播种土地成功播种{name}!仓库还剩下{count}个种子"
|
||||
else:
|
||||
str = f"播种{name}成功!仓库还剩下{plantDict[name]}个种子"
|
||||
str = f"播种{name}成功!仓库还剩下{count}个种子"
|
||||
|
||||
await g_pSqlManager.updateUserSeedByUid(
|
||||
uid,
|
||||
','.join([f"{k}|{v}" for k, v in plantDict.items() if v != 0])
|
||||
)
|
||||
await g_pSqlManager.addUserSeedByPlant(uid, name, number)
|
||||
|
||||
return str
|
||||
|
||||
@ -596,8 +633,6 @@ class CFarmManager:
|
||||
await g_pSqlManager.executeDB(sql)
|
||||
|
||||
return "\n".join(harvestRecords)
|
||||
# @classmethod
|
||||
# async def reclamation(cls, uid: str) -> str:
|
||||
|
||||
@classmethod
|
||||
async def reclamationCondition(cls, uid: str) -> str:
|
||||
@ -641,6 +676,8 @@ class CFarmManager:
|
||||
point = rec['point']
|
||||
item = rec['item']
|
||||
|
||||
logger.info(f"{level[0]}")
|
||||
|
||||
if level[0] < levelFileter:
|
||||
return f"当前用户等级不足,升级所需等级为{levelFileter}"
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 912 KiB After Width: | Height: | Size: 912 KiB |
BIN
resource/background/fisheries.png
Normal file
|
After Width: | Height: | Size: 160 KiB |
BIN
resource/background/hut.png
Normal file
|
After Width: | Height: | Size: 551 KiB |
BIN
resource/background/kennel.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
resource/background/magic.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
resource/background/mailbox.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
resource/background/trade.png
Normal file
|
After Width: | Height: | Size: 49 KiB |