Created
December 31, 2018 16:56
-
-
Save joaoescribano/778ce80d4867b11bcc7d2c000d6a2208 to your computer and use it in GitHub Desktop.
A Tibia 12 bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! python3 | |
from PIL import Image | |
import pyautogui, sys, time, random, pytesseract, os | |
print('At any time, press Ctrl-C to quit the bot.\n') | |
clientDetected = False | |
clientPlaying = False | |
accountName = 'account' # Account | |
accountPass = 'password' # Password | |
accountChar = 'Character Name' # Desired character to login | |
accountPremium = False # Auto detected, just a variable | |
accountTotalChars = 4 # Total chars at account (still need to find a way to do it better) | |
accountChars = [] | |
acctountLoggedChar = None | |
def getDirectionAxis(fromX, fromY, toX, toY): | |
if (toX == fromX): | |
if (toY < fromY): | |
return 0 | |
else: | |
return 4 | |
else: | |
if (toY == fromY): | |
if (toX < fromX): | |
return 6 | |
else: | |
return 2 | |
else: | |
if (toX < fromX): | |
if (toY < fromY): | |
return 7 | |
else: | |
return 5 | |
else: | |
if (toY < fromY): | |
return 1 | |
else: | |
return 3 | |
def getDirName(directionAxis): | |
return { | |
0: 'N', | |
1: 'NE', | |
2: 'E', | |
3: 'SE', | |
4: 'S', | |
5: 'SW', | |
6: 'W', | |
7: 'NW', | |
}[directionAxis] | |
def getPid(program): | |
os.system('(pidof ' + program + ') > .tmp') | |
pid = open('.tmp', 'r').read() | |
return pid.strip() | |
def getWindow(pid): | |
os.system('(xdotool search --pid ' + pid + ') > .tmp') | |
window = open('.tmp', 'r').read() | |
return window.strip() | |
def getActualDesktop(): | |
os.system('(xdotool get_desktop) > .tmp') | |
desktop = open('.tmp', 'r').read() | |
return desktop.strip() | |
def goToDesktop(desktop): | |
os.system('(xdotool set_desktop ' + desktop + ') > .tmp') | |
return True | |
def getWindowDesktop(window): | |
os.system('(xdotool get_desktop_for_window ' + window + ') > .tmp') | |
windowDesktop = open('.tmp', 'r').read() | |
return windowDesktop.strip() | |
def setFocus(window): | |
os.system('(xdotool windowfocus ' + window + ') > .tmp') | |
window = open('.tmp', 'r').read() | |
return True | |
def maximizeWindow(window): | |
os.system('(xdotool windowmove ' + window + ' 0 0) > .tmp') | |
os.system('(xdotool windowsize ' + window + ' $(xdotool getdisplaygeometry)) > .tmp') | |
os.system('(xdotool windowactivate ' + window + ') > .tmp') | |
return True | |
def minimizeWindow(window): | |
os.system('(xdotool windowminimize ' + window + ') > .tmp') | |
return True | |
def setWindowPos(window, x, y): | |
os.system('(xdotool windowmove ' + window + ' ' + str(x) + ' ' + str(y) +') > .tmp') | |
return True | |
return True | |
def resizeWindow(window, x, y): | |
os.system('(xdotool windowsize ' + window + ' ' + str(x) + ' ' + str(y) + ') > .tmp') | |
return True | |
def getWindowTitle(window): | |
os.system('(xdotool getwindowname ' + window + ') > .tmp') | |
windowTitle = open('.tmp', 'r').read() | |
return windowTitle.strip() | |
def clearImage(image): | |
pixels = image.load() | |
for i in range(image.size[0]): | |
for j in range(image.size[1]): | |
x,y,z = pixels[i,j][0],pixels[i,j][1],pixels[i,j][2] | |
x,y,z = abs(x-255), abs(y-255), abs(z-255) | |
# Black Range | |
if (x >= 100 and x <= 254): | |
if (y >= 100 and y <= 254): | |
if (y >= 100 and y <= 254): | |
x,y,z=255,255,255 | |
pixels[i,j] = (x,y,z) | |
width, height = image.size | |
image = image.resize(((width * 2), (height * 2)), Image.NEAREST) | |
return image | |
def accountLogin(): | |
global clientDetected, clientPlaying, accountPremium, accountChars, acctountLoggedChar | |
dialog = pyautogui.locateOnScreen('./images/client_login.png'); | |
if (dialog != None): | |
dialogX = dialog[0] | |
dialogY = dialog[1] | |
delay = (random.randint(1, 25) / 100) | |
# Account Name | |
pyautogui.moveTo(dialogX + random.randint(170, 255), dialogY + random.randint(35, 45)) | |
pyautogui.click(button='left', clicks=2, interval=delay) | |
time.sleep(delay) | |
pyautogui.press('backspace') | |
time.sleep(delay) | |
pyautogui.typewrite(accountName, delay) | |
time.sleep((random.randint(3,10) / 100)) | |
delay = (random.randint(1, 25) / 100) | |
# Account Password | |
pyautogui.moveTo(dialogX + random.randint(170, 255), dialogY + random.randint(65, 75)) | |
pyautogui.click(button='left', clicks=2, interval=delay) | |
time.sleep(delay) | |
pyautogui.press('backspace') | |
time.sleep(delay) | |
pyautogui.typewrite(accountPass, delay) | |
time.sleep((random.randint(3,10) / 100)) | |
delay = (random.randint(1, 25) / 100) | |
# Login Button | |
pyautogui.moveTo(dialogX + random.randint(170, 255), dialogY + random.randint(145, 161)) | |
pyautogui.click(button='left') | |
time.sleep(1 + (random.randint(2,5) / 100)) | |
delay = (random.randint(1, 25) / 100) | |
dialogError = pyautogui.locateOnScreen('./images/login_error.png') | |
if (dialogError != None): | |
print('Account login erro detected, trying again.') | |
dialogErrorX = dialogError[0] | |
dialogErrorY = dialogError[1] | |
delay = (random.randint(1, 25) / 100) | |
pyautogui.moveTo(dialogX + random.randint(243, 280), dialogY + random.randint(66, 84)) | |
pyautogui.click(button='left', clicks=1, interval=delay) | |
time.sleep((random.randint(3,10) / 100)) | |
delay = (random.randint(1, 25) / 100) | |
return False | |
else: | |
print('Login successfully.') | |
dialogChars = pyautogui.locateOnScreen('./images/client_characters.png'); | |
if (dialogChars != None): | |
charactersImg = pyautogui.screenshot(region=(dialogChars[0], dialogChars[1], (dialogChars[0] + 635), (dialogChars[1] + 430))) | |
showOutfit = pyautogui.locate('./images/active_show_outfit.png', charactersImg) | |
if (showOutfit != None): | |
delay = (random.randint(1, 25) / 100) | |
pyautogui.moveTo(dialogChars[0] + 215, dialogChars[1] + 404) | |
pyautogui.click(button='left', clicks=1, interval=delay) | |
time.sleep(1) | |
charactersImg = pyautogui.screenshot(region=(dialogChars[0], dialogChars[1], (dialogChars[0] + 635), (dialogChars[1] + 430))) | |
premium = pyautogui.locate('./images/premium.png', charactersImg) | |
if (premium != None): | |
print("Detected that this account is a Premium Account."); | |
accountPremium = True; | |
for x in range(0, accountTotalChars): | |
charName = charactersImg.crop((17,(47 + (x * 29)),294,(76 + (x * 29)))) | |
charName = clearImage(charName) | |
charNameTxt = pytesseract.image_to_string(charName); | |
charLvl = charactersImg.crop((296,(47 + (x * 29)),339,(76 + (x * 29)))) | |
charLvl = clearImage(charLvl) | |
charLvlTxt = pytesseract.image_to_string(charLvl); | |
charClasse = charactersImg.crop((341,(47 + (x * 29)),454,(76 + (x * 29)))) | |
charClasse = clearImage(charClasse) | |
charClasseTxt = pytesseract.image_to_string(charClasse); | |
selectedChar = False | |
if (charNameTxt == accountChar): | |
selectedChar = True | |
accountChars.insert(x, (charNameTxt, charClasseTxt, charLvlTxt, selectedChar)) | |
print('Char: ' + charNameTxt + ' - ' + charClasseTxt + ' (' + charLvlTxt + ') ', ("","[Playing]")[selectedChar == True]) | |
for charIdx, char in enumerate(accountChars): | |
if (char[3] == True): | |
delay = (random.randint(1, 25) / 100) | |
pyautogui.moveTo(dialogChars[0] + random.randint(341,454), dialogChars[1] + random.randint((47 + (charIdx * 29)), (76 + (charIdx * 29)))) | |
pyautogui.click(button='left', clicks=2, interval=delay) | |
time.sleep(1) | |
clientPlaying = True | |
acctountLoggedChar = charIdx | |
print("Account logged successfully") | |
return True | |
else: | |
print('No character selection dialog detected, trying again.') | |
time.sleep(10) | |
return False | |
def detectGameOpen(): | |
global clientDetected, clientPlaying, accountChars, acctountLoggedChar | |
clientDetected = False | |
clientPlaying = False | |
pid = getPid('Tibia/client') | |
if (pid != False and pid != ""): | |
window = getWindow(pid) | |
if (window != False and window != ""): | |
clientDetected = True | |
title = getWindowTitle(window).split(" - ") | |
if (len(title) == 2): | |
clientPlaying = True | |
accountChars.insert(0, (title[1], "Unknow", "00", True)) | |
acctountLoggedChar = 0 | |
def detectAlreadyLoggedCharacter(): | |
return True; # TODO | |
def start(): | |
try: | |
while True: | |
if (clientDetected == False): | |
print('Detecting Tibia Client') | |
detectGameOpen() | |
if (clientDetected == False and clientPlaying == False): | |
print('Could not find the Tibia Client'); | |
time.sleep(15) | |
if (clientDetected == True and clientPlaying == False): | |
print('Logging into Tibia account') | |
accountLogin() | |
if (clientDetected == True and clientPlaying == True): | |
# if (acctountLoggedChar == None): | |
# detectAlreadyLoggedCharacter() | |
return False | |
except KeyboardInterrupt: | |
print('\n\nBot stoped...\n\n') | |
# main start | |
start(); | |
if (clientDetected == True and clientPlaying == True): | |
char = accountChars[acctountLoggedChar] | |
x, y = pyautogui.position() | |
positionStr = '\n\nCharacter: ' + char[0] + '\n' + 'Profession: ' + char[1] + '\n' + 'Level: ' + char[2] + '\n\nMouse Position:\nX: ' + str(x).rjust(4) + '\nY: ' + str(y).rjust(4) + '\nDir: ' + getDirName(getDirectionAxis(x,y,2925,191)).ljust(2, ' ') | |
print(positionStr, end='') | |
print('\b' * len(positionStr), end='', flush=True) |
Opa, valew por compartilhar essa informação! não conhecia o FASTGRAB, provavelmente utilize em outras aplicações.
Valew
from fastgrab import screenshot
import pyautogui
import time
inicio = time.time()
for x in range(0,100):
img = screenshot.Screenshot().capture()
fim = time.time()
print(fim - inicio)
inicio = time.time()
for x in range(0,100):
img = pyautogui.screenshot()
fim = time.time()
print(fim - inicio)
Output:
1.085~
10.25~
eu gostei foi do seu projeto "pyxdotool-wrapper", aproveitei ele todo, performance 100x melhor que do meu projeto.
Não sei se você percebeu nos seus testes(se testou já haha), mas o PyAutoGUI freeza o jogo (.5sec~ no linux) quando faz interações (click e Hotkeys). O pynput (keyboard) já não tive esse problema...
Nunca trabalhei com programação, mas fico brincando com python pra desenvolver minha logica haha
Espero ter compartilhado algo de útil também... tmj
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
PyautoGUI é muito bom, porem o FASTGRAB não se compara na performance...
Vlw por compartilhar jovem!