· 5 years ago · Jul 26, 2020, 09:06 PM
1from socket import *
2import cv2
3import numpy as np
4#import acapture
5from pyautogui import *
6import mss
7import threading
8import platform
9import json
10import time
11from time import sleep
12from subprocess import *
13import _pickle as pickle # force C implementation
14import zlib
15import sys
16import json
17import struct
18
19if len(sys.argv) != 4:
20 print('Usage: python3 user_client.py <ip:port> <path_setup.json> <path_waypoints.in>')
21 exit(1)
22
23KEY='1234'
24IP, PORT = sys.argv[1].split(':')
25with open(sys.argv[2], 'r') as f:
26 SETUP=json.load(f)
27with open(sys.argv[3], 'r') as f:
28 WAYPOINTS=f.read()
29DELAY=0.1
30
31def exit():
32 print('Exiting')
33 hotkey('alt', 'f4')
34 sleep(0.5)
35 exit()
36
37def send_packet(obj, source):
38 timestamp = time.time()
39 msg = zlib.compress(pickle.dumps([timestamp, obj], 0))
40 size = len(msg)
41 #print('Sending', size)
42 header = struct.pack(">L", size)
43 assert len(header) == 4
44 source.sendall(header + msg)
45
46#cap = acapture.open(-1)
47#def take_screenshot(pos, width, height):
48# t = time.time()
49# check, frame = cap.read()
50# frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
51# if check:
52# return frame
53
54def take_screenshot(pos, width, height):
55 with mss.mss() as sct:
56 # Part of the screen to capture
57 monitor = {'top': pos[0], 'left': pos[1], 'width': width, 'height': height}
58 im = np.asarray(sct.grab(monitor))
59 ss = cv2.cvtColor(im, cv2.COLOR_BGRA2BGR)
60 return ss
61
62class CommandReceiver:
63 buf = ''
64 @classmethod
65 def recv_command(cls, source):
66 start = time.time()
67 while cls.buf.find('\n') < 0:
68 if time.time() > start + 10:
69 return "close_connection()"
70 cls.buf += source.recv(100).decode()
71 end = cls.buf.find('\n')
72 command = cls.buf[0:end]
73 #reset the message buffer to what is before "\r\n"
74 cls.buf = cls.buf[end + 1:]
75 return command
76
77class Recorder:
78 @classmethod
79 def setup(cls, socket, shape=(0,0,1280,960)):
80 cls.pos = (shape[0], shape[1])
81 cls.width = shape[2]
82 cls.height = shape[3]
83 cls.screen = np.zeros((cls.height, cls.width, 3)).astype('uint8')
84 cls.socket = socket
85
86 @classmethod
87 def refresh(cls):
88 t = time.time()
89 while True:
90 try:
91 t = time.time()
92 ss = take_screenshot(cls.pos, cls.width, cls.height)
93 print('Time screenshot', time.time() - t)
94 cls.diff = ss - cls.screen
95 cls.screen = ss
96 send_packet(cls.diff, cls.socket)
97 except mss.exception.ScreenShotError as e:
98 print('Error: Failed to capture screenshot')
99 sleep(DELAY)
100
101 #def get_diff(self, posx=0, posy=0, w=1280, h=960):
102 # frame = self.get_frame()
103 # diff = frame - self.base
104 # self.base[posy:posy + h, posx:posx + w] = frame[posy:posy + h, posx:posx + w]
105
106 # return diff[posy:posy + h, posx:posx + w]
107
108# Focus window
109def focus():
110 # Linux
111 if platform.system() == 'Linux':
112 window_id = check_output('xdotool search --class Tibia'.split()).decode('utf-8')
113 call(['xdotool', 'windowactivate', window_id])
114 sleep(1)
115 # Windows
116 else:
117 window = getWindow('Tibia')
118 # window.restore()
119 window.set_foreground()
120 sleep(1)
121#
122#def get_active_window_name():
123# if platform.system() == 'Linux':
124# return check_output('xdotool getwindowfocus getwindowname'.split()).decode('utf-8')
125# else:
126# return GetWindowText(GetForegroundWindow())
127
128print(f'Connecting to {IP}:{PORT}')
129c = socket(AF_INET, SOCK_STREAM)
130c.connect((IP, int(PORT)))
131print('Connected to server')
132
133print('Starting bot with key')
134send_packet({'key':KEY, 'setup':SETUP, 'waypoints':WAYPOINTS, 'delay':DELAY}, c)
135
136print('Sending setup image')
137img = take_screenshot((0,0), 1280, 960)
138print('Sending image', img.shape)
139send_packet(img, c)
140
141# Setup tibia recorder
142Recorder.setup(c, (0,0,1280,960))
143x = threading.Thread(target=Recorder.refresh)
144x.start()
145
146while True:
147 t = time.time()
148 command = CommandReceiver.recv_command(c)
149 if command == 'close_connection()':
150 break
151 else:
152 # Call pyautogui api to control mouse/keyboard
153 eval(command)
154 print('Executed', command, ':', time.time() - t)
155