created interface for sslib and choose one using config

This commit is contained in:
Adam Saudagar 2023-03-07 00:37:26 +05:30
parent 788e78b9bb
commit 5dc7c09cb7
5 changed files with 111 additions and 16 deletions

View File

@ -10,3 +10,5 @@ libgps = ("LibGPS", "https://cdn.esoui.com/downloads/file601/LibGPS_3_2_0.zip",
libmapping = ("LibMapPing", "https://cdn.esoui.com/downloads/file1302/LibMapPing_2_0_0.zip", 200) libmapping = ("LibMapPing", "https://cdn.esoui.com/downloads/file1302/LibMapPing_2_0_0.zip", 200)
libdl = ("LibDebugLogger", "https://cdn.esoui.com/downloads/file2275/LibDebugLogger_2_4_1.zip", 241) libdl = ("LibDebugLogger", "https://cdn.esoui.com/downloads/file2275/LibDebugLogger_2_4_1.zip", 241)
libchatmsg = ("LibChatMessage", "https://cdn.esoui.com/downloads/file2382/LibChatMessage_1_2_0.zip", 120) libchatmsg = ("LibChatMessage", "https://cdn.esoui.com/downloads/file2382/LibChatMessage_1_2_0.zip", 120)
d3dshot_git = "git+https://github.com/fauskanger/D3DShot.git#egg=D3DShot"

View File

@ -0,0 +1,90 @@
import logging
import subprocess
import sys
from abc import ABC, abstractmethod
from typing import Optional
import numpy as np
from numpy import ndarray
from fishy import constants
from fishy.helper.config import config
from fishy.helper.depless import singleton_proxy, install_and_import
from fishy.osservices.os_services import os_services
class IScreenShot(ABC):
@abstractmethod
def setup(self) -> bool:
...
@abstractmethod
def grab(self) -> ndarray:
...
def get_monitor_id(monitors_iterator, get_top_left) -> Optional[int]:
monitor_rect = os_services.get_monitor_rect()
if monitor_rect is None:
logging.error("Game window not found")
return None
for i, m in enumerate(monitors_iterator):
top, left = get_top_left(m)
if top == monitor_rect[0] and left == monitor_rect[1]:
return i
return None
class MSS(IScreenShot):
def __init__(self):
from mss import mss
self.monitor_id = None
self.sct = mss()
def setup(self) -> bool:
self.monitor_id = get_monitor_id(self.sct.monitors, lambda m: (m["top"], m["left"]))
return self.monitor_id is not None
# noinspection PyTypeChecker
def grab(self) -> ndarray:
sct_img = self.sct.grab(self.sct.monitors[self.monitor_id])
return np.array(sct_img)
class PyAutoGUI(IScreenShot):
def setup(self) -> bool:
return True
def grab(self) -> ndarray:
import pyautogui
image = pyautogui.screenshot(all_screens=True)
return np.array(image)
class D3DShot(IScreenShot):
# noinspection PyPackageRequirements
def __init__(self):
for i in range(2):
install_and_import("d3dshot", constants.d3dshot_git)
# noinspection PyUnresolvedReferences
self.d3 = d3dshot.create(capture_output="numpy")
def setup(self) -> bool:
monitor_id = get_monitor_id(self.d3.display, lambda m: (m.top, m.left))
if monitor_id is None:
return False
self.d3.display = self.d3.displays[monitor_id]
return True
def grab(self) -> ndarray:
return self.d3.screenshot()
LIBS = [MSS, PyAutoGUI, D3DShot]
def create() -> IScreenShot:
return LIBS[config.get("sslib", 0)]()

View File

@ -3,10 +3,9 @@ from enum import Enum
from threading import Thread from threading import Thread
import numpy as np import numpy as np
from mss import mss
from mss.base import MSSBase from mss.base import MSSBase
from fishy.engine.common import screenshot
from fishy.helper.helper import print_exc from fishy.helper.helper import print_exc
from fishy.osservices.os_services import os_services from fishy.osservices.os_services import os_services
@ -24,10 +23,8 @@ class WindowServer:
Screen: np.ndarray = None Screen: np.ndarray = None
windowOffset = None windowOffset = None
status = Status.STOPPED status = Status.STOPPED
sct: MSSBase = None sslib = None
crop = None crop = None
monitor_id = -1
def init(): def init():
@ -35,26 +32,18 @@ def init():
Executed once before the main loop, Executed once before the main loop,
Finds the game window, and calculates the offset to remove the title bar Finds the game window, and calculates the offset to remove the title bar
""" """
WindowServer.sslib = screenshot.create()
WindowServer.status = Status.RUNNING WindowServer.status = Status.RUNNING
WindowServer.sct = mss()
WindowServer.crop = os_services.get_game_window_rect() WindowServer.crop = os_services.get_game_window_rect()
monitor_rect = os_services.get_monitor_rect()
if monitor_rect is None or WindowServer.crop is None: if WindowServer.crop is None or not WindowServer.sslib.setup():
logging.error("Game window not found") logging.error("Game window not found")
WindowServer.status = Status.CRASHED WindowServer.status = Status.CRASHED
return return
for i, m in enumerate(WindowServer.sct.monitors):
if m["top"] == monitor_rect[0] and m["left"] == monitor_rect[1]:
WindowServer.monitor_id = i
def get_cropped_screenshot(): def get_cropped_screenshot():
sct_img = WindowServer.sct.grab(WindowServer.sct.monitors[WindowServer.monitor_id]) ss = WindowServer.sslib.grab()
# noinspection PyTypeChecker
ss = np.array(sct_img)
crop = WindowServer.crop crop = WindowServer.crop
cropped_ss = ss[crop[1]:crop[3], crop[0]:crop[2]] cropped_ss = ss[crop[1]:crop[3], crop[0]:crop[2]]
if cropped_ss.size == 0: if cropped_ss.size == 0:

View File

@ -1,6 +1,7 @@
""" """
no imports from fishy itself here, or anything which depends on fishy no imports from fishy itself here, or anything which depends on fishy
""" """
import importlib
def singleton_proxy(instance_name): def singleton_proxy(instance_name):
@ -18,3 +19,15 @@ def singleton_proxy(instance_name):
return NewClass return NewClass
return decorator return decorator
def install_and_import(package, package_url=None):
try:
importlib.import_module(package)
except ImportError:
import pip
if package_url is None:
package_url = package
pip.main(['install', package_url])
finally:
globals()[package] = importlib.import_module(package)

View File

@ -14,4 +14,5 @@ keyboard
playsound playsound
event-scheduler event-scheduler
mouse mouse
pyautogui
mss mss