def run(self) -> None: """ Start everything because the tray controls most of the components """ try: self.tray = ps.Icon( "FOV Changer", icon=self.icon_image, title="FOV Changer", menu=ps.Menu( ps.MenuItem("FOV Changer", self.void, enabled=False), ps.Menu.SEPARATOR, ps.MenuItem("Open Window", self.action), ps.MenuItem("Enabled", self.action, checked=lambda item: self.states["Enabled"]), ps.Menu.SEPARATOR, ps.MenuItem("Exit", self.action))) # Start GUI self.root_thread.start() # Start Processing stuff self.processing_thread.start() # Start tray Logger.log("System Tray", add=True) self.tray.run() Logger.log("System Tray", add=False) self.on_shutdown() except Exception: exceptions.handle_error(self.references)
def main(): """ Wraps the main logic of the program into one function. """ args = handle_args() # determine log level logger = Logger(verbosity=4) logger.verbosity = 4 if args.verbose else 0 # logger up TMP Client logger.log("TMPCLI", "INFO", "Creating TMP Client") client = TmpClient( args.server, args.port, logger, args.business_type, args.version, ) if args.use_tdp: client.use_tdp = True logger.log("TMPCLI", "INFO", "Sending payload") if args.use_tdp: client.send(args.opcode, args.payload, args.packet_type) else: client.send(args.opcode, args.payload)
def on_settings_save_button(self): """ Save settings """ if self.storage.settings.tk_vars: settings = self.storage.settings.data for name, value in self.storage.settings.tk_vars.items(): try: # Try to cast value = type(settings[name])(value.get()) # Set new value settings[name] = value except ValueError: Logger.log( msg := f"Invalid value for {' '.join(x[0].upper() + x[1:] for x in name.split('_'))}" ) queue_alert_message(self.references, msg, warning=True) return Logger.log("Saved new settings!") queue_alert_message(self.references, "Saved new settings!") self.storage.update_file()
def create_notebook(self): """ The notebook which contains settings and more is Gets execute in createContent """ notebook = ttk.Notebook(self.main_frame, width=600, takefocus=False) notebook.grid(column=3, row=1, sticky="WENS", ipadx=0) # Create instances self.feature_frame = tk.Frame(notebook) self.settings_frame = tk.Frame(notebook) self.log_frame = tk.Frame(notebook) self.info_frame = tk.Frame(notebook) # Update to get height self.update() # Add them before to be then able to calculate the height notebook.add(self.feature_frame, text="Features") notebook.add(self.settings_frame, text="Settings") notebook.add(self.log_frame, text="Log") notebook.add(self.info_frame, text="Info") # Notebook Features # If there are features, render them if features := self.storage.features: self.create_tab_features(features) Logger.log("Rendered Features!")
def send_gmail(recipients: Iterable[str], subject: str, body: str, debug: bool = False): recipients_string = ", ".join(recipients) Logger.log("Sending {:s} to {:s}:\n{:s}".format(subject, recipients_string, body)) if debug: return user, pwd = get_credentials() # Prepare actual message #message = """From: %s\nTo: %s\nSubject: %s\n\n%s #""" % (user, ", ".join(recipient), subject, body) # message = f"From: {user:s}\nTo: {recipients_string:s}\nSubject: {subject:s}\n\n{body:s}" message = MIMEText(body, "html") message["From"] = user message["To"] = recipients_string message["Subject"] = subject server = smtplib.SMTP("smtp.gmail.com", 587) server.ehlo() server.starttls() server.login(user, pwd) server.sendmail(user, recipients, message.as_string()) server.close()
def at_start(self): """ Gets called before the loop """ Logger.log("ProcessingThread", add=True) # Create basic ui to be able to display events self.references["RootThread"].queue.append( {"cmd": "create_widgets", "params": [], "kwargs": {}}) # Initialize storage self.storage = storage.Storage(self.references) # Initialize network self.network = network.Network(self.references) # Initialize gateway self.gateway = Gateway(self.references) # Not initialize listener, because its a thread # Initialize discord (rich presence) and event loop loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) self.discord = Discord(self.references, loop=loop) # Finish UI content self.references["RootThread"].queue.append( {"cmd": "create_content", "params": [], "kwargs": {}})
def __init__(self, references: dict, loop): """ Initialize :param references: (dict) the references """ self.references = references try: self.rpc = pypresence.Presence(client_id="733376215737434204", loop=loop) self.rpc.connect() # Discord not open (or not installed) except pypresence.InvalidPipe: self.rpc = None self.last_server = None self.last_time = None self.partner_servers = { "hivebedrock.network": "The Hive", "inpvp.net": "Mineville", "mineplex.com": "Mineplex", "galaxite.net": "Galaxite", "lbsg.net": "Lifeboat", "cubecraft.net": "CubeCraft" } self.feature = None # For ui self.tk_vars = {} # Add to references self.references.update({"Discord": self}) Logger.log("Discord", add=True)
def search(): 'Route to search' if request.method == 'GET': term = request.args.get('term') services_string = request.args.get('services') services = services_string.split(',') Logger.log(services) else: # try and get the term term = request.form.get('term', None) # try and get the selected services as a list services = request.form.getlist('services', None) # add the search to the user's profile USER_MANAGER.add_search(session['username'], term, services) # initialize the api service requestor = Requestor() # create a blank result results = Result() # check for each of the available selected service if 'Twitter' in services or 'twitter' in services: Logger.log('Twitter') results.tweets = requestor.search_twitter(term) if 'Giphy' in services or 'giphy' in services: Logger.log('Giphy') results.gifs = requestor.search_giphy(term) if 'Wikipedia' in services or 'wikipedia' in services: Logger.log('Wikipedia') results.articles = requestor.search_wiki(term) Logger.log('returning dict of results %s' % results) return render_template('home.html', results=results)
def callback(): """ End of the start part, own method, so it can be invoked after the creation of features tab """ try: # Get addresses self.gateway.get_addresses() # Set up and start listener self.listener = listener.Listener(self.references) self.listener.register_keys() self.listener.start() # Change start and tray button self.references["SystemTray"].states["Enabled"] = True self.references["SystemTray"].tray.update_menu() root.start_button_var.set("■ Stop") # Cooldown, need to copy root.after(self.storage.get("settings")["attach_cooldown"], (lambda: button.configure(state="active"))) root.config(cursor="arrow") except (pymem.exception.ProcessNotFound, pymem.exception.WinAPIError, pymem.exception.CouldNotOpenProcess) as e: Logger.log(f"Minecraft not found! {e}") ui.queue_alert_message(self.references, "Minecraft not found!", warning=True)
def home(): '''search form''' if check_for_user(): Logger.log('user logged in, sending to home') return render_template('home.html', results=list()) Logger.log('user not logged in, sending to index') return redirect('index.html')
def signout(): '''sign the current user out''' if check_for_user(): Logger.log('user logged in, signing out') sign_user_out() Logger.log('redirecting to index') return redirect('/')
def _flash_finished(self, code): Logger.log("Flash output contents:\r\n") Logger.log(self._flash_output) if code == 0: self._flash_output.extend(b"Rebooting from flash mode...\n") self._update_output() try: s = serial.Serial(self._port, 115200) s.dtr = False s.rts = True time.sleep(0.1) s.rts = False time.sleep(0.1) self._flash_output.extend( b"Done, you may now use the device.\n") self._update_output() except (OSError, serial.SerialException): QMessageBox.critical(self, "Flashing Error", "Failed to reboot into working mode.") elif code == -1: QMessageBox.critical( self, "Flashing Error", "Failed to run script.\nCheck that path to python is correct.") else: QMessageBox.critical(self, "Flashing Error", "Failed to flash new firmware") self.eraseButton.setEnabled(True) self.flashButton.setEnabled(True) self._flashing = False
def index(): 'Main template route' if check_for_user(): # make sure that we go to home if the user is logged in Logger.log('user exists sending home.html') return redirect('/home.html') Logger.log('user does not exist, returning index.html') return render_template('index.html')
def searches(): '''get the search history for this user''' if check_for_user(): username = session['username'] Logger.log(username) user = USER_MANAGER.get_user_profile(username) Logger.log(user.searches) return jsonify( searches=list(map(lambda s: s.search_text, user.searches))) return jsonify(searches=list())
def __init__(self, references: dict): """ Initialize :param references: the references """ self.references = references self.storage = references["Storage"] # Add to references self.references.update({"Network": self}) Logger.log("Network", add=True)
def add_search(self, username, term, services): '''add a search to the user's profile''' if username is None or\ services is None or\ term is None or\ len(services) < 1: return user = self.database.get_user(username) if term in list(map(lambda s: s.search_text, user.searches)): Logger.log('term already used, not saving') else: self.database.add_search(UserSearch(None, term, services, user.user_id ))
def check_version(self) -> bool: """ Check mc version if new features are required """ self.current_mc_version = self.get_mc_version() saved_mc_version = self.storage.get("mc_version") # When they aren't equal, update needed if self.current_mc_version != saved_mc_version: Logger.log("Saved version doesn't match!") return False Logger.log("Saved version ist correct!") return True
def inner(self, key, index: str, on_press: bool): """ To shorten up code, for register_keys :param key: key from pynput :param index: new setting index :param on_press: (bool) if from on press """ try: # Normalize the key code if isinstance(key, keyboard.KeyCode): code = self.unctrl(key.vk).lower() # Key exists? if code in self.keys: # First press? if ( code in self.pressed ) is not on_press or self.pressed[code] is not on_press: self.pressed.update({code: on_press}) # Do memory stuff for feature_id in self.keys[code]: feature_value = self.features[feature_id] # Enabled? if not feature_value["enabled"]: continue try: self.gateway.write_address( feature_id, feature_value["settings"][index]) # Minecraft was closed except pymem.exception.MemoryWriteError: self.gateway.close_process() self.gateway.status_check() # Alert user Logger.log("Minecraft was closed!") ui.queue_alert_message(self.references, "Minecraft was closed!", warning=True) self.references["Root"].bell() self.references["Root"].start_button_var.set( "Start") return self.stop() except Exception: exceptions.handle_error(self.references)
def status_check(self): """ Checks all sort of things for the status """ # Check if minecraft is open self.status["Connected"] = bool(self.process_handle) # Check the minecraft version self.status["Version"] = bool( self.current_mc_version == self.storage.get("mc_version")) if self.storage.features: # Addresses for addr_id, addr_value in { _id: _addr for _id, sublist in self.storage.features.addresses.items() for _addr in sublist }.items(): feature = self.storage.features[addr_id] try: # Not enabled or not available if not feature["enabled"] or not feature[ "available"] or not self.process_handle: status = None # Custom check elif "a_status_check" in self.storage.features.presets[ addr_id]: status = self.storage.features.presets[addr_id][ "a_status_check"](self) # Else just try to read else: self.read_address(addr_id) status = True self.status[addr_id] = status except pymem.exception.MemoryReadError: Logger.log(f"{feature['name']} is unavailable!", add=False) self.status[addr_id] = False # Update ui self.references["RootThread"].queue.append({ "cmd": "render_status", "params": [self.status], "kwargs": {} })
def get_html_targets() -> List[TargetElement]: targets = [] for filename in os.listdir(html_dir): if not filename.endswith(".json"): continue full_path = os.path.join(html_dir, filename) each_target = TargetElement(full_path) if any(each_target.name == _t.name for _t in targets): Logger.log("Double name {:s} in file {:s}.".format( each_target.name, filename)) continue targets.append(each_target) return targets
def get_mc_version() -> str: """ Get current mc version by using a powshell command """ startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW version = subprocess.check_output( "powershell.exe Get-AppxPackage -name Microsoft.MinecraftUWP | select -expandproperty Version", stdin=subprocess.PIPE, stderr=subprocess.PIPE, startupinfo=startupinfo)\ .decode("utf8").rstrip() if version: Logger.log(f"Found MC Version '{version}'") return version else: return ""
def get_address(self, feature_id: str, *, log=True): """ Get one address :param feature_id: the id of the following feature :param log: if to log getting the address """ feature = self.storage.features[feature_id] presets = self.storage.features.presets[feature_id] addresses = self.storage.features.addresses offset_outer = feature["offsets"] try: # If only one offset, so prepare list if presets["o_count"] == 1 or not isinstance(offset_outer, list): offset_outer = [offset_outer] addresses.update({feature_id: []}) for i, offs in enumerate(offset_outer): # Find the address temp = RemotePointer(self.process_handle, self.process_base.lpBaseOfDll + offs[0]) for offset in offs[1:-1]: temp = RemotePointer(self.process_handle, temp.value + offset) # Add it addresses[feature_id].append(temp.value + offs[-1]) if log: Logger.log( f"Found {i}. address for {feature['name']} [{hex(self.storage.features.addresses[feature_id][i])}]!", add=True) status = True except pymem.exception.MemoryReadError: status = False if log: Logger.log(f"No address for {feature['name']}!", add=False) self.status.update({ feature_id: status })
def sign_up(): 'Sign up a new user' if request.method == 'POST': Logger.log('POST') username = request.form.get('username') password = request.form.get('password') first_name = request.form.get('first-name') last_name = request.form.get('last-name') email = request.form.get('email') try: USER_MANAGER.add_user(first_name, last_name, username, password, email) sign_user_in(username) Logger.log('user created') except RuntimeError as err: Logger.log('failed to create user') return render_template('signup.html', error_text=err.args[0]) Logger.log('redirecting to home') return redirect('home.html') Logger.log('sending signup') return render_template('signup.html')
def save(self, feature_id: str): """ Click event for save button :param feature_id: the id of the feature """ if self.open: # Hide window self.top_levels[feature_id].withdraw() self.top_levels[feature_id].grab_release() # Get some values to clean up code feature = self.storage.features[feature_id] tk_var = self.storage.features.tk_vars[feature_id]["settings"] presets = self.storage.features.presets[feature_id] settings = {x: y.get() for x, y in tk_var.items()} # Save new values into the real settings field and check type # Also translate the values if needed if self.storage.features.check_settings(self.storage.features, feature_id, feature, override=settings): feature["settings"] = settings self.references["Storage"].update_file() Logger.log(f"Saved new values! [{settings}]") # queue_alert_message(self.references, "Saved new values!") # Reset from real saved value else: Logger.log(f"Invalid value entered! [{settings}]") queue_alert_message(self.references, "Invalid value entered!", warning=True) for var_name, var_obj in tk_var.items(): var_obj.set( (str(temp if (temp := feature["settings"][var_name] ) is not None else ""))) self.open = False
def repeat_indefinitely(function: Callable[[], None], minutes_interval: int): last_second = -1 while True: now = datetime.datetime.now() this_minute = now.minute while this_minute % minutes_interval != 0 or this_minute == last_second: Logger.log("{:s}: waiting".format(now.strftime(time_format))) time.sleep(10) now = datetime.datetime.now() this_minute = now.minute last_second = this_minute Logger.log("{:s}: executing function".format( now.strftime(time_format))) # noinspection PyBroadException try: function() except Exception as e: Logger.log(traceback.format_exc()) continue
def update_state_files(targets: Iterable[TargetFile]) -> List[str]: text = [] tmp_file_path = local_dir + "file_state.json" if os.path.isfile(tmp_file_path): with open(tmp_file_path, mode="r") as file: temp_storage = json.load(file) else: Logger.log("Initializing temp file storage.") temp_storage = dict() for target_file in targets: Logger.log("Polling {:s}...".format(target_file.url)) response = requests.get(target_file.url, headers=headers) size = len(response.content) last_size = temp_storage.get(target_file.name) if last_size is None: Logger.log("Initializing {:s}...".format(target_file.name)) elif not last_size == size: text.append(target_file.url) temp_storage[target_file.name] = size with open(tmp_file_path, mode="w") as file: json.dump(temp_storage, file, indent=2, sort_keys=True) return text
def __init__(self, references: dict): """ Handles memory thanks to pymem, especially their discord helps a lot :param references: the references """ super().__init__() self.references = references # Data components self.storage = references["Storage"] self.status = { "Connected": False, "Version": None, } # I just dont want to add strings every 20secs self.valid_domain_letters = set(string.ascii_letters + string.digits + "-.") self.fallback_server_address = None self.current_mc_version = None # Finish self.references.update({"Gateway": self}) Logger.log("Gateway", add=True)
def _flash_job(self, python_path, firmware_file, erase_flash): try: params = [python_path, "flash.py", self._port] if firmware_file: params.append("--fw={}".format(firmware_file)) if erase_flash: params.append("--erase") if Settings().debug_mode: params.append("--debug") with subprocess.Popen(params, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1) as sub: buf = bytearray() delete = 0 Logger.log("Pipe receiving:\r\n") while True: x = sub.stdout.read(1) Logger.log(x) # Flushing content only in large blocks helps with flickering # Flush output if: # - didn't receive any character (timeout?) # - received first backspace (content is going to be deleted) # - received whitespace or dot (used to signal progress) if not x \ or (x[0] == 8 and delete == 0) \ or (x[0] in b"\r\n\t ."): with self._flash_output_mutex: if delete > 0: self._flash_output = self._flash_output[: -delete] self._flash_output.extend(buf) self._flash_output_signal.emit() buf = bytearray() delete = 0 if not x: break if x[0] == 8: delete += 1 else: buf.append(x[0]) Logger.log("\r\nPipe end.\r\n") sub.stdout.close() code = sub.wait() self._flash_finished_signal.emit(code) except (FileNotFoundError, OSError): self._flash_finished_signal.emit(-1) return
def run(self) -> None: """ Run method of thread """ try: Logger.log("Root Thread", add=True) # Initialize root and start the queue update self.root = Root(self.references) self.root.queue_update() # Start mainloop Logger.log("Root Gui", add=True) self.root.mainloop() Logger.log("Root Gui", add=False) Logger.log("Root Thread", add=False) # If something happens, log it except Exception as e: exceptions.handle_error(self.references)
def profile(): '''get the user profile''' if request.method == 'GET': Logger.log('GET') if check_for_user(): username = session['username'] Logger.log(username) user = USER_MANAGER.get_user_profile(username) Logger.log(user) if user is None: return render_template('profile.html', error='Unable to find user') return render_template('profile.html', user=user) return redirect('/index.html')