From 588c5c3497c1baf656a3ad27946347f54541dd73 Mon Sep 17 00:00:00 2001 From: Florian Kostenzer Date: Thu, 30 Apr 2020 18:35:27 +0200 Subject: [PATCH] Leveling Mode (#7) --- .../RDMUICManager/BuildController.swift | 47 ++-- .../.idea/RealDeviceMap-UIControl.iml | 11 - RealDeviceMap-UIControl/.idea/misc.xml | 7 - RealDeviceMap-UIControl/.idea/modules.xml | 8 - RealDeviceMap-UIControl/.idea/workspace.xml | 105 -------- .../DeviceConfig/DeviceConfigProtocol.swift | 14 +- .../DeviceConfig/DeviceRatio1333.swift | 27 +- .../DeviceConfig/DeviceRatio1775.swift | 31 ++- RealDeviceMap-UIControl/Misc.swift | 240 +++++++++++++----- .../RealDeviceMap_UIControlUITests.swift | 114 ++++++--- 10 files changed, 332 insertions(+), 272 deletions(-) delete mode 100644 RealDeviceMap-UIControl/.idea/RealDeviceMap-UIControl.iml delete mode 100644 RealDeviceMap-UIControl/.idea/misc.xml delete mode 100644 RealDeviceMap-UIControl/.idea/modules.xml delete mode 100644 RealDeviceMap-UIControl/.idea/workspace.xml diff --git a/Manager/Sources/RDMUICManager/BuildController.swift b/Manager/Sources/RDMUICManager/BuildController.swift index 15d9a665..bc1a195e 100644 --- a/Manager/Sources/RDMUICManager/BuildController.swift +++ b/Manager/Sources/RDMUICManager/BuildController.swift @@ -4,7 +4,7 @@ // // Created by Florian Kostenzer on 28.11.18. // -// swiftlint:disable type_body_length function_body_length cyclomatic_complexity +// swiftlint:disable type_body_length function_body_length // import Foundation @@ -243,37 +243,20 @@ class BuildController { outputPipe.fileHandleForReading.readabilityHandler = { fileHandle in let string = String(data: fileHandle.availableData, encoding: .utf8) if string != nil && string!.trimmingCharacters(in: .whitespacesAndNewlines) != "" { - if string!.contains(string: "[STATUS] Started") && locked { - Log.debug(message: "[\(device.name)] Done building") - self.setStatus(uuid: device.uuid, status: "Running: Starting") - locked = false - self.buildLock.lock() - self.buildingCount -= 1 - self.buildLock.unlock() - } - if string!.contains(string: "[STATUS] Startup") { - self.setStatus(uuid: device.uuid, status: "Running: Startup") - } - if string!.contains(string: "[STATUS] Logout") { - self.setStatus(uuid: device.uuid, status: "Running: Logout") - } - if string!.contains(string: "[STATUS] Login") { - self.setStatus(uuid: device.uuid, status: "Running: Login") - } - if string!.contains(string: "[STATUS] Tutorial") { - self.setStatus(uuid: device.uuid, status: "Running: Tutorial") - } - if string!.contains(string: "[STATUS] Pokemon") { - self.setStatus(uuid: device.uuid, status: "Running: Pokemon") - } - if string!.contains(string: "[STATUS] Raid") { - self.setStatus(uuid: device.uuid, status: "Running: Raid") - } - if string!.contains(string: "[STATUS] Quest") { - self.setStatus(uuid: device.uuid, status: "Running: Quest") - } - if string!.contains(string: "[STATUS] IV") { - self.setStatus(uuid: device.uuid, status: "Running: IV") + for line in string!.components(separatedBy: .newlines) { + if line.contains(string: "[STATUS] Started") && locked { + Log.debug(message: "[\(device.name)] Done building") + self.setStatus(uuid: device.uuid, status: "Running: Starting") + locked = false + self.buildLock.lock() + self.buildingCount -= 1 + self.buildLock.unlock() + } else if line.starts(with: "[STATUS]") { + self.setStatus( + uuid: device.uuid, + status: line.replacingOccurrences(of: "[STATUS] ", with: "") + ) + } } fullLog.uic(message: string!, all: true) diff --git a/RealDeviceMap-UIControl/.idea/RealDeviceMap-UIControl.iml b/RealDeviceMap-UIControl/.idea/RealDeviceMap-UIControl.iml deleted file mode 100644 index 67116063..00000000 --- a/RealDeviceMap-UIControl/.idea/RealDeviceMap-UIControl.iml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/RealDeviceMap-UIControl/.idea/misc.xml b/RealDeviceMap-UIControl/.idea/misc.xml deleted file mode 100644 index f99b3111..00000000 --- a/RealDeviceMap-UIControl/.idea/misc.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/RealDeviceMap-UIControl/.idea/modules.xml b/RealDeviceMap-UIControl/.idea/modules.xml deleted file mode 100644 index 9c46618f..00000000 --- a/RealDeviceMap-UIControl/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/RealDeviceMap-UIControl/.idea/workspace.xml b/RealDeviceMap-UIControl/.idea/workspace.xml deleted file mode 100644 index 8e7a4483..00000000 --- a/RealDeviceMap-UIControl/.idea/workspace.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - true - DEFINITION_ORDER - - - - - - - - - - - - - - - - - - - - - - - - - - - 1538351440306 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/RealDeviceMap-UIControl/DeviceConfig/DeviceConfigProtocol.swift b/RealDeviceMap-UIControl/DeviceConfig/DeviceConfigProtocol.swift index 10898865..516f5a55 100644 --- a/RealDeviceMap-UIControl/DeviceConfig/DeviceConfigProtocol.swift +++ b/RealDeviceMap-UIControl/DeviceConfig/DeviceConfigProtocol.swift @@ -117,14 +117,14 @@ protocol DeviceConfigProtocol { var openQuest: DeviceCoordinate { get } /** First delete quests button. */ var questDelete: DeviceCoordinate { get } - /** Color of the top quest rectangle. */ - var questFilledColor1: DeviceCoordinate { get } /** First delete Quest Button if stacked Encounter is present */ var questDeleteWithStack: DeviceCoordinate { get } - /** Color of the top quest rectangle if stacked Encounter is present. */ - var questFilledColorWithStack1: DeviceCoordinate { get } /** Green confirm quest deletion button */ var questDeleteConfirm: DeviceCoordinate { get } + /** Check for the pokeball on Willow's desk. */ + var questWillow: DeviceCoordinate { get } + /** Third delete Quest Button if stacked Encounter is present */ + var questDeleteThirdSlot: DeviceCoordinate { get } // MARK: - Item Clearing @@ -146,6 +146,12 @@ protocol DeviceConfigProtocol { var itemEggMenuItem: DeviceCoordinate { get } /** Tap Location for Egg Deployment */ var itemEggDeploy: DeviceCoordinate { get } + /** The Y values for all item delete buttons. */ + var itemIncenseYs: [Int] { get } + /** Free Pass OK button. */ + var itemFreePass: DeviceCoordinate { get } + /** Gift info OK button. */ + var itemGiftInfo: DeviceCoordinate { get } // MARK: - Login diff --git a/RealDeviceMap-UIControl/DeviceConfig/DeviceRatio1333.swift b/RealDeviceMap-UIControl/DeviceConfig/DeviceRatio1333.swift index 57c48078..8bd39a0a 100644 --- a/RealDeviceMap-UIControl/DeviceConfig/DeviceRatio1333.swift +++ b/RealDeviceMap-UIControl/DeviceConfig/DeviceRatio1333.swift @@ -186,21 +186,21 @@ class DeviceRatio1333: DeviceConfigProtocol { var questDelete: DeviceCoordinate { return DeviceCoordinate(x: 1434, y: 1272, scaler: scaler) } - var questFilledColor1: DeviceCoordinate { - return DeviceCoordinate(x: 108, y: 1258, scaler: scaler) - } var questDeleteWithStack: DeviceCoordinate { return DeviceCoordinate(x: 1445, y: 1677, scaler: scaler) } - var questFilledColorWithStack1: DeviceCoordinate { - return DeviceCoordinate(x: 108, y: 1665, scaler: scaler) - } var questDeleteConfirm: DeviceCoordinate { return DeviceCoordinate(x: 768, y: 1143, scaler: scaler) } var openItems: DeviceCoordinate { return DeviceCoordinate(x: 1165, y: 1620, scaler: scaler) } + var questWillow: DeviceCoordinate { + return DeviceCoordinate(x: 0, y: 0, scaler: scaler) + } + var questDeleteThirdSlot: DeviceCoordinate { + return DeviceCoordinate(x: 1445, y: 2030, scaler: scaler) //not accurate + } // MARK: - Item Clearing @@ -235,6 +235,21 @@ class DeviceRatio1333: DeviceConfigProtocol { scaler.scaleY(y: 2010) ] } + var itemIncenseYs: [Int] { + return [ + scaler.scaleY(y: 0), + scaler.scaleY(y: 0), + scaler.scaleY(y: 0), + scaler.scaleY(y: 0), + scaler.scaleY(y: 0) + ] + } + var itemFreePass: DeviceCoordinate { + return DeviceCoordinate(x: 0, y: 0, scaler: scaler) + } + var itemGiftInfo: DeviceCoordinate { + return DeviceCoordinate(x: 0, y: 0, scaler: scaler) + } // MARK: - Login diff --git a/RealDeviceMap-UIControl/DeviceConfig/DeviceRatio1775.swift b/RealDeviceMap-UIControl/DeviceConfig/DeviceRatio1775.swift index c22c81ec..b4b4b359 100644 --- a/RealDeviceMap-UIControl/DeviceConfig/DeviceRatio1775.swift +++ b/RealDeviceMap-UIControl/DeviceConfig/DeviceRatio1775.swift @@ -169,10 +169,10 @@ class DeviceRatio1775: DeviceConfigProtocol { return DeviceCoordinate(x: 320, y: 585, scaler: scaler) } var rocketLogoGirl: DeviceCoordinate { - return DeviceCoordinate(x: 390, y: 468, scaler: scaler) + return DeviceCoordinate(x: 350, y: 500, scaler: scaler) } var rocketLogoGuy: DeviceCoordinate { - return DeviceCoordinate(x: 302, y: 463, scaler: scaler) + return DeviceCoordinate(x: 254, y: 484, scaler: scaler) } var closeInvasion: DeviceCoordinate { return DeviceCoordinate(x: 320, y: 1000, scaler: scaler) @@ -186,21 +186,21 @@ class DeviceRatio1775: DeviceConfigProtocol { var questDelete: DeviceCoordinate { return DeviceCoordinate(x: 596, y: 570, scaler: scaler) } - var questFilledColor1: DeviceCoordinate { - return DeviceCoordinate(x: 44, y: 567, scaler: scaler) - } var questDeleteWithStack: DeviceCoordinate { return DeviceCoordinate(x: 596, y: 739, scaler: scaler) } - var questFilledColorWithStack1: DeviceCoordinate { - return DeviceCoordinate(x: 44, y: 736, scaler: scaler) - } var questDeleteConfirm: DeviceCoordinate { return DeviceCoordinate(x: 320, y: 620, scaler: scaler) } var openItems: DeviceCoordinate { return DeviceCoordinate(x: 500, y: 950, scaler: scaler) } + var questWillow: DeviceCoordinate { + return DeviceCoordinate(x: 50, y: 1125, scaler: scaler) + } + var questDeleteThirdSlot: DeviceCoordinate { + return DeviceCoordinate(x: 600, y: 860, scaler: scaler) + } // MARK: - Item Clearing @@ -234,6 +234,21 @@ class DeviceRatio1775: DeviceConfigProtocol { scaler.scaleY(y: 1124) ] } + var itemIncenseYs: [Int] { + return [ + scaler.scaleY(y: 232), + scaler.scaleY(y: 460), + scaler.scaleY(y: 687), + scaler.scaleY(y: 914), + scaler.scaleY(y: 1141) + ] + } + var itemFreePass: DeviceCoordinate { + return DeviceCoordinate(x: 320, y: 930, scaler: scaler) + } + var itemGiftInfo: DeviceCoordinate { + return DeviceCoordinate(x: 320, y: 850, scaler: scaler) + } // MARK: - Login diff --git a/RealDeviceMap-UIControl/Misc.swift b/RealDeviceMap-UIControl/Misc.swift index 55b35fca..cc34e8be 100644 --- a/RealDeviceMap-UIControl/Misc.swift +++ b/RealDeviceMap-UIControl/Misc.swift @@ -930,7 +930,7 @@ extension XCTestCase { Log.debug("Log out confirmation button found") deviceConfig.logoutConfirm.toXCUICoordinate(app: app).tap() - for index in 1...20 { + for _ in 1...20 { let screenshotComp = XCUIScreen.main.screenshot() if screenshotComp.rgbAtLocation( @@ -1025,12 +1025,12 @@ extension XCTestCase { // Rocket invasion detection if screenshotComp.rgbAtLocation( pos: deviceConfig.rocketLogoGirl, - min: (red: 0.62, green: 0.24, blue: 0.13), - max: (red: 0.87, green: 0.36, blue: 0.20)) || + min: (red: 0.76, green: 0.30, blue: 0.15), + max: (red: 0.87, green: 0.38, blue: 0.22)) || screenshotComp.rgbAtLocation( pos: deviceConfig.rocketLogoGuy, - min: (red: 0.62, green: 0.24, blue: 0.13), - max: (red: 0.87, green: 0.36, blue: 0.20)) { + min: (red: 0.76, green: 0.30, blue: 0.15), + max: (red: 0.87, green: 0.38, blue: 0.22)) { Log.info("Rocket invasion encountered") // Tap through dialog 4 times and wait 3 seconds between each @@ -1046,9 +1046,21 @@ extension XCTestCase { } func clearQuest() { + Log.test("Starting ClearQuest()") let start = Date() deviceConfig.openQuest.toXCUICoordinate(app: app).tap() sleep(1 * config.delayMultiplier) + + var screenshotComp = XCUIScreen.main.screenshot() + while screenshotComp.rgbAtLocation(pos: deviceConfig.questWillow, + min: (red: 0.50, green: 0.00, blue: 0.00), + max: (red: 0.55, green: 0.02, blue: 0.02)) { + Log.test("Clearing Prof Willow") + deviceConfig.openPokestop.toXCUICoordinate(app: app).tap() + sleep(1 * config.delayMultiplier) + screenshotComp = XCUIScreen.main.screenshot() + } + //get us to a known location by swiping left twice (placing us on the special research tab) app.swipeLeft() sleep(1 * config.delayMultiplier) @@ -1058,52 +1070,92 @@ extension XCTestCase { app.swipeRight() sleep(1 * config.delayMultiplier) - var screenshotComp = getScreenshot() - if screenshotComp.rgbAtLocation( pos: deviceConfig.questDelete, min: (red: 0.98, green: 0.60, blue: 0.22), max: (red: 1.0, green: 0.65, blue: 0.27) ) { + //If the top quest is orange, might be clearing stacked quests + //Theres a chance that we have a normal completed quests on top + //We will eventually have a stack so I did not add logic for this check + Log.test("Clearing stacked quests") - for i in 0...2 { + for i in 0...3 { if screenshotComp.rgbAtLocation( - pos: deviceConfig.questFilledColorWithStack1, - min: (red: 0.98, green: 0.98, blue: 0.98), + pos: deviceConfig.questDeleteWithStack, + min: (red: 0.80, green: 0.80, blue: 0.80), max: (red: 1.0, green: 1.0, blue: 1.0) ) { - //top slot is normal quest. delete it. + //second slot is normal quest. delete it. + Log.test("Clearing stacked quests: clearing a normal quest (slot 2).") deviceConfig.questDeleteWithStack.toXCUICoordinate(app: app).tap() sleep(1 * config.delayMultiplier) deviceConfig.questDeleteConfirm.toXCUICoordinate(app: app).tap() sleep(1 * config.delayMultiplier) - if i < 2 { - screenshotComp = getScreenshot() + if i < 3 { + screenshotComp = XCUIScreen.main.screenshot() } } else if screenshotComp.rgbAtLocation( - pos: deviceConfig.questFilledColorWithStack1, - min: (red: 0.98, green: 0.60, blue: 0.22), + pos: deviceConfig.questDeleteWithStack, + min: (red: 0.90, green: 0.56, blue: 0.21), max: (red: 1.0, green: 0.65, blue: 0.27) ) { - //top slot is a completed quest. Click on the quest to initiate the encounter - deviceConfig.questDeleteWithStack.toXCUICoordinate(app: app).tap() - sleep(1 * config.delayMultiplier) - self.freeScreen() //run from the encounter + //second slot is a completed quest. Check the next one so + //we dont leave the quest log. Then click on the quests to initiate the encounter + if screenshotComp.rgbAtLocation( + pos: deviceConfig.questDeleteThirdSlot, + min: (red: 0.80, green: 0.80, blue: 0.80), + max: (red: 1.0, green: 1.0, blue: 1.0) + ) { + //third slot is normal quest. delete it. + Log.test("Clearing stacked quests: clearing a normal quest (slot 3).") + deviceConfig.questDeleteThirdSlot.toXCUICoordinate(app: app).tap() + sleep(1 * config.delayMultiplier) + deviceConfig.questDeleteConfirm.toXCUICoordinate(app: app).tap() + sleep(1 * config.delayMultiplier) + screenshotComp = XCUIScreen.main.screenshot() + } else if screenshotComp.rgbAtLocation( + pos: deviceConfig.questDeleteThirdSlot, + min: (red: 0.98, green: 0.60, blue: 0.22), + max: (red: 1.0, green: 0.65, blue: 0.27) + ) { + //third slot is a completed quest + Log.test("Clearing stacked quests: clearing a completed quest (slot 3).") + deviceConfig.questDeleteThirdSlot.toXCUICoordinate(app: app).tap() + sleep(1 * config.delayMultiplier) + self.freeScreen() //run from the encounter + self.clearQuest() //to finish clearing the quests since we exited the quest log + } else { + //tap the second slot if nothing is in the third slot + Log.test( + "Clearing stacked quests: clearing a completed quest (slot 2). " + + "RGB for quest slot: " + + "\(screenshotComp.rgbAtLocation(pos: deviceConfig.questDelete))" + ) + deviceConfig.questDeleteWithStack.toXCUICoordinate(app: app).tap() + sleep(1 * config.delayMultiplier) + self.freeScreen() //run from the encounter + } } else { //top slot is empty. No more quests to delete, so exit. + deviceConfig.closeMenu.toXCUICoordinate(app: app).tap() + Log.test("No more quests detected. RGB for quest slot: " + + "\(screenshotComp.rgbAtLocation(pos: deviceConfig.questDelete))") break } } - } else { - Log.test("Clearing unstacked quests") + } else {//else we are clearing non-stacked quests because the top spot had the delete icon + Log.test("Clearing unstacked quests. RGB for quest slot: " + + "\(screenshotComp.rgbAtLocation(pos: deviceConfig.questDelete))") for i in 0...2 { if screenshotComp.rgbAtLocation( - pos: deviceConfig.questFilledColor1, - min: (red: 0.98, green: 0.98, blue: 0.98), + pos: deviceConfig.questDelete, + min: (red: 0.80, green: 0.80, blue: 0.80), max: (red: 1.0, green: 1.0, blue: 1.0) ) { //top slot is normal quest. delete it. + Log.test("Clearing unstacked quests: clearing a normal quest (slot 1).") deviceConfig.questDelete.toXCUICoordinate(app: app).tap() sleep(1 * config.delayMultiplier) deviceConfig.questDeleteConfirm.toXCUICoordinate(app: app).tap() @@ -1112,16 +1164,41 @@ extension XCTestCase { screenshotComp = getScreenshot() } } else if screenshotComp.rgbAtLocation( - pos: deviceConfig.questFilledColor1, + pos: deviceConfig.questDelete, min: (red: 0.98, green: 0.60, blue: 0.22), max: (red: 1.0, green: 0.65, blue: 0.27) ) { - //top slot is a completed quest. Click on the quest to initiate the encounter - deviceConfig.questDeleteWithStack.toXCUICoordinate(app: app).tap() - sleep(1 * config.delayMultiplier) - self.freeScreen() //run from the encounter + //top slot is a completed quest. Check the next one so we dont leave the quest log. + //Then click on the quests to initiate the encounter + if screenshotComp.rgbAtLocation( + pos: deviceConfig.questDeleteWithStack, + min: (red: 0.80, green: 0.80, blue: 0.80), + max: (red: 1.0, green: 1.0, blue: 1.0) + ) { + //second slot is normal quest. delete it. + Log.test("Clearing unstacked quests: clearing a normal quest (slot 2).") + deviceConfig.questDeleteWithStack.toXCUICoordinate(app: app).tap() + sleep(1 * config.delayMultiplier) + deviceConfig.questDeleteConfirm.toXCUICoordinate(app: app).tap() + sleep(1 * config.delayMultiplier) + screenshotComp = XCUIScreen.main.screenshot() + } else if screenshotComp.rgbAtLocation( + pos: deviceConfig.questDeleteWithStack, + min: (red: 0.98, green: 0.60, blue: 0.22), + max: (red: 1.0, green: 0.65, blue: 0.27) + ) { + //second slot is a completed quest + Log.test("Clearing unstacked quests: clearing a completed quest (slot 2).") + deviceConfig.questDeleteWithStack.toXCUICoordinate(app: app).tap() + sleep(1 * config.delayMultiplier) + self.freeScreen() //run from the encounter + self.clearQuest() //to finish clearing the last quest since we exited the quest log + } } else { //top slot is empty. No more quests to delete, so exit. + deviceConfig.closeMenu.toXCUICoordinate(app: app).tap() + Log.test("No more quests detected. RGB for quest slot: " + + "\(screenshotComp.rgbAtLocation(pos: deviceConfig.questDelete))") break } } @@ -1145,7 +1222,6 @@ extension XCTestCase { let normalized = app.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0)) var index = 0 var done = false - var hasEgg = false deviceConfig.closeMenu.toXCUICoordinate(app: app).tap() sleep(1 * config.delayMultiplier) @@ -1153,29 +1229,39 @@ extension XCTestCase { sleep(1 * config.delayMultiplier) while !done && deviceConfig.itemDeleteYs.count != 0 { - let screenshot = getScreenshot() + let screenshot = XCUIScreen.main.screenshot() - if itemIsEgg(screenshot, x: deviceConfig.itemEggX, y: deviceConfig.itemDeleteYs[index]) { - hasEgg = true + if screenshot.rgbAtLocation( + pos: deviceConfig.itemFreePass, + min: (red: 0.42, green: 0.81, blue: 0.59), + max: (red: 0.46, green: 0.85, blue: 0.63) + ) { + Log.test("Closing free raid pass popup") + deviceConfig.itemFreePass.toXCUICoordinate(app: app).tap() + sleep(1 * config.delayMultiplier) + } + if screenshot.rgbAtLocation( + pos: deviceConfig.itemGiftInfo, + min: (red: 0.42, green: 0.81, blue: 0.59), + max: (red: 0.46, green: 0.85, blue: 0.63) + ) { + Log.test("Closing gift info popup") + deviceConfig.itemGiftInfo.toXCUICoordinate(app: app).tap() + sleep(1 * config.delayMultiplier) } - if itemHasDelete( - screenshot, - x: deviceConfig.itemDeleteX, - y: deviceConfig.itemDeleteYs[index] - ) && !itemIsGift( - screenshot, - x: deviceConfig.itemGiftX, - y: deviceConfig.itemDeleteYs[index] - ) && !itemIsEgg( - screenshot, - x: deviceConfig.itemEggX, - y: deviceConfig.itemDeleteYs[index] - ) && !itemIsEggActive( - screenshot, - x: deviceConfig.itemEggX, - y: deviceConfig.itemDeleteYs[index] - ) { + if itemHasDelete(screenshot, x: deviceConfig.itemDeleteX, + y: deviceConfig.itemDeleteYs[index]) && + !itemIsGift(screenshot, x: deviceConfig.itemGiftX, + y: deviceConfig.itemDeleteYs[index]) && + !itemIsEgg(screenshot, x: deviceConfig.itemEggX, + y: deviceConfig.itemDeleteYs[index]) && + !itemIsEggActive(screenshot, x: deviceConfig.itemEggX, + y: deviceConfig.itemDeleteYs[index]) || + itemIsPokeball(screenshot, x: deviceConfig.itemGiftX, + y: deviceConfig.itemDeleteYs[index]) || + itemIsIncense(screenshot, x: deviceConfig.itemGiftX, + y: deviceConfig.itemIncenseYs[index]) { let delete = normalized.withOffset( CGVector(dx: lround(Double(deviceConfig.itemDeleteX)*tapMultiplier), @@ -1185,7 +1271,6 @@ extension XCTestCase { sleep(1 * config.delayMultiplier) deviceConfig.itemDeleteIncrease.toXCUICoordinate(app: app).press(forDuration: 3) deviceConfig.itemDeleteConfirm.toXCUICoordinate(app: app).tap() - sleep(1 * config.delayMultiplier) } else if index + 1 < deviceConfig.itemDeleteYs.count { index += 1 @@ -1193,24 +1278,49 @@ extension XCTestCase { done = true } } + sleep(1 * config.delayMultiplier) + } + + func eggDeploy() -> Bool { + Log.test("Starting eggDeploy()") + var hasEgg = false + + deviceConfig.closeMenu.toXCUICoordinate(app: app).tap() + sleep(1 * config.delayMultiplier) + deviceConfig.openItems.toXCUICoordinate(app: app).tap() + sleep(1 * config.delayMultiplier) + + let screenshot = XCUIScreen.main.screenshot() + if itemIsEgg(screenshot, x: deviceConfig.itemEggX, y: deviceConfig.itemDeleteYs[0]) { + hasEgg = true + } else { + //If the top line is not an egg, clear items again just in case and recheck the top line + Log.test("No egg found. Checking for items to clear before a recheck.") + deviceConfig.closeMenu.toXCUICoordinate(app: app).tap() + sleep(1 * config.delayMultiplier) + clearItems() + let screenshot = XCUIScreen.main.screenshot() + if itemIsEgg(screenshot, x: deviceConfig.itemEggX, y: deviceConfig.itemDeleteYs[0]) { + hasEgg = true + } + } - let deployEnabled: Bool = config.deployEggs - Log.test("deployEnabled: \(deployEnabled)") - if hasEgg && deployEnabled { + if hasEgg { + Log.test("New egg found. Deploying it.") deviceConfig.itemEggMenuItem.toXCUICoordinate(app: app).tap() sleep(1 * config.delayMultiplier) deviceConfig.itemEggDeploy.toXCUICoordinate(app: app).tap() sleep(2 * config.delayMultiplier) + return true } else { + Log.test("No egg found or there's already has an active egg. Closing Menu.") deviceConfig.closeMenu.toXCUICoordinate(app: app).tap() - Log.test("Closing Menu") + sleep(1 * config.delayMultiplier) + return false } - sleep(1 * config.delayMultiplier) - } func itemHasDelete(_ screenshot: XCUIScreenshot, x: Int, y: Int) -> Bool { - return screenshot.rgbAtLocation( pos: (x: x, y: y), min: (red: 0.50, green: 0.50, blue: 0.50), @@ -1218,6 +1328,22 @@ extension XCTestCase { ) } + func itemIsPokeball(_ screenshot: XCUIScreenshot, x: Int, y: Int) -> Bool { + return screenshot.rgbAtLocation( + pos: (x: x, y: y), + min: (red: 0.9, green: 0.7, blue: 0.7), + max: (red: 0.99, green: 0.8, blue: 0.8) + ) + } + + func itemIsIncense(_ screenshot: XCUIScreenshot, x: Int, y: Int) -> Bool { + return screenshot.rgbAtLocation( + pos: (x: x, y: y), + min: (red: 0.01, green: 0.9, blue: 0.4), + max: (red: 0.09, green: 1.0, blue: 0.5) + ) + } + func itemIsGift(_ screenshot: XCUIScreenshot, x: Int, y: Int) -> Bool { return screenshot.rgbAtLocation( pos: (x: x, y: y), diff --git a/RealDeviceMap-UIControl/RealDeviceMap_UIControlUITests.swift b/RealDeviceMap-UIControl/RealDeviceMap_UIControlUITests.swift index b3b48c62..4345dcef 100644 --- a/RealDeviceMap-UIControl/RealDeviceMap_UIControlUITests.swift +++ b/RealDeviceMap-UIControl/RealDeviceMap_UIControlUITests.swift @@ -611,8 +611,6 @@ class RealDeviceMap_UIControlUITests: XCTestCase { return } - let normalized = app.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0)) - Log.tutorial("Solving Tutorial for \(username!)") /* Start Reworked Changes Here */ @@ -622,7 +620,7 @@ class RealDeviceMap_UIControlUITests: XCTestCase { usleep(UInt32(1500000 * config.delayMultiplier)) } sleep(2 * config.delayMultiplier) - var gender: Bool = tutorialGenderSelection() + let gender: Bool = tutorialGenderSelection() tutorialPhysicalFeature() tutorialStyleSelection(gender) Log.tutorial("Begin Willow Encounter Speech") @@ -824,14 +822,16 @@ class RealDeviceMap_UIControlUITests: XCTestCase { "lat": currentLocation!.lat, "lng": currentLocation!.lon ] - if self.config.ultraQuests == true && self.action == "scan_quest" { + if self.config.ultraQuests == true && + (self.action == "scan_quest" || self.action == "spin_pokestop") { //autospinning should happen only when ultraQuests is set and the instance is scan_quest type if self.level >= 30 { responseData["actions"] = ["pokemon", "pokestop"] } else { responseData["actions"] = ["pokestop"] } - } else if self.config.ultraQuests == false && self.action == "scan_quest" { + } else if self.config.ultraQuests == false && + (self.action == "scan_quest" || self.action == "spin_pokestop") { //autospinning should happen only when ultraQuests is set and the instance is scan_quest type if self.level >= 30 { responseData["actions"] = ["pokemon"] @@ -881,7 +881,9 @@ class RealDeviceMap_UIControlUITests: XCTestCase { jsonData!["lat_target"] = currentLocation!.lat jsonData!["lon_target"] = currentLocation!.lon jsonData!["target_max_distnace"] = targetMaxDistance - jsonData!["username"] = self.username + if self.username != nil { + jsonData!["username"] = self.username + } jsonData!["pokemon_encounter_id"] = pokemonEncounterId jsonData!["pokemon_encounter_id_for_encounter"] = pokemonEncounterIdForEncounter jsonData!["list_scatter_pokemon"] = listScatterPokemon @@ -897,6 +899,7 @@ class RealDeviceMap_UIControlUITests: XCTestCase { let nearby = data?["nearby"] as? Int ?? 0 let wild = data?["wild"] as? Int ?? 0 //let forts = data?["forts"] as? Int ?? 0 + let fortSearch = data?["fort_search"] as? Int ?? 0 let quests = data?["quests"] as? Int ?? 0 let encounters = data?["encounters"] as? Int ?? 0 let pokemonLat = data?["pokemon_lat"] as? Double @@ -972,9 +975,11 @@ class RealDeviceMap_UIControlUITests: XCTestCase { } else { toPrint = "[DEBUG] Got Data without GMO" } - if !self.gotQuest && quests != 0 { - self.gotQuest = true - self.gotQuestEarly = true + if !self.gotQuest { + if quests > 0 || (self.action == "spin_pokestop" && fortSearch > 0) { + self.gotQuest = true + self.gotQuestEarly = true + } } if !self.gotIV && encounters != 0 { self.gotIV = true @@ -1028,7 +1033,7 @@ class RealDeviceMap_UIControlUITests: XCTestCase { var currentQuests = self.config.questFullCount var currentItems = self.config.itemFullCount - + var eggStart = Date(timeInterval: -1860, since: Date()) var failedToGetJobCount = 0 var failedCount = 0 emptyGmoCount = 0 @@ -1063,7 +1068,7 @@ class RealDeviceMap_UIControlUITests: XCTestCase { if !isStartupCompleted { Log.debug("Performing Startup sequence") currentLocation = config.startupLocation - isStartup() + _ = isStartup() sleep(2 * config.delayMultiplier) deviceConfig.closeNews.toXCUICoordinate(app: app).tap() @@ -1329,13 +1334,19 @@ class RealDeviceMap_UIControlUITests: XCTestCase { } self.lock.unlock() } - } else if action == "scan_quest" { - print("[STATUS] Quest") - + } else if action == "scan_quest" || action == "spin_pokestop" { let lat = data["lat"] as? Double ?? 0 let lon = data["lon"] as? Double ?? 0 let delay = data["delay"] as? Double ?? 0 - Log.debug("Scanning for Quest at \(lat) \(lon) in \(Int(delay))s") + + if action == "scan_quest" { + print("[STATUS] Quest") + Log.debug("Scanning for Quest at \(lat) \(lon) in \(Int(delay))s") + } else { + print("[STATUS] Spin Pokestop") + Log.debug("Spinning Pokestop at \(lat) \(lon) in \(Int(delay))s") + } + if !self.config.ultraQuests { self.zoom( out: false, @@ -1404,7 +1415,9 @@ class RealDeviceMap_UIControlUITests: XCTestCase { sleep(1) } - if currentQuests >= self.config.questFullCount && !self.newCreated { + if action == "scan_quest" && + currentQuests >= self.config.questFullCount && + !self.newCreated { self.freeScreen() Log.debug("Clearing Quests") self.clearQuest() @@ -1413,9 +1426,26 @@ class RealDeviceMap_UIControlUITests: XCTestCase { sleep(1) } } + + if self.config.deployEggs && eggStart < Date() { + self.freeScreen() + Log.debug("Deploying an egg") + let i = Double.random(in: 0...60) + if self.eggDeploy() { + // if an egg was used, set the timer to 31 minutes + eggStart = Date(timeInterval: 1860+i, since: Date()) + } else { + // if no egg was used, set the timer to 16 minutes so it rechecks + // useful if you get more eggs from leveling up + eggStart = Date(timeInterval: 960+i, since: Date()) + } + Log.debug("Egg timer set to \(eggStart) UTC for a recheck") + } + self.newCreated = false self.lock.lock() + let lastLocation = self.currentLocation self.currentLocation = (lat, lon) self.waitRequiresPokemon = false self.pokemonEncounterId = nil @@ -1424,15 +1454,24 @@ class RealDeviceMap_UIControlUITests: XCTestCase { self.gotQuest = false self.lock.unlock() Log.debug("Scanning prepared") - self.freeScreen() let start = Date() - - self.app.swipeLeft() + if !self.config.ultraQuests { + self.freeScreen() + self.app.swipeLeft() + } var success = false var locked = true var found = false + let lastLocationCL = CLLocation(latitude: lastLocation!.lat, + longitude: lastLocation!.lon) + let newLocationCL = CLLocation(latitude: lat, longitude: lon) + if lastLocationCL.distance(from: newLocationCL) <= 100 && delay <= 1 { + locked = false + success = true + } + while locked { usleep(100000 * self.config.delayMultiplier) if Date().timeIntervalSince(start) <= 5 { @@ -1476,23 +1515,26 @@ class RealDeviceMap_UIControlUITests: XCTestCase { self.lock.unlock() } - // Check if previus spin had quest data - self.lock.lock() - if self.gotQuest { - self.noQuestCount = 0 - } else { - self.noQuestCount += 1 - } - self.gotQuest = false + if action == "scan_quest" { + // Check if previus spin had quest data + self.lock.lock() + if self.gotQuest { + self.noQuestCount = 0 + } else { + self.noQuestCount += 1 + } + self.gotQuest = false - if self.noQuestCount >= self.config.maxNoQuestCount { + if self.noQuestCount >= self.config.maxNoQuestCount { + self.lock.unlock() + Log.debug("Stuck somewhere. Restarting") + self.app.terminate() + self.shouldExit = true + return + } self.lock.unlock() - Log.debug("Stuck somewhere. Restarting") - self.app.terminate() - self.shouldExit = true - return } - self.lock.unlock() + if !self.config.ultraQuests { if success { self.freeScreen() @@ -1502,7 +1544,9 @@ class RealDeviceMap_UIControlUITests: XCTestCase { while attempts < 5 { attempts += 1 self.lock.lock() + Log.test("Got quest data: " + self.gotQuest.description) if !self.gotQuest { + Log.test("Respinning stop attempt: " + attempts.description) self.lock.unlock() usleep(100000 * self.config.delayMultiplier) self.freeScreen() @@ -1519,13 +1563,15 @@ class RealDeviceMap_UIControlUITests: XCTestCase { } else { if success { var attempts = 0 - while attempts < 5 { + while attempts < 15 { attempts += 1 self.lock.lock() if !self.gotQuest { + Log.test("No quest data!. Re-attempt: " + attempts.description) self.lock.unlock() sleep(1 * self.config.delayMultiplier) } else { + Log.test("Got quest data") self.lock.unlock() break }