From d17c1b8ed71fd1b77ab9ee98a5e1975d089b0f5c Mon Sep 17 00:00:00 2001 From: Art_Sakura <1754798088@qq.com> Date: Tue, 8 Apr 2025 19:00:17 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20=E6=9B=B4=E6=96=B0=E4=BA=86?= =?UTF-8?q?=E5=AF=B9=E6=95=B0=E6=8D=AE=E5=BA=93=E7=9A=84=E8=A1=A8=E3=80=81?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __init__.py | 31 +++++++--- command.py | 27 --------- config/level.json | 25 -------- database.py | 145 +++++++++++++++++++++++++++++++++------------- farm/farm.py | 20 +++++-- request.py | 37 ++++++++++++ 6 files changed, 179 insertions(+), 106 deletions(-) create mode 100644 request.py diff --git a/__init__.py b/__init__.py index 297a380..784b1ae 100644 --- a/__init__.py +++ b/__init__.py @@ -1,11 +1,11 @@ from nonebot import get_driver from nonebot.plugin import PluginMetadata -from zhenxun.configs.utils import Command, PluginExtraData +from zhenxun.configs.utils import Command, PluginExtraData, RegisterConfig from zhenxun.services.log import logger from zhenxun.utils.message import MessageUtils -from .command import diuse_farm, diuse_register +from .command import diuse_farm, diuse_register, reclamation from .config import g_pJsonManager from .database import g_pSqlManager from .farm.farm import g_pFarmManager @@ -30,13 +30,33 @@ __plugin_meta__ = PluginMetadata( 出售作物 [作物/种子名称] [数量] 偷菜 at 开垦 - 购买农场币 [数量] 金币转换农场币比率是 1 : 2 + 购买农场币 [数量] 数量为消耗金币的数量 """.strip(), extra=PluginExtraData( author="Art_Sakura", version="1.0", commands=[Command(command="我的农场")], - menu_type="群内小游戏" + menu_type="群内小游戏", + configs=[ + RegisterConfig( + key="兑换倍数", + value="2", + help="金币兑换农场币的倍数 默认值为: 2倍", + default_value="2", + ), + RegisterConfig( + key="手续费", + value="0.2", + help="金币兑换农场币的手续费 默认值为: 0.2 实际意义为20%手续费", + default_value="0.2", + ), + RegisterConfig( + key="服务地址", + value="http://diuse.work", + help="签到、交易行、活动等服务器地址", + default_value="http://diuse.work", + ) + ] ).to_dict(), ) driver = get_driver() @@ -51,9 +71,6 @@ async def start(): # 初始化读取Json await g_pJsonManager.init() - # await g_pFarmManager.reclamation("1754798088") - # await g_pSqlManager.initUserInfoByUid("1754798088", "Art_Sakura", 0, 100) - # 析构函数 @driver.on_shutdown async def shutdown(): diff --git a/command.py b/command.py index c65354b..550dd44 100644 --- a/command.py +++ b/command.py @@ -258,33 +258,6 @@ async def _(session: Uninfo): res = await g_pFarmManager.reclamation(uid) await MessageUtils.build_message(res).send(reply_to=True) -diuse_farm.shortcut( - "开垦", - command="我的农场", - arguments=["reclamation"], - prefix=True, -) - -@diuse_farm.assign("reclamation") -async def _(session: Uninfo): - uid = str(session.user.id) - point = await g_pSqlManager.getUserPointByUid(uid) - - if point < 0: - await MessageUtils.build_message("尚未开通农场,快at我发送 开通农场 开通吧").send() - return None - - result = await g_pFarmManager.getUserPlantByUid(uid) - await MessageUtils.build_message(result).send(reply_to=True) - - diuse_farm.set_path_arg("reclamation", "result") - - -@diuse_farm.got_path("test", "测试一下") -async def _(name: str): - await MessageUtils.build_message(name).send(reply_to=True) - - diuse_farm.shortcut( "出售作物(?P.*?)", command="我的农场", diff --git a/config/level.json b/config/level.json index 37dfee7..6fb4d88 100644 --- a/config/level.json +++ b/config/level.json @@ -1,32 +1,7 @@ { -<<<<<<< HEAD "soil":[1, 1, 1, 2, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 70 -======= - "level": - { - "0": 0, - "1": 50, - "2": 75, - "3": 125, - "4": 185, - "5": 200, - "6": 250, - "7": 275, - "8": 350, - "9": 500, - "10": 850, - "11": 1250, - "12": 2250, - "13": 3500, - "14": 4500, - "15": 5800 - }, - "soil":[1, 1, 1, 2, 3, 5, 7, 9, 12, 15, - 18, 21, 25, 29, 33, 38, 43, 48, 54, 60, - 66, 72, 78, 85, 92, 99, 106, 114, 120, 130 ->>>>>>> f85ab9758c44ce45c6aae9e792f7a5d9e2f7459a ], "reclamation": { diff --git a/database.py b/database.py index 269b047..ef4777e 100644 --- a/database.py +++ b/database.py @@ -1,5 +1,6 @@ import math import os +import re from datetime import date, datetime, timedelta from io import StringIO from math import e @@ -20,7 +21,6 @@ class CSqlManager: async def cleanup(cls): if cls.m_pDB: await cls.m_pDB.close() - cls.m_pDB = None @classmethod async def init(cls) -> bool: @@ -28,62 +28,125 @@ class CSqlManager: cls.m_pDB = await aiosqlite.connect(g_sDBFilePath) - if bIsExist == False: - # TODO 缺少判断创建失败事件 - await cls.createDB() + #if bIsExist == False: + #TODO 缺少判断创建失败事件 + #await cls.createDB() + + await cls.checkDB() return True @classmethod - async def createDB(cls) -> bool: - """初始化数据库用户信息表 + async def getColumns(cls, tableName): + """ 由AI生成 + 获取表的列信息 + """ + try: + cursor = await cls.m_pDB.execute(f'PRAGMA table_info("{tableName}")') + columns = [row[1] for row in await cursor.fetchall()] + return columns + except aiosqlite.Error as e: + logger.error(f"获取表结构失败: {str(e)}") + raise + + @classmethod + async def ensure_table_exists(cls, tableName, columns) -> bool: + """智能创建并分析数据库表、字段是否存在 由AI生成 + + Args: + tableName (_type_): 表名 + columns (_type_): 字典 Returns: - bool: 是否创建成功 + _type_: _description_ """ + try: + current_columns = await cls.getColumns(tableName) - #用户信息 - userInfo = """ - CREATE TABLE user ( - uid INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT NOT NULL, - exp INTEGER DEFAULT 0, - point INTEGER DEFAULT 0, - soil INTEGER DEFAULT 3, - stealing TEXT DEFAULT NULL - ); - """ + #检查表是否存在 + table_exists = bool(current_columns) - #用户仓库 - userStorehouse = """ - CREATE TABLE storehouse ( - uid INTEGER PRIMARY KEY AUTOINCREMENT, - item TEXT DEFAULT '', - plant TEXT DEFAULT '', - seed TEXT DEFAULT '' - ); - """ + #如果表不存在,直接创建 + if not table_exists: + create_sql = f''' + CREATE TABLE "{tableName}" ( + {", ".join(f'"{k}" {v}' for k, v in columns.items())} + ); + ''' + await cls.m_pDB.execute(create_sql) + await cls.m_pDB.commit() #显式提交新建表操作 + return True - #用户土地信息 - with StringIO() as buffer: - buffer.write("CREATE TABLE soil (") - buffer.write("uid INTEGER PRIMARY KEY AUTOINCREMENT,") + #表存在时的处理 + columns_to_add = [] + columns_to_remove = [] - fields = [f"soil{i} TEXT DEFAULT ''" for i in range(1, 31)] - buffer.write(",\n".join(fields)) + #检查需要添加的列 + for k, v in columns.items(): + if k not in current_columns: + columns_to_add.append(f'"{k}" {v}') - buffer.write(");") + #检查需要移除的列 + for col in current_columns: + if col not in columns.keys(): + columns_to_remove.append(col) - userSoilInfo = buffer.getvalue() + #执行修改 + if columns_to_add or columns_to_remove: + try: + #开启事务(使用connection级别的事务控制) + await cls.m_pDB.execute('BEGIN TRANSACTION') + + #添加新列 + for col_def in columns_to_add: + await cls.m_pDB.execute(f'ALTER TABLE "{tableName}" ADD COLUMN {col_def}') + + #删除旧列 + for col in columns_to_remove: + await cls.m_pDB.execute(f'ALTER TABLE "{tableName}" DROP COLUMN "{col}"') + + #显式提交事务 + await cls.m_pDB.commit() + return True + except Exception as e: + #回滚事务 + await cls.m_pDB.rollback() + logger.error(f"表结构迁移失败: {str(e)}") - if not await cls.executeDB(userInfo): return False + except aiosqlite.Error as e: + logger.error(f"表结构迁移失败: {str(e)}") - if not await cls.executeDB(userStorehouse): - return False + return True - if not await cls.executeDB(userSoilInfo): - return False + @classmethod + async def checkDB(cls) -> bool: + userInfo = { + "uid": "INTEGER PRIMARY KEY AUTOINCREMENT", + "name": "TEXT NOT NULL", + "exp": "INTEGER DEFAULT 0", + "point": "INTEGER DEFAULT 0", + "soil": "INTEGER DEFAULT 3", + "stealing": "TEXT DEFAULT NULL" + } + + userStorehouse = { + "uid": "INTEGER PRIMARY KEY AUTOINCREMENT", + "item": "TEXT DEFAULT ''", + "plant": "TEXT DEFAULT ''", + "seed": "TEXT DEFAULT ''" + } + + userSoilInfo = { + "uid": "INTEGER PRIMARY KEY AUTOINCREMENT", + **{f"soil{i}": "TEXT DEFAULT ''" for i in range(1, 31)} + } + + await cls.ensure_table_exists("user", userInfo) + + await cls.ensure_table_exists("storehouse", userStorehouse) + + await cls.ensure_table_exists("soil", userSoilInfo) return True @@ -373,7 +436,7 @@ class CSqlManager: s = "" else: #获取种子信息 这里能崩我吃 - plantInfo = g_pJsonManager.m_pPlant['plant'][plant] # type: ignore + plantInfo = g_pJsonManager.m_pPlant['plant'][plant] #type: ignore currentTime = datetime.now() newTime = currentTime + timedelta(hours=int(plantInfo['time'])) diff --git a/farm/farm.py b/farm/farm.py index 2dbc3c0..d14efbf 100644 --- a/farm/farm.py +++ b/farm/farm.py @@ -4,6 +4,9 @@ from datetime import date, datetime from io import StringIO from typing import Dict, List, Tuple +from numpy import number + +from zhenxun.configs.config import Config from zhenxun.models.user_console import UserConsole from zhenxun.services.log import logger from zhenxun.utils._build_image import BuildImage @@ -22,18 +25,23 @@ class CFarmManager: user = await UserConsole.get_user(uid) - point = num // 2 - - if user.gold < point: + if user.gold < num: return "你的金币不足" - await UserConsole.reduce_gold(uid, point, GoldHandle.BUY , 'zhenxun_plugin_farm') + await UserConsole.reduce_gold(uid, num, GoldHandle.BUY , 'zhenxun_plugin_farm') + + pro = Config.get_config("zhenxun_plugin_farm", "兑换倍数") + tax = Config.get_config("zhenxun_plugin_farm", "手续费") + + exc = num * pro + point = exc - (exc * tax) p = await g_pSqlManager.getUserPointByUid(uid) + number = point + p - await g_pSqlManager.updateUserPointByUid(uid, num + p) + await g_pSqlManager.updateUserPointByUid(uid, number) - return f"充值{num}农场币成功,当前农场币:{num + p}" + return f"充值{num}农场币成功,当前农场币:{number}" @classmethod async def drawFarmByUid(cls, uid: str) -> bytes: diff --git a/request.py b/request.py new file mode 100644 index 0000000..93a44ef --- /dev/null +++ b/request.py @@ -0,0 +1,37 @@ +from unittest import result + +import requests + + +class CRequestManager: + + @classmethod + async def post(cls, url, json_data=None, form_data=None): + """发送 POST 请求(支持 JSON/Form-Data 格式)""" + 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}") + return {} + + @classmethod + async def sign(cls, uid: str) -> str: + a = await cls.post("http://diuse.work:9099/testPost", json_data={"level":3}) + + result = "" + if int(a["type"]) == 1: + result = f"签到成功" + + return result + + +g_pRequestManager = CRequestManager()