Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # TODO: add a way to stop the bot instead of CTRL + C
- # TODO: possible code duplication with x, y, h, w variables and window_dimensions[] in 'def capture_window(window_handle):' function
- # maybe make a function that returns the x, y, h, w variables, but will lose the real time windows resizing functionality
- # Done: generate updated requirements.txt file
- import os
- import sys
- import cv2
- import time
- import datetime
- import pytesseract
- import numpy
- import win32con
- import win32gui
- import pynput
- import win32ui
- from PIL import Image
- phrase = "bobber splashes"
- pytesseract.pytesseract.tesseract_cmd = "C:\\Program Files\\Tesseract-OCR\\tesseract.exe"
- # hotbar dictionary for key switwinch in Minecraft, the values are the number of items in the slot, or a keyword for the item
- # the slot 3 to 9 filled with a full stack - 1 becuase we need to reserve inventory space for the exp bottles. without it the inventory
- # will be filled with fishing drops
- hotbar = {
- "1": 43, # food slot
- "2": "Rod", # weapon slot
- "3": 63, # exp potion slot
- "4": 63, # exp potion slot
- "5": 63, # exp potion slot
- "6": 63, # exp potion slot
- "7": 63, # exp potion slot
- "8": 63, # exp potion slot
- "9": 63 # exp potion slot
- }
- # getting all the windows handles with the name "Minecraft" at the start into a list ::should be only ONE in the list!::
- def get_window_handles(winName):
- def callback(handle, extra):
- if win32gui.IsWindowVisible(handle) and win32gui.GetWindowText(handle)[0:9] == winName:
- window_handles.append(handle)
- window_handles = []
- win32gui.EnumWindows(callback, None)
- return window_handles
- def capture_window(window_handle):
- if window_handle is None:
- window_handle = win32gui.GetDesktopWindow()
- # getting Minecraft window dimensions into 4 variables for convenience of use
- window_dimensions = win32gui.GetWindowRect(window_handle)
- left = window_dimensions[0]
- top = window_dimensions[1]
- right = window_dimensions[2]
- bottom = window_dimensions[3]
- # setting the borders for the capture area (buttom-left side of the Minecraft window)
- left_border = 8
- right_border = 8
- top_border = 30
- bottom_border = 8
- # calculating the capture area for cropping the screenshot
- width = right - left - left_border - right_border
- height = bottom - top - top_border - bottom_border
- cropped_x = left_border
- cropped_y = top_border
- # capturing the screenshot based on the calculated dimensions
- window_device_context = win32gui.GetWindowDC(window_handle)
- device_context_object = win32ui.CreateDCFromHandle(window_device_context)
- create_device_context = device_context_object.CreateCompatibleDC()
- # creating a bitmap object for because the screenshot is a bitmap
- data_bit_map = win32ui.CreateBitmap()
- data_bit_map.CreateCompatibleBitmap(device_context_object, width, height)
- create_device_context.SelectObject(data_bit_map)
- # BitBlt is a Windows API function that copies the contents of one device context into another
- create_device_context.BitBlt(
- (0, 0),
- (width, height),
- device_context_object,
- (cropped_x, cropped_y),
- win32con.SRCCOPY,
- )
- # instead of saving the screenshot to a file, we can just get the raw data from the bitmap object
- image = numpy.frombuffer(data_bit_map.GetBitmapBits(True), dtype="uint8")
- # the 4 is for the number of color channels (RGB + alpha), may change it to 3 if the alpha channel is not needed
- image.shape = (height, width, 4)
- # releasing the device contexts and deleting the bitmap object, if we dont do this, we will get a memory leak
- device_context_object.DeleteDC()
- create_device_context.DeleteDC()
- win32gui.ReleaseDC(window_handle, window_device_context)
- win32gui.DeleteObject(data_bit_map.GetHandle())
- return image
- def type_a_command(command_string):
- pynput.keyboard.Controller().press(pynput.keyboard.KeyCode.from_char("/"))
- pynput.keyboard.Controller().release(pynput.keyboard.KeyCode.from_char("/"))
- time.sleep(0.2)
- pynput.keyboard.Controller().type(command_string[1:])
- time.sleep(0.2)
- pynput.keyboard.Controller().press(pynput.keyboard.Key.enter)
- pynput.keyboard.Controller().release(pynput.keyboard.Key.enter)
- time.sleep(0.2)
- pynput.mouse.Controller().click(pynput.mouse.Button.left)
- time.sleep(0.2)
- def fill_exp_potions(hotbar):
- # this function is for filling the empty bottles from the SlimeFun plugin with exp
- if hotbar['3'] > 0:
- hotbar['3'] = hotbar['3'] - 1
- pynput.keyboard.Controller().type('3')
- time.sleep(0.2)
- pynput.mouse.Controller().click(pynput.mouse.Button.right)
- time.sleep(0.2)
- elif hotbar['4'] > 0:
- hotbar['4'] = hotbar['4'] - 1
- pynput.keyboard.Controller().type('4')
- time.sleep(0.2)
- pynput.mouse.Controller().click(pynput.mouse.Button.right)
- time.sleep(0.2)
- elif hotbar['5'] > 0:
- hotbar['5'] = hotbar['5'] - 1
- pynput.keyboard.Controller().type('5')
- time.sleep(0.2)
- pynput.mouse.Controller().click(pynput.mouse.Button.right)
- time.sleep(0.2)
- elif hotbar['6'] > 0:
- hotbar['6'] = hotbar['6'] - 1
- pynput.keyboard.Controller().type('6')
- time.sleep(0.2)
- pynput.mouse.Controller().click(pynput.mouse.Button.right)
- time.sleep(0.2)
- elif hotbar['7'] > 0:
- hotbar['7'] = hotbar['7'] - 1
- pynput.keyboard.Controller().type('7')
- time.sleep(0.2)
- pynput.mouse.Controller().click(pynput.mouse.Button.right)
- time.sleep(0.2)
- elif hotbar['8'] > 0:
- hotbar['8'] = hotbar['8'] - 1
- pynput.keyboard.Controller().type('8')
- time.sleep(0.2)
- pynput.mouse.Controller().click(pynput.mouse.Button.right)
- time.sleep(0.2)
- elif hotbar['9'] > 0:
- hotbar['9'] = hotbar['9'] - 1
- pynput.keyboard.Controller().type('9')
- time.sleep(0.2)
- pynput.mouse.Controller().click(pynput.mouse.Button.right)
- time.sleep(0.2)
- # switch back to fishing rod slot which is "2"
- pynput.keyboard.Controller().type('2')
- time.sleep(0.2)
- #return hotbar
- def eat(hotbar):
- # this function is for eating food from the food slot in the hotbar
- if hotbar['1'] > 0:
- hotbar['1'] = hotbar['1'] - 1
- pynput.keyboard.Controller().type('1')
- time.sleep(0.2)
- # eat
- pynput.mouse.Controller().click(pynput.mouse.Button.right)
- # switch back to fishing rod slot which is "2"
- pynput.keyboard.Controller().type('2')
- #return hotbar
- def main():
- fishing_count = 0
- left_right = False
- while True:
- if len(get_window_handles("Minecraft")) == 0:
- print("Error: no windows with the name \"Minecraft\" were found")
- break
- screenshot = capture_window(get_window_handles("Minecraft")[0])
- x, y, w, h = (
- # this will limit the capture area to the buttom-left side of the Minecraft window
- screenshot.shape[1] * 3 // 4,
- screenshot.shape[0] * 3 // 4,
- screenshot.shape[1] // 4,
- screenshot.shape[0] // 4,
- )
- screenshot = screenshot[y : y + h, x : x + w]
- screenshot_filter = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)
- text = pytesseract.image_to_string(
- cv2.threshold(screenshot_filter, 220, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
- )
- # print("debug: text value is: ", text)
- if phrase in text.lower():
- print("fish on, ", end=" ")
- pynput.mouse.Controller().click(pynput.mouse.Button.right)
- fishing_count += 1
- print("bobber retrieved, num: {},".format(fishing_count) , end=" ")
- time.sleep(0.4)
- # fill exp bottles every 3 fishings
- if (fishing_count % 3) == 0:
- time.sleep(0.5)
- fill_exp_potions(hotbar)
- time.sleep(0.9)
- # eat every 10 fishings
- # rotate the camera back and forth every fishing
- if left_right:
- pynput.mouse.Controller().move(400, 0)
- left_right = False
- print("Moved to the Right")
- else:
- pynput.mouse.Controller().move(-400, 0)
- left_right = True
- print("Moved to the Left")
- # executing the /balance command to track how much money you get from fishing (/jobs plugin)
- # type_a_command("/bal")
- time.sleep(0.8)
- pynput.mouse.Controller().click(pynput.mouse.Button.right)
- print("bobbern thrown,", end=" ")
- time.sleep(2.5)
- # converting the screenshot into grayscale and then back to BGR and finally trimming to the same color channels as the screenshot
- screenshot_filter = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)
- screenshot_filter = cv2.cvtColor(screenshot_filter, cv2.COLOR_GRAY2BGR)
- screenshot = screenshot[:,:,:3]
- tess_view = cv2.threshold(cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY), 128, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
- tess_view = cv2.cvtColor(tess_view, cv2.COLOR_GRAY2BGR)
- """
- # attempting adaptiveThreshold to see if the text readbilty from the screenshot is easier for the Tesseract
- tess_view2 = cv2.adaptiveThreshold(cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY),255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,2)
- tess_view2 = cv2.cvtColor(tess_view2, cv2.COLOR_GRAY2BGR)
- # testing print for image shapes , ALL image output have to be the same size AND same color format in order to stack in numpy imshow
- print("screenshot\t", screenshot.shape)
- print("screenshot_filter\t", screenshot_filter.shape)
- print("teseract\t", tess_view.shape)
- print("teseract2\t", tess_view2.shape)
- """
- cv2.imshow("Computer Vision - ALL", numpy.vstack((
- screenshot
- ,screenshot_filter
- ,tess_view
- #,tess_view2
- )))
- if cv2.waitKey(1) == ord("q"):
- cv2.destroyAllWindows()
- break
- if __name__ == "__main__":
- start_time = datetime.datetime.now().time()
- end_time = datetime.datetime.now().time()
- print("starting fishing at: {}".format(start_time))
- try:
- main()
- except KeyboardInterrupt:
- # execute the next lines after KeyboardInterrupt: Ctrl+C
- end_time = datetime.datetime.now().time()
- td_start = datetime.timedelta(hours=start_time.hour, minutes=start_time.minute, seconds=start_time.second)
- td_end = datetime.timedelta(hours=end_time.hour, minutes=end_time.minute, seconds=end_time.second)
- print("fished for: {} (hh:mm:ss)".format(td_end - td_start))
- try:
- sys.exit(130)
- except SystemExit:
- os._exit(130)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement