screenshot.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import time
  2. import datetime
  3. import numpy as np
  4. import io
  5. from ppadb.client import Client as AdbClient
  6. from PIL import Image
  7. from helper import (
  8. cv2,
  9. find_template,
  10. tap as tap_helper,
  11. swipe as swipe_helper,
  12. capture_current_screen,
  13. )
  14. # templates
  15. close_sub_fights = cv2.imread("templates/close_sub_fights.jpg")
  16. close_fight = cv2.imread("templates/close_fight.jpg")
  17. fight_button = cv2.imread("templates/i.jpg")
  18. end_of_log = cv2.imread("templates/end_of_log.jpg")
  19. end_of_log2 = cv2.imread("templates/end_of_log2.jpg")
  20. # cursor positions
  21. fight_scroll_top = "2200 626"
  22. fight_scroll_bottom = "2200 1500"
  23. titan_fight = "1400 860"
  24. damage_taken = "450 850"
  25. close_details = "2175 450"
  26. close_titan_fight = "2650 570"
  27. defense_log = "350 870"
  28. def non_max_suppression(boxes, overlapThresh):
  29. if len(boxes) == 0:
  30. return []
  31. # Convert to float
  32. boxes = np.array(boxes, dtype="float")
  33. # Initialize the list of picked indexes
  34. pick = []
  35. # Grab the coordinates of the bounding boxes
  36. x1 = boxes[:, 0]
  37. y1 = boxes[:, 1]
  38. x2 = boxes[:, 2]
  39. y2 = boxes[:, 3]
  40. # Compute the area of the bounding boxes and sort by bottom-right y-coordinate
  41. area = (x2 - x1 + 1) * (y2 - y1 + 1)
  42. idxs = np.argsort(y2)
  43. # Keep looping while some indexes still remain in the indexes list
  44. while len(idxs) > 0:
  45. # Grab the last index in the indexes list and add the index value to the list of picked indexes
  46. last = len(idxs) - 1
  47. i = idxs[last]
  48. pick.append(i)
  49. # Find the largest (x, y) coordinates for the start of the bounding box and the smallest (x, y)
  50. # coordinates for the end of the bounding box
  51. xx1 = np.maximum(x1[i], x1[idxs[:last]])
  52. yy1 = np.maximum(y1[i], y1[idxs[:last]])
  53. xx2 = np.minimum(x2[i], x2[idxs[:last]])
  54. yy2 = np.minimum(y2[i], y2[idxs[:last]])
  55. # Compute the width and height of the bounding box
  56. w = np.maximum(0, xx2 - xx1 + 1)
  57. h = np.maximum(0, yy2 - yy1 + 1)
  58. # Compute the ratio of overlap
  59. overlap = (w * h) / area[idxs[:last]]
  60. # Delete all indexes from the index list that have overlap greater than the threshold
  61. idxs = np.delete(
  62. idxs, np.concatenate(([last], np.where(overlap > overlapThresh)[0]))
  63. )
  64. # Return only the bounding boxes that were picked
  65. return boxes[pick].astype("int")
  66. def save_screenshot():
  67. # Take a screenshot
  68. result = capture_current_screen()
  69. timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
  70. image = Image.open(io.BytesIO(result))
  71. jpeg_filename = f"/mnt/t/nextcloud/InstantUpload/Herowars/{timestamp}.jpg"
  72. image = image.convert("RGB") # Convert to RGB mode for JPEG
  73. with open(jpeg_filename, "wb") as fp:
  74. image.save(fp, format="JPEG", quality=85) # Adjust quality as needed
  75. print(f"snap: {jpeg_filename}")
  76. time.sleep(0.5)
  77. def tap(location):
  78. tap_helper(location)
  79. time.sleep(1)
  80. def swipe(start, end, duration=1000):
  81. swipe_helper(start, end, duration)
  82. time.sleep(0.5)
  83. def tap_button(template):
  84. button = find_templates(template)
  85. if len(button) == 0:
  86. return
  87. tap(f"{button[0][0]} {button[0][1]}")
  88. def is_end_of_log():
  89. templates = find_templates(end_of_log)
  90. if len(templates) == 0:
  91. templates = find_templates(end_of_log2)
  92. result = len(templates) > 0
  93. if result:
  94. print("reached end of guild war log!")
  95. return result
  96. def find_max_y_pair(coordinates):
  97. # find the coordinate pair with the maximum y value
  98. result = max(coordinates, key=lambda x: x[1])
  99. return f"{result[0]} {result[1]}"
  100. def take_fight_screenshots():
  101. save_screenshot()
  102. # # if you desperately need submits
  103. # tap(damage_taken)
  104. # save_screenshot()
  105. tap_button(close_fight)
  106. time.sleep(1)
  107. def find_templates(template):
  108. capture_current_screen()
  109. return find_template(template)
  110. def process_war_log():
  111. buttons = find_templates(fight_button)
  112. if len(buttons) == 0:
  113. swipe(fight_scroll_bottom, fight_scroll_top)
  114. return
  115. # process all found buttons
  116. for pair in buttons:
  117. tap(f"{pair[0]} {pair[1]}")
  118. sub_buttons = find_templates(fight_button)
  119. if len(sub_buttons) == 0:
  120. take_fight_screenshots()
  121. else:
  122. for pair2 in sub_buttons:
  123. tap(f"{pair2[0]} {pair2[1]}")
  124. take_fight_screenshots()
  125. tap_button(close_sub_fights)
  126. swipe(find_max_y_pair(buttons), fight_scroll_top)
  127. # start
  128. while not is_end_of_log():
  129. process_war_log()
  130. # possible duplicates here, but necessary to be sure to get the last fights
  131. process_war_log()