From fe66e24c5a7ccda2a65eda5e268c5fee93e7a535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laure=CE=B7t?= Date: Sun, 20 Mar 2022 23:00:30 +0100 Subject: [PATCH] feat: optimized color picking --- .gitignore | 1 + .vscode/launch.json | 2 +- src/{db.py => database.py} | 0 src/database_recoder.py | 190 ---------------------------------- src/garage.py | 207 +++++++++++++++++++++++++++++++++++++ src/{gen.py => init.py} | 36 ++----- src/main.py | 41 ++++++++ 7 files changed, 256 insertions(+), 221 deletions(-) rename src/{db.py => database.py} (100%) delete mode 100644 src/database_recoder.py create mode 100644 src/garage.py rename src/{gen.py => init.py} (75%) diff --git a/.gitignore b/.gitignore index 5fd554b..86160c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .venv .mypy_cache data +**/__pycache__ diff --git a/.vscode/launch.json b/.vscode/launch.json index 24322c6..417f785 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ "name": "Python: Current File", "type": "python", "request": "launch", - "program": "${file}", + "program": "${workspaceFolder}/src/main.py", "console": "integratedTerminal", "justMyCode": true } diff --git a/src/db.py b/src/database.py similarity index 100% rename from src/db.py rename to src/database.py diff --git a/src/database_recoder.py b/src/database_recoder.py deleted file mode 100644 index 4689a80..0000000 --- a/src/database_recoder.py +++ /dev/null @@ -1,190 +0,0 @@ -import itertools -import logging -from subprocess import call -from time import sleep - -import numpy as np - -CENTER = (1000, 500) - -GARAGE = (340, 980) - -EDIT_LOADOUT_BTN = (1950, 850) -SELECT_CAR_BTN = (1950, 980) - -BACK_BTN = (50, 50) - -itemX = (200, 450, 700) -itemY = (300, 580, 860) - -STICKER_MENU_BTN = (220, 60) -WHEEL_MENU_BTN = (330, 60) -HAT_MENU_BTN = (440, 60) -COLOR_MENU_BTN = (660, 60) - -PRIMARY_COLOR_SLIDER = (290, 542) -SECONDARY_COLOR_SLIDER = (380, 632) - -color_min = 366 -color_max = 708 -color_center = (color_min + color_max) / 2 -color_dist = color_max - color_min - -# Nsticker = [2, 2] # [3, 3, 8, 9] -NB_STICKERS = 2 -NB_WHEELS = 19 -NB_HATS = 22 -NB_TEAMS = 2 - -DELAY = 0.2 - -NB_PRIMARY_COLORS = 1 # 3 -NB_SECONDARY_COLORS = 1 # 3 - -NB_HORIZONTAL_ROTATIONS = 1 # 3 -NB_VERTICAL_ROTATIONS = 1 # 3 - - -def tap(pos): - call(["adb", "shell", "input", "tap", str(pos[0]), str(pos[1])]) - # device.shell(f"input tap {pos[0]} {pos[1]}") - - -def motion(pos, type): - call(["adb", "shell", "input", "motionevent", type, str(pos[0]), str(pos[1])]) - - -def setColor(c: int, p: float, a: float): - tap(COLOR_MENU_BTN) - - # set principal color - motion((color_center, PRIMARY_COLOR_SLIDER[c]), "DOWN") - motion((color_min + 100, PRIMARY_COLOR_SLIDER[c]), "MOVE") - motion((color_min + p * color_dist, PRIMARY_COLOR_SLIDER[c]), "MOVE") - motion((color_min + p * color_dist, PRIMARY_COLOR_SLIDER[c]), "UP") - - # set accent color - motion((color_center, SECONDARY_COLOR_SLIDER[c]), "DOWN") - motion((color_min + 100, SECONDARY_COLOR_SLIDER[c]), "MOVE") - motion((color_min + a * color_dist, SECONDARY_COLOR_SLIDER[c]), "MOVE") - motion((color_min + a * color_dist, SECONDARY_COLOR_SLIDER[c]), "UP") - - -def rotate(x, y): - sleep(2) - motion(CENTER, "DOWN") - motion(CENTER, "MOVE") - motion(np.array(CENTER) + np.array((x, y)), "MOVE") - motion(np.array(CENTER) + np.array((x, y)), "UP") - - -def selectItem(kind, i): - tap(kind) - sleep(DELAY) - - col = i % 3 - row = i // 3 - - # slide up item list - if row > 2: - nslide = row - 2 - slide = itemY[0] - itemY[1] - - motion((itemX[1], itemY[2]), "DOWN") - motion((itemX[1], itemY[1]), "MOVE") - motion((itemX[1], itemY[1] + nslide * slide), "MOVE") - motion((itemX[1], itemY[1] + nslide * slide), "UP") - - row -= nslide - - tap((itemX[col], itemY[row])) - - -def nextModel(n): - motion(CENTER, "DOWN") - motion(CENTER, "MOVE") - motion(np.array(CENTER) + np.array((n * -1700, 0)), "MOVE") - motion(np.array(CENTER) + np.array((n * -1700, 0)), "UP") - tap(SELECT_CAR_BTN) - - -def newCar(s=-1, w=-1, h=-1, c=-1, p=-1.0, a=-1.0, n=0): - tap(GARAGE) - sleep(DELAY) - - if n: - nextModel(n) - sleep(DELAY) - - tap(EDIT_LOADOUT_BTN) - sleep(DELAY) - - if s >= 0: - selectItem(STICKER_MENU_BTN, s) - sleep(DELAY) - - if w >= 0: - selectItem(WHEEL_MENU_BTN, w) - sleep(DELAY) - - if h >= 0: - selectItem(HAT_MENU_BTN, h) - sleep(DELAY) - - if c >= 0: - setColor(c, p, a) - sleep(DELAY) - - tap(BACK_BTN) - sleep(DELAY) - - tap(BACK_BTN) - sleep(DELAY) - - -# # primary color dicho -# primary_colors = [] -# for ip in range(3): -# ori_p = 1 / 2 ** (ip + 1) -# dec_p = 1 / 2**ip -# for jp in range(2**ip): -# primary_colors.append(ori_p + jp * dec_p) - -# # secondary color dicho -# secondary_colors = [] -# for ia in range(3): -# ori_a = 1 / 2 ** (ia + 1) -# dec_a = 1 / 2**ia -# for ja in range(2**ia): -# secondary_colors.append(ori_a + ja * dec_a) - -primary_colors = np.linspace(0, 1, 5, endpoint=True) -secondary_colors = np.linspace(0, 1, 5, endpoint=True) - -teams = range(NB_TEAMS) - -stickers = range(NB_STICKERS) - -wheels = range(NB_WHEELS) - -hats = range(NB_HATS) - -vertical_rotations = range(NB_VERTICAL_ROTATIONS) -horizontal_rotations = range(NB_HORIZONTAL_ROTATIONS) - -loadouts = itertools.product(wheels, hats, primary_colors, secondary_colors, teams) -nb_loadouts = ( - len(teams) * len(wheels) * len(hats) * len(primary_colors) * len(secondary_colors) -) # find something prettier - -logging.basicConfig( - level=logging.DEBUG, - format="%(asctime)s %(name)s %(levelname)-8s %(message)s", - datefmt="(%F %T)", -) - -logging.debug(f"number of loadouts: {nb_loadouts}") - -for (wheel, hat, primary_color, secondary_color, team) in loadouts: - logging.debug(f"next loadout: {(team, wheel, hat, primary_color, secondary_color)}") - newCar(w=wheel, h=hat, p=primary_color, a=secondary_color, c=team) diff --git a/src/garage.py b/src/garage.py new file mode 100644 index 0000000..2b847e1 --- /dev/null +++ b/src/garage.py @@ -0,0 +1,207 @@ +import itertools +import logging +from subprocess import call +from time import sleep + +import numpy as np + +CENTER = (1000, 500) + +STICKER_MENU_BTN = (220, 60) +WHEEL_MENU_BTN = (330, 60) +HAT_MENU_BTN = (440, 60) +COLOR_MENU_BTN = (660, 60) +GARAGE_BTN = (340, 980) +EDIT_LOADOUT_BTN = (1950, 850) +SELECT_CAR_BTN = (1950, 980) +BACK_BTN = (50, 50) + +COLOR_MIN = 375 +COLOR_MAX = 715 +COLOR_CENTER = (COLOR_MIN + COLOR_MAX) // 2 +COLOR_DIST = COLOR_MAX - COLOR_MIN +TEAM_OFFSET = 250 +PRIMARY_COLOR_SLIDER = (290, 290 + TEAM_OFFSET) +SECONDARY_COLOR_SLIDER = (380, 380 + TEAM_OFFSET) + +itemX = (200, 450, 700) +itemY = (300, 580, 860) + +# Nsticker = [2, 2] # [3, 3, 8, 9] +NB_STICKERS = 2 +NB_WHEELS = 19 +NB_HATS = 22 +NB_TEAMS = 2 + +DELAY = 0.08 + +NB_PRIMARY_COLORS = 5 +NB_SECONDARY_COLORS = 5 + +NB_HORIZONTAL_ROTATIONS = 3 +NB_VERTICAL_ROTATIONS = 3 + + +old_model = None +old_sticker = None +old_wheel = None +old_hat = None +old_primary_color = 0.5 +old_secondary_color = 0.5 +old_team = None + + +def tap(pos): + call(["adb", "shell", "input", "tap", str(pos[0]), str(pos[1])]) + # device.shell(f"input tap {pos[0]} {pos[1]}") + + +def motion(pos, type): + call(["adb", "shell", "input", "motionevent", type, str(pos[0]), str(pos[1])]) + + +def setColor(team: int, primary_color: float, secondary_color: float): + + global old_primary_color + global old_secondary_color + + tap(COLOR_MENU_BTN) + + # set primary color, if necessary + if primary_color != old_primary_color: + motion((COLOR_MIN + old_primary_color * COLOR_DIST, PRIMARY_COLOR_SLIDER[team]), "DOWN") + motion((COLOR_MIN + old_primary_color * COLOR_DIST, PRIMARY_COLOR_SLIDER[team]), "MOVE") + motion((COLOR_MIN + primary_color * COLOR_DIST, PRIMARY_COLOR_SLIDER[team]), "MOVE") + motion((COLOR_MIN + primary_color * COLOR_DIST, PRIMARY_COLOR_SLIDER[team]), "UP") + + # set secondary color, if necessary + if secondary_color != old_secondary_color: + motion((COLOR_MIN + old_secondary_color * COLOR_DIST, SECONDARY_COLOR_SLIDER[team]), "DOWN") + motion((COLOR_MIN + old_secondary_color * COLOR_DIST, SECONDARY_COLOR_SLIDER[team]), "MOVE") + motion((COLOR_MIN + secondary_color * COLOR_DIST, SECONDARY_COLOR_SLIDER[team]), "MOVE") + motion((COLOR_MIN + secondary_color * COLOR_DIST, SECONDARY_COLOR_SLIDER[team]), "UP") + + +def rotate(x, y): + sleep(2) + motion(CENTER, "DOWN") + motion(CENTER, "MOVE") + motion(np.array(CENTER) + np.array((x, y)), "MOVE") + motion(np.array(CENTER) + np.array((x, y)), "UP") + + +def selectItem(kind, i): + tap(kind) + sleep(DELAY) + + col = i % 3 + row = i // 3 + + # slide up item list + if row > 2: + nslide = row - 2 + slide = itemY[0] - itemY[1] + + motion((itemX[1], itemY[2]), "DOWN") + motion((itemX[1], itemY[1]), "MOVE") + motion((itemX[1], itemY[1] + nslide * slide), "MOVE") + motion((itemX[1], itemY[1] + nslide * slide), "UP") + + row -= nslide + + tap((itemX[col], itemY[row])) + + +def nextModel(n): + motion(CENTER, "DOWN") + motion(CENTER, "MOVE") + motion(np.array(CENTER) + np.array((n * -1700, 0)), "MOVE") + motion(np.array(CENTER) + np.array((n * -1700, 0)), "UP") + tap(SELECT_CAR_BTN) + + +# def newCar(model: int, sticker: int, wheel: int, hat: int, team: int, primary_color: float, secondary_color: float): +def newCar(wheel: int, hat: int, team: int, primary_color: float, secondary_color: float): + + global old_model + global old_sticker + global old_wheel + global old_hat + global old_primary_color + global old_secondary_color + global old_team + + # goto garage menu + tap(GARAGE_BTN) + sleep(DELAY) + + # # select new model, if necessary + # if model != old_model: + # nextModel(model) + # old_model = model + # sleep(DELAY) + + # goto loadout editor + tap(EDIT_LOADOUT_BTN) + sleep(DELAY) + + # # select sticker, if necessary + # if sticker != old_sticker: + # selectItem(STICKER_MENU_BTN, sticker) + # old_sticker = sticker + # sleep(DELAY) + + # select wheel, if necessary + if wheel != old_wheel: + selectItem(WHEEL_MENU_BTN, wheel) + old_wheel = wheel + sleep(DELAY) + + # select hat, if necessary + if hat != old_hat: + selectItem(HAT_MENU_BTN, hat) + old_hat = hat + sleep(DELAY) + + # select color, if necessary + if team != old_team or primary_color != old_primary_color or secondary_color != old_secondary_color: + setColor(team, primary_color, secondary_color) + old_team = team + old_primary_color = primary_color + old_secondary_color = secondary_color + sleep(DELAY) + + # goto main menu + tap(BACK_BTN) + sleep(DELAY) + tap(BACK_BTN) + sleep(DELAY) + + +def generate_loadouts(): + primary_colors = np.linspace(0, 1, NB_PRIMARY_COLORS, endpoint=True) + secondary_colors = np.linspace(0, 1, NB_SECONDARY_COLORS, endpoint=True) + + teams = range(NB_TEAMS) + # stickers = range(NB_STICKERS) + wheels = range(NB_WHEELS) + hats = range(NB_HATS) + + loadouts = itertools.product(wheels, hats, teams, primary_colors, secondary_colors) + nb_loadouts = NB_WHEELS * NB_HATS * NB_PRIMARY_COLORS * NB_SECONDARY_COLORS * NB_TEAMS + + logging.debug(f"number of loadouts: {nb_loadouts}") + + return loadouts + + +def generate_rotations(): + vertical_rotations = range(NB_VERTICAL_ROTATIONS) + horizontal_rotations = range(NB_HORIZONTAL_ROTATIONS) + + rotations = itertools.product(vertical_rotations, horizontal_rotations) + nb_rotations = NB_HORIZONTAL_ROTATIONS * NB_VERTICAL_ROTATIONS + + logging.debug(f"number of rotations: {nb_rotations}") + + return rotations diff --git a/src/gen.py b/src/init.py similarity index 75% rename from src/gen.py rename to src/init.py index e42b3e1..0267d3b 100644 --- a/src/gen.py +++ b/src/init.py @@ -1,6 +1,5 @@ import logging import re -from time import sleep from ppadb.client import Client as AdbClient @@ -13,12 +12,6 @@ PSYONIX_ACTIVITY_NAME = "com.epicgames.ue4.SplashActivity" ADB_HOST = "127.0.0.1" ADB_PORT = 5037 -logging.basicConfig( - level=logging.DEBUG, - format="%(asctime)s %(name)s %(levelname)-8s %(message)s", - datefmt="(%F %T)", -) - def connect_adb(): client = AdbClient(host=ADB_HOST, port=ADB_PORT) @@ -50,12 +43,13 @@ def get_users(device): def detect_game(device, users): - users = [ - (id, name) for (id, name) in users if "package:" in device.shell(f"pm path --user {id} {PSYONIX_PACKAGE_NAME}") - ] + playable_users = [] + for (id, name) in users: + if "package:" in device.shell(f"pm path --user {id} {PSYONIX_PACKAGE_NAME}"): + playable_users.append((id, name)) - logging.debug(f"playable users: {users}") - return users + logging.debug(f"playable users: {playable_users}") + return playable_users def start_game(device, users): @@ -86,21 +80,3 @@ def detect_focus(device) -> bool: activity_dump = device.shell("dumpsys activity activities") result = REGEX_FOCUS.search(activity_dump) return result is not None - - -if __name__ == "__main__": - - device = connect_adb() - - users = get_users(device) - - users = detect_game(device, users) - - start_game(device, users) - - set_notifications(device, False) - - while detect_focus(device): - sleep(1) - - set_notifications(device, True) diff --git a/src/main.py b/src/main.py index e69de29..558941c 100644 --- a/src/main.py +++ b/src/main.py @@ -0,0 +1,41 @@ +import logging +from time import sleep +from tkinter import VERTICAL + +from garage import generate_loadouts, generate_rotations, newCar, rotate +from init import ( + connect_adb, + detect_focus, + detect_game, + get_users, + set_notifications, + start_game, +) + +logging.basicConfig( + level=logging.DEBUG, + format="%(asctime)s %(name)s %(levelname)-8s %(message)s", + datefmt="(%F %T)", +) + +if __name__ == "__main__": + + device = connect_adb() + + users = get_users(device) + users = detect_game(device, users) + start_game(device, users) + set_notifications(device, False) + + loadouts = generate_loadouts() + rotations = generate_rotations() + + while detect_focus(device): + for (wheel, hat, team, primary_color, secondary_color) in loadouts: + logging.debug(f"next loadout: {(wheel, hat, team, primary_color, secondary_color)}") + newCar(wheel, hat, team, primary_color, secondary_color) + + # for (horizontal_rotation, vertical_rotation) in rotations: + # rotate(horizontal_rotation, vertical_rotation) + + set_notifications(device, True)