import os, time, cv2, numpy from functools import reduce, wraps from fgoSchedule import schedule from fgoFuse import fuse from fgoLogging import getLogger, logMeta, logit logger = getLogger('Detect') IMG = type( 'IMG', (), { i[:-4].upper(): (lambda x: (x, numpy.max(x, axis=2) >> 1))(cv2.imread(f'fgoImage/{i}')) for i in os.listdir('fgoImage') if i[-4:] == '.png' }) class Detect(metaclass=logMeta(logger)): # The accuracy of each API here is designed to be 100% at 1920x1080 resolution, if you find any mismatches, please submit an issue, with a screenshot saved via Detect.cache.save() or fuse.save(). cache = None device = None def retryOnError(interval=.1, err=TypeError): def wrapper(func): @wraps(func) def wrap(self, *args, **kwargs): try: if (ans := func(self, *args, **kwargs)) is not None: return ans except err: pass logger.warning( f'Retry {getattr(func,"__qualname__",getattr(type(func),"__qualname__","Unknown"))}({",".join(repr(i)for i in args)}{","if kwargs else""}{",".join("%s=%r"%i for i in kwargs.items())})'
import json from flask import Flask, redirect, render_template, request, url_for from zmq import device import fgoKernel from fgoLogging import getLogger from fgoIniParser import IniParser logger = getLogger('fgo.Web') teamup = IniParser('fgoTeamup.ini') with open('fgoConfig.json', 'r') as f: config = json.load(f) app = Flask(__name__, static_folder='fgoWebUI', template_folder='fgoWebUI') @app.route('/') def root(): return redirect('/index') @app.route('/index') def index(): return render_template('index.html', teamups=teamup.sections(), config=config, device=fgoKernel.device.name) @app.route('/api/connect', methods=['POST']) def connect(): fgoKernel.device = fgoKernel.Device(request.form['serial']) return fgoKernel.device.name
from fgoSchedule import ScriptTerminate from fgoLogging import getLogger logger = getLogger('Fuse') class Fuse: def __init__(self, fv=300, logsize=10): self.value = 0 self.max = fv self.logsize = logsize self.log = [None] * logsize self.logptr = 0 def increase(self): logger.debug(f'{self.value}') if self.value > self.max: self.save() raise ScriptTerminate('Fused') self.value += 1 def reset(self, detect=None): self.value = 0 if detect is not None and detect is not self.log[(self.logptr - 1) % self.logsize]: self.log[self.logptr] = detect self.logptr = (self.logptr + 1) % self.logsize return True def save(self, path='fgoLog'): [ self.log[(i + self.logptr) %
import os, cv2, numpy, platform from fgoLogging import getLogger logger = getLogger('ImageListener') if platform.system() == 'Windows': import threading, win32con, win32file class DirListener: def __init__(self, dir): self.hDir = win32file.CreateFile( dir, win32con.GENERIC_READ, win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE | win32con.FILE_SHARE_DELETE, None, win32con.OPEN_EXISTING, win32con.FILE_FLAG_BACKUP_SEMANTICS, None) self.msg = [] self.lock = threading.Lock() self.ren = '' def f(): while True: self.add( win32file.ReadDirectoryChangesW( self.hDir, 0x1000, False, win32con.FILE_NOTIFY_CHANGE_FILE_NAME | win32con.FILE_NOTIFY_CHANGE_LAST_WRITE, None, None)) threading.Thread(target=f, daemon=True, name=f'DirListener({dir})').start() def add(self, x):
from fgoLogging import getLogger logger = getLogger('ConnectHelper') helpers = {} def regHelper(func): helpers[func.__name__] = func return func def convert(text): if text is None: return None text = text.removeprefix(' ').removesuffix(' ') if not text.startswith('/'): return text try: return helpers[text[1:]]() except Exception as e: return logger.exception(e) @regHelper def gw(): import netifaces return f'{netifaces.gateways()["default"][netifaces.AF_INET][0]}:5555' @regHelper def bs4(): import winreg with winreg.OpenKey(
import re import threading import time import cv2 import numpy from airtest.core.android.adb import ADB from airtest.core.android.android import Android as Airtest from airtest.core.android.constant import CAP_METHOD from fgoConst import KEYMAP from fgoSchedule import schedule from fgoLogging import getLogger logger=getLogger('Android') class Android(Airtest): def __init__(self,serial=None,**kwargs): self.lock=threading.Lock() if serial is None: self.name=None return try: super().__init__(serial,**{'cap_method':CAP_METHOD.JAVACAP}|kwargs) self.rotation_watcher.reg_callback(lambda _:self.adjustOffset()) except Exception as e: logger.exception(e) self.name=None else:self.name=self.serialno @property def available(self): if not self.name:return False