move deprecated harnesses to deprecated folder (#5)

This commit is contained in:
Derek Hirotsu
2023-09-14 11:48:00 -07:00
committed by GitHub
parent 5c3a6e67cf
commit 7f47dc38a3
149 changed files with 0 additions and 0 deletions

View File

@@ -1,191 +0,0 @@
import logging
import os
import time
from enum import Enum
import cv2
import imutils
import numpy as np
import pyautogui as gui
import pydirectinput as user
DEFAULT_MATCH_THRESHOLD = 0.8
DEFAULT_INTERVAL = 2 # seconds
DEFAULT_TIMEOUT = 60 # seconds
# path relative to script
script_dir = os.path.dirname(os.path.realpath(__file__))
images_dir = os.path.join(script_dir, "images")
dir16x9 = os.path.join(images_dir, "16x9")
dir16x10 = os.path.join(images_dir, "16x10")
templates = {
"options": {
"16x10": cv2.imread(os.path.join(dir16x9, "options_menu_1080.png"), cv2.IMREAD_UNCHANGED),
"16x9": cv2.imread(os.path.join(dir16x9, "options_menu_1080.png"), cv2.IMREAD_UNCHANGED)
},
"benchmark": {
"16x10": cv2.imread(os.path.join(dir16x9, "benchmark_1080.png"), cv2.IMREAD_UNCHANGED),
"16x9": cv2.imread(os.path.join(dir16x9, "benchmark_1080.png"), cv2.IMREAD_UNCHANGED)
},
"header": {
"16x10": cv2.imread(os.path.join(dir16x9, "results_header_1080.png"), cv2.IMREAD_UNCHANGED),
"16x9": cv2.imread(os.path.join(dir16x9, "results_header_1080.png"), cv2.IMREAD_UNCHANGED)
},
}
def get_template(name, set="16x9"):
return templates[name][set]
class ClickType(Enum):
SINGLE = 0 # uses .click()
DOUBLE = 1 # uses .doubleclick()
HARD = 2 # uses mouse.down() and mouse.up()
def get_middle_of_rect(top_left_corner, height, width):
x = top_left_corner[0] + (width / 2)
y = top_left_corner[1] + (height / 2)
return int(x), int(y) # round to avoid fractional pixels
def click(top_left_corner, img):
click_loc = get_middle_of_rect(top_left_corner, img.shape[0], img.shape[1])
logging.info(f"Clicking {click_loc}")
gui.click(click_loc[0], click_loc[1])
def double_click(top_left_corner, img):
click_loc = get_middle_of_rect(top_left_corner, img.shape[0], img.shape[1])
logging.info(f"Double clicking {click_loc}")
user.doubleClick(click_loc[0], click_loc[1])
def hard_click(top_left_corner, img):
click_loc = get_middle_of_rect(top_left_corner, img.shape[0], img.shape[1])
print(f"Hard click loc {click_loc}")
user.moveTo(click_loc[0], click_loc[1])
user.mouseDown()
user.mouseUp()
def wait_and_click(template_name, name, click_type: ClickType = ClickType.SINGLE, timeout=DEFAULT_TIMEOUT):
logging.info(f"Waiting to find and click on {name}")
img, img_loc = wait_for_image_on_screen(template_name, timeout=timeout)
print(f"Wait and click: {img_loc}")
if click_type == ClickType.SINGLE:
click(img_loc, img)
elif click_type == ClickType.DOUBLE:
double_click(img_loc, img)
elif click_type == ClickType.HARD:
hard_click(img_loc, img)
else:
raise ValueError("Unknown click type")
class ImageNotFoundTimeout(Exception):
pass
class ImageNotFound(Exception):
pass
def gcd(a, b):
return a if b == 0 else gcd(b, a % b)
def aspect_ratio(w, h):
denom = int(gcd(w, h))
x = int(w / denom)
y = int(h / denom)
if x == 8 and y == 5:
return "16x10"
elif x == 16 and y == 9:
return "16x9"
def locate_on_screen(template_name, threshold=DEFAULT_MATCH_THRESHOLD, debug=1):
screen = gui.screenshot()
screen = np.array(
screen) # pyautogui is using Pillow which is giving a format that must be adapted to work with opencv.
screen = cv2.cvtColor(screen, cv2.COLOR_RGB2BGR)
(h, w) = screen.shape[:2]
r = aspect_ratio(w, h)
needle = get_template(template_name, r)
return needle, locate_in_image(needle, screen, threshold=DEFAULT_MATCH_THRESHOLD, debug=0)
# This approach was largely inspired by the article
# https://pyimagesearch.com/2015/01/26/multi-scale-template-matching-using-python-opencv/
def locate_in_image(needle, haystack, threshold=DEFAULT_MATCH_THRESHOLD, debug=0):
(tH, tW) = needle.shape[:2]
if debug:
cv2.imshow("Looking For", needle)
cv2.waitKey(0)
for scale in np.linspace(0.2, 1.0, 20)[::-1]:
# resize the image according to the scale, and keep track
# of the ratio of the resizing
resized = imutils.resize(haystack, width=int(haystack.shape[1] * scale), inter=cv2.INTER_NEAREST)
r = haystack.shape[1] / float(resized.shape[1])
# if the resized image is smaller than the template, then break
# from the loop
if resized.shape[0] < tH or resized.shape[1] < tW:
break
result = cv2.matchTemplate(resized, needle, cv2.TM_CCOEFF_NORMED)
(_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)
if debug:
# draw a bounding box around the detected region
# clone = np.dstack([edged, edged, edged])
cv2.rectangle(resized, (maxLoc[0], maxLoc[1]),
(maxLoc[0] + tW, maxLoc[1] + tH), (0, 0, 255), 2)
cv2.imshow("Searching", resized)
cv2.waitKey(0)
if maxVal >= threshold:
found = (maxVal, maxLoc, r)
# unpack the bookkeeping variable and compute the (x, y) coordinates
# of the bounding box based on the resized ratio
(_, maxLoc, r) = found
(startX, startY) = (int(maxLoc[0] * r), int(maxLoc[1] * r))
(endX, endY) = (int((maxLoc[0] + tW) * r), int((maxLoc[1] + tH) * r))
# if debug:
# draw a bounding box around the detected result and display the image
cv2.rectangle(haystack, (startX, startY), (endX, endY), (0, 0, 255), 2)
# cv2.imshow("Found", haystack)
print(f"x: {startX} y: {startY}")
cv2.imwrite("found.png", haystack)
# cv2.waitKey(0)
return startX, startY
raise ImageNotFound("Image not found on screen")
def wait_for_image_on_screen(template_name, match_threshold=DEFAULT_MATCH_THRESHOLD, interval=DEFAULT_INTERVAL,
timeout=DEFAULT_TIMEOUT):
"""Function that will wait for an image to appear on screen. This function will check every
interval for a match that meets is greater than the match threshold. The function will raise
an error if the image is not found within the timeout given. Will return the location
of the image if found"""
t0 = time.time()
t1 = t0
while not t1 - t0 > timeout:
try:
img, loc = locate_on_screen(template_name, match_threshold)
return img, loc
except ImageNotFound:
pass
time.sleep(interval)
t1 = time.time()
raise ImageNotFoundTimeout("Could not find image on screen within timeout")

View File

@@ -1,3 +0,0 @@
# Stub
def get_resolution():
return 0,0

View File

@@ -1,84 +0,0 @@
import os
from subprocess import Popen
import logging
import time
import pydirectinput as user
import sys
from cv2_utils import *
from far_cry_6_utils import get_resolution
sys.path.insert(1, os.path.join(sys.path[0], '..'))
from harness_utils.logging import *
from harness_utils.process import terminate_processes
DEFAULT_INSTALLATION_PATH = "C:\\Program Files (x86)\\Ubisoft\\Ubisoft Game Launcher\\games\\Far Cry 6\\bin"
EXECUTABLE = "FarCry6.exe"
SCRIPT_DIRECTORY = os.path.dirname(os.path.realpath(__file__))
LOG_DIRECTORY = os.path.join(SCRIPT_DIRECTORY, "run")
PROCESS_NAME = "FarCry6"
def start_game():
cmd = DEFAULT_INSTALLATION_PATH + '\\' + EXECUTABLE
logging.info(cmd)
return Popen(cmd)
def run_benchmark():
start_game()
t1 = time.time()
time.sleep(50)
user.press("space")
user.press("space")
wait_and_click('options', 'options button', click_type=ClickType.HARD)
time.sleep(2)
wait_and_click('benchmark', 'options button', click_type=ClickType.HARD)
t2 = time.time()
logging.info(f"Setup took {round((t2 - t1), 2)} seconds")
start_time = time.time()
time.sleep(75) # wait for benchmark to complete 60 + 15 grace
wait_for_image_on_screen('header', 'results', interval=2, timeout=60)
end_time = time.time()
logging.info(f"Benchark took {round((end_time - start_time), 2)} seconds")
# Exit
terminate_processes(PROCESS_NAME)
return start_time, end_time
setup_log_directory(LOG_DIRECTORY)
logging.basicConfig(filename=f'{LOG_DIRECTORY}/harness.log',
format=DEFAULT_LOGGING_FORMAT,
datefmt=DEFAULT_DATE_FORMAT,
level=logging.DEBUG)
console = logging.StreamHandler()
formatter = logging.Formatter(DEFAULT_LOGGING_FORMAT)
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)
try:
start_time, end_time = run_benchmark()
height, width = get_resolution()
result = {
"resolution": format_resolution(width, height),
"graphics_preset": "current",
"start_time": seconds_to_milliseconds(start_time),
"end_time": seconds_to_milliseconds(end_time)
}
write_report_json(LOG_DIRECTORY, "report.json", result)
except Exception as e:
logging.error("Something went wrong running the benchmark!")
logging.exception(e)
terminate_processes(PROCESS_NAME)
exit(1)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

View File

@@ -1,8 +0,0 @@
friendly_name: "Far Cry 6"
executable: "farcry6.py"
process_name: "FarCry6.exe"
output_dir: "run"
options:
- name: preset
type: select
values: [current]

View File

@@ -1,17 +0,0 @@
import cv2
import os
from cv2_utils import *
script_dir = os.path.dirname(os.path.realpath(__file__))
images_dir = os.path.join(script_dir, "images")
test_images_dir = os.path.join(images_dir, "tests")
test_menus = {
"mainmenu_1080": cv2.imread(os.path.join(test_images_dir, "main_menu_1080_32inch.png"), cv2.IMREAD_UNCHANGED),
}
# found = locate_in_image(get_template('press_any'), test_menus['mainmenu_2k'], debug = 0)
# print(found)
found = locate_in_image(get_template('options'), test_menus['mainmenu_1080'], debug=0, threshold=0.8)
print(found)