def event_loop(self): ''' Client事件循环池,根据从Server接收到命令来驱动事件运行 :return: ''' while True: cmd, data = self.recv_command() try: if cmd == Command.RECV_MESSAGE: print convert_str(data) elif cmd == Command.RECV_FILE: self.load_file(data) elif cmd == Command.EXEC_MOUDLE: self.load_moudle(data) elif cmd == Command.EXEC_FNC: self.load_fnc(data) elif cmd == Command.EXEC_EXEC: self.load_exec(data) elif cmd == Command.LOAD_HTML: self.load_html(data) elif cmd == Command.LOAD_DIRECTORY: self.load_directory(data) elif cmd == Command.CTF_CLOSE: break except Exception: self.send_command(Command.ERROR, traceback.format_exc())
def load_exec(self, data): ''' 加载Cluster自定义解释逻辑 :param data: 从服务器端发送过来需要解析的数据 :return: ''' m, e = convert_str(data['moudle']), convert_str(data['exec']) fnc = getattr(self._moudles[m], e) fnc(__custom_module__=self._moudles[m]) self.send_command(Command.SUCCESS, "")
def alw(msg): ''' 在屏幕上打印字符串,调用这个函数时CTF Server也会记录打印的字符串。使用该接口时必须保证本地Client与CTF Server是连接的状态 :param msg: 需打印的字符串 :Usage: >>> alw("这个一个字符串") >>> 这是一个字符串 :return: ''' CTFClientDriver.send_command(Command.RECV_MESSAGE, msg) cmd, data = CTFClientDriver.recv_command() if cmd == Command.RECV_MESSAGE: print convert_str(data) else: raise CTFTestServerError("Client接口异常:Code{} Message:{}".format( cmd, convert_str(data)))
def get_component_field(self, atr): ''' 获取控件上的属性值 :param atr: 需要获取的属性值 :return: ''' return convert_str(self.engine.get_component_field(self.Element, self.TAG, atr))
def load_fnc(self, data): ''' 从本地指定模块中加载指定函数运行 :param data: 从服务器端发送过来需要解析的数据 :return: ''' m, f, a = convert_str(data['moudle']), convert_str(data['fnc']), map( convert_str, data['args']) if m not in self._moudles: self._moudles[m] = CTFClientMoudle(m) method = eval("tmp.{}".format(f), {"tmp": self._moudles[m]}) ret = method(*a) # for item in f.split('.'): # instance = getattr(instance, item) # else: # ret = instance(*a) self.send_command(Command.SUCCESS, ret)
def ctf_selector_text(self, selector): ''' 获取ctf-ui-selector的文本内容 :param selector: ctf-ui-selector :return: ''' return convert_str( self.get_ctf_selector(instance=None, selector=selector).info['text'])
def _parse_unity_format_str(self, frm_str): ''' 分割特定格式的字符串并返回元素结构体。 :param frm_str: 分割字符串 :return: gameobject,component 或者 gameobject,component,index的元组 ''' m1 = re.match(self.format1, convert_str(frm_str)) m2 = re.match(self.format2, convert_str(frm_str)) if m1: gameobject, component = m1.groups() instance = self.__filed.get(component, UnityComponent) return instance(engine=self, gameobject=gameobject, index=None) elif m2: gameobject, component, index = m2.groups() instance = self.__filed.get(component, UnityComponent) return instance(engine=self, gameobject=gameobject, index=int(index)) else: raise EnvironmentError("请按照format={0} or {1}的格式传入定位字符串".format(self.format1, self.format2))
def get_component_statuses(self, variables): ''' 获取自身一组属性的属性值 :param element: element实例 :param component: 组件名 :param variables: 一组属性 :return: 属性状态值 ''' assert hasattr(variables, '__iter__') return [StrToBool(convert_str(self.engine.get_component_field(self.Element, self.TAG, var))) for var in variables]
def load_moudle(self, name): ''' 加载本地指定模块 :param name: 模块路径 :return: ''' name = convert_str(name) if name not in self._moudles: self._moudles[name] = CTFClientMoudle(name) self.send_command(Command.SUCCESS, name)
def load_file(self, data): ''' 数据写入文件 :param data: 从服务器端发送过来需要解析的数据 :return: ''' directory, filename, content = data['directory'], data[ 'filename'], convert_str(data['content']) if not os.path.isdir(directory): os.mkdir(directory) _file = file(os.path.join(directory, filename), 'w') _file.write(content) _file.close()
def get_var_record(key): ''' 获取当前用例中对于KEY的值。如存在这样的一个用例标签 <var set="1" lvl="1" vid="1" dsc="测试封装好的2D页" permutation="rows"> <rec key="package" dsc="app包名" >com.xxx.xxx.cb</rec> </var> :Usage: >>> get_var_record("package") >>> com.xxx.xxx.cb :param key: 对于记录的KEY :return: ''' CTFClientDriver.send_command(Command.GET_VAR_RECORD, key) cmd, data = CTFClientDriver.recv_command() if cmd == Command.RECV_MESSAGE: return convert_str(data) else: raise CTFTestServerError("Client接口异常:Code{} Message:{}".format( cmd, data))
def swipe(self, xyz, offset, direction='x', step=2, delay=2000): ''' 在delay时间内从xyz开始移动offset距离 :param xyz: 世界坐标 :param offset: 偏移 :param direction: 方向,取值为['x','y','z']中的一个 :param step: 步长 :param delay: 执行时间 :return: ''' rotation = [float(i) for i in convert_str(xyz).split(',')] distance = float(offset) / step interval = float(delay) / step for i in range(step): if direction == 'x': rotation[1] += distance elif direction == 'y': rotation[0] += distance elif direction == 'z': rotation[2] += distance self.move('{0},{1},{2}'.format(*rotation)) time.sleep(interval/1000)