Add: fake module PIL for webui (#4374)

* Add: fake module PIL for webui

* Fix: Load runtime before module PIL

* Upd: Error message of MAA loading failure

* Upd: Adjust timing of import fake module
This commit is contained in:
SarContDeli 2024-11-19 12:37:59 +08:00 committed by GitHub
parent bc5e6ed86a
commit bd680eb3a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 65 additions and 12 deletions

View File

@ -1,6 +1,5 @@
import importlib import importlib
from module.config.config import AzurLaneConfig
from module.logger import logger from module.logger import logger
from module.submodule.utils import * from module.submodule.utils import *
@ -15,6 +14,8 @@ def load_mod(name):
def load_config(config_name): def load_config(config_name):
from module.config.config import AzurLaneConfig
mod_name = get_config_mod(config_name) mod_name = get_config_mod(config_name)
if mod_name == 'alas': if mod_name == 'alas':
return AzurLaneConfig(config_name, '') return AzurLaneConfig(config_name, '')

View File

@ -1,12 +1,18 @@
import argparse import sys
import json import json
import queue
import threading
import time import time
import queue
import argparse
import threading
from datetime import datetime from datetime import datetime
from functools import partial from functools import partial
from typing import Dict, List, Optional from typing import Dict, List, Optional
# Import fake module before import pywebio to avoid importing unnecessary module PIL
from module.webui.fake_pil_module import import_fake_pil_module
import_fake_pil_module()
from pywebio import config as webconfig from pywebio import config as webconfig
from pywebio.input import file_upload, input, input_group, select from pywebio.input import file_upload, input, input_group, select
from pywebio.output import ( from pywebio.output import (

View File

@ -0,0 +1,15 @@
import sys
from types import ModuleType
def import_fake_pil_module():
fake_pil_module = ModuleType('PIL')
fake_pil_module.Image = ModuleType('PIL.Image')
fake_pil_module.Image.Image = type('MockPILImage', (), dict(__init__=None))
sys.modules['PIL'] = fake_pil_module
sys.modules['PIL.Image'] = fake_pil_module.Image
def remove_fake_pil_module():
sys.modules.pop('PIL', None)
sys.modules.pop('PIL.Image', None)

View File

@ -1,6 +1,7 @@
import argparse
import os import os
import sys
import queue import queue
import argparse
import threading import threading
from multiprocessing import Process from multiprocessing import Process
from typing import Dict, List, Union from typing import Dict, List, Union
@ -9,6 +10,12 @@ import inflection
from filelock import FileLock from filelock import FileLock
from rich.console import Console, ConsoleRenderable from rich.console import Console, ConsoleRenderable
# Since this file does not run under the same process or subprocess of app.py
# the following code needs to be repeated
# Import fake module before import pywebio to avoid importing unnecessary module PIL
from module.webui.fake_pil_module import *
import_fake_pil_module()
from module.config.utils import filepath_config from module.config.utils import filepath_config
from module.logger import logger, set_file_logger, set_func_logger from module.logger import logger, set_file_logger, set_func_logger
from module.submodule.submodule import load_mod from module.submodule.submodule import load_mod
@ -141,6 +148,9 @@ class ProcessManager:
from module.config.config import AzurLaneConfig from module.config.config import AzurLaneConfig
# Remove fake PIL module, because subprocess will use it
remove_fake_pil_module()
AzurLaneConfig.stop_event = e AzurLaneConfig.stop_event = e
try: try:
# Run alas # Run alas

View File

@ -1,8 +1,29 @@
import os import os
import json import json
import ctypes
from cached_property import cached_property from cached_property import cached_property
# In order for MAA submodule to exexute,
# it is necessary to load runtime before module PIL
if os.name == 'nt':
# This DLL is the dependency for next DLL
# Try loading to avoid mix different versions of runtime
try:
ctypes.WinDLL(os.path.join(os.environ['SystemRoot'], 'System32/vcruntime140_1.dll'))
except Exception as e:
print(e)
# This DLL must be loaded due to conflict issues
ctypes.WinDLL(os.path.join(os.environ['SystemRoot'], 'System32/msvcp140.dll'))
# These DLLS are other DLLS that MAA depends on
# Try loading to avoid mix different versions of runtime
try:
ctypes.WinDLL(os.path.join(os.environ['SystemRoot'], 'System32/msvcp140_1.dll'))
ctypes.WinDLL(os.path.join(os.environ['SystemRoot'], 'System32/concrt140.dll'))
except Exception as e:
print(e)
from alas import AzurLaneAutoScript from alas import AzurLaneAutoScript
from module.exception import RequestHumanTakeover from module.exception import RequestHumanTakeover
from module.logger import logger from module.logger import logger

View File

@ -50,11 +50,6 @@ class Asst:
platform_type = platform.system().lower() platform_type = platform.system().lower()
if platform_type == 'windows': if platform_type == 'windows':
lib_import_func = ctypes.WinDLL lib_import_func = ctypes.WinDLL
try:
# Override by System32 dll
lib_import_func(os.path.join(os.environ['SystemRoot'], 'System32/msvcp140.dll'))
except Exception as e:
pass
else: else:
lib_import_func = ctypes.CDLL lib_import_func = ctypes.CDLL

View File

@ -31,7 +31,12 @@ class AssistantHandler:
AssistantHandler.Asst = asst.Asst AssistantHandler.Asst = asst.Asst
AssistantHandler.Message = utils.Message AssistantHandler.Message = utils.Message
AssistantHandler.InstanceOptionType = utils.InstanceOptionType AssistantHandler.InstanceOptionType = utils.InstanceOptionType
AssistantHandler.Asst.load(path, user_dir=path, incremental_path=incremental_path) try:
AssistantHandler.Asst.load(path, user_dir=path, incremental_path=incremental_path)
except OSError as e:
logger.critical(e)
logger.critical("MAA加载失败请检查MAA本体能否正常打开")
raise RequestHumanTakeover
AssistantHandler.ASST_HANDLER = None AssistantHandler.ASST_HANDLER = None