diff --git a/.gitignore b/.gitignore index cb3dd7ab..d8bc4873 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ src/resources/templates/latest-debug.html test.py line_count.py +mypy.ini # nuitka main.build/ diff --git a/docs/usage/lyapi.md b/docs/usage/lyapi.md index 8fedd484..e96adb2f 100644 --- a/docs/usage/lyapi.md +++ b/docs/usage/lyapi.md @@ -10,36 +10,4 @@ tag: ## **轻雪API** -轻雪API是轻雪运行中部分服务的支持,由`go`语言编写,例如错误反馈,图床链接等,目前服务由轻雪服务器提供,用户无需额外部署 - -接口 - -- `url` `https://api.liteyuki.icu` - -- `POST` `/register` 注册一个Bot - - 参数 - - `name` `string` Bot名称 - - `version` `string` Bot版本 - - `version_id` `int` Bot版本ID - - `python` `string` Python版本 - - `os` `string` 操作系统 - - 返回 - - `code` `int` 状态码 - - `liteyuki_id` `string` 轻雪ID - -- `POST` `/bug_report` 上报错误 - - 参数 - - `liteyuki_id` `string` 轻雪ID - - `content` `string` 错误信息 - - `device_info` `string` 设备信息 - - 返回 - - `code` `int` 状态码 - - `report_id` `string` 错误ID - -- `POST` `/upload_image` 图床上传 - - 参数 - - `image` `file` 图片文件 - - `liteyuki_id` `string` 轻雪ID,用于鉴权 - - 返回 - - `code` `int` 状态码 - - `url` `string` 图床链接 \ No newline at end of file +轻雪API是轻雪运行中部分服务的支持,由`go`语言编写,例如错误反馈,图床链接等,目前服务由轻雪服务器提供,用户无需额外部署 \ No newline at end of file diff --git a/liteyuki/_plugins/plugin_loader/__init__.py b/liteyuki/_plugins/plugin_loader/__init__.py deleted file mode 100644 index 6763b57f..00000000 --- a/liteyuki/_plugins/plugin_loader/__init__.py +++ /dev/null @@ -1,41 +0,0 @@ -import asyncio -import multiprocessing -import time - -from liteyuki.plugin import PluginMetadata -from liteyuki import get_bot, chan - -__plugin_metadata__ = PluginMetadata( - name="plugin_loader", - description="轻雪插件加载器", - usage="", - type="liteyuki-main", - homepage="" -) - -from src.utils import TempConfig, common_db - -liteyuki = get_bot() - - -@liteyuki.on_after_start -def _(): - temp_data = common_db.where_one(TempConfig(), default=TempConfig()) - # 储存重启计时信息 - if temp_data.data.get("reload", False): - delta_time = time.time() - temp_data.data.get("reload_time", 0) - temp_data.data["delta_time"] = delta_time - common_db.save(temp_data) # 更新数据 - - -print("轻雪实例", liteyuki) -chan.send(liteyuki, "instance") -# @liteyuki.on_before_start -# def _(): -# print("轻雪启动中") -# -# -# @liteyuki.on_after_start -# async def _(): -# print("轻雪启动完成") -# chan.send("轻雪启动完成") diff --git a/liteyuki/_plugins/plugin_loader/data_source.py b/liteyuki/_plugins/plugin_loader/data_source.py deleted file mode 100644 index e744bd8c..00000000 --- a/liteyuki/_plugins/plugin_loader/data_source.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved - -@Time : 2024/7/23 下午11:21 -@Author : snowykami -@Email : snowykami@outlook.com -@File : data_source.py -@Software: PyCharm -""" diff --git a/liteyuki/bot/__init__.py b/liteyuki/bot/__init__.py index 4871a247..55163a8e 100644 --- a/liteyuki/bot/__init__.py +++ b/liteyuki/bot/__init__.py @@ -1,3 +1,4 @@ +import threading import time import asyncio from typing import Any, Optional @@ -29,7 +30,10 @@ class LiteyukiBot: self.lifespan: Lifespan = Lifespan() self.chan = Channel() # 进程通信通道 - self.pm: Optional[ProcessManager] = None # 启动时实例化 + self.pm: ProcessManager = ProcessManager(bot=self, chan=self.chan) + self.loop = asyncio.new_event_loop() + asyncio.set_event_loop(self.loop) + self.loop_thread = threading.Thread(target=self.loop.run_forever, daemon=True) print("\033[34m" + r""" __ ______ ________ ________ __ __ __ __ __ __ ______ @@ -44,8 +48,10 @@ $$$$$$$$/ $$$$$$/ $$/ $$$$$$$$/ $$/ $$$$$$/ $$/ $$/ $$$$$$/ """ + "\033[0m") def run(self): - # load_plugins("liteyuki/plugins") # 加载轻雪插件 - self.pm = ProcessManager(bot=self, chan=self.chan) + load_plugins("liteyuki/plugins") # 加载轻雪插件 + + self.loop_thread.start() # 启动事件循环 + asyncio.run(self.lifespan.before_start()) # 启动前钩子 self.pm.add_target("nonebot", nb_run, **self.config) self.pm.start("nonebot") @@ -53,7 +59,7 @@ $$$$$$$$/ $$$$$$/ $$/ $$$$$$$$/ $$/ $$$$$$/ $$/ $$/ $$$$$$/ self.pm.add_target("melobot", mb_run, **self.config) self.pm.start("melobot") - run_coroutine(self.lifespan.after_start()) # 启动前 + asyncio.run(self.lifespan.after_start()) # 启动后钩子 def restart(self, name: Optional[str] = None): """ @@ -64,14 +70,14 @@ $$$$$$$$/ $$$$$$/ $$/ $$$$$$$$/ $$/ $$$$$$/ $$/ $$/ $$$$$$/ """ logger.info("Stopping LiteyukiBot...") - logger.debug("Running before_restart functions...") - run_coroutine(self.lifespan.before_restart()) - logger.debug("Running before_shutdown functions...") - run_coroutine(self.lifespan.before_shutdown()) + + self.loop.create_task(self.lifespan.before_shutdown()) # 重启前钩子 + self.loop.create_task(self.lifespan.before_shutdown()) # 停止前钩子 + if name: self.chan.send(1, name) else: - for name in self.pm.processes: + for name in self.pm.targets: self.chan.send(1, name) def init(self, *args, **kwargs): @@ -114,7 +120,7 @@ $$$$$$$$/ $$$$$$/ $$/ $$$$$$$$/ $$/ $$$$$$/ $$/ $$/ $$$$$$/ def on_before_shutdown(self, func: LIFESPAN_FUNC): """ - 注册停止前的函数 + 注册停止前的函数,为子进程停止时调用 Args: func: @@ -136,7 +142,7 @@ $$$$$$$$/ $$$$$$/ $$/ $$$$$$$$/ $$/ $$$$$$/ $$/ $$/ $$$$$$/ def on_before_restart(self, func: LIFESPAN_FUNC): """ - 注册重启前的函数 + 注册重启前的函数,为子进程重启时调用 Args: func: diff --git a/liteyuki/bot/lifespan.py b/liteyuki/bot/lifespan.py index eec69492..75327bf0 100644 --- a/liteyuki/bot/lifespan.py +++ b/liteyuki/bot/lifespan.py @@ -10,6 +10,7 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved """ from typing import Any, Awaitable, Callable, TypeAlias +from liteyuki.log import logger from liteyuki.utils import is_coroutine_callable SYNC_LIFESPAN_FUNC: TypeAlias = Callable[[], Any] @@ -135,6 +136,7 @@ class Lifespan: 启动前 Returns: """ + logger.debug("Running before_start functions") await self._run_funcs(self._before_start_funcs) async def after_start(self) -> None: @@ -142,6 +144,7 @@ class Lifespan: 启动后 Returns: """ + logger.debug("Running after_start functions") await self._run_funcs(self._after_start_funcs) async def before_shutdown(self) -> None: @@ -149,6 +152,7 @@ class Lifespan: 停止前 Returns: """ + logger.debug("Running before_shutdown functions") await self._run_funcs(self._before_shutdown_funcs) async def after_shutdown(self) -> None: @@ -156,6 +160,7 @@ class Lifespan: 停止后 Returns: """ + logger.debug("Running after_shutdown functions") await self._run_funcs(self._after_shutdown_funcs) async def before_restart(self) -> None: @@ -163,6 +168,7 @@ class Lifespan: 重启前 Returns: """ + logger.debug("Running before_restart functions") await self._run_funcs(self._before_restart_funcs) async def after_restart(self) -> None: @@ -171,6 +177,7 @@ class Lifespan: Returns: """ + logger.debug("Running after_restart functions") await self._run_funcs(self._after_restart_funcs) async def after_nonebot_init(self) -> None: @@ -178,4 +185,5 @@ class Lifespan: NoneBot 初始化后 Returns: """ + logger.debug("Running after_nonebot_init functions") await self._run_funcs(self._after_nonebot_init_funcs) diff --git a/liteyuki/core/manager.py b/liteyuki/core/manager.py index fb7dd67a..f88ac555 100644 --- a/liteyuki/core/manager.py +++ b/liteyuki/core/manager.py @@ -8,12 +8,17 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved @File : manager.py @Software: PyCharm """ +import asyncio import threading from multiprocessing import Process +from typing import TYPE_CHECKING from liteyuki.comm import Channel from liteyuki.log import logger +if TYPE_CHECKING: + from liteyuki.bot import LiteyukiBot + TIMEOUT = 10 __all__ = [ @@ -26,14 +31,15 @@ class ProcessManager: 在主进程中被调用 """ - def __init__(self, bot, chan: Channel): + def __init__(self, bot: "LiteyukiBot", chan: Channel): self.bot = bot self.chan = chan - self.processes: dict[str, tuple[callable, tuple, dict]] = {} + self.targets: dict[str, tuple[callable, tuple, dict]] = {} + self.processes: dict[str, Process] = {} def start(self, name: str, delay: int = 0): """ - 开启后自动监控进程 + 开启后自动监控进程,并添加到进程字典中 Args: name: delay: @@ -42,33 +48,30 @@ class ProcessManager: """ - if name not in self.processes: + if name not in self.targets: raise KeyError(f"Process {name} not found.") def _start(): should_exit = False while not should_exit: - process = Process(target=self.processes[name][0], args=(self.chan, *self.processes[name][1]), kwargs=self.processes[name][2]) + process = Process(target=self.targets[name][0], args=(self.chan, *self.targets[name][1]), kwargs=self.targets[name][2]) + self.processes[name] = process process.start() while not should_exit: # 0退出 1重启 data = self.chan.receive(name) - print("Received data: ", data, name) if data == 1: - logger.info("Restarting LiteyukiBot...") - process.terminate() - process.join(TIMEOUT) - if process.is_alive(): - process.kill() + logger.info(f"Restarting process {name}") + asyncio.run(self.bot.lifespan.before_shutdown()) + asyncio.run(self.bot.lifespan.before_restart()) + self.terminate(name) break elif data == 0: - logger.info("Stopping LiteyukiBot...") + logger.info(f"Stopping process {name}") + asyncio.run(self.bot.lifespan.before_shutdown()) should_exit = True - process.terminate() - process.join(TIMEOUT) - if process.is_alive(): - process.kill() + self.terminate(name) else: logger.warning("Unknown data received, ignored.") @@ -78,16 +81,25 @@ class ProcessManager: threading.Thread(target=_start).start() def add_target(self, name: str, target, *args, **kwargs): - self.processes[name] = (target, args, kwargs) + self.targets[name] = (target, args, kwargs) def join(self): - for name, process in self.processes: + for name, process in self.targets: process.join() - def terminate(self): - for name, process in self.processes: - process.terminate() - process.join(TIMEOUT) - if process.is_alive(): - process.kill() - self.processes = [] + def terminate(self, name: str): + """ + 终止进程并从进程字典中删除 + Args: + name: + + Returns: + + """ + if name not in self.targets: + raise logger.warning(f"Process {name} not found.") + process = self.processes[name] + process.terminate() + process.join(TIMEOUT) + if process.is_alive(): + process.kill() diff --git a/liteyuki/core/spawn_process.py b/liteyuki/core/spawn_process.py index 6ea91425..089a770e 100644 --- a/liteyuki/core/spawn_process.py +++ b/liteyuki/core/spawn_process.py @@ -1,16 +1,16 @@ -import threading -from multiprocessing import Event, Queue -from typing import Optional +from typing import Optional, TYPE_CHECKING import nonebot -import liteyuki from liteyuki.core.nb import adapter_manager, driver_manager +if TYPE_CHECKING: + from liteyuki.comm.channel import Channel + timeout_limit: int = 20 -"""导出对象,用于进程通信""" -chan_in_spawn: Optional["liteyuki.Channel"] = None +"""导出对象,用于主进程与nonebot通信""" +chan_in_spawn_nb: Optional["Channel"] = None def nb_run(chan, *args, **kwargs): @@ -18,14 +18,15 @@ def nb_run(chan, *args, **kwargs): 初始化NoneBot并运行在子进程 Args: + chan: *args: **kwargs: Returns: """ - global chan_in_spawn - chan_in_spawn = chan + global chan_in_spawn_nb + chan_in_spawn_nb = chan nonebot.init(**kwargs) driver_manager.init(config=kwargs) adapter_manager.init(kwargs) diff --git a/liteyuki/plugin/model.py b/liteyuki/plugin/model.py index 70f8dab6..a741415e 100644 --- a/liteyuki/plugin/model.py +++ b/liteyuki/plugin/model.py @@ -16,10 +16,10 @@ from pydantic import BaseModel class PluginMetadata(BaseModel): """ - 轻雪插件元数据,由插件编写者提供 + 轻雪插件元数据,由插件编写者提供,name为必填项 """ name: str - description: str + description: str = "" usage: str = "" type: str = "" homepage: str = "" diff --git a/liteyuki/_plugins/process_manager/__init__.py b/liteyuki/plugins/process_manager/__init__.py similarity index 100% rename from liteyuki/_plugins/process_manager/__init__.py rename to liteyuki/plugins/process_manager/__init__.py diff --git a/liteyuki/_plugins/resource_loader/__init__.py b/liteyuki/plugins/resource_loader/__init__.py similarity index 100% rename from liteyuki/_plugins/resource_loader/__init__.py rename to liteyuki/plugins/resource_loader/__init__.py diff --git a/liteyuki/plugins/what_litaco/__init__.py b/liteyuki/plugins/what_litaco/__init__.py new file mode 100644 index 00000000..ffce5f45 --- /dev/null +++ b/liteyuki/plugins/what_litaco/__init__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +""" +Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved + +@Time : 2024/7/25 上午2:28 +@Author : snowykami +@Email : snowykami@outlook.com +@File : __init__.py +@Software: PyCharm +""" +# -*- coding: utf-8 -*- +# +# Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved +# +# @Time : 2024/7/22 上午11:25 +# @Author : snowykami +# @Email : snowykami@outlook.com +# @File : asa.py +# @Software: PyCharm \ No newline at end of file diff --git a/liteyuki/utils.py b/liteyuki/utils.py index 3f3bfab3..ccb67a76 100644 --- a/liteyuki/utils.py +++ b/liteyuki/utils.py @@ -8,6 +8,8 @@ import threading from pathlib import Path from typing import Any, Callable, Coroutine +from liteyuki.log import logger + def is_coroutine_callable(call: Callable[..., Any]) -> bool: """ @@ -55,7 +57,7 @@ def run_coroutine(*coro: Coroutine): loop.close() except Exception as e: # 捕获其他异常,防止协程被重复等待 - print(f"Exception occurred: {e}") + logger.error(f"Exception occurred: {e}") def path_to_module_name(path: Path) -> str: diff --git a/src/libs/ly_api_windows_amd64.dll b/src/libs/ly_api_windows_amd64.dll new file mode 100644 index 00000000..94fef90d Binary files /dev/null and b/src/libs/ly_api_windows_amd64.dll differ diff --git a/src/liteyuki_main/core.py b/src/liteyuki_main/core.py index 39d904e3..1904be49 100644 --- a/src/liteyuki_main/core.py +++ b/src/liteyuki_main/core.py @@ -19,7 +19,7 @@ from src.utils.base.ly_typing import T_Bot, T_MessageEvent from src.utils.message.message import MarkdownMessage as md, broadcast_to_superusers # from src.liteyuki.core import Reloader from src.utils import event as event_utils, satori_utils -from liteyuki.core.spawn_process import chan_in_spawn +from liteyuki.core.spawn_process import chan_in_spawn_nb from .api import update_liteyuki from liteyuki.bot import get_bot diff --git a/src/plugins/liteyuki_crt_utils/__init__.py b/src/plugins/liteyuki_crt_utils/__init__.py index fd219f6f..7c6196a9 100644 --- a/src/plugins/liteyuki_crt_utils/__init__.py +++ b/src/plugins/liteyuki_crt_utils/__init__.py @@ -1,7 +1,6 @@ import multiprocessing from nonebot.plugin import PluginMetadata -from liteyuki.plugin import get_loaded_plugins from .rt_guide import * from .crt_matchers import * @@ -16,6 +15,4 @@ __plugin_meta__ = PluginMetadata( "toggleable" : True, "default_enable": True, } -) - -print("Loaded plugins:", len(get_loaded_plugins())) \ No newline at end of file +) \ No newline at end of file diff --git a/src/plugins/liteyuki_minigame/game.py b/src/plugins/liteyuki_minigame/game.py index 7875e3d7..b6ff63b8 100644 --- a/src/plugins/liteyuki_minigame/game.py +++ b/src/plugins/liteyuki_minigame/game.py @@ -153,7 +153,6 @@ class Minesweeper: text += "\n\n" for i, row in enumerate(self.board): text += start + f"{self.NUMS[i]}" + dis*2 - print([d.value for d in row]) for dot in row: if dot.mask and not dot.flagged: text += md.btn_cmd(self.MASK, f"minesweeper reveal {dot.row} {dot.col}") diff --git a/src/plugins/liteyuki_pacman/common.py b/src/plugins/liteyuki_pacman/common.py index c52dbc9a..16bd0913 100644 --- a/src/plugins/liteyuki_pacman/common.py +++ b/src/plugins/liteyuki_pacman/common.py @@ -146,7 +146,6 @@ def set_plugin_session_enable(event: T_MessageEvent, plugin_name: str, enable: b else: session: User = user_db.where_one(User(), "user_id = ?", str(event_utils.get_user_id(event)), default=User(user_id=str(event_utils.get_user_id(event)))) - print(session) default_enable = get_plugin_default_enable(plugin_name) if default_enable: if enable: diff --git a/src/plugins/liteyuki_statistics/stat_matchers.py b/src/plugins/liteyuki_statistics/stat_matchers.py index 07e36fb4..144e094b 100644 --- a/src/plugins/liteyuki_statistics/stat_matchers.py +++ b/src/plugins/liteyuki_statistics/stat_matchers.py @@ -119,7 +119,6 @@ async def _(result: Arparma, event: T_MessageEvent, bot: Bot): ulang = Language(event_utils.get_user_id(event)) rank_type = "user" duration = convert_time_to_seconds(result.other_args.get("duration", "1d")) - print(result) if result.subcommands.get("rank").options.get("user"): rank_type = "user" elif result.subcommands.get("rank").options.get("group"): diff --git a/src/plugins/liteyuki_statistics/stat_monitors.py b/src/plugins/liteyuki_statistics/stat_monitors.py index f91dc691..bbebc530 100644 --- a/src/plugins/liteyuki_statistics/stat_monitors.py +++ b/src/plugins/liteyuki_statistics/stat_monitors.py @@ -15,7 +15,7 @@ require("nonebot_plugin_alconna") async def general_event_monitor(bot: T_Bot, event: T_MessageEvent): - print("POST PROCESS") + pass # if isinstance(bot, satori.Bot): # print("POST PROCESS SATORI EVENT") # return await satori_event_monitor(bot, event) diff --git a/src/plugins/liteyuki_status/status.py b/src/plugins/liteyuki_status/status.py index 96d2e2c1..237dfd57 100644 --- a/src/plugins/liteyuki_status/status.py +++ b/src/plugins/liteyuki_status/status.py @@ -52,9 +52,9 @@ async def _(event: T_MessageEvent, bot: T_Bot): @status_alc.assign("memory") async def _(): - print("memory") + pass @status_alc.assign("process") async def _(): - print("process") + pass diff --git a/src/plugins/webdash/restful_api.py b/src/plugins/webdash/restful_api.py index 873cb691..3ec5f8ac 100644 --- a/src/plugins/webdash/restful_api.py +++ b/src/plugins/webdash/restful_api.py @@ -7,7 +7,6 @@ bot_info_router = APIRouter(prefix="/api/bot-info") @device_info_router.get("/") async def device_info(): - print("Hello Device Info") return { "message": "Hello Device Info" } diff --git a/src/utils/base/__init__.py b/src/utils/base/__init__.py index 9800f856..af167e0c 100644 --- a/src/utils/base/__init__.py +++ b/src/utils/base/__init__.py @@ -1,7 +1,7 @@ import threading from nonebot import logger -from liteyuki.core.spawn_process import chan_in_spawn +from liteyuki.core.spawn_process import chan_in_spawn_nb def reload(delay: float = 0.0, receiver: str = "nonebot"): @@ -15,5 +15,5 @@ def reload(delay: float = 0.0, receiver: str = "nonebot"): """ - chan_in_spawn.send(1, receiver) + chan_in_spawn_nb.send(1, receiver) logger.info(f"Reloading LiteyukiBot({receiver})...") diff --git a/src/utils/base/ly_api.py b/src/utils/base/ly_api.py index 3b79b90e..81e45684 100644 --- a/src/utils/base/ly_api.py +++ b/src/utils/base/ly_api.py @@ -6,10 +6,9 @@ import aiohttp import nonebot import psutil import requests -from aiohttp import FormData -from .. import __VERSION_I__, __VERSION__, __NAME__ from .config import load_from_yaml +from .. import __NAME__, __VERSION_I__, __VERSION__ class LiteyukiAPI: @@ -69,6 +68,10 @@ class LiteyukiAPI: else: nonebot.logger.warning(f"Bug report is disabled: {content}") + def register(self): + pass + + async def heartbeat_report(self): """ 提交心跳,预留接口 diff --git a/liteyuki/_plugins/what_litaco/__init__.py b/src/utils/extension/__init__.py similarity index 67% rename from liteyuki/_plugins/what_litaco/__init__.py rename to src/utils/extension/__init__.py index c3e1c095..80977e8a 100644 --- a/liteyuki/_plugins/what_litaco/__init__.py +++ b/src/utils/extension/__init__.py @@ -2,9 +2,14 @@ """ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved -@Time : 2024/7/25 上午2:28 +@Time : 2024/8/7 下午10:40 @Author : snowykami @Email : snowykami@outlook.com @File : __init__.py @Software: PyCharm """ +from .lib_loader import * + +__all__ = [ + "load_lib" +] \ No newline at end of file diff --git a/src/utils/extension/lib_loader.py b/src/utils/extension/lib_loader.py new file mode 100644 index 00000000..b6bcaa1d --- /dev/null +++ b/src/utils/extension/lib_loader.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +""" +Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved + +@Time : 2024/8/7 下午10:40 +@Author : snowykami +@Email : snowykami@outlook.com +@File : lib_loader.py +@Software: PyCharm +""" +import os +import sys +import platform +import ctypes + +LIB_EXT = None +PLATFORM = platform.system().lower() # linux, windows, darwin etc +ARCH = platform.machine().lower() # x86_64/amd64 i386 i686 arm aarch64 ppc64 ppc mips sparc + +if "linux" in PLATFORM: + LIB_EXT = 'so' +elif sys.platform == 'darwin': + LIB_EXT = 'dylib' +elif sys.platform == 'win32': + LIB_EXT = 'dll' +else: + raise RuntimeError("Unsupported platform") + + +def load_lib(lib_name: str) -> ctypes.CDLL: + """ + Load a dll/so/dylib library, without extension. + Args: + lib_name: str, path/to/library without extension + Returns: + xxx_{platform}_{arch}.{ext} ctypes.CDLL + """ + whole_path = f"{lib_name}_{PLATFORM}_{ARCH}.{LIB_EXT}" + if not os.path.exists(whole_path): + raise FileNotFoundError(f"Library {whole_path} not found") + return ctypes.CDLL(whole_path) diff --git a/tests/test_dll.py b/tests/test_dll.py new file mode 100644 index 00000000..8d443788 --- /dev/null +++ b/tests/test_dll.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +""" +Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved + +@Time : 2024/8/7 下午11:44 +@Author : snowykami +@Email : snowykami@outlook.com +@File : test_dll.py +@Software: PyCharm +""" +from src.utils.extension import load_lib + + +a = load_lib("src/libs/ly_api") + +a.Register("sss", "sss", 64, "sss", "sss") \ No newline at end of file