def restart_redis(self): try: subprocess.run("sudo service redis restart", shell=True, check=True) except subprocess.CalledProcessError: Logger.error("重启redis失败")
def restart_ssh(self): try: subprocess.run("sudo /etc/init.d/sshresart", shell=True, check=True) except subprocess.CalledProcessError: Logger.error("重启失败")
def install_mosquitto(self): Logger.info("准备安装Mosquitto Broker") try: subprocess.run("sudo apt install mosquitto mosquitto-clients", shell=True, check=True) mqtt_user_name = input("请输入MQTT用户名:") subprocess.run("sudo mosquitto_passwd -c /etc/mosquitto/passwd " + mqtt_user_name, shell=True, check=True) try: with open("/etc/mosquitto/conf.d/default.conf", "w+") as f: f.write("allow_anonymous false\n" "password_file /etc/mosquitto/pwfile\n" "listener 1883\n") Logger.info("写入MQTT配置成功!") except FileNotFoundError: Logger.error("未发现mqtt配置文件,请重新安装...") except subprocess.CalledProcessError: Logger.error("安装失败,请重新安装") finally: Logger.info("重启MQTT服务") subprocess.run("sudo systemctl restart mosquitto", shell=True, check=True)
def install_redis(self): try: subprocess.run("sudo apt install redis-server", shell=True, check=True) except subprocess.CalledProcessError: Logger.error("安装redis失败")
def startListening(self): # _thread.start_new_thread(self.makeItems, ()) try: self.clientSocket.connect((self.IP, self.PORT)) self.hasConnected = True self.clientSocket.send(str.encode(f'USERNAME<>{Username}')) Logger.log('Connected to server correctly.') # self.clientSocket.send(str.encode('CLIENT_INFORMATION<>' + str(clientInformation))) except Exception as e: self.notificationText.set('Could not connect to the local server.') self.Window.after(3000, lambda: self.notificationText.set('')) Logger.error(e) Logger.log('Failed to connect to the local game server.', 'ERROR') if self.hasConnected: while True: try: receive_data = self.clientSocket.recv(35) # print(receive_data.decode()) arguments = receive_data.decode().split('<>') if arguments[0] == 'CONN_ERROR': Logger.log('Server rejected connection based on client information.', 'DISCONNECT') Logger.log(arguments[1]) break elif arguments[0] == 'CONN_SUCCESS': Logger.log(arguments[1]) elif arguments[0] == 'SERVER_INFORMATION': serverInfo = ast.literal_eval(str(arguments[1])) serverData = [] for field in ['Server Name', 'Uptime', 'Minimum Version', 'Server Version']: serverData.append(serverInfo['Server Information'][field]) Logger.log(f'{field}: {str(serverInfo["Server Information"][field])}', 'SERVER') elif arguments[0] == 'ITEM': # print(receive_data.decode()) posArgs2 = receive_data.decode().strip('ITEM<>') posArgs2 = posArgs2.split(',') self.createItem(float(posArgs2[0]), float(posArgs2[1])) elif arguments[0] == 'USER_LIST': all_users = arguments[1].split(';') for user in all_users: if user is not '': Logger.log(user, 'USER LIST') elif arguments[0] == 'BALL': posArgs3 = receive_data.decode().strip('BALL<>') posArgs3 = posArgs3.split(',') self.drawBullet(posArgs3[0], posArgs3[1], posArgs3[2], posArgs3[3], posArgs3[4]) elif arguments[0] == 'POSITION': # print(receive_data.decode()) userName = arguments[1] if userName != Username: posArgs = receive_data.decode().strip('POSITION<>' + userName) posArgs = posArgs.split(',') self.setOLoc(posArgs[0], posArgs[1], userName) except Exception as e: self.notificationText.set('Lost connection to the game server.') self.Window.after(3000, lambda: self.notificationText.set('')) Logger.error(e) Logger.log('Lost connection to the game server or received invalid data.', 'ERROR') break
def send(self, m): print('HOST', m) try: for connectedSocket in self.LIST: if connectedSocket != self.gameSocket: connectedSocket.send(str.encode(str(self.randomID) + m)) except Exception as error: Logger.error(error)
def connect(self): try: self.gameSocket.connect(('127.0.0.1', 6969)) self.gameSocket.settimeout(None) return True except Exception as e: Logger.error(e) return False
def set_timezone(self): try: Logger.info("开始设置中国时区") subprocess.run("timedatectl set-timezone Asia/Shanghai", shell=True, check=True) subprocess.run("date -R", shell=True) except subprocess.CalledProcessError: Logger.error("时区设置错误")
def broadcast(self, message): global tempMsg try: for connectedSocket in self.LIST: if connectedSocket != self.serverSocket: connectedSocket.send(str.encode(message)) if message != tempMsg: Logger.log(message.rstrip().lstrip(), 'BROADCAST') tempMsg = message except Exception as error: Logger.error(error)
def update_source_list(self): Logger.info("准备更新软件包列表") try: subprocess.run("sudo apt update", shell=True, check=True) Logger.info("软件包列表更新完毕") Logger.info("是否更新软件(y or n, default: n)") confirm = input("(不输入可直接回车使用默认值)>") if confirm == "y" or confirm == "Y": self.upgrade_software() except subprocess.CalledProcessError: Logger.error("更新失败")
def get_python_version(self): try: Logger.info("Python3版本") subprocess.run("python3 -V", shell=True, check=True) except subprocess.CalledProcessError: Logger.error("没有找到Python3") try: Logger.info("Python2版本") subprocess.run("python2 -V", shell=True, check=True) except subprocess.CalledProcessError: Logger.error("没有找到Python2")
def collisionDetection(self): while True: time.sleep(1 / self.tickrate * 1.5) while self.bullet is not None: try: diffX = self.locations[self.locIndex][0] - 1.00 diffY = self.locations[self.locIndex][1] - 1.00 if diffX < 0: diffX = diffX * -1 if diffY < 0: diffY = diffY * -1 diffXItem = float(self.newLX) - 1 diffYItem = float(self.newLY) - 1 if 1 < float(self.newLX) or float(self.newLX) < 0: self.bullet.place_forget() self.bullet = None print('bullet out of bounds') if 1 < float(self.newLY) or float(self.newLY) < 0: self.bullet.place_forget() self.bullet = None print('bullet out of bounds') if diffXItem < 0: diffXItem = diffXItem * -1 if diffYItem < 0: diffYItem = diffYItem * -1 # print(diffX, diffY, diffXItem, diffYItem) if self.bullet.cget("foreground") != self.playerColours[ self.locIndex]: if diffXItem - 0.08 < diffX < diffXItem + 0.08: if diffYItem - 0.08 < diffY < diffYItem + 0.08: self.notificationText.set('You were hit!') self.bullet.place_forget() self.bullet = None self.Window.after( 3000, lambda: self.notificationText.set('')) except Exception as e: Logger.error(e)
def start_capture(self, input_path: str) -> (int, int): """ Begin the video capture, returning the estimated frame length and rate. """ if not os.path.exists(input_path): message = "The specified input file {} does not exist.".format( input_path) Logger.error(message) raise FileNotFoundError(message) self.cap = cv2.VideoCapture(input_path) self.cap.set(cv2.CAP_PROP_POS_FRAMES, 0) frame_length = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT)) frame_rate = int(self.cap.get(cv2.CAP_PROP_FPS)) return frame_length, frame_rate
def listen(self): while True: try: data = self.gameSocket.recv(40, ).decode() except Exception as e: Logger.error(e) break if data: print(data) arguments = data.split(';') if arguments[0] != str(self.randomID): if arguments[1] == str(self.gameInstance.getPage()): self.gameInstance.getPlayer().setLocation( round(float(arguments[2]), 2), round(float(arguments[3]), 2)) else: self.gameInstance.getPlayer().hide()
def install_java(self): try: # 文件存在不需要重复下载 if os.path.exists('jdk-8u231-linux-x64.tar.gz'): subprocess.run('sudo mkdir /usr/lib/jvm', shell=True, check=True) subprocess.run( 'sudo tar -zxvf jdk-8u231-linux-x64.tar.gz -C /usr/lib/jvm' ) else: Logger.info('开始下载jdk8') subprocess.run( 'sudo wget https://github.com/morestart/auto_deploy/releases/download/1.0/jdk-8u231' '-linux-x64.tar.gz', shell=True, check=True) subprocess.run('sudo mkdir /usr/lib/jvm', shell=True, check=True) subprocess.run( 'sudo tar -zxvf jdk-8u231-linux-x64.tar.gz -C /usr/lib/jvm' ) with open('sudo nano ~/.bashrc', 'a+') as f: f.writelines('\n') f.writelines('export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_231') f.writelines('\n') f.writelines('export JRE_HOME=${JAVA_HOME}/jre') f.writelines('\n') f.writelines( 'export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib') f.writelines('\n') f.writelines('export PATH=${JAVA_HOME}/bin:$PATH') subprocess.run('source ~/.bashrc', shell=True) subprocess.run( 'sudo update-alternatives --install /usr/bin/java java ' '/usr/lib/jvm/jdk1.8.0_231/bin/java 300', shell=True) subprocess.run('java -version', shell=True) except subprocess.CalledProcessError: Logger.error('下载jdk8失败')
def listen(self): while True: try: read_sockets, write_sockets, error_sockets = select.select( self.LIST, [], []) for sock in read_sockets: if sock == self.gameSocket: sockfd, address = self.gameSocket.accept() self.LIST.append(sockfd) Logger.log( f'Client [{address[0]}:{address[1]}] connected to the server.', 'CONNECT') else: try: receivedData = sock.recv(40, ).decode() except: try: try: disconnected_user = self.connectedUsers[ address] del self.connectedUsers[address] except: disconnected_user = '******' Logger.log( f'Client [{address[0]}:{address[1]}] ({disconnected_user}) disconnected from the server.', 'DISCONNECT') except Exception as error: Logger.error(error) sock.close() self.LIST.remove(sock) continue if receivedData: arguments = receivedData.split(';') if arguments[0] != str(self.randomID): if arguments[1] == str( self.gameInstance.getPage()): self.otherPlayer.setLocation( round(float(arguments[2]), 2), round(float(arguments[3]), 2)) else: self.otherPlayer.hide() except Exception as error: Logger.error(error)
def install_ssh(self): try: Logger.info("开始安装ssh-server") subprocess.run("sudo apt install openssh-server", shell=True, check=True) try: Logger.info("启动ssh-server") subprocess.run("sudo /etc/init.d/ssh start", shell=True, check=True) Logger.info("写入自启配置") # 写入自启动配置 with open("/etc/rc.local", 'a+') as f: f.writelines('\n') f.writelines('/etc/init.d/ssh start') Logger.info("自启配置写入成功") except subprocess.CalledProcessError: Logger.error("启动失败") except subprocess.CalledProcessError: Logger.error("安装失败,请重新安装")
def start_emqx(self): try: subprocess.run("sudo emqx start", shell=True, check=True) except subprocess.CalledProcessError: Logger.error('启动失败')
def get_emq_status(self): try: subprocess.run("sudo emqx_ctl status", shell=True, check=True) except subprocess.CalledProcessError: Logger.error('查询状态失败')
def receive(self): Logger.log(f'Started listening for connections at [{self.EXTERNAL_IP}:{self.PORT}]') Logger.log(f'Accepting local connections at [127.0.0.1:{self.PORT}]') while self.serverStatus: try: read_sockets, write_sockets, error_sockets = select.select(self.LIST, [], []) for sock in read_sockets: if sock == self.serverSocket: sockfd, address = self.serverSocket.accept() self.LIST.append(sockfd) Logger.log(f'Client [{address[0]}:{address[1]}] connected to the server.', 'CONNECT') else: try: receivedData = sock.recv(self.BUFFER_SIZE, ) except: try: try: disconnected_user = self.connectedUsers[address] del self.connectedUsers[address] del self.extendedUsers[disconnected_user] except: disconnected_user = '******' Logger.log(f'Client [{address[0]}:{address[1]}] ({disconnected_user}) disconnected from the server.', 'DISCONNECT') self.broadcast(f'({disconnected_user}) left the server') self.broadcast(f'LEFT<>{disconnected_user}') except Exception as error: Logger.error(error) sock.close() self.LIST.remove(sock) continue if receivedData: arguments = receivedData.decode().split('<>') if 'DISCONNECT' in receivedData.decode(): try: disconnected_user = self.connectedUsers[address] del self.connectedUsers[address] del self.extendedUsers[disconnected_user] except: disconnected_user = '******' Logger.log(f'Client [{address[0]}:{address[1]}] ({disconnected_user}) disconnected from the server.', 'DISCONNECT') Logger.log(f'Received quit command from client [{address[0]}:{address[1]}]') self.broadcast(f'({disconnected_user}) left the server') self.broadcast(f'LEFT<>{disconnected_user}') sock.close() self.LIST.remove(sock) continue elif arguments[0] == 'USERNAME': self.connectedUsers[address] = arguments[1] self.extendedUsers[arguments[1]] = sock Logger.log(f'Allowed connection from [{address[0]}:{address[1]}] ({arguments[1]})', 'CONNECT') elif arguments[0] == 'CONNECT4': self.handle_game_commands(arguments, sock, self.connectedUsers[address]) elif arguments[0] == 'ONLINE': userList = '' for user in self.connectedUsers: userList = userList + self.connectedUsers[user] + ';' sock.send(str.encode('USER_LIST<>' + userList)) Logger.log(f'[{address[0]}:{address[1]}] ({self.connectedUsers[address]}) requested user list.') Logger.log(f'Current connected users: {userList.replace(";", " ")}') elif arguments[0] == 'CLIENT_INFORMATION': Logger.log(f'Received client information from [{address[0]}:{address[1]}]') clientInformation = ast.literal_eval(arguments[1]) clientData = [] for field in ['Username', 'Version', 'Rank']: clientData.append(str([clientInformation['Client Information'][field]][0])) if clientData[0] == '' or clientData[0] == ' ': sock.send(b'CONN_ERROR<>Invalid username (username not allowed)') Logger.log(f'Rejected connection from [{address[0]}:{address[1]}] due to invalid username.') sock.close() self.LIST.remove(sock) else: userListByName = [] for user in self.connectedUsers: userListByName.append(self.connectedUsers[user]) if clientData[0] in userListByName: sock.send(b'CONN_ERROR<>A user with that name is already connected (use a different username)') Logger.log(f'Rejected connection from [{address[0]}:{address[1]}] ({clientData[0]}) due to duplicate username.', 'DISCONNECT') sock.close() self.LIST.remove(sock) else: if float(clientData[1]) < self.MIN_VERSION: sock.send(str.encode(f'CONN_ERROR<>Client is out of date (latest version is {str(self.MIN_VERSION)})')) Logger.log(f'Rejected connection from [{address[0]}:{address[1]}] ({clientData[0]}) due to outdated client [{clientData[1]}]', 'DISCONNECT') sock.close() self.LIST.remove(sock) else: self.connectedUsers[address] = clientData[0] self.extendedUsers[clientData[0]] = sock sock.send(b'CONN_SUCCESS<>Successfully connected to the server.') Logger.log(f'Allowed connection from [{address[0]}:{address[1]}] ({clientData[0]}) [{clientData[1]}]', 'CONNECT') time.sleep(0.10) start_dt = datetime.strptime(self.serverInformation['Server Information']['Uptime'], '%H:%M:%S') end_dt = datetime.strptime(datetime.now().strftime('%H:%M:%S'), '%H:%M:%S') diff = (end_dt - start_dt) serverInformationTemp = self.serverInformation serverInformationTemp['Server Information']['Uptime'] = str(diff) time.sleep(0.10) sock.send(str.encode(f'SERVER_INFORMATION<>{str(serverInformationTemp)}')) Logger.log(f'Sent server information to client [{address[0]}:{address[1]}] ({clientData[0]})') self.serverInformation['Server Information']['Uptime'] = self.LAUNCH_TIME else: self.broadcast(receivedData.decode()) except Exception as error: Logger.error(error)
challengedSocket.send(str.encode('CONNECT4<>CHALLENGED<>' + name)) else: sender.send(b'GAME_ERROR<>MEMBER_NOT_FOUND') elif args[1] == 'ACCEPTED': time.sleep(0.1) challengedSocket = self.extendedUsers[args[2]] challengedSocket.send(str.encode('<>'.join(args))) def broadcast(self, message): global tempMsg try: for connectedSocket in self.LIST: if connectedSocket != self.serverSocket: connectedSocket.send(str.encode(message)) if message != tempMsg: Logger.log(message.rstrip().lstrip(), 'BROADCAST') tempMsg = message except Exception as error: Logger.error(error) tempMsg = '' if __name__ == '__main__': try: Server = GameServer() Server.run() except Exception as e: Logger.error(e)
class CommandManager: PRIVATE_CHANNEL = "priv" ORG_CHANNEL = "org" PRIVATE_MESSAGE = "msg" def __init__(self): self.handlers = collections.defaultdict(list) self.logger = Logger("command_manager") self.channels = {} self.ignore_regexes = [ re.compile(" is AFK \(Away from keyboard\) since ", re.IGNORECASE), re.compile("I am away from my keyboard right now", re.IGNORECASE), re.compile("Unknown command or access denied!", re.IGNORECASE), re.compile("I am responding", re.IGNORECASE), re.compile("I only listen", re.IGNORECASE), re.compile("Error!", re.IGNORECASE), re.compile("Unknown command input", re.IGNORECASE), re.compile("You have been auto invited", re.IGNORECASE), ] def inject(self, registry): self.db = registry.get_instance("db") self.util: Util = registry.get_instance("util") self.access_manager: AccessManager = registry.get_instance("access_manager") self.bot: Mangopie = registry.get_instance("mangopie") self.character_manager: CharacterManager = registry.get_instance("character_manager") self.setting_manager: SettingManager = registry.get_instance("setting_manager") self.command_alias_manager = registry.get_instance("command_alias_manager") def pre_start(self): self.bot.add_packet_handler(server_packets.PrivateMessage.id, self.handle_private_message) self.bot.add_packet_handler(server_packets.PrivateChannelMessage.id, self.handle_private_channel_message) self.register_command_channel("Private Message", self.PRIVATE_MESSAGE) self.register_command_channel("Org Channel", self.ORG_CHANNEL) self.register_command_channel("Private Channel", self.PRIVATE_CHANNEL) def start(self): # process decorators for _, inst in Registry.get_all_instances().items(): for name, method in get_attrs(inst).items(): if hasattr(method, "command"): cmd_name, params, access_level, description, help_file, sub_command = getattr(method, "command") handler = getattr(inst, name) module = self.util.get_module_name(handler) help_text = self.get_help_file(module, help_file) self.register(handler, cmd_name, params, access_level, description, module, help_text, sub_command) def register(self, handler, command, params, access_level, description, module, help_text=None, sub_command=None): command = command.lower() if sub_command: sub_command = sub_command.lower() else: sub_command = "" access_level = access_level.lower() module = module.lower() command_key = self.get_command_key(command, sub_command) if help_text is None: help_text = self.generate_help(command, description, params) if not self.access_manager.get_access_level_by_label(access_level): self.logger.error("Could not add command '%s': could not find access level '%s'" % (command, access_level)) return for channel, label in self.channels.items(): row = self.db.find('command_config', {"command": command, "sub_command": sub_command, 'channel': channel}) if row is None: # add new command commands self.db.insert('command_config', {'command': command, 'sub_command': sub_command, 'access_level': access_level, 'channel': channel, 'module': module, 'verified': 1, 'enabled': 1}) elif 'verified' in row and row['verified']: if row['module'] != module: self.logger.warning("module different for different forms of command '%s' and sub_command '%s'" % ( command, sub_command)) else: # mark command as verified self.db.update('command_config', {'module': module, 'command': command, 'channel': channel, 'access_level': access_level, 'sub_command': sub_command}, {'verified': 1}) # save reference to command handler r = re.compile(self.get_regex_from_params(params), re.IGNORECASE) self.handlers[command_key].append( {"regex": r, "callback": handler, "help": help_text, "description": description, "params": params}) def handle_private_message(self, packet: server_packets.PrivateMessage): # since the command symbol is not required for private messages, # the command_str must have length of at least 1 in order to be valid, # otherwise it is ignored if len(packet.message) < 1 or not self.bot.is_ready(): return for regex in self.ignore_regexes: if regex.search(packet.message): return if packet.message[:1] == '!': command_str = packet.message[1:] else: command_str = packet.message self.process_command( command_str, "msg", packet.char_id, lambda msg: self.bot.send_private_message(packet.char_id, msg)) def handle_private_channel_message(self, packet: server_packets.PrivateChannelMessage): # since the command symbol is required in the private channel, # the command_str must have length of at least 2 in order to be valid, # otherwise it is ignored if len(packet.message) < 2: return symbol = packet.message[:1] command_str = packet.message[1:] if symbol == self.setting_manager.get( "symbol").get_value() and packet.private_channel_id == self.bot.char_id: self.process_command( command_str, "priv", packet.char_id, lambda msg: self.bot.send_private_channel_message(msg)) def process_command(self, message: str, channel: str, char_id, reply): try: command_str, command_args = self.get_command_parts(message) # check for command alias command_alias = self.command_alias_manager.check_for_alias(command_str) if command_alias: command_str, command_args = self.get_command_parts( command_alias + " " + command_args if command_args else command_alias) cmd_configs = self.get_command_configs(command_str, channel, 1) cmd_configs = list(cmd_configs) if cmd_configs: # given a list of cmd_configs that are enabled, see if one has regex that matches incoming command_str cmd_config, matches, handler = self.get_matches(cmd_configs, command_args) if matches: if self.access_manager.check_access(char_id, cmd_config['access_level']): sender = MapObject( {"name": self.character_manager.resolve_char_to_name(char_id), "char_id": char_id}) handler["callback"](channel, sender, reply, self.process_matches(matches, handler["params"])) else: self.access_denied_response(char_id, cmd_config, reply) else: # handlers were found, but no handler regex matched help_text = self.get_help_text(char_id, command_str, channel) if help_text: reply(self.format_help_text(command_str, help_text)) else: reply("Error! Invalid syntax.") else: reply("Error! Unknown command.") except Exception as e: self.logger.error("error processing command: %s" % message, e) reply("There was an error processing your request.") def get_help_text(self, char, command_str, channel): data = self.db.find_all('command_config', {'command': command_str, 'channel': channel, 'enabled': 1}) # filter out commands that character does not have access level for data = filter(lambda row: self.access_manager.check_access(char, row['access_level']), data) def read_help_text(row): command_key = self.get_command_key(row['command'], row['sub_command']) return filter(lambda x: x is not None, map(lambda handler: handler["help"], self.handlers[command_key])) content = "\n\n".join(flatmap(read_help_text, data)) return content if content else None def get_help_file(self, module, help_file): if help_file: try: help_file = "./" + module.replace(".", "/") + "/" + help_file with open(help_file) as f: return f.read().strip() except FileNotFoundError as e: self.logger.error("Error reading help file", e) return None def format_help_text(self, topic, help_text): return ChatBlob("Help (" + topic + ")", help_text) def generate_help(self, command, description, params): return description + ":\n" + "<tab><symbol>" + command + " " + " ".join(map(lambda x: x.get_name(), params)) def access_denied_response(self, char_id, cmd_config, reply): reply("Error! Access denied.") def get_command_key(self, command, sub_command): if sub_command: return command + ":" + sub_command else: return command def get_command_key_parts(self, command_str): parts = command_str.split(":", 1) if len(parts) == 2: return parts[0], parts[1] else: return parts[0], "" def get_matches(self, cmd_configs, command_args): if command_args: command_args = " " + command_args for row in cmd_configs: command_key = self.get_command_key(row['command'], row['sub_command']) handlers = self.handlers[command_key] for handler in handlers: matches = handler["regex"].match(command_args) if matches: return row, matches, handler return None, None, None def process_matches(self, matches, params): groups = list(matches.groups()) processed = [] for param in params: processed.append(param.process_matches(groups)) return processed def format_matches(self, command_args, matches): # convert matches to list m = list(matches.groups()) m.insert(0, command_args) # strip leading spaces for each group, if they group exists return list(map(lambda x: x[1:] if x else x, m)) def get_command_parts(self, message): parts = message.split(" ", 1) if len(parts) == 2: return parts[0].lower(), parts[1] else: return parts[0].lower(), "" def get_command_configs(self, command, channel=None, enabled=1, sub_command=None): query = {"command": command} if channel: query['channel'] = channel if enabled: query['enabled'] = enabled if sub_command: query['sub_command'] = sub_command return self.db.find_all('command_config', query) def get_handlers(self, command_key): return self.handlers.get(command_key, None) def register_command_channel(self, label, value): if value in self.channels: self.logger.error("Could not register command channel '%s': command channel already registered" % value) return self.logger.debug("Registering command channel '%s'" % value) self.channels[value] = label def is_command_channel(self, channel): return channel in self.channels def get_regex_from_params(self, params): # params must be wrapped with line-beginning and line-ending anchors in order to match # when no params are specified (eg. "^$") return "^" + "".join(map(lambda x: x.get_regex(), params)) + "$"
class Cutout: def __init__(self, survey, position, radius, **kwargs): self.survey = survey self.position = position self.ra = self.position.ra.to_value(u.deg) self.dec = self.position.dec.to_value(u.deg) self.radius = radius self.basesurvey = kwargs.get('basesurvey', 'racsI') self.psf = kwargs.get('psf') self.cmap = kwargs.get('cmap', 'gray_r') self.color = 'k' if self.cmap == 'hot' else 'black' self.band = kwargs.get('band', 'g') level = 'DEBUG' if kwargs.get('verbose') else 'INFO' self.logger = Logger(__name__, kwargs.get('log'), streamlevel=level).logger self.logger.propagate = False self.kwargs = kwargs try: self._get_cutout() except Exception as e: msg = f"{survey} failed: {e}" raise FITSException(msg) finally: if 'racs' not in self.survey and 'vast' not in self.survey: self.plot_sources = False self.plot_neighbours = False def __repr__(self): return f"Cutout({self.survey}, ra={self.ra:.2f}, dec={self.dec:.2f})" def _get_source(self): try: pattern = re.compile(r'\S*(\d{4}[+-]\d{2}[AB])\S*') selpath = SURVEYS.loc[self.survey]['selavy'] sel = glob.glob(f'{selpath}/*components.txt') sel = [s for s in sel if pattern.sub(r'\1', self.filepath) in s] if len(sel) > 1: df = pd.concat([pd.read_fwf(s, skiprows=[ 1, ]) for s in sel]) else: df = pd.read_fwf(sel[0], skiprows=[ 1, ]) coords = SkyCoord(df.ra_deg_cont, df.dec_deg_cont, unit=u.deg) d2d = self.position.separation(coords) df['d2d'] = d2d sources = df.iloc[np.where(d2d.deg < 0.5 * self.radius)[0]] sources = sources.sort_values('d2d', ascending=True) if any(sources.d2d < self.pos_err / 3600): self.source = sources.iloc[0] self.neighbours = sources.iloc[1:] self.plot_sources = True else: self.source = None self.neighbours = sources self.plot_sources = False self.plot_neighbours = self.kwargs.get('neighbours', True) self.logger.debug(f'Source: \n {self.source}') if len(self.neighbours) > 0: nn = self.neighbours.iloc[0] self.logger.debug( f'Nearest neighbour coords: \n {nn.ra_deg_cont, nn.dec_deg_cont}' ) self.logger.debug( f'Nearest 5 Neighbours \n {self.neighbours.head()}') except IndexError: self.plot_sources = False self.plot_neighbours = False self.logger.warning('No nearby sources found.') def _get_cutout(self): if not os.path.exists(cutout_cache + self.survey): msg = f"{cutout_cache}{self.survey} cutout directory does not exist, creating." self.logger.info(msg) os.makedirs(cutout_cache + self.survey) if os.path.isfile(self.survey): self._get_local_cutout() elif 'racs' in self.survey or 'vast' in self.survey or 'vlass' in self.survey: self._get_local_cutout() elif self.survey == 'skymapper': self._get_skymapper_cutout() elif self.survey == 'panstarrs': self._get_panstarrs_cutout() elif self.survey == 'decam': self._get_decam_cutout() else: self._get_skyview_cutout() def _get_local_cutout(self): """Fetch cutout data via local FITS images (e.g. RACS / VLASS).""" fields = self._find_image() assert len( fields ) > 0, f"No fields located at {self.position.ra:.2f}, {self.position.dec:.2f}" closest = fields[fields.dist_field_centre == fields.dist_field_centre.min()].iloc[0] image_path = SURVEYS.loc[self.survey]['images'] if self.survey == 'vlass': filepath = f'{closest.epoch}/{closest.tile}/{closest.image}/{closest.filename}' image_path = vlass_path elif 'racs' in self.survey: pol = self.survey[-1] if on_system == 'ada': filepath = f'RACS_test4_1.05_{closest.field}.fits' else: filepath = f'RACS_{closest.field}.EPOCH00.{pol}.fits' elif 'vast' in self.survey: pattern = re.compile(r'vastp(\dx*)([IV])') epoch = pattern.sub(r'\1', self.survey) pol = pattern.sub(r'\2', self.survey) filepath = f'VAST_{closest.field}.EPOCH0{epoch}.{pol}.fits' else: filepath = f'*{closest.field}*0.restored.fits' try: self.filepath = glob.glob(image_path + filepath)[0] except IndexError: raise FITSException( f'Could not match {self.survey} image filepath: \n{image_path + filepath}' ) with fits.open(self.filepath) as hdul: self.header, data = hdul[0].header, hdul[0].data wcs = WCS(self.header, naxis=2) self.mjd = Time(self.header['DATE']).mjd try: cutout = Cutout2D(data[0, 0, :, :], self.position, self.radius * u.deg, wcs=wcs) except IndexError: cutout = Cutout2D(data, self.position, self.radius * u.deg, wcs=wcs) self.data = cutout.data * 1000 self.wcs = cutout.wcs if 'racs' in self.survey or 'vast' in self.survey: self.pos_err = SURVEYS.loc[self.basesurvey].pos_err self._get_source() else: # Probably using vlass, yet to include aegean catalogs self.plot_sources = False self.plot_neighbours = False def _get_panstarrs_cutout(self): """Fetch cutout data via PanSTARRS DR2 API.""" path = cutout_cache + 'panstarrs/{}_{}arcmin_{}_{}.fits'.format( self.band, '{:.3f}', '{:.3f}', '{:.3f}', ) imgpath = path.format(self.radius * 60, self.ra, self.dec) if not os.path.exists(imgpath): pixelrad = int(self.radius * 120 * 120) service = "https://ps1images.stsci.edu/cgi-bin/ps1filenames.py" url = ( f"{service}?ra={self.ra}&dec={self.dec}&size={pixelrad}&format=fits" f"&filters=grizy") table = Table.read(url, format='ascii') msg = f"No PS1 image at {self.position.ra:.2f}, {self.position.dec:.2f}" assert len(table) > 0, msg urlbase = ( f"https://ps1images.stsci.edu/cgi-bin/fitscut.cgi?" f"ra={self.ra}&dec={self.dec}&size={pixelrad}&format=fits&red=" ) flist = ["yzirg".find(x) for x in table['filter']] table = table[np.argsort(flist)] for row in table: self.mjd = row['mjd'] filt = row['filter'] url = urlbase + row['filename'] path = cutout_cache + 'panstarrs/{}_{}arcmin_{}_{}.fits'.format( filt, '{:.3f}', '{:.3f}', '{:.3f}', ) path = path.format(self.radius * 60, self.ra, self.dec) img = requests.get(url, allow_redirects=True) if not os.path.exists(path): with open(path, 'wb') as f: f.write(img.content) with fits.open(imgpath) as hdul: self.header, self.data = hdul[0].header, hdul[0].data self.wcs = WCS(self.header, naxis=2) def _get_skymapper_cutout(self): """Fetch cutout data via Skymapper API.""" path = cutout_cache + self.survey + '/dr2_jd{:.3f}_{:.3f}arcmin_{:.3f}_{:.3f}' linka = 'http://api.skymapper.nci.org.au/aus/siap/dr2/' linkb = 'query?POS={:.5f},{:.5f}&SIZE={:.3f}&BAND=all&RESPONSEFORMAT=CSV' linkc = '&VERB=3&INTERSECT=covers' sm_query = linka + linkb + linkc link = linka + 'get_image?IMAGE={}&SIZE={}&POS={},{}&FORMAT=fits' table = requests.get(sm_query.format(self.ra, self.dec, self.radius)) df = pd.read_csv(io.StringIO(table.text)) assert len( df ) > 0, f'No Skymapper image at {self.position.ra:.2f}, {self.position.dec:.2f}' df = df[df.band == 'z'] self.mjd = df.iloc[0]['mjd_obs'] link = df.iloc[0].get_image img = requests.get(link) path = path.format(self.mjd, self.radius * 60, self.ra, self.dec) if not os.path.exists(path): with open(path, 'wb') as f: f.write(img.content) with fits.open(path) as hdul: self.header, self.data = hdul[0].header, hdul[0].data self.wcs = WCS(self.header, naxis=2) def _get_decam_cutout(self): """Fetch cutout data via DECam LS API.""" size = int(self.radius * 3600 / 0.262) if size > 512: size = 512 maxradius = size * 0.262 / 3600 self.logger.warning( f"Using maximum DECam LS cutout radius of {maxradius:.3f} deg") link = f"http://legacysurvey.org/viewer/fits-cutout?ra={self.ra}&dec={self.dec}" link += f"&size={size}&layer=dr8&pixscale=0.262&bands={self.band}" img = requests.get(link) path = cutout_cache + self.survey + '/dr8_jd{:.3f}_{:.3f}arcmin_{:.3f}_{:.3f}_{}band' path = path.format(self.mjd, self.radius * 60, self.ra, self.dec, self.band) if not os.path.exists(path): with open(path, 'wb') as f: f.write(img.content) with fits.open(path) as hdul: self.header, self.data = hdul[0].header, hdul[0].data self.wcs = WCS(self.header, naxis=2) msg = f"No DECam LS image at {self.position.ra:.2f}, {self.position.dec:.2f}" assert self.data is not None, msg def _get_skyview_cutout(self): """Fetch cutout data via SkyView API.""" sv = SkyView() path = cutout_cache + self.survey + '/{:.3f}arcmin_{:.3f}_{:.3f}.fits' path = path.format(self.radius * 60, self.ra, self.dec) progress = self.kwargs.get('progress', False) if not os.path.exists(path): skyview_key = SURVEYS.loc[self.survey].sv try: hdul = sv.get_images(position=self.position, survey=[skyview_key], radius=self.radius * u.deg, show_progress=progress)[0][0] except IndexError: raise FITSException('Skyview image list returned empty.') except ValueError: raise FITSException( f'{self.survey} is not a valid SkyView survey.') except HTTPError: raise FITSException('No response from Skyview server.') with open(path, 'wb') as f: hdul.writeto(f) with fits.open(path) as hdul: self.header, self.data = hdul[0].header, hdul[0].data self.wcs = WCS(self.header, naxis=2) try: self.mjd = Time(self.header['DATE']).mjd except KeyError: try: self.epoch = self.kwargs.get('epoch') msg = "Could not detect epoch, PM correction disabled." assert self.epoch is not None, msg self.mjd = self.epoch if self.epoch > 3000 else Time( self.epoch, format='decimalyear').mjd except AssertionError as e: if self.kwargs.get('pm'): self.logger.warning(e) self.mjd = None self.data *= 1000 def _find_image(self): """Return DataFrame of survey fields containing coord.""" survey = self.survey.replace('I', '').replace('V', '') try: image_df = pd.read_csv(aux_path + f'{survey}_fields.csv') except FileNotFoundError: raise FITSException(f"Missing field metadata csv for {survey}.") beam_centre = SkyCoord(ra=image_df['cr_ra_pix'], dec=image_df['cr_dec_pix'], unit=u.deg) image_df['dist_field_centre'] = beam_centre.separation( self.position).deg pbeamsize = 1 * u.degree if self.survey == 'vlass' else 5 * u.degree return image_df[image_df.dist_field_centre < pbeamsize].reset_index( drop=True) def _obfuscate(self): """Remove all coordinates and identifying information.""" lon = self.ax.coords[0] lat = self.ax.coords[1] lon.set_ticks_visible(False) lon.set_ticklabel_visible(False) lat.set_ticks_visible(False) lat.set_ticklabel_visible(False) lon.set_axislabel('') lat.set_axislabel('') def _plot_setup(self, fig, ax): """Create figure and determine normalisation parameters.""" if ax: self.fig = fig self.ax = ax else: self.fig = plt.figure() self.ax = self.fig.add_subplot(111, projection=self.wcs) if self.kwargs.get('grid', True): self.ax.coords.grid(color='white', alpha=0.5) self.ax.set_xlabel('RA (J2000)') self.ax.set_ylabel('Dec (J2000)') if self.kwargs.get('title', True): self.ax.set_title(SURVEYS.loc[self.survey]['name'], fontdict={ 'fontsize': 20, 'fontweight': 10 }) if self.kwargs.get('obfuscate', False): self._obfuscate() if self.kwargs.get('annotation'): color = 'white' if self.cmap == 'hot' else 'k' self.ax.text(0.05, 0.85, self.kwargs.get('annotation'), color=color, weight='bold', transform=self.ax.transAxes) def _add_cornermarker(self, ra, dec, span, offset): color = 'white' if self.cmap != 'gray_r' else 'r' cosdec = np.cos(np.radians(dec)) raline = Line2D( xdata=[ra + offset / cosdec, ra + span / cosdec], ydata=[dec, dec], color=color, linewidth=2, path_effects=[pe.Stroke(linewidth=3, foreground='k'), pe.Normal()], transform=self.ax.get_transform('world')) decline = Line2D( xdata=[ra, ra], ydata=[dec + offset, dec + span], color=color, linewidth=2, path_effects=[pe.Stroke(linewidth=3, foreground='k'), pe.Normal()], transform=self.ax.get_transform('world')) self.ax.add_artist(raline) self.ax.add_artist(decline) def plot(self, fig=None, ax=None): """Plot survey data and position overlay.""" self.sign = self.kwargs.get('sign', 1) self._plot_setup(fig, ax) self.data *= self.sign absmax = max(self.data.max(), self.data.min(), key=abs) self.logger.debug(f"Max flux in cutout: {absmax:.2f} mJy.") rms = np.sqrt(np.mean(np.square(self.data))) self.logger.debug(f"RMS flux in cutout: {rms:.2f} mJy.") assert (sum((~np.isnan(self.data).flatten())) > 0 and sum(self.data.flatten()) != 0), \ f"No data in {self.survey}" if self.kwargs.get('maxnorm'): self.norm = ImageNormalize(self.data, interval=ZScaleInterval(), vmax=self.data.max(), clip=True) else: self.norm = ImageNormalize(self.data, interval=ZScaleInterval(contrast=0.2), clip=True) self.im = self.ax.imshow(self.data, cmap=self.cmap, norm=self.norm) if self.kwargs.get('bar', True): try: self.fig.colorbar(self.im, label=r'Flux Density (mJy beam$^{-1}$)', ax=self.ax) except UnboundLocalError: self.logger.error( "Colorbar failed. Upgrade to recent version of astropy ") if self.psf: try: self.bmaj = self.header['BMAJ'] * 3600 self.bmin = self.header['BMIN'] * 3600 self.bpa = self.header['BPA'] except KeyError: self.logger.warning('Header did not contain PSF information.') try: self.bmaj = self.psf[0] self.bmin = self.psf[1] self.bpa = 0 self.logger.warning( 'Using supplied BMAJ/BMin. Assuming BPA=0') except ValueError: self.logger.error('No PSF information supplied.') rhs = self.wcs.wcs_pix2world(self.data.shape[0], 0, 1) lhs = self.wcs.wcs_pix2world(0, 0, 1) # Offset PSF marker by the major axis in pixel coordinates try: cdelt = self.header['CDELT1'] except KeyError: cdelt = self.header['CD1_1'] beamavg = (self.bmaj + self.bmin) / 2 beamsize_pix = beamavg / abs(cdelt) / 3600 ax_len_pix = abs(lhs[0] - rhs[0]) / abs(cdelt) / 3600 beam = self.wcs.wcs_pix2world(beamsize_pix, beamsize_pix, 1) self.beamx = beam[0] self.beamy = beam[1] self.beam = Ellipse((self.beamx, self.beamy), self.bmin / 3600, self.bmaj / 3600, -self.bpa, facecolor='white', edgecolor='k', transform=self.ax.get_transform('world'), zorder=10) self.ax.add_patch(self.beam) # Optionally plot square around the PSF # Set size to greater of 110% PSF size or 10% ax length if self.kwargs.get('beamsquare', False): boxsize = max(beamsize_pix * 1.15, ax_len_pix * .1) offset = beamsize_pix - boxsize / 2 self.square = Rectangle( (offset, offset), boxsize, boxsize, facecolor='white', edgecolor='k', # transform=self.ax.get_transform('world'), zorder=5) self.ax.add_patch(self.square) if self.plot_sources: if self.kwargs.get('corner'): self._add_cornermarker( self.source.ra_deg_cont, self.source.dec_deg_cont, self.kwargs.get('corner_span', 20 / 3600), self.kwargs.get('corner_offset', 10 / 3600)) else: self.sourcepos = Ellipse( (self.source.ra_deg_cont, self.source.dec_deg_cont), self.source.min_axis / 3600, self.source.maj_axis / 3600, -self.source.pos_ang, facecolor='none', edgecolor='r', ls=':', lw=2, transform=self.ax.get_transform('world')) self.ax.add_patch(self.sourcepos) else: if self.kwargs.get('corner'): self._add_cornermarker( self.ra, self.dec, self.kwargs.get('corner_span', 20 / 3600), self.kwargs.get('corner_offset', 10 / 3600)) else: self.bmin = 15 self.bmaj = 15 self.bpa = 0 overlay = SphericalCircle( (self.ra * u.deg, self.dec * u.deg), self.bmaj * u.arcsec, edgecolor='r', linewidth=2, facecolor='none', transform=self.ax.get_transform('world')) self.ax.add_artist(overlay) if self.plot_neighbours: for idx, neighbour in self.neighbours.iterrows(): n = Ellipse((neighbour.ra_deg_cont, neighbour.dec_deg_cont), neighbour.min_axis / 3600, neighbour.maj_axis / 3600, -neighbour.pos_ang, facecolor='none', edgecolor='c', ls=':', lw=2, transform=self.ax.get_transform('world')) self.ax.add_patch(n) def save(self, path, fmt='png'): """Save figure with tight bounding box.""" self.fig.savefig(path, format=fmt, bbox_inches='tight') def savefits(self, path): """Export FITS cutout to path""" header = self.wcs.to_header() hdu = fits.PrimaryHDU(data=self.data, header=header) hdu.writeto(path)
class EventManager: def __init__(self): self.handlers = {} self.logger = Logger("event_manager") self.event_types = [] self.last_timer_event = 0 def inject(self, registry): self.db = registry.get_instance("db") self.util = registry.get_instance("util") def pre_start(self): self.register_event_type("timer") def start(self): # process decorators for _, inst in Registry.get_all_instances().items(): for name, method in get_attrs(inst).items(): if hasattr(method, "event"): event_type, description = getattr(method, "event") handler = getattr(inst, name) module = self.util.get_module_name(handler) self.register(handler, event_type, description, module) def register_event_type(self, event_type): event_type = event_type.lower() if event_type in self.event_types: self.logger.error( "Could not register event type '%s': event type already registered" % event_type) return self.logger.debug("Registering event type '%s'" % event_type) self.event_types.append(event_type) def is_event_type(self, event_base_type): return event_base_type in self.event_types def register(self, handler, event_type, description, module): event_base_type, event_sub_type = self.get_event_type_parts(event_type) module = module.lower() handler_name = self.util.get_handler_name(handler).lower() if event_base_type not in self.event_types: self.logger.error( "Could not register handler '%s' for event type '%s': event type does not exist" % (handler_name, event_type)) return if not description: self.logger.warning( "No description for event_type '%s' and handler '%s'" % (event_type, handler_name)) row = self.db.find('event_config', { 'event_type': event_base_type, 'handler': handler_name }) if row is None: # add new event commands self.db.insert( 'event_config', { 'event_type': event_base_type, 'event_sub_type': event_sub_type, 'handler': handler_name, 'description': description, 'module': module, 'verified': 1, 'enabled': 1, 'next_run': int(time.time()) }) else: # mark command as verified self.db.update('event_config', { 'event_type': event_base_type, 'handler': handler_name }, { 'verified': 1, 'module': module, 'description': description, 'event_sub_type': event_sub_type, }) # load command handler self.handlers[handler_name] = handler def fire_event(self, event_type, event_data=None): event_base_type, event_sub_type = self.get_event_type_parts(event_type) if event_base_type not in self.event_types: self.logger.error( "Could not fire event type '%s': event type does not exist" % event_type) return data = self.db.find_all( 'event_config', { 'event_type': event_base_type, 'event_sub_type': event_sub_type, 'enabled': 1 }) for row in data: handler = self.handlers.get(row['handler'], None) if not handler: self.logger.error( "Could not find handler callback for event type '%s' and handler '%s'" % (event_type, row.handler)) return try: handler(event_type, event_data) except Exception as e: self.logger.error("error processing event '%s'" % event_type, e) def get_event_type_parts(self, event_type): parts = event_type.lower().split(":", 1) if len(parts) == 2: return parts[0], parts[1] else: return parts[0], "" def get_event_type_key(self, event_base_type, event_sub_type): return event_base_type + ":" + event_sub_type def check_for_timer_events(self, timestamp): data = self.db.find('event_config', { 'enabled': 1, 'event_type': 'timer', 'next_run': { '$gte': timestamp } }) if data is not None: for row in data: event_type_key = self.get_event_type_key( row['event_type'], row['event_sub_type']) # timer event run times should be consistent, so we base the next run time off the last run time, # instead of the current timestamp next_run = row['next_run'] + int(row['event_sub_type']) # prevents timer events from getting too far behind, or having a large "catch-up" after # the bot has been offline for a time if next_run < timestamp: next_run = timestamp + int(row['event_sub_type']) self.db.update('event_config', { 'event_type': 'timer', 'handler': row['handler'] }, {'next_run': next_run}) self.fire_event(event_type_key)
bot.connect("chat.dt.funcom.com", 7109) elif int(config["dimension"]) == 3: bot.connect("localhost", 9993) else: print('Invalid server!') bot.disconnect() time.sleep(5) exit(1) if not bot.login(config["username"], config["password"], config["character"]): bot.disconnect() time.sleep(5) exit(3) else: status = bot.run() bot.disconnect() exit(status.value) except ConnectionFailure: print("Connection to database failed.") exit(1) except KeyboardInterrupt: exit(0) except Exception as e: logger = Logger("bootstrap") logger.error("", e) exit(4)
def stop_ssh(self): try: subprocess.run("sudo /etc/init.d/ssh stop", shell=True, check=True) except subprocess.CalledProcessError: Logger.error("停止失败")
def updateItem(self, item, lx, ly, vx, vy): self.newLX = lx self.newLY = ly localNewLX = lx localNewLY = ly while True: time.sleep(1 / self.tickrate) self.newLX = float(self.newLX) + float(vx) self.newLY = float(self.newLY) + float(vy) localNewLX = float(localNewLX) + float(vx) localNewLY = float(localNewLY) + float(vy) item.place(relx=localNewLX, rely=localNewLY) print(self.newLX, self.newLY) try: cached = self.locations MYdiffX = cached[self.locIndex][0] - 1.00 MYdiffY = cached[self.locIndex][1] - 1.00 diffX = cached[0][0] - 1.00 diffY = cached[0][1] - 1.00 diffX2 = cached[1][0] - 1.00 diffY2 = cached[1][1] - 1.00 diffX3 = cached[2][0] - 1.00 diffY3 = cached[2][1] - 1.00 diffX4 = cached[3][0] - 1.00 diffY4 = cached[3][1] - 1.00 if diffX < 0: diffX = diffX * -1 if diffY < 0: diffY = diffY * -1 if diffX2 < 0: diffX2 = diffX2 * -1 if diffY2 < 0: diffY2 = diffY2 * -1 if diffX3 < 0: diffX3 = diffX3 * -1 if diffY3 < 0: diffY3 = diffY3 * -1 if diffX4 < 0: diffX4 = diffX4 * -1 if diffY4 < 0: diffY4 = diffY4 * -1 if MYdiffX < 0: MYdiffX = MYdiffX * -1 if MYdiffY < 0: MYdiffY = MYdiffY * -1 differences = [[diffX, diffY], [diffX2, diffY2], [diffX3, diffY3], [diffX4, diffY4]] # print(differences) # print(MYdiffX, MYdiffY) myIndex = differences.index([MYdiffX, MYdiffY]) # print(myIndex) diffXItem = float(self.newLX) - 1 diffYItem = float(self.newLY) - 1 if 1 < float(self.newLX) or float(self.newLX) < 0: item.place_forget() item = None print('bullet out of bounds') break if 1 < float(self.newLY) or float(self.newLY) < 0: item.place_forget() item = None print('bullet out of bounds') break if diffXItem < 0: diffXItem = diffXItem * -1 if diffYItem < 0: diffYItem = diffYItem * -1 GOTHIT = None # print(diffX, diffY, diffXItem, diffYItem) if self.bullet.cget("foreground") != self.playerColours[ self.locIndex]: if diffXItem - 0.04 < diffX < diffXItem + 0.04: if diffYItem - 0.04 < diffY < diffYItem + 0.04: item.place_forget() item = None GOTHIT = 0 elif diffXItem - 0.04 < diffX2 < diffXItem + 0.04: if diffYItem - 0.04 < diffY2 < diffYItem + 0.04: item.place_forget() item = None GOTHIT = 1 elif diffXItem - 0.04 < diffX3 < diffXItem + 0.04: if diffYItem - 0.04 < diffY3 < diffYItem + 0.04: item.place_forget() item = None GOTHIT = 2 elif diffXItem - 0.04 < diffX4 < diffXItem + 0.04: if diffYItem - 0.04 < diffY4 < diffYItem + 0.04: item.place_forget() item = None GOTHIT = 3 if GOTHIT != None: print('SOMEONE GOT HIT') print(GOTHIT, myIndex) if GOTHIT == myIndex: self.notificationText.set( 'You were hit by a bullet!') self.Window.after( 3000, lambda: self.notificationText.set('')) break except Exception as e: Logger.error(e)
class Profile(object): def __init__(self, profile_dir=None): self.profile_dir = profile_dir self.config = configparser.ConfigParser() self.logger = Logger() self.name = '' self.device = {'Device': 'SERIAL|IP:PORT', 'TCP': True} self.advanced = {'Debugging': False} if self.profile_dir is None: self.init_new() self.modify_profile() else: self.read_profile() self.adb = Device(self.__dict__) def __eq__(self, other): return (self.__class__ == other.__class__ and self.name == other.name and self.profile_dir == other.profile_dir) def read_profile(self): self.config.read(self.profile_dir) if not self.malformed(): self.update_local() else: self.logger.error( 'Profile is malformed. Please check the file or create a new profile.' ) def update_local(self): self.__read_device() self.__read_advanced() self.profile_dir = './profiles/{}.prof'.format(self.name) def __read_device(self): self.name = self.config.get('Profile', 'Name') self.device['Device'] = self.config.get('Device', 'Device') self.device['TCP'] = self.config.getboolean('Device', 'TCP') def __read_advanced(self): self.advanced['Debugging'] = self.config.getboolean( 'Advanced', 'Debugging') if self.advanced['Debugging']: self.logger.enable_debugging() else: self.logger.disable_debugging() def malformed(self): return not (self.config.has_option('Profile', 'Name') and self.config.has_option('Device', 'Device') and self.config.has_option('Device', 'TCP') and self.config.has_option('Advanced', 'Debugging')) def init_new(self): default_profile = { 'Profile': { 'Name': self.name }, 'Device': self.device, 'Advanced': self.advanced } self.config.read_dict(default_profile) def save_profile(self): os.makedirs(os.path.dirname(self.profile_dir), exist_ok=True) with open(self.profile_dir, 'w') as config_file: self.config.write(config_file) def modify_profile(self): self.config.set('Profile', 'Name', input('Enter profile name: ')) self.config.set('Device', 'Device', input('Enter device: ')) self.config.set('Device', 'TCP', input('Enter TCP: ')) self.config.set('Advanced', 'Debugging', input('Enter debugging: ')) self.update_local() def kill_consoles(self): self.logger.receiver.kill()
def main(radius, contours, clabels, pm, epoch, sign, psf, corner, neighbours, annotation, basesurvey, cmap, maxnorm, band, obfuscate, verbose, save, savefits, ra, dec, survey): """Generate image cutout from multi-wavelength survey data. Available surveys: \b Radio --------------------------------- gw1I s190814bv Epoch 1 (I) gw2I s190814bv Epoch 2 (I) gw3I s190814bv Epoch 3 (I) gw4I s190814bv Epoch 4 (I) racsI RACS (I) racsV RACS (V) vastp1I VAST P1 (I) vastp1V VAST P1 (V) vastp2I VAST P2 (I) vastp2V VAST P2 (V) vastp3xI VAST P3x (I) vastp3xV VAST P3x (V) vastp4xI VAST P4x (I) vastp4xV VAST P4x (V) vastp5xI VAST P5x (I) vastp5xV VAST P5x (V) vastp6xI VAST P6x (I) vastp6xV VAST P6x (V) vastp7xI VAST P7x (I) vastp7xV VAST P7x (V) vastp8I VAST P8 (I) vastp8V VAST P8 (V) vastp9I VAST P9 (I) vastp9V VAST P9 (V) vastp10xI VAST P10x (I) vastp10xV VAST P10x (V) vastp11xI VAST P11x (I) vastp11xV VAST P11x (V) vlass VLASS sumss SUMSS nvss NVSS tgss TGSS gleam GLEAM --------------------------------- Infra-red --------------------------------- 2massh 2MASS H 2massj 2MASS J 2massk 2MASS K wise3_4 WISE 3.4 wise4_6 WISE 4.6 wise12 WISE 12 wise22 WISE 22 --------------------------------- Optical --------------------------------- decam DECam LS panstarrs PanSTARRS skymapper Skymapper dss DSS --------------------------------- UV / X-ray / Gamma-ray --------------------------------- galex_nuv GALEX Near UV fermi Fermi 3-300 GeV rass_soft RASS Soft (ROSAT) swift_xrtcnt SWIFT Counts """ level = 'DEBUG' if verbose else 'INFO' logger = Logger(__name__, streamlevel=level).logger unit = u.hourangle if ':' in ra or 'h' in ra else u.deg position = SkyCoord(ra=ra, dec=dec, unit=(unit, u.deg)) psign = -1 if sign else 1 s = SURVEYS.loc[survey] if not radius: radius = s.radius try: if s.radio and not contours: cutout = Cutout(survey, position, radius=radius, psf=psf, corner=corner, neighbours=neighbours, annotation=annotation, basesurvey=basesurvey, band=band, maxnorm=maxnorm, cmap=cmap, obfuscate=obfuscate, verbose=verbose, sign=psign, pm=pm, epoch=epoch) elif contours: cutout = ContourCutout(survey, position, radius=radius, contours=contours, clabels=clabels, psf=psf, corner=corner, neighbours=neighbours, annotation=annotation, basesurvey=basesurvey, band=band, cmap=cmap, maxnorm=maxnorm, obfuscate=obfuscate, verbose=verbose, sign=psign, pm=pm, epoch=epoch) else: cutout = ContourCutout(survey, position, radius=radius, contours='racsI', psf=psf, corner=corner, neighbours=neighbours, annotation=annotation, basesurvey=basesurvey, band=band, cmap=cmap, maxnorm=maxnorm, obfuscate=obfuscate, verbose=verbose, sign=psign, pm=pm, epoch=epoch) cutout.plot() except FITSException as e: if verbose: logger.exception(e) else: logger.error(e) if save: cutout.save(save) if savefits: cutout.savefits(savefits) plt.show()
def find_materials(): """Find material models """ logger = Logger("console") errors = [] mat_libs = {} rx = re.compile(r"(?:^|[\\b_\\.-])[Mm]at") a = ["MaterialModel", "AbaqusMaterial"] # gather and verify all files search_dirs = [d for d in MAT_LIB_DIRS] if not SUPPRESS_USER_ENV: for user_mat in cfgparse("materials"): user_mat = os.path.realpath(user_mat) if user_mat not in search_dirs: search_dirs.append(user_mat) # go through each item in search_dirs and generate a list of material # interface files. if item is a directory gather all files that match rx; # if it's a file, add it to the list of material files for item in search_dirs: if os.path.isfile(item): d, files = os.path.split(os.path.realpath(item)) files = [files] elif os.path.isdir(item): d = item files = [f for f in os.listdir(item) if rx.search(f)] else: logger.warn("{0} no such directory or file, skipping".format(d), report_who=1) continue files = [f for f in files if f.endswith(".py")] if not files: logger.warn("{0}: no mat files found".format(d), report_who=1) # go through files and determine if it's an interface file. if it is, # load it and add it to mat_libs for f in files: module = f[:-3] try: libs = xpyclbr.readmodule(module, [d], ancestors=a) except AttributeError as e: errors.append(e.args[0]) logger.error(e.args[0]) continue for lib in libs: if lib in mat_libs: logger.error("{0}: duplicate material".format(lib)) errors.append(lib) continue module = load_file(libs[lib].file) mat_class = getattr(module, libs[lib].class_name) if not mat_class.name: raise AFEPYError("{0}: material name attribute " "not defined".format(lib)) libs[lib].mat_class = mat_class mat_libs.update({mat_class.name.lower(): libs[lib]}) if errors: raise AFEPYError(", ".join(errors)) return mat_libs