diff --git a/README.md b/README.md index 66216b1..56c0dee 100644 --- a/README.md +++ b/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* ## 许可证 diff --git a/command.py b/command.py index 681ea6b..f9b6e1c 100644 --- a/command.py +++ b/command.py @@ -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( "请在指令后跟需要播种的种子名称" diff --git a/database.py b/database.py index a760e3d..f1f93d7 100644 --- a/database.py +++ b/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,8 +552,11 @@ class CSqlManager: if seed in seedsDict: seedsDict[seed] += num + if seedsDict[seed] <= 0: + del seedsDict[seed] else: - seedsDict[seed] = num + if num > 0: + seedsDict[seed] = num updatedSeeds = ','.join([f"{name}|{count}" for name, count in seedsDict.items()]) diff --git a/farm/farm.py b/farm/farm.py index d14efbf..e4ba61b 100644 --- a/farm/farm.py +++ b/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}" diff --git a/resource/background/background.jpg b/resource/background/background.png similarity index 100% rename from resource/background/background.jpg rename to resource/background/background.png diff --git a/resource/background/fisheries.png b/resource/background/fisheries.png new file mode 100644 index 0000000..b667060 Binary files /dev/null and b/resource/background/fisheries.png differ diff --git a/resource/background/hut.png b/resource/background/hut.png new file mode 100644 index 0000000..81d166a Binary files /dev/null and b/resource/background/hut.png differ diff --git a/resource/background/kennel.png b/resource/background/kennel.png new file mode 100644 index 0000000..c1d8484 Binary files /dev/null and b/resource/background/kennel.png differ diff --git a/resource/background/magic.png b/resource/background/magic.png new file mode 100644 index 0000000..4dd467f Binary files /dev/null and b/resource/background/magic.png differ diff --git a/resource/background/mailbox.png b/resource/background/mailbox.png new file mode 100644 index 0000000..3a73ec7 Binary files /dev/null and b/resource/background/mailbox.png differ diff --git a/resource/background/trade.png b/resource/background/trade.png new file mode 100644 index 0000000..421ad13 Binary files /dev/null and b/resource/background/trade.png differ