feat: support MuMuPlayer12 5.0

This commit is contained in:
2026-07-06 22:40:54 +08:00
parent 6774c2070b
commit 3dc24d56e1
4 changed files with 57 additions and 24 deletions
+25 -8
View File
@@ -29,8 +29,27 @@ class Button(Resource):
def button(self): def button(self):
return area_offset(self._button, self._button_offset) return area_offset(self._button, self._button_offset)
def load_offset(self, button): def load_offset(self, offset):
self._button_offset = button._button_offset """
Args:
offset (Button | ButtonWrapper | tuple[int, int]):
"""
if isinstance(offset, ButtonWrapper):
offset = offset.matched_button._button_offset
elif isinstance(offset, Button):
offset = offset._button_offset
self._button_offset = offset
def load_search(self, search):
"""
Args:
search (Button | ButtonWrapper | tuple[int, int]):
"""
if isinstance(search, ButtonWrapper):
search = search.search
elif isinstance(search, Button):
search = search.search
self.search = search
def clear_offset(self): def clear_offset(self):
self._button_offset = (0, 0) self._button_offset = (0, 0)
@@ -338,10 +357,8 @@ class ButtonWrapper(Resource):
Load offset from another button. Load offset from another button.
Args: Args:
button (Button, ButtonWrapper): button (Button | ButtonWrapper | tuple[int, int]):
""" """
if isinstance(button, ButtonWrapper):
button = button.matched_button
for b in self.iter_buttons(): for b in self.iter_buttons():
b.load_offset(button) b.load_offset(button)
@@ -360,16 +377,16 @@ class ButtonWrapper(Resource):
""" """
return self.matched_button.is_offset_in(x=x, y=y) return self.matched_button.is_offset_in(x=x, y=y)
def load_search(self, area): def load_search(self, search):
""" """
Set `search` attribute. Set `search` attribute.
Note that this method is irreversible. Note that this method is irreversible.
Args: Args:
area: search (Button | ButtonWrapper | tuple[int, int, int, int]):
""" """
for b in self.iter_buttons(): for b in self.iter_buttons():
b.search = area b.load_search(search)
def set_search_offset(self, offset): def set_search_offset(self, offset):
""" """
+24 -14
View File
@@ -219,7 +219,30 @@ class NemuIpcImpl:
self.instance_id: int = instance_id self.instance_id: int = instance_id
self.display_id: int = display_id self.display_id: int = display_id
ipc_dll = os.path.abspath(os.path.join(nemu_folder, './shell/sdk/external_renderer_ipc.dll')) # try to load dll from various path
list_dll = [
# MuMuPlayer12
os.path.abspath(os.path.join(nemu_folder, './shell/sdk/external_renderer_ipc.dll')),
# MuMuPlayer12 5.0
os.path.abspath(os.path.join(nemu_folder, './nx_device/12.0/shell/sdk/external_renderer_ipc.dll')),
]
ipc_dll = ''
for ipc_dll in list_dll:
if not os.path.exists(ipc_dll):
continue
try:
self.lib = ctypes.CDLL(ipc_dll)
break
except OSError as e:
logger.error(e)
logger.error(f'ipc_dll={ipc_dll} exists, but cannot be loaded')
continue
if not ipc_dll:
# not found
raise NemuIpcIncompatible(
f'NemuIpc requires MuMu12 version >= 3.8.13, please check your version. '
f'None of the following path exists: {list_dll}')
# success
logger.info( logger.info(
f'NemuIpcImpl init, ' f'NemuIpcImpl init, '
f'nemu_folder={nemu_folder}, ' f'nemu_folder={nemu_folder}, '
@@ -227,19 +250,6 @@ class NemuIpcImpl:
f'instance_id={instance_id}, ' f'instance_id={instance_id}, '
f'display_id={display_id}' f'display_id={display_id}'
) )
try:
self.lib = ctypes.CDLL(ipc_dll)
except OSError as e:
logger.error(e)
# OSError: [WinError 126] 找不到指定的模块。
if not os.path.exists(ipc_dll):
raise NemuIpcIncompatible(
f'ipc_dll={ipc_dll} does not exist, '
f'NemuIpc requires MuMu12 version >= 3.8.13, please check your version')
else:
raise NemuIpcIncompatible(
f'ipc_dll={ipc_dll} exists, but cannot be loaded')
self.connect_id: int = 0 self.connect_id: int = 0
self.width = 0 self.width = 0
self.height = 0 self.height = 0
+7 -2
View File
@@ -119,7 +119,7 @@ class Emulator(EmulatorBase):
return cls.MuMuPlayerX return cls.MuMuPlayerX
else: else:
return cls.MuMuPlayer return cls.MuMuPlayer
if exe == 'mumuplayer.exe': if exe in ['mumuplayer.exe', 'mumunxmain.exe']:
return cls.MuMuPlayer12 return cls.MuMuPlayer12
if exe == 'memu.exe': if exe == 'memu.exe':
return cls.MEmuPlayer return cls.MEmuPlayer
@@ -168,6 +168,9 @@ class Emulator(EmulatorBase):
""" """
if 'MuMuPlayer.exe' in exe: if 'MuMuPlayer.exe' in exe:
return exe.replace('MuMuPlayer.exe', 'MuMuManager.exe') return exe.replace('MuMuPlayer.exe', 'MuMuManager.exe')
# MuMuPlayer12 5.0
elif 'MuMuNxMain.exe' in exe:
return exe.replace('MuMuNxMain.exe', 'MuMuManager.exe')
elif 'LDPlayer.exe' in exe: elif 'LDPlayer.exe' in exe:
return exe.replace('LDPlayer.exe', 'ldconsole.exe') return exe.replace('LDPlayer.exe', 'ldconsole.exe')
elif 'dnplayer.exe' in exe: elif 'dnplayer.exe' in exe:
@@ -461,7 +464,9 @@ class EmulatorManager(EmulatorManagerBase):
'leidian9', 'leidian9',
'Nemu', 'Nemu',
'Nemu9', 'Nemu9',
'MuMuPlayer-12.0' 'MuMuPlayer',
'MuMuPlayer-12.0',
'MuMu Player 12.0',
'MEmu', 'MEmu',
] ]
for path in known_uninstall_registry_path: for path in known_uninstall_registry_path:
@@ -97,6 +97,7 @@ class PlatformWindows(PlatformBase, EmulatorManager):
self.execute(f'"{exe}" -m {instance.name}') self.execute(f'"{exe}" -m {instance.name}')
elif instance == Emulator.MuMuPlayer12: elif instance == Emulator.MuMuPlayer12:
# MuMuPlayer.exe -v 0 # MuMuPlayer.exe -v 0
# MuMuNxMain.exe -v 0
if instance.MuMuPlayer12_id is None: if instance.MuMuPlayer12_id is None:
logger.warning(f'Cannot get MuMu instance index from name {instance.name}') logger.warning(f'Cannot get MuMu instance index from name {instance.name}')
self.execute(f'"{exe}" -v {instance.MuMuPlayer12_id}') self.execute(f'"{exe}" -v {instance.MuMuPlayer12_id}')