完善显示用户农场图片,优化部分JSON

This commit is contained in:
Art_Sakura 2025-03-19 01:16:08 +08:00
parent 2bf5ab8052
commit ca6eb3343f
9 changed files with 335 additions and 112 deletions

View File

@ -31,17 +31,11 @@ driver = get_driver()
@driver.on_startup @driver.on_startup
async def start(): async def start():
# 初始化数据库 # 初始化数据库
# await g_pSqlManager.init()
await g_pSqlManager.init() await g_pSqlManager.init()
# 初始化读取Json # 初始化读取Json
# await g_pJsonManager.init()
await g_pJsonManager.init() await g_pJsonManager.init()
# await g_pDrawImage.drawMyFarm("11223")
await g_pDrawImage.drawMyFarm("22")
# 析构函数 # 析构函数
@driver.on_shutdown @driver.on_shutdown
async def shutdown(): async def shutdown():

View File

@ -1,14 +1,14 @@
{ {
"zhuShi":
[
"name: 名称",
"level: 等级",
"price: 单价",
"icon: 显示图片",
"sell: 是否可以上架交易行"
],
"item": "item":
{ {
"zhuShi":
[
"name: 名称",
"level: 等级",
"price: 单价",
"icon: 显示图片",
"sell: 是否可以上架交易行"
],
"muBan": "muBan":
{ {
"name": "木板", "name": "木板",

View File

@ -2,9 +2,10 @@
"level": "level":
{ {
"1": 0, "1": 0,
"2": 3000, "2": 500,
"3": 7500 "3": 1250,
"4": 3000
}, },
"soil":[1, 5, 10, 15, 25, 35], "soil":[1, 1, 1, 5, 10, 15, 25],
"point":[0, 2000, 5000, 10000, 30000, 50000] "point":[0, 2000, 5000, 10000, 30000, 50000]
} }

View File

@ -1,21 +1,21 @@
{ {
"zhuShi":
[
"name: 名称",
"level: 解锁等级",
"limit: 限制等级 0普通土地 1红土地 2黄土地 3黑土地",
"experience: 收获经验",
"harvest: 收获数量",
"price: 单价",
"time: 成熟时间 单位:分钟",
"crop: 作物可以收几次",
"again: 再次成熟时间 单位:分钟",
"phase: 阶段 目前为 成熟时间 / 阶段 来显示每阶段图片",
"general: 第一阶段是否为通用阶段素材",
"sell: 是否可以上架交易行"
],
"plant": "plant":
{ {
"zhuShi":
[
"name: 名称",
"level: 解锁等级",
"limit: 限制等级 0普通土地 1红土地 2黄土地 3黑土地",
"experience: 收获经验",
"harvest: 收获数量",
"price: 单价",
"time: 成熟时间 单位:分钟",
"crop: 作物可以收几次",
"again: 再次成熟时间 单位:分钟",
"phase: 阶段 目前为 成熟时间 / 阶段 来显示每阶段图片",
"general: 第一阶段是否为通用阶段素材",
"sell: 是否可以上架交易行"
],
"daBaiCai": "daBaiCai":
{ {
"name": "大白菜", "name": "大白菜",

View File

@ -1,155 +1,156 @@
{ {
"size":[234.378, 156.252],
"soil": "soil":
{ {
"1": "1":
{ {
"x": 1341, "x": 1352,
"y": 571 "y": 552
}, },
"2": "2":
{ {
"x": 1455, "x": 1462,
"y": 627 "y": 611
}, },
"3": "3":
{ {
"x": 1574, "x": 1572,
"y": 686 "y": 670
}, },
"4": "4":
{ {
"x": 1689, "x": 1682,
"y": 745 "y": 729
}, },
"5": "5":
{ {
"x": 1806, "x": 1792,
"y": 804 "y": 788
}, },
"6": "6":
{ {
"x": 1926, "x": 1902,
"y": 863 "y": 847
}, },
"7": "7":
{ {
"x": 1226, "x": 1242,
"y": 627 "y": 611
}, },
"8": "8":
{ {
"x": 1340, "x": 1343,
"y": 683 "y": 670
}, },
"9": "9":
{ {
"x": 1455, "x": 1462,
"y": 739 "y": 729
}, },
"10": "10":
{ {
"x": 1573, "x": 1572,
"y": 798 "y": 788
}, },
"11": "11":
{ {
"x": 1690, "x": 1682,
"y": 857 "y": 847
}, },
"12": "12":
{ {
"x": 1807, "x": 1792,
"y": 916 "y": 906
}, },
"13": "13":
{ {
"x": 1111, "x": 1123,
"y": 683 "y": 670
}, },
"14": "14":
{ {
"x": 1226, "x": 1233,
"y": 739 "y": 729
}, },
"15": "15":
{ {
"x": 1340, "x": 1343,
"y": 795 "y": 788
}, },
"16": "16":
{ {
"x": 1458, "x": 1462,
"y": 855 "y": 847
}, },
"17": "17":
{ {
"x": 1575, "x": 1572,
"y": 912 "y": 906
}, },
"18": "18":
{ {
"x": 1693, "x": 1678,
"y": 972 "y": 965
}, },
"19": "19":
{ {
"x": 997, "x": 1013,
"y": 739 "y": 729
}, },
"20": "20":
{ {
"x": 1111, "x": 1114,
"y": 795 "y": 788
}, },
"21": "21":
{ {
"x": 1225, "x": 1233,
"y": 851 "y": 847
}, },
"22": "22":
{ {
"x": 1341, "x": 1352,
"y": 910 "y": 906
}, },
"23": "23":
{ {
"x": 1461, "x": 1458,
"y": 967 "y": 965
}, },
"24": "24":
{ {
"x": 1578, "x": 1572,
"y": 1025 "y": 1024
}, },
"25": "25":
{ {
"x": 882, "x": 894,
"y": 795 "y": 788
}, },
"26": "26":
{ {
"x": 997, "x": 1004,
"y": 851 "y": 847
}, },
"27": "27":
{ {
"x": 1111, "x": 1123,
"y": 907 "y": 906
}, },
"28": "28":
{ {
"x": 1226, "x": 1233,
"y": 963 "y": 965
}, },
"29": "29":
{ {
"x": 1343, "x": 1347,
"y": 1025 "y": 1024
}, },
"30": "30":
{ {
"x": 1460, "x": 1462,
"y": 1084 "y": 1083
} }
} }
} }

View File

@ -1,10 +1,12 @@
import os import os
from io import StringIO
from typing import Any, List, Optional
import aiosqlite import aiosqlite
from zhenxun.services.log import logger from zhenxun.services.log import logger
from .config import CJsonManager, g_sDBFilePath, g_sDBPath from .config import g_pJsonManager, g_sDBFilePath, g_sDBPath
class CSqlManager: class CSqlManager:
@ -31,27 +33,100 @@ class CSqlManager:
@classmethod @classmethod
async def createDB(cls) -> bool: async def createDB(cls) -> bool:
"""初始化数据库 """初始化数据库用户信息
Returns: Returns:
bool: 是否创建成功 bool: 是否创建成功
""" """
#用户信息
userInfo = """
CREATE TABLE user (
uid INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
exp INTEGER DEFAULT 0,
point INTEGER DEFAULT 0
);
"""
#用户仓库
userStorehouse = """
CREATE TABLE storehouse (
uid INTEGER PRIMARY KEY AUTOINCREMENT,
item TEXT DEFAULT '',
plant TEXT DEFAULT ''
);
"""
#用户土地信息
with StringIO() as buffer:
buffer.write("CREATE TABLE soil (")
buffer.write("uid INTEGER PRIMARY KEY AUTOINCREMENT,")
fields = [f"soil{i} TEXT DEFAULT ''" for i in range(1, 31)]
buffer.write(",\n".join(fields))
buffer.write(");")
userSoilInfo = buffer.getvalue()
if not await cls.executeDB(userInfo):
return False
if not await cls.executeDB(userStorehouse):
return False
if not await cls.executeDB(userSoilInfo):
return False
return True
@classmethod
async def executeDB(cls, command: str) -> bool:
"""执行自定义SQL
Args:
command (str): SQL语句
Returns:
bool: 是否执行成功
"""
if len(command) <= 0:
logger.warning("数据库语句长度不能!")
return False
try: try:
await cls.m_pDB.execute(""" await cls.m_pDB.execute(command)
CREATE TABLE user (
uid INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
exp INTEGER DEFAULT 0,
point INTEGER DEFAULT 0
);
""")
await cls.m_pDB.commit() await cls.m_pDB.commit()
return True return True
except Exception as e: except Exception as e:
print(f"An error occurred: {e}") logger.warning("数据库语句执行出错:" + command)
return False return False
@classmethod
async def executeDBCursor(cls, command: str) -> Optional[List[Any]]:
"""执行自定义SQL并返回查询结果
Args:
command (str): SQL查询语句
Returns:
Optional[List[Any]]: 查询结果列表成功时None失败时
"""
if len(command) <= 0:
logger.warning("空数据库命令")
return None
try:
async with cls.m_pDB.execute(command) as cursor:
# 将Row对象转换为字典列表
results = [dict(row) for row in await cursor.fetchall()]
return results
except Exception as e:
logger.error(f"数据库执行失败: {e}")
return None
@classmethod @classmethod
async def getUserInfoByUid(cls, uid: str) -> list[dict]: async def getUserInfoByUid(cls, uid: str) -> list[dict]:
"""根据用户Uid获取用户信息 """根据用户Uid获取用户信息
@ -108,6 +183,40 @@ class CSqlManager:
logger.warning(f"查询失败: {e}") logger.warning(f"查询失败: {e}")
return -1 return -1
@classmethod
async def updateUserPointByUid(cls, uid: str, point: int) -> int:
"""根据用户Uid修改用户农场币
Args:
uid (str): 用户Uid
point (int): 要更新的新农场币数量 0
Returns:
int: 更新后的农场币数量成功时-1失败时
"""
if len(uid) <= 0:
logger.warning("参数校验失败: uid为空或农场币值无效")
return -1
try:
async with cls.m_pDB.execute(
"""UPDATE user
SET point = ?
WHERE uid = ?
RETURNING point""",
(point, uid)
) as cursor:
async for row in cursor:
return int(row[0])
logger.info(f"未找到用户或未修改数据: uid={uid}")
return -1
except Exception as e:
# 记录详细错误日志(建议记录堆栈)
logger.error(f"更新失败: {e}")
return -1
@classmethod @classmethod
async def getUserLevelByUid(cls, uid: str) -> int: async def getUserLevelByUid(cls, uid: str) -> int:
"""根据用户Uid获取用户等级 """根据用户Uid获取用户等级
@ -135,6 +244,8 @@ class CSqlManager:
for key in sorted_keys: for key in sorted_keys:
if exp >= levelDict[key]: if exp >= levelDict[key]:
return int(key) return int(key)
return -1
except Exception as e: except Exception as e:
logger.warning(f"查询失败: {e}") logger.warning(f"查询失败: {e}")
return -1 return -1
@ -188,4 +299,55 @@ class CSqlManager:
logger.warning(f"添加失败: {e}") logger.warning(f"添加失败: {e}")
return False return False
# @classmethod
# async def getUserStorehousePlant(cls, info: list[dict]) -> str:
# """获取用户仓库种子信息
# Args:
# info (list[dict]): 用户信息
# Returns:
# str: 仓库种子信息
# """
# try:
# await cls.m_pDB.execute(
# """
# INSERT INTO user (uid, name, exp, point) VALUES (?, ?, ?, ?)
# """,
# (info["uid"], info["name"], info["exp"], info["point"]),
# )
# await cls.m_pDB.commit()
# return True
# except Exception as e:
# logger.warning(f"添加失败: {e}")
# return False
# @classmethod
# async def appendUserByUserInfo(cls, info: list[dict]) -> bool:
# """添加用户信息
# Args:
# info (list[dict]): 用户信息
# Returns:
# bool: 是否添加成功
# """
# try:
# await cls.m_pDB.execute(
# """
# INSERT INTO user (uid, name, exp, point) VALUES (?, ?, ?, ?)
# """,
# (info["uid"], info["name"], info["exp"], info["point"]),
# )
# await cls.m_pDB.commit()
# return True
# except Exception as e:
# logger.warning(f"添加失败: {e}")
# return False
g_pSqlManager = CSqlManager() g_pSqlManager = CSqlManager()

View File

@ -1,5 +1,3 @@
from ast import arg
from zhenxun.services.log import logger from zhenxun.services.log import logger
from zhenxun.utils._build_image import BuildImage from zhenxun.utils._build_image import BuildImage
@ -19,24 +17,26 @@ class CDrawImageManager:
Returns: Returns:
bytes: 返回绘制结果 bytes: 返回绘制结果
""" """
# soilNumber = await self.m_pSql.getUserLevelByUid(uid) soilNumber = await g_pSqlManager.getUserLevelByUid(uid)
soilNumber = 1
img = BuildImage(background=g_sResourcePath / "background/background.jpg") img = BuildImage(background=g_sResourcePath / "background/background.jpg")
soilSize = g_pJsonManager.m_pSoil['size'] # type: ignore
#TODO 缺少判断用户土地资源状况
soil = BuildImage(background=g_sResourcePath / "soil/普通土地.png") soil = BuildImage(background=g_sResourcePath / "soil/普通土地.png")
await soil.resize(0, 229, 112) await soil.resize(0, soilSize[0], soilSize[1])
grass = BuildImage(background=g_sResourcePath / "soil/草土地.png") grass = BuildImage(background=g_sResourcePath / "soil/草土地.png")
await grass.resize(0, 229, 112) await grass.resize(0, soilSize[0], soilSize[1])
soilPos = g_pJsonManager.m_pSoil['soil'] soilPos = g_pJsonManager.m_pSoil['soil'] # type: ignore
for key, value in soilPos.items(): for key, value in soilPos.items():
if soilNumber >= int(key): if soilNumber >= int(key):
await img.paste(soil, (value['x'], value['y']), center_type="center") await img.paste(soil, (value['x'], value['y']))
else: else:
await img.paste(grass, (value['x'], value['y']), center_type="center") await img.paste(grass, (value['x'], value['y']))
return img.pic2bytes() return img.pic2bytes()

View File

@ -0,0 +1,41 @@
from zhenxun.services.log import logger
from zhenxun.utils._build_image import BuildImage
from ..config import g_pJsonManager, g_sResourcePath
from ..database import g_pSqlManager
class CFarmManager:
@classmethod
async def drawFarm(cls, uid: str) -> bytes:
"""绘制农场
Args:
uid (str): 用户UID
Returns:
bytes: 返回绘制结果
"""
soilNumber = await g_pSqlManager.getUserLevelByUid(uid)
img = BuildImage(background=g_sResourcePath / "background/background.jpg")
soilSize = g_pJsonManager.m_pSoil['size'] # type: ignore
#TODO 缺少判断用户土地资源状况
soil = BuildImage(background=g_sResourcePath / "soil/普通土地.png")
await soil.resize(0, soilSize[0], soilSize[1])
grass = BuildImage(background=g_sResourcePath / "soil/草土地.png")
await grass.resize(0, soilSize[0], soilSize[1])
soilPos = g_pJsonManager.m_pSoil['soil'] # type: ignore
for key, value in soilPos.items():
if soilNumber >= int(key):
await img.paste(soil, (value['x'], value['y']))
else:
await img.paste(grass, (value['x'], value['y']))
return img.pic2bytes()

View File

@ -1,3 +1,8 @@
from zhenxun.services.log import logger
from zhenxun.utils._build_image import BuildImage
from ..config import g_pJsonManager, g_sResourcePath
from ..database import g_pSqlManager
class CShopManager: class CShopManager:
@ -5,3 +10,22 @@ class CShopManager:
@classmethod @classmethod
async def getPlantShopImage(cls) -> bytes: async def getPlantShopImage(cls) -> bytes:
return bytes() return bytes()
@classmethod
async def buyPlant(cls, uid: str, name: str, num: int = 1) -> str:
if num <= 0:
return "请输入购买数量!"
plants = g_pJsonManager.m_pPlant['plant'] # type: ignore
for key, plant in plants.items():
if plant['name'] == name:
point = g_pSqlManager.getUserPointByUid(uid)
total = int(plant['price']) * num
if point < total
return "你的农场币不够哦~ 快速速氪金吧!"
else:
await g_pSqlManager.updateUserPointByUid(uid, point - total)
pass