✨ 更新数据库逻辑
@ -28,7 +28,7 @@ __plugin_meta__ = PluginMetadata(
|
||||
收获
|
||||
铲除
|
||||
我的作物
|
||||
出售作物 [作物/种子名称] [数量]
|
||||
出售作物 [作物/种子名称] [数量] (不填写作物
|
||||
偷菜 at
|
||||
开垦
|
||||
购买农场币 [数量] 数量为消耗金币的数量
|
||||
|
||||
@ -8,80 +8,164 @@
|
||||
{
|
||||
"4":
|
||||
{
|
||||
"level": 2,
|
||||
"level": 2,
|
||||
"point": 800,
|
||||
"item": []
|
||||
},
|
||||
"5":
|
||||
{
|
||||
"level": 3,
|
||||
"level": 3,
|
||||
"point": 1300,
|
||||
"item": []
|
||||
},
|
||||
"6":
|
||||
{
|
||||
"level": 5,
|
||||
"level": 5,
|
||||
"point": 3200,
|
||||
"item": []
|
||||
},
|
||||
"7":
|
||||
{
|
||||
"level": 7,
|
||||
"level": 7,
|
||||
"point": 5500,
|
||||
"item": []
|
||||
},
|
||||
"8":
|
||||
{
|
||||
"level": 9,
|
||||
"level": 9,
|
||||
"point": 12000,
|
||||
"item": []
|
||||
},
|
||||
"9":
|
||||
{
|
||||
"level": 15,
|
||||
"level": 11,
|
||||
"point": 19800,
|
||||
"item": []
|
||||
},
|
||||
"10":
|
||||
{
|
||||
"level":3,
|
||||
"point": 3000,
|
||||
"level": 13,
|
||||
"point": 30000,
|
||||
"item": []
|
||||
},
|
||||
"11":
|
||||
{
|
||||
"level":3,
|
||||
"point": 3000,
|
||||
"level": 15,
|
||||
"point": 50000,
|
||||
"item": []
|
||||
},
|
||||
"12":
|
||||
{
|
||||
"level":3,
|
||||
"point": 3000,
|
||||
"level": 17,
|
||||
"point": 70000,
|
||||
"item": []
|
||||
},
|
||||
"13":
|
||||
{
|
||||
"level":3,
|
||||
"point": 3000,
|
||||
"level": 19,
|
||||
"point": 90000,
|
||||
"item": []
|
||||
},
|
||||
"14":
|
||||
{
|
||||
"level":3,
|
||||
"point": 3000,
|
||||
"level": 21,
|
||||
"point": 130000,
|
||||
"item": []
|
||||
},
|
||||
"15":
|
||||
{
|
||||
"level":3,
|
||||
"point": 3000,
|
||||
"level": 23,
|
||||
"point": 150000,
|
||||
"item": []
|
||||
},
|
||||
"16":
|
||||
{
|
||||
"level":3,
|
||||
"point": 3000,
|
||||
"level": 25,
|
||||
"point": 180000,
|
||||
"item": []
|
||||
},
|
||||
"17":
|
||||
{
|
||||
"level": 27,
|
||||
"point": 230000,
|
||||
"item": []
|
||||
},
|
||||
"18":
|
||||
{
|
||||
"level": 29,
|
||||
"point": 300000,
|
||||
"item": []
|
||||
},
|
||||
"19":
|
||||
{
|
||||
"level": 31,
|
||||
"point": 500000,
|
||||
"item": []
|
||||
},
|
||||
"20":
|
||||
{
|
||||
"level": 33,
|
||||
"point": 850000,
|
||||
"item": []
|
||||
},
|
||||
"21":
|
||||
{
|
||||
"level": 36,
|
||||
"point": 1100000,
|
||||
"item": []
|
||||
},
|
||||
"22":
|
||||
{
|
||||
"level": 39,
|
||||
"point": 1300000,
|
||||
"item": []
|
||||
},
|
||||
"23":
|
||||
{
|
||||
"level": 42,
|
||||
"point": 1500000,
|
||||
"item": []
|
||||
},
|
||||
"24":
|
||||
{
|
||||
"level": 45,
|
||||
"point": 1700000,
|
||||
"item": []
|
||||
},
|
||||
"25":
|
||||
{
|
||||
"level": 48,
|
||||
"point": 2000000,
|
||||
"item": []
|
||||
},
|
||||
"26":
|
||||
{
|
||||
"level": 51,
|
||||
"point": 2200000,
|
||||
"item": []
|
||||
},
|
||||
"27":
|
||||
{
|
||||
"level": 54,
|
||||
"point": 2800000,
|
||||
"item": []
|
||||
},
|
||||
"28":
|
||||
{
|
||||
"level": 57,
|
||||
"point": 3500000,
|
||||
"item": []
|
||||
},
|
||||
"29":
|
||||
{
|
||||
"level": 60,
|
||||
"point": 4300000,
|
||||
"item": []
|
||||
},
|
||||
"30":
|
||||
{
|
||||
"level": 70,
|
||||
"point": 5200000,
|
||||
"item": []
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,10 +3,11 @@
|
||||
"zhuShi":
|
||||
[
|
||||
"level: 解锁等级",
|
||||
"buy: 购买价格",
|
||||
"limit: 限制等级 0:普通土地 1:红土地 2:黄土地 3:黑土地",
|
||||
"experience: 收获经验",
|
||||
"harvest: 收获数量",
|
||||
"price: 单价",
|
||||
"price: 果实售价",
|
||||
"time: 成熟时间 小时",
|
||||
"crop: 作物可以收几次",
|
||||
"again: 再次成熟时间 单位:小时",
|
||||
@ -19,6 +20,7 @@
|
||||
"胡萝卜":
|
||||
{
|
||||
"level": 0,
|
||||
"buy": 163,
|
||||
"limit": 0,
|
||||
"experience": 18,
|
||||
"harvest": 17,
|
||||
@ -33,6 +35,7 @@
|
||||
"白萝卜":
|
||||
{
|
||||
"level": 0,
|
||||
"buy": 125,
|
||||
"limit": 0,
|
||||
"experience": 15,
|
||||
"harvest": 16,
|
||||
@ -47,6 +50,7 @@
|
||||
"牧草":
|
||||
{
|
||||
"level": 0,
|
||||
"buy": 80,
|
||||
"limit": 0,
|
||||
"experience": 10,
|
||||
"harvest": 25,
|
||||
@ -61,6 +65,7 @@
|
||||
"大白菜":
|
||||
{
|
||||
"level": 1,
|
||||
"buy": 168,
|
||||
"limit": 0,
|
||||
"experience": 19,
|
||||
"harvest": 17,
|
||||
@ -75,6 +80,7 @@
|
||||
"大蒜":
|
||||
{
|
||||
"level": 1,
|
||||
"buy": 169,
|
||||
"limit": 0,
|
||||
"experience": 19,
|
||||
"harvest": 17,
|
||||
@ -89,6 +95,7 @@
|
||||
"水稻":
|
||||
{
|
||||
"level": 2,
|
||||
"buy": 168,
|
||||
"limit": 0,
|
||||
"experience": 19,
|
||||
"harvest": 18,
|
||||
@ -96,13 +103,14 @@
|
||||
"time": 14,
|
||||
"crop": 1,
|
||||
"again": 0,
|
||||
"phase": 6,
|
||||
"general": true,
|
||||
"phase": 5,
|
||||
"general": false,
|
||||
"sell": false
|
||||
},
|
||||
"小麦":
|
||||
{
|
||||
"level": 2,
|
||||
"buy": 168,
|
||||
"limit": 0,
|
||||
"experience": 19,
|
||||
"harvest": 18,
|
||||
@ -117,6 +125,7 @@
|
||||
"玉米":
|
||||
{
|
||||
"level": 3,
|
||||
"buy": 175,
|
||||
"limit": 0,
|
||||
"experience": 19,
|
||||
"harvest": 17,
|
||||
@ -131,6 +140,7 @@
|
||||
"油菜":
|
||||
{
|
||||
"level": 4,
|
||||
"buy": 194,
|
||||
"limit": 0,
|
||||
"experience": 29,
|
||||
"harvest": 23,
|
||||
@ -145,6 +155,7 @@
|
||||
"生菜":
|
||||
{
|
||||
"level": 4,
|
||||
"buy": 195,
|
||||
"limit": 0,
|
||||
"experience": 25,
|
||||
"harvest": 21,
|
||||
@ -155,6 +166,96 @@
|
||||
"phase": 6,
|
||||
"general": true,
|
||||
"sell": false
|
||||
},
|
||||
"小白菜":
|
||||
{
|
||||
"level": 4,
|
||||
"buy": 195,
|
||||
"limit": 0,
|
||||
"experience": 15,
|
||||
"harvest": 18,
|
||||
"price": 21,
|
||||
"time": 11,
|
||||
"crop": 1,
|
||||
"again": 0,
|
||||
"phase": 5,
|
||||
"general": true,
|
||||
"sell": false
|
||||
},
|
||||
"红枣":
|
||||
{
|
||||
"level": 5,
|
||||
"buy": 237,
|
||||
"limit": 0,
|
||||
"experience": 21,
|
||||
"harvest": 20,
|
||||
"price": 25,
|
||||
"time": 16,
|
||||
"crop": 1,
|
||||
"again": 0,
|
||||
"phase": 6,
|
||||
"general": true,
|
||||
"sell": false
|
||||
},
|
||||
"茄子":
|
||||
{
|
||||
"level": 5,
|
||||
"buy": 237,
|
||||
"limit": 0,
|
||||
"experience": 21,
|
||||
"harvest": 20,
|
||||
"price": 25,
|
||||
"time": 16,
|
||||
"crop": 1,
|
||||
"again": 0,
|
||||
"phase": 6,
|
||||
"general": true,
|
||||
"sell": false
|
||||
},
|
||||
"番茄":
|
||||
{
|
||||
"level": 6,
|
||||
"buy": 99999,
|
||||
"limit": 0,
|
||||
"experience": 22,
|
||||
"harvest": 21,
|
||||
"price": 7000,
|
||||
"time": 17,
|
||||
"crop": 1,
|
||||
"again": 0,
|
||||
"phase": 6,
|
||||
"general": true,
|
||||
"sell": false
|
||||
},
|
||||
"红玫瑰":
|
||||
{
|
||||
"level": 7,
|
||||
"buy": 251,
|
||||
"limit": 0,
|
||||
"experience": 23,
|
||||
"harvest": 22,
|
||||
"price": 27,
|
||||
"time": 18,
|
||||
"crop": 1,
|
||||
"again": 0,
|
||||
"phase": 6,
|
||||
"general": true,
|
||||
"sell": false
|
||||
},
|
||||
"豌豆":
|
||||
{
|
||||
"level": 7,
|
||||
"buy": 266,
|
||||
"limit": 0,
|
||||
"experience": 23,
|
||||
"harvest": 22,
|
||||
"price": 27,
|
||||
"time": 18,
|
||||
"crop": 1,
|
||||
"again": 0,
|
||||
"phase": 6,
|
||||
"general": true,
|
||||
"sell": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
122
database.py
@ -28,10 +28,7 @@ class CSqlManager:
|
||||
bIsExist = os.path.exists(g_sDBFilePath)
|
||||
|
||||
cls.m_pDB = await aiosqlite.connect(g_sDBFilePath)
|
||||
|
||||
#if bIsExist == False:
|
||||
#TODO 缺少判断创建失败事件
|
||||
#await cls.createDB()
|
||||
cls.m_pDB.row_factory = aiosqlite.Row
|
||||
|
||||
await cls.checkDB()
|
||||
|
||||
@ -50,11 +47,11 @@ class CSqlManager:
|
||||
await cls.m_pDB.execute("COMMIT;")
|
||||
|
||||
@classmethod
|
||||
async def getTableInfo(cls, table_name: str) -> list:
|
||||
if not re.match(r'^[A-Za-z_][A-Za-z0-9_]*$', table_name):
|
||||
raise ValueError(f"Illegal table name: {table_name}")
|
||||
async def getTableInfo(cls, tableName: str) -> list:
|
||||
if not re.match(r'^[A-Za-z_][A-Za-z0-9_]*$', tableName):
|
||||
raise ValueError(f"Illegal table name: {tableName}")
|
||||
try:
|
||||
cursor = await cls.m_pDB.execute(f'PRAGMA table_info("{table_name}")')
|
||||
cursor = await cls.m_pDB.execute(f'PRAGMA table_info("{tableName}")')
|
||||
rows = await cursor.fetchall()
|
||||
return [{"name": row[1], "type": row[2]} for row in rows]
|
||||
except aiosqlite.Error:
|
||||
@ -62,7 +59,7 @@ class CSqlManager:
|
||||
|
||||
|
||||
@classmethod
|
||||
async def ensureTableSchema(cls, table_name: str, columns: dict) -> bool:
|
||||
async def ensureTableSchema(cls, tableName: str, columns: dict) -> bool:
|
||||
"""由AI生成
|
||||
创建表或为已存在表添加缺失字段。
|
||||
返回 True 表示有变更(创建或新增列),False 则无操作
|
||||
@ -75,34 +72,44 @@ class CSqlManager:
|
||||
_type_: _description_
|
||||
"""
|
||||
|
||||
info = await cls.getTableInfo(table_name)
|
||||
info = await cls.getTableInfo(tableName)
|
||||
existing = {col['name']: col['type'].upper() for col in info}
|
||||
desired = {k: v.upper() for k, v in columns.items()}
|
||||
desired = {k: v.upper() for k, v in columns.items() if k != "PRIMARY KEY"}
|
||||
primaryKey = columns.get("PRIMARY KEY", "")
|
||||
|
||||
if not existing:
|
||||
cols_def = ", ".join(f'"{k}" {v}' for k, v in columns.items())
|
||||
await cls.m_pDB.execute(f'CREATE TABLE "{table_name}" ({cols_def});')
|
||||
colsDef = ", ".join(f'"{k}" {v}' for k, v in desired.items())
|
||||
if primaryKey:
|
||||
colsDef += f", PRIMARY KEY {primaryKey}"
|
||||
await cls.m_pDB.execute(f'CREATE TABLE "{tableName}" ({colsDef});')
|
||||
return True
|
||||
to_add = [k for k in desired if k not in existing]
|
||||
to_remove = [k for k in existing if k not in desired]
|
||||
type_mismatch = [k for k in desired if k in existing and existing[k] != desired[k]]
|
||||
if to_add and not to_remove and not type_mismatch:
|
||||
for col in to_add:
|
||||
|
||||
toAdd = [k for k in desired if k not in existing]
|
||||
toRemove = [k for k in existing if k not in desired]
|
||||
typeMismatch = [k for k in desired if k in existing and existing[k] != desired[k]]
|
||||
|
||||
if toAdd and not toRemove and not typeMismatch:
|
||||
for col in toAdd:
|
||||
await cls.m_pDB.execute(
|
||||
f'ALTER TABLE "{table_name}" ADD COLUMN "{col}" {columns[col]}'
|
||||
f'ALTER TABLE "{tableName}" ADD COLUMN "{col}" {columns[col]}'
|
||||
)
|
||||
return True
|
||||
|
||||
async with cls._transaction():
|
||||
tmp_table = f"{table_name}_new"
|
||||
cols_def = ", ".join(f'"{k}" {v}' for k, v in columns.items())
|
||||
await cls.m_pDB.execute(f'CREATE TABLE "{tmp_table}" ({cols_def});')
|
||||
common_cols = [k for k in desired if k in existing]
|
||||
if common_cols:
|
||||
cols_str = ", ".join(f'"{c}"' for c in common_cols)
|
||||
tmpTable = f"{tableName}_new"
|
||||
colsDef = ", ".join(f'"{k}" {v}' for k, v in desired.items())
|
||||
if primaryKey:
|
||||
colsDef += f", PRIMARY KEY {primaryKey}"
|
||||
await cls.m_pDB.execute(f'CREATE TABLE "{tmpTable}" ({colsDef});')
|
||||
|
||||
commonCols = [k for k in desired if k in existing]
|
||||
if commonCols:
|
||||
colsStr = ", ".join(f'"{c}"' for c in commonCols)
|
||||
await cls.m_pDB.execute(
|
||||
f'INSERT INTO "{tmp_table}" ({cols_str}) SELECT {cols_str} FROM "{table_name}";'
|
||||
f'INSERT INTO "{tmpTable}" ({colsStr}) SELECT {colsStr} FROM "{tableName}";'
|
||||
)
|
||||
await cls.m_pDB.execute(f'DROP TABLE "{table_name}";')
|
||||
await cls.m_pDB.execute(f'ALTER TABLE "{tmp_table}" RENAME TO "{table_name}";')
|
||||
await cls.m_pDB.execute(f'DROP TABLE "{tableName}";')
|
||||
await cls.m_pDB.execute(f'ALTER TABLE "{tmpTable}" RENAME TO "{tableName}";')
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
@ -155,17 +162,16 @@ class CSqlManager:
|
||||
Returns:
|
||||
bool: 是否执行成功
|
||||
"""
|
||||
|
||||
if len(command) <= 0:
|
||||
logger.warning("数据库语句长度不能!")
|
||||
logger.warning("数据库语句长度为空!")
|
||||
return False
|
||||
|
||||
try:
|
||||
await cls.m_pDB.execute(command)
|
||||
await cls.m_pDB.commit()
|
||||
async with cls._transaction():
|
||||
await cls.m_pDB.execute(command)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning("数据库语句执行出错:" + command)
|
||||
logger.warning("数据库语句执行出错:" + command)
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
@ -483,8 +489,6 @@ class CSqlManager:
|
||||
"DELETE FROM userSeed WHERE uid = ? AND seed = ?",
|
||||
(uid, seed)
|
||||
)
|
||||
|
||||
await cls.m_pDB.commit()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning(f"真寻农场addUserSeedByUid 失败: {e}")
|
||||
@ -543,17 +547,18 @@ class CSqlManager:
|
||||
Returns:
|
||||
bool: 是否成功
|
||||
"""
|
||||
|
||||
try:
|
||||
if count <= 0:
|
||||
return await cls.deleteUserSeedByName(uid, seed)
|
||||
|
||||
async with cls._transaction():
|
||||
await cls.m_pDB.execute(
|
||||
"UPDATE userSeed SET count = ? WHERE uid = ? AND seed = ?",
|
||||
(count, uid, seed)
|
||||
)
|
||||
await cls.m_pDB.commit()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning(f"真寻农场updateUserSeedByName 更新失败: {e}")
|
||||
logger.warning(f"真寻农场updateUserSeedByName失败:{e}")
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
@ -573,7 +578,6 @@ class CSqlManager:
|
||||
"DELETE FROM userSeed WHERE uid = ? AND seed = ?",
|
||||
(uid, seed)
|
||||
)
|
||||
await cls.m_pDB.commit()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning(f"真寻农场deleteUserSeedByName 删除失败: {e}")
|
||||
@ -613,12 +617,28 @@ class CSqlManager:
|
||||
"INSERT INTO userPlant (uid, plant, count) VALUES (?, ?, ?)",
|
||||
(uid, plant, count)
|
||||
)
|
||||
await cls.m_pDB.commit()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning(f"真寻农场addUserPlantByUid 失败: {e}")
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def getUserPlantByUid(cls, uid: str) -> Dict[str, int]:
|
||||
"""根据用户uid获取全部作物信息
|
||||
|
||||
Args:
|
||||
uid (str): 用户uid
|
||||
|
||||
Returns:
|
||||
Dict[str, int]: 作物名称和数量
|
||||
"""
|
||||
cursor = await cls.m_pDB.execute(
|
||||
"SELECT plant, count FROM userPlant WHERE uid=?",
|
||||
(uid,)
|
||||
)
|
||||
rows = await cursor.fetchall()
|
||||
return {row["plant"]: row["count"] for row in rows}
|
||||
|
||||
@classmethod
|
||||
async def getUserPlantByName(cls, uid: str, plant: str) -> Optional[int]:
|
||||
"""根据作物名称获取用户的作物数量
|
||||
@ -642,7 +662,7 @@ class CSqlManager:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
async def updateUserPlantByUid(cls, uid: str, plant: str, count: int) -> bool:
|
||||
async def updateUserPlantByName(cls, uid: str, plant: str, count: int) -> bool:
|
||||
"""更新 userPlant 表中某个作物的数量
|
||||
|
||||
Args:
|
||||
@ -654,28 +674,21 @@ class CSqlManager:
|
||||
bool: 是否更新成功
|
||||
"""
|
||||
try:
|
||||
if count <= 0:
|
||||
return await cls.deleteUserPlantByName(uid, plant)
|
||||
|
||||
async with cls._transaction():
|
||||
#更新作物数量
|
||||
await cls.m_pDB.execute(
|
||||
"UPDATE userPlant SET count = ? WHERE uid = ? AND plant = ?",
|
||||
(count, uid, plant)
|
||||
)
|
||||
|
||||
#如果作物数量为 0,删除记录
|
||||
if count <= 0:
|
||||
await cls.m_pDB.execute(
|
||||
"DELETE FROM userPlant WHERE uid = ? AND plant = ?",
|
||||
(uid, plant)
|
||||
)
|
||||
|
||||
await cls.m_pDB.commit()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning(f"真寻农场updateUserPlantByUid 更新失败: {e}")
|
||||
logger.warning(f"真寻农场updateUserPlantByName失败:{e}")
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def deleteUserPlantByUid(cls, uid: str, plant: str) -> bool:
|
||||
async def deleteUserPlantByName(cls, uid: str, plant: str) -> bool:
|
||||
"""从 userPlant 表中删除某个作物记录
|
||||
|
||||
Args:
|
||||
@ -691,10 +704,9 @@ class CSqlManager:
|
||||
"DELETE FROM userPlant WHERE uid = ? AND plant = ?",
|
||||
(uid, plant)
|
||||
)
|
||||
await cls.m_pDB.commit()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning(f"真寻农场deleteUserPlantByUid 删除失败: {e}")
|
||||
logger.warning(f"真寻农场deleteUserPlantByName 失败: {e}")
|
||||
return False
|
||||
|
||||
g_pSqlManager = CSqlManager()
|
||||
|
||||
64
farm/farm.py
@ -213,9 +213,12 @@ class CFarmManager:
|
||||
|
||||
currentStage = int(elapsedHour / (plantInfo['time'] / (plantInfo['phase'] - 1)))
|
||||
|
||||
#TODO 缺少判断部分种子是否是通用0阶段图片
|
||||
if currentStage <= 0:
|
||||
plant = BuildImage(background = g_sResourcePath / f"plant/basic/0.png")
|
||||
if plantInfo['general'] == False:
|
||||
plant = BuildImage(background = g_sResourcePath / f"plant/{soilInfo[0]}/0.png")
|
||||
else:
|
||||
plant = BuildImage(background = g_sResourcePath / f"plant/basic/0.png")
|
||||
|
||||
await plant.resize(0, 35, 58)
|
||||
else:
|
||||
plant = BuildImage(background = g_sResourcePath / f"plant/{soilInfo[0]}/{currentStage}.png")
|
||||
@ -395,7 +398,7 @@ class CFarmManager:
|
||||
harvestRecords.append(f"收获作物:{plantId},数量为:{number},经验为:{plantInfo['experience']}")
|
||||
|
||||
#更新数据库操作
|
||||
await g_pSqlManager.addUserPlantByPlant(uid, plantId, number)
|
||||
await g_pSqlManager.addUserPlantByUid(uid, plantId, number)
|
||||
await g_pSqlManager.updateUserSoilStatusByPlantName(uid, soil_name, "", 4)
|
||||
|
||||
if experience > 0:
|
||||
@ -455,7 +458,6 @@ class CFarmManager:
|
||||
Returns:
|
||||
bytes: 返回图片
|
||||
"""
|
||||
|
||||
data_list = []
|
||||
column_name = [
|
||||
"-",
|
||||
@ -468,48 +470,40 @@ class CFarmManager:
|
||||
|
||||
plant = await g_pSqlManager.getUserPlantByUid(uid)
|
||||
|
||||
if plant == None:
|
||||
if plant is None:
|
||||
result = await ImageTemplate.table_page(
|
||||
"作物仓库",
|
||||
"播种示例:@小真寻 出售作物 大白菜 [数量]",
|
||||
column_name,
|
||||
data_list,
|
||||
)
|
||||
|
||||
return result.pic2bytes()
|
||||
|
||||
sell = ""
|
||||
for item in plant.split(','):
|
||||
if '|' in item:
|
||||
plantName, count = item.split('|', 1) #分割一次,避免多竖线问题
|
||||
try:
|
||||
plantInfo = g_pJsonManager.m_pPlant['plant'][plantName]
|
||||
for name, count in plant.items(): # 使用 .items() 来遍历字典
|
||||
plantInfo = g_pJsonManager.m_pPlant['plant'][name]
|
||||
icon = ""
|
||||
icon_path = g_sResourcePath / f"plant/{name}/icon.png"
|
||||
if icon_path.exists():
|
||||
icon = (icon_path, 33, 33)
|
||||
|
||||
icon = ""
|
||||
icon_path = g_sResourcePath / f"plant/{plantName}/icon.png"
|
||||
if icon_path.exists():
|
||||
icon = (icon_path, 33, 33)
|
||||
if plantInfo['again'] == True:
|
||||
sell = "可以"
|
||||
else:
|
||||
sell = "不可以"
|
||||
|
||||
if plantInfo['again'] == True:
|
||||
sell = "可以"
|
||||
else:
|
||||
sell = "不可以"
|
||||
number = int(count) * plantInfo['price']
|
||||
|
||||
number = int(count) * plantInfo['price']
|
||||
|
||||
data_list.append(
|
||||
[
|
||||
icon,
|
||||
plantName,
|
||||
count,
|
||||
plantInfo['price'],
|
||||
number,
|
||||
sell
|
||||
]
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
continue
|
||||
data_list.append(
|
||||
[
|
||||
icon,
|
||||
name,
|
||||
count,
|
||||
plantInfo['price'],
|
||||
number,
|
||||
sell
|
||||
]
|
||||
)
|
||||
|
||||
result = await ImageTemplate.table_page(
|
||||
"作物仓库",
|
||||
@ -611,7 +605,7 @@ class CFarmManager:
|
||||
logger.info(f"{randomNumber}")
|
||||
|
||||
if randomNumber > 0:
|
||||
await g_pSqlManager.addUserPlantByPlant(uid, plantId, randomNumber)
|
||||
await g_pSqlManager.addUserPlantByUid(uid, plantId, randomNumber)
|
||||
|
||||
harvestRecords.append(f"成功偷到作物:{plantId},数量为:{randomNumber}")
|
||||
stealingStatus.append(f"{uid}-{randomNumber}")
|
||||
|
||||
99
farm/shop.py
@ -1,4 +1,5 @@
|
||||
import math
|
||||
from re import I
|
||||
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.utils._build_image import BuildImage
|
||||
@ -22,8 +23,9 @@ class CShopManager:
|
||||
column_name = [
|
||||
"-",
|
||||
"种子名称",
|
||||
"种子单价"
|
||||
"解锁等级",
|
||||
"种子单价",
|
||||
"果实单价",
|
||||
"收获经验",
|
||||
"收获数量",
|
||||
"成熟时间(小时)",
|
||||
@ -53,6 +55,7 @@ class CShopManager:
|
||||
[
|
||||
icon,
|
||||
key,
|
||||
plant['buy'],
|
||||
plant['level'],
|
||||
plant['price'],
|
||||
plant['experience'],
|
||||
@ -105,7 +108,7 @@ class CShopManager:
|
||||
return "你的等级不够哦,努努力吧"
|
||||
|
||||
point = await g_pSqlManager.getUserPointByUid(uid)
|
||||
total = int(plantInfo['price']) * num
|
||||
total = int(plantInfo['buy']) * num
|
||||
|
||||
logger.debug(f"用户:{uid}购买{name},数量为{num}。用户农场币为{point},购买需要{total}")
|
||||
|
||||
@ -114,7 +117,7 @@ class CShopManager:
|
||||
else:
|
||||
await g_pSqlManager.updateUserPointByUid(uid, point - total)
|
||||
|
||||
if await g_pSqlManager.addUserSeedByPlant(uid, name, num) == False:
|
||||
if await g_pSqlManager.addUserSeedByUid(uid, name, num) == False:
|
||||
return "购买失败,执行数据库错误!"
|
||||
|
||||
return f"成功购买{name},花费{total}农场币, 剩余{point - total}农场币"
|
||||
@ -129,81 +132,39 @@ class CShopManager:
|
||||
Returns:
|
||||
str:
|
||||
"""
|
||||
|
||||
plant = await g_pSqlManager.getUserPlantByUid(uid)
|
||||
|
||||
if plant == None:
|
||||
plantDict = await g_pSqlManager.getUserPlantByUid(uid)
|
||||
if not plantDict:
|
||||
return "你仓库没有可以出售的作物"
|
||||
|
||||
point = 0
|
||||
totalSold = 0
|
||||
remainingItems = []
|
||||
totalPoint = 0
|
||||
|
||||
isAll = False
|
||||
if num == -1:
|
||||
isAll = True
|
||||
|
||||
items = plant.split(',')
|
||||
if len(name) <= 0:
|
||||
#出售全部
|
||||
for item in items:
|
||||
if '|' in item:
|
||||
plant_name, count_str = item.split('|', 1)
|
||||
try:
|
||||
count = int(count_str)
|
||||
plant_info = g_pJsonManager.m_pPlant['plant'][plant_name]
|
||||
point += plant_info['price'] * count
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
await g_pSqlManager.updateUserPlantByUid(uid, "") # 清空仓库
|
||||
if not name:
|
||||
for plantName, count in plantDict.items():
|
||||
plantInfo = g_pJsonManager.m_pPlant['plant'][plantName]
|
||||
totalPoint += plantInfo['price'] * count
|
||||
await g_pSqlManager.deleteUserPlantByName(uid, plantName)
|
||||
else:
|
||||
for item in items:
|
||||
if '|' in item:
|
||||
plantName, countStr = item.split('|', 1)
|
||||
try:
|
||||
count = int(countStr)
|
||||
if plantName == name:
|
||||
currentCount = plantDict.get(name)
|
||||
if currentCount is None:
|
||||
return f"出售作物{name}出错:你没有这种作物"
|
||||
|
||||
if isAll:
|
||||
sellAmount = count
|
||||
else:
|
||||
sellAmount = min(num, count)
|
||||
if num == -1:
|
||||
sellCount = currentCount
|
||||
else:
|
||||
if num > currentCount:
|
||||
return f"出售作物{name}出错:数量不足"
|
||||
sellCount = num
|
||||
|
||||
totalSold += sellAmount
|
||||
remaining = count - sellAmount
|
||||
|
||||
if remaining > 0:
|
||||
remainingItems.append(f"{plantName}|{remaining}")
|
||||
|
||||
if isAll == False:
|
||||
num -= sellAmount
|
||||
|
||||
break
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
|
||||
if num > 0 and isAll == False:
|
||||
return f"出售作物{name}出错:数量不足"
|
||||
|
||||
#计算收益
|
||||
try:
|
||||
plantInfo = g_pJsonManager.m_pPlant['plant'][name]
|
||||
totalPoint = plantInfo['price'] * totalSold
|
||||
except KeyError:
|
||||
return f"出售作物{name}出错:作物不存在"
|
||||
totalPoint = plantInfo['price'] * sellCount
|
||||
await g_pSqlManager.addUserPlantByUid(uid, name, -sellCount)
|
||||
|
||||
#更新剩余作物
|
||||
remainingPlant = ','.join(remainingItems) if remainingItems else ""
|
||||
await g_pSqlManager.updateUserPlantByUid(uid, remainingPlant)
|
||||
point = await g_pSqlManager.getUserPointByUid(uid)
|
||||
await g_pSqlManager.updateUserPointByUid(uid, point + totalPoint)
|
||||
|
||||
#更新农场币
|
||||
p = await g_pSqlManager.getUserPointByUid(uid)
|
||||
await g_pSqlManager.updateUserPointByUid(uid, p + totalPoint)
|
||||
|
||||
if name:
|
||||
return f"成功出售{name},获得农场币:{totalPoint}"
|
||||
if not name:
|
||||
return f"成功出售所有作物,获得农场币:{totalPoint},当前农场币:{point + totalPoint}"
|
||||
else:
|
||||
return f"成功出售所有作物,获得农场币:{totalPoint}"
|
||||
return f"成功出售{name},获得农场币:{totalPoint},当前农场币:{point + totalPoint}"
|
||||
|
||||
g_pShopManager = CShopManager()
|
||||
|
||||
88
request.py
@ -1,31 +1,87 @@
|
||||
from email.mime import base
|
||||
from unittest import result
|
||||
|
||||
import requests
|
||||
import httpx
|
||||
|
||||
from zhenxun.configs.config import Config
|
||||
from zhenxun.services.log import logger
|
||||
|
||||
|
||||
class CRequestManager:
|
||||
|
||||
@classmethod
|
||||
async def post(cls, url, json_data=None, form_data=None):
|
||||
"""发送 POST 请求(支持 JSON/Form-Data 格式)"""
|
||||
async def download(cls, url: str, savePath: str, fileName: str) -> bool:
|
||||
"""下载文件到指定路径
|
||||
|
||||
Args:
|
||||
url (str): 文件的下载链接
|
||||
savePath (str): 保存文件的文件夹路径
|
||||
fileName (str): 保存后的文件名
|
||||
|
||||
Returns:
|
||||
bool: 是否下载成功
|
||||
"""
|
||||
try:
|
||||
headers = {"Content-Type": "application/json"} if json_data else None
|
||||
response = requests.post(
|
||||
url,
|
||||
json=json_data,
|
||||
data=form_data,
|
||||
headers=headers,
|
||||
timeout=5
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"请求失败: {e}")
|
||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
||||
response = await client.get(url)
|
||||
if response.status_code == 200:
|
||||
fullPath = savePath.rstrip("/") + "/" + fileName
|
||||
with open(fullPath, "wb") as f:
|
||||
f.write(response.content)
|
||||
return True
|
||||
else:
|
||||
logger.warning(f"文件下载失败: HTTP {response.status_code} {response.text}")
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.warning(f"下载文件异常: {e}")
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def post(cls, endpoint: str, name: str = "", jsonData: dict = None, formData: dict = None) -> dict:
|
||||
"""发送POST请求到指定接口,供其他方法统一调用
|
||||
|
||||
Args:
|
||||
endpoint (str): 请求的接口路径
|
||||
name (str, optional): 操作名称用于日志记录
|
||||
jsonData (dict, optional): 以JSON格式发送的数据
|
||||
formData (dict, optional): 以表单格式发送的数据
|
||||
|
||||
Raises:
|
||||
ValueError: 当jsonData和formData都未提供时抛出
|
||||
|
||||
Returns:
|
||||
dict: 返回请求结果的JSON数据
|
||||
"""
|
||||
if jsonData is None and formData is None:
|
||||
raise ValueError("post请求必须提供jsonData或formData其中之一")
|
||||
|
||||
baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
|
||||
|
||||
url = f"{baseUrl.rstrip('/')}/{endpoint.lstrip('/')}"
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=5.0) as client:
|
||||
if jsonData is not None:
|
||||
response = await client.post(url, json=jsonData)
|
||||
else:
|
||||
response = await client.post(url, data=formData)
|
||||
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
else:
|
||||
logger.warning(f"真寻农场{name}请求失败: HTTP {response.status_code} {response.text}")
|
||||
return {}
|
||||
except httpx.RequestError as e:
|
||||
logger.warning(f"真寻农场{name}请求异常: {e}")
|
||||
return {}
|
||||
except Exception as e:
|
||||
logger.warning(f"真寻农场{name}处理异常: {e}")
|
||||
return {}
|
||||
|
||||
|
||||
@classmethod
|
||||
async def sign(cls, uid: str) -> str:
|
||||
a = await cls.post("http://diuse.work:9099/testPost", json_data={"level":3})
|
||||
a = await cls.post("http://diuse.work:9099/testPost", jsonData={"level":3})
|
||||
|
||||
result = ""
|
||||
|
||||
|
||||
BIN
resource/plant/水稻/0.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |