diff --git a/commands/__pycache__/cmd_cd.cpython-313.pyc b/commands/__pycache__/cmd_cd.cpython-313.pyc new file mode 100644 index 0000000..268372b Binary files /dev/null and b/commands/__pycache__/cmd_cd.cpython-313.pyc differ diff --git a/commands/__pycache__/cmd_credits.cpython-313.pyc b/commands/__pycache__/cmd_credits.cpython-313.pyc new file mode 100644 index 0000000..ca9e6f4 Binary files /dev/null and b/commands/__pycache__/cmd_credits.cpython-313.pyc differ diff --git a/commands/__pycache__/cmd_exit.cpython-313.pyc b/commands/__pycache__/cmd_exit.cpython-313.pyc new file mode 100644 index 0000000..272f98a Binary files /dev/null and b/commands/__pycache__/cmd_exit.cpython-313.pyc differ diff --git a/commands/__pycache__/cmd_fastfetch.cpython-313.pyc b/commands/__pycache__/cmd_fastfetch.cpython-313.pyc new file mode 100644 index 0000000..7ef3947 Binary files /dev/null and b/commands/__pycache__/cmd_fastfetch.cpython-313.pyc differ diff --git a/commands/__pycache__/cmd_nano.cpython-313.pyc b/commands/__pycache__/cmd_nano.cpython-313.pyc new file mode 100644 index 0000000..a801605 Binary files /dev/null and b/commands/__pycache__/cmd_nano.cpython-313.pyc differ diff --git a/commands/__pycache__/cmd_new.cpython-313.pyc b/commands/__pycache__/cmd_new.cpython-313.pyc new file mode 100644 index 0000000..1bf2d04 Binary files /dev/null and b/commands/__pycache__/cmd_new.cpython-313.pyc differ diff --git a/commands/__pycache__/cmd_run.cpython-313.pyc b/commands/__pycache__/cmd_run.cpython-313.pyc new file mode 100644 index 0000000..c47bda1 Binary files /dev/null and b/commands/__pycache__/cmd_run.cpython-313.pyc differ diff --git a/commands/cmd_cd.py b/commands/cmd_cd.py new file mode 100644 index 0000000..ef8fc18 --- /dev/null +++ b/commands/cmd_cd.py @@ -0,0 +1,46 @@ +# commands/cmd_cd.py +import os +from colorama import Fore + +class CdCommand: + def __init__(self, files_dir, shell_ref, target_dir): + # files_dir = ~/m5rcode/files + self.files_dir = files_dir + self.project_root = os.path.dirname(files_dir) # ~/m5rcode + self.shell = shell_ref[0] # the M5RShell instance + self.target = target_dir.strip() + + def run(self): + if not self.target or self.target == '.': + # Stay in current directory + return + + # Compute new absolute path + candidate = os.path.abspath( + os.path.normpath( + os.path.join(self.shell.cwd, self.target) + ) + ) + + # If they typed '..' from files_dir, allow up to project_root + if self.target == '..': + # from files_dir → project_root + if self.shell.cwd == self.files_dir: + new_path = self.project_root + # from any subfolder of files_dir → one level up, but not above project_root + else: + new_path = os.path.dirname(self.shell.cwd) + if not new_path.startswith(self.project_root): + new_path = self.project_root + else: + new_path = candidate + + # Check it stays within project_root + if not new_path.startswith(self.project_root): + print(Fore.RED + "Access denied: You cannot leave the m5rcode project.") + return + + if os.path.isdir(new_path): + self.shell.cwd = new_path + else: + print(Fore.RED + f"No such directory: {self.target}") diff --git a/commands/cmd_credits.py b/commands/cmd_credits.py new file mode 100644 index 0000000..2524839 --- /dev/null +++ b/commands/cmd_credits.py @@ -0,0 +1,35 @@ +# commands/cmd_credits.py +from colorama import Fore, Style + + +class CreditsCommand: + def run(self): + box_width = 70 + title = "Credits" + + credits = [ + (f"{Fore.CYAN}m5rcel{Fore.RESET}", "Lead Developer"), + (f"{Fore.YELLOW}pythonjs.cfd{Fore.RESET}", "Project Hosting & Deployment"), + (f"{Fore.MAGENTA}colorama{Fore.RESET}", "Used for terminal styling"), + (f"{Fore.GREEN}fastfetch inspired{Fore.RESET}", "Design influence"), + (f"{Fore.RED}openai.com{Fore.RESET}", "Some smart AI help ;)"), + ] + + # Top border + print(Fore.MAGENTA + "╭" + "─" * (box_width - 2) + "╮") + print(Fore.MAGENTA + "│" + Fore.CYAN + f"{title:^{box_width - 2}}" + Fore.MAGENTA + "│") + print(Fore.MAGENTA + "├" + "─" * (box_width - 2) + "┤") + + # Content + for name, role in credits: + line = f"{name:<30} {Fore.WHITE}- {role}" + padding = box_width - 3 - len(strip_ansi(line)) + print(Fore.MAGENTA + "│ " + line + " " * padding + Fore.MAGENTA + "│") + + # Bottom border + print(Fore.MAGENTA + "╰" + "─" * (box_width - 2) + "╯" + Style.RESET_ALL) + + +def strip_ansi(text): + import re + return re.sub(r'\x1b\[[0-9;]*m', '', text) diff --git a/commands/cmd_exit.py b/commands/cmd_exit.py new file mode 100644 index 0000000..aea361b --- /dev/null +++ b/commands/cmd_exit.py @@ -0,0 +1,6 @@ +from colorama import Fore + +class ExitCommand: + def run(self): + print(Fore.YELLOW + "Bye!") + return True # Signals to shell to exit diff --git a/commands/cmd_fastfetch.py b/commands/cmd_fastfetch.py new file mode 100644 index 0000000..6947487 --- /dev/null +++ b/commands/cmd_fastfetch.py @@ -0,0 +1,202 @@ +# commands/cmd_fastfetch.py +import platform +import re +import datetime +from pathlib import Path + +# Try to import psutil for uptime, provide a fallback if not available +try: + import psutil + _PSUTIL_AVAILABLE = True +except ImportError: + _PSUTIL_AVAILABLE = False + +# In a real terminal, colorama would handle ANSI escape codes. +# For direct output in a web environment, these colors might not render +# unless the terminal emulator supports them. +# We'll include them as they would be in a real terminal script. +class Fore: + BLACK = '\x1b[30m' + RED = '\x1b[31m' + GREEN = '\x1b[32m' + YELLOW = '\x1b[33m' + BLUE = '\x1b[34m' + MAGENTA = '\x1b[35m' + CYAN = '\x1b[36m' + WHITE = '\x1b[37m' + RESET = '\x1b[39m' + +class Style: + BRIGHT = '\x1b[1m' + DIM = '\x1b[2m' + NORMAL = '\x1b[22m' + RESET_ALL = '\x1b[0m' + +def strip_ansi(text): + """Removes ANSI escape codes from a string.""" + return re.sub(r'\x1b\[[0-9;]*m', '', text) + +class FastfetchCommand: + def _get_uptime(self): + """Calculates and returns the system uptime in a human-readable format.""" + if not _PSUTIL_AVAILABLE: + return "N/A (psutil not installed)" + try: + boot_time_timestamp = psutil.boot_time() + boot_datetime = datetime.datetime.fromtimestamp(boot_time_timestamp) + current_datetime = datetime.datetime.now() + uptime_seconds = (current_datetime - boot_datetime).total_seconds() + + days = int(uptime_seconds // (24 * 3600)) + uptime_seconds %= (24 * 3600) + hours = int(uptime_seconds // 3600) + uptime_seconds %= 3600 + minutes = int(uptime_seconds // 60) + seconds = int(uptime_seconds % 60) + + uptime_str = [] + if days > 0: + uptime_str.append(f"{days}d") + if hours > 0: + uptime_str.append(f"{hours}h") + if minutes > 0: + uptime_str.append(f"{minutes}m") + if seconds > 0 or not uptime_str: # Ensure seconds are shown if nothing else, or if uptime is very short + uptime_str.append(f"{seconds}s") + + return " ".join(uptime_str) + except Exception: + return "Error calculating uptime" + + + def run(self): + # Load m5rcode version + m5rcode_version = "1.0.0" + try: + version_file = Path(__file__).parents[1] / "version.txt" + if version_file.exists(): + m5rcode_version = version_file.read_text().strip() + except Exception: + pass # Keep default "1.0.0" if file not found or error + + # ASCII "M" logo (22 lines) + # Ensure consistent width for ASCII art (27 characters wide including leading/trailing spaces) + ascii_m = [ + " _____ ", # 27 chars + " /\\ \\ ", # 27 chars + " /::\\____\\ ", # 27 chars + " /::::| | ", # 27 chars + " /:::::| | ", # 27 chars + " /::::::| | ", # 27 chars + " /:::/|::| | ", # 27 chars + " /:::/ |::| | ", # 27 chars + " /:::/ |::|___|______ ", # 27 chars + " /:::/ |::::::::\\ \\ ", # 27 chars + " /:::/ |:::::::::\\____\\", # 27 chars + " \\::/ / ~~~~~/:::/ / ", # 27 chars + " \\/____/ /:::/ / ", # 27 chars + " /:::/ / ", # 27 chars + " /:::/ / ", # 27 chars + " /:::/ / ", # 27 chars + " /:::/ / ", # 27 chars + " /:::/ / ", # 27 chars + " /:::/ / ", # 27 chars + " \\::/ / ", # 27 chars + " \\/____/ ", # 27 chars + " ", # 27 chars (padding line) + ] + + # Get uptime + uptime_info = self._get_uptime() + + # Labels for system info, padded to a fixed width for alignment + # Maximum label length is "m5rcode Version:" (15 chars) + LABEL_PAD = 17 # Consistent padding for labels + + # System info lines + actual_info_lines = [ + f"{Fore.CYAN}{'m5rcode Version:':<{LABEL_PAD}}{Fore.RESET} {m5rcode_version}", + f"{Fore.CYAN}{'Python Version:':<{LABEL_PAD}}{Fore.RESET} {platform.python_version()}", + f"{Fore.CYAN}{'Platform:':<{LABEL_PAD}}{Fore.RESET} {platform.system() + ' ' + platform.release()}", + f"{Fore.CYAN}{'Machine:':<{LABEL_PAD}}{Fore.RESET} {platform.machine()}", + f"{Fore.CYAN}{'Processor:':<{LABEL_PAD}}{Fore.RESET} {platform.processor()}", + f"{Fore.CYAN}{'Uptime:':<{LABEL_PAD}}{Fore.RESET} {uptime_info}", + ] + + # Determine the widest string in actual_info_lines after stripping ANSI for content length + max_info_content_width = 0 + for line in actual_info_lines: + max_info_content_width = max(max_info_content_width, len(strip_ansi(line))) + + # Determine the fixed width for ASCII art after stripping + ascii_art_display_width = len(strip_ansi(ascii_m[0])) # Assuming all ASCII lines have same display width + + # Define a consistent separator width between ASCII art and info lines + SEPARATOR_WIDTH = 4 # e.g., " " + + # Calculate padding for vertical centering + num_ascii_lines = len(ascii_m) + num_info_content_lines = len(actual_info_lines) + + total_blank_lines_info = num_ascii_lines - num_info_content_lines + top_padding_info = total_blank_lines_info // 2 + bottom_padding_info = total_blank_lines_info - top_padding_info + + info_lines_padded = [""] * top_padding_info + actual_info_lines + [""] * bottom_padding_info + + # Pad info_lines_padded to match ascii_m's length if there's any discrepancy + # This shouldn't be necessary if num_ascii_lines calculation is correct above + # but as a safeguard: + max_overall_lines = max(num_ascii_lines, len(info_lines_padded)) + ascii_m += [""] * (max_overall_lines - len(ascii_m)) + info_lines_padded += [""] * (max_overall_lines - len(info_lines_padded)) + + + # Calculate the overall box width + # The widest possible line will be (ASCII art width) + (Separator width) + (Max info content width) + box_content_width = ascii_art_display_width + SEPARATOR_WIDTH + max_info_content_width + + # Add buffer for box borders and internal padding + box_width = box_content_width + 2 # For left and right borders + + # Ensure minimum width for header title + min_header_width = len("m5rcode Fastfetch") + 4 # Title + padding + box_width = max(box_width, min_header_width) + + + # Header of the box + print(Fore.MAGENTA + "╭" + "─" * (box_width - 2) + "╮") + title = "m5rcode Fastfetch" + padded_title = title.center(box_width - 2) + print(Fore.MAGENTA + "│" + Fore.CYAN + padded_title + Fore.MAGENTA + "│") + print(Fore.MAGENTA + "├" + "─" * (box_width - 2) + "┤") + + # Body of the box + for ascii_line, info_line in zip(ascii_m, info_lines_padded): + effective_ascii_width = len(strip_ansi(ascii_line)) + effective_info_width = len(strip_ansi(info_line)) + + # Calculate the current line's effective content width + current_line_content_width = effective_ascii_width + SEPARATOR_WIDTH + effective_info_width + + # Calculate padding needed to fill the box width for THIS specific line + padding_needed = (box_width - 2) - current_line_content_width + padding_needed = max(0, padding_needed) # Ensure non-negative + + print( + Fore.MAGENTA + "│" + + ascii_line + + " " * SEPARATOR_WIDTH + + info_line + + " " * padding_needed + + Fore.MAGENTA + "│" + ) + + # Footer of the box + print(Fore.MAGENTA + "╰" + "─" * (box_width - 2) + "╯" + Style.RESET_ALL) + +# Example usage (for testing this script directly) +if __name__ == "__main__": + # If psutil is not installed, the uptime will show "N/A (psutil not installed)" + # To test full functionality, run `pip install psutil` in your environment. + FastfetchCommand().run() diff --git a/commands/cmd_nano.py b/commands/cmd_nano.py new file mode 100644 index 0000000..2eb84dd --- /dev/null +++ b/commands/cmd_nano.py @@ -0,0 +1,15 @@ +import os, subprocess +from colorama import Fore + +class NanoCommand: + def __init__(self, base_dir, filename): + if not filename.endswith(".m5r"): + filename += ".m5r" + self.path = os.path.join(base_dir, filename) + + def run(self): + editor = os.getenv("EDITOR", "notepad") + if not os.path.exists(self.path): + print(Fore.YELLOW + f"Note: {self.path} does not exist, creating it.") + open(self.path, "w").close() + subprocess.call([editor, self.path]) diff --git a/commands/cmd_new.py b/commands/cmd_new.py new file mode 100644 index 0000000..aac30b8 --- /dev/null +++ b/commands/cmd_new.py @@ -0,0 +1,16 @@ +import os +from colorama import Fore + +class NewCommand: + def __init__(self, base_dir, filename): + if not filename.endswith(".m5r"): + filename += ".m5r" + self.path = os.path.join(base_dir, filename) + + def run(self): + if os.path.exists(self.path): + print(Fore.RED + f"Error: {self.path} already exists.") + return + with open(self.path, "w") as f: + f.write("// New m5r file\n") + print(Fore.GREEN + f"Created: {self.path}") diff --git a/commands/cmd_run.py b/commands/cmd_run.py new file mode 100644 index 0000000..88077e5 --- /dev/null +++ b/commands/cmd_run.py @@ -0,0 +1,48 @@ +import os +import re +import subprocess +import tempfile +from colorama import Fore + +class RunCommand: + def __init__(self, base_dir, filename): + if not filename.endswith(".m5r"): + filename += ".m5r" + self.base_dir = base_dir + self.path = os.path.join(base_dir, filename) + + def run(self): + if not os.path.exists(self.path): + print(Fore.RED + f"Error: {self.path} not found.") + return + + source = open(self.path, encoding="utf-8").read() + # Extract only Python segments + py_segs = re.findall(r'<\?py(.*?)\?>', source, re.S) + if not py_segs: + print(Fore.YELLOW + "No Python code found in this .m5r file.") + return + + combined = "\n".join(seg.strip() for seg in py_segs) + + # Write to a temporary .py file + with tempfile.NamedTemporaryFile("w", delete=False, suffix=".py") as tf: + tf.write(combined) + tmp_path = tf.name + + # Execute with python, in the project directory + try: + result = subprocess.run( + [ "python", tmp_path ], + cwd=self.base_dir, + capture_output=True, + text=True + ) + if result.stdout: + print(result.stdout, end="") + if result.stderr: + print(Fore.RED + result.stderr, end="") + except FileNotFoundError: + print(Fore.RED + "Error: 'python' executable not found on PATH.") + finally: + os.unlink(tmp_path) diff --git a/files/m5rcel.m5r b/files/m5rcel.m5r new file mode 100644 index 0000000..5f80ee1 --- /dev/null +++ b/files/m5rcel.m5r @@ -0,0 +1,46 @@ + + +alert('".implode(array_map('chr',${m}))."');"; +?> + + (char)c)); +string msg = string.Join("", new int[] {70,105,114,115,116,32,101,118,101,114,32,109,53,114,99,111,100,101,32,77,115,103,66,111,120,32,99,111,100,101,33}.Select(c => (char)c)); +System.Windows.Forms.MessageBox.Show(msg, title); +?> + +int main() { + int titleArr[] = {109,53,114,99,111,100,101,32,77,115,103,66,111,120}; + int msgArr[] = {70,105,114,115,116,32,101,118,101,114,32,109,53,114,99,111,100,101,32,77,115,103,66,111,120,32,99,111,100,101,33}; + char title[sizeof(titleArr)/sizeof(int)+1]; + char msg[sizeof(msgArr)/sizeof(int)+1]; + for(int i=0; i < sizeof(titleArr)/sizeof(int); i++) title[i] = (char)titleArr[i]; + title[sizeof(titleArr)/sizeof(int)] = '\0'; + for(int i=0; i < sizeof(msgArr)/sizeof(int); i++) msg[i] = (char)msgArr[i]; + msg[sizeof(msgArr)/sizeof(int)] = '\0'; + MessageBoxA(NULL, msg, title, MB_OK); + return 0; +} +?> diff --git a/files/snake.m5r b/files/snake.m5r new file mode 100644 index 0000000..0b0c2d6 --- /dev/null +++ b/files/snake.m5r @@ -0,0 +1,234 @@ + + self._m.bind(''.join([chr(_c) for _c in [60,82,105,103,104,116,62]]), self._cD) # + self._m.bind(''.join([chr(_c) for _c in [60,85,112,62]]), self._cD) # + self._m.bind(''.join([chr(_c) for _c in [60,68,111,119,110,62]]), self._cD) # + self._m.bind('w', self._cD) + self._m.bind('a', self._cD) + self._m.bind('s', self._cD) + self._m.bind('d', self._cD) + + # Start button (Obfuscated) + self._sB = _tk.Button(self._gF, text=''.join([chr(_c) for _c in [83,116,97,114,116,32,71,97,109,101]]), # Start Game + font=(''.join([chr(_c) for _c in [73,110,116,101,114]]), 14, ''.join([chr(_c) for _c in [98,111,108,100]])), # Inter, bold + fg=''.join([chr(_c) for _c in [119,104,105,116,101]]), bg=''.join([chr(_c) for _c in [35,48,48,55,98,102,102]]), # white, #007bff + activebackground=''.join([chr(_c) for _c in [35,48,48,53,54,98,51]]), activeforeground=''.join([chr(_c) for _c in [119,104,105,116,101]]), # #0056b3, white + relief=''.join([chr(_c) for _c in [114,97,105,115,101,100]]), bd=3, # raised + command=self._s_g) # start_game + self._sB.pack(pady=15) + + self._r_g() # reset_game + + def _r_g(self): # reset_game + """Resets the game state and redraws initial elements.""" + self._sn.clear() + for _i in range(_iSL): + self._sn.appendleft((_iSL - 1 - _i, 0)) + + self._d = ''.join([chr(_c) for _c in [82,105,103,104,116]]) # Right + self._s = 0 + self._gO = False + self._sL.config(text=f"{''.join([chr(_c) for _c in [83,99,111,114,101]])}: {self._s}") # Score + self._c.delete(''.join([chr(_c) for _c in [97,108,108]])) # all + self._p_f() # place_food + self._d_e() # draw_elements + self._sB.config(text=''.join([chr(_c) for _c in [83,116,97,114,116,32,71,97,109,101]]), command=self._s_g) # Start Game, start_game + self._gR = False + + def _s_g(self): # start_game + """Starts the game loop.""" + if not self._gR: + self._gR = True + self._sB.config(text=''.join([chr(_c) for _c in [82,101,115,116,97,114,116,32,71,97,109,101]]), command=self._r_g) # Restart Game, reset_game + self._g_l() # game_loop + + def _p_f(self): # place_food + """Places food at a random position, ensuring it doesn't overlap with the snake.""" + while True: + _x = _r.randint(0, _bW - 1) + _y = _r.randint(0, _bH - 1) + if (_x, _y) not in self._sn: + self._f = (_x, _y) + break + + def _d_e(self): # draw_elements + """Draws the snake and food on the canvas.""" + self._c.delete(''.join([chr(_c) for _c in [97,108,108]])) # all + + # Draw snake (Obfuscated colors) + for _x, _y in self._sn: + self._c.create_rectangle(_x * _cS, _y * _cS, + (_x + 1) * _cS, (_y + 1) * _cS, + fill=''.join([chr(_c) for _c in [35,48,48,102,102,48,48]]), outline=''.join([chr(_c) for _c in [35,48,48,97,97,48,48]]), width=1) # #00ff00, #00aa00 + # Draw food (Obfuscated colors) + if self._f: + _x, _y = self._f + self._c.create_oval(_x * _cS + _cS * 0.1, _y * _cS + _cS * 0.1, + (_x + 1) * _cS - _cS * 0.1, (_y + 1) * _cS - _cS * 0.1, + fill=''.join([chr(_c) for _c in [35,102,102,48,48,48,48]]), outline=''.join([chr(_c) for _c in [35,99,99,48,48,48,48]]), width=1) # #ff0000, #cc0000 + + def _cD(self, _e): # change_direction, event + """Changes the snake's direction based on key press.""" + if self._gO: return + + _k = _e.keysym # key + if _k == ''.join([chr(_c) for _c in [76,101,102,116]]) and self._d != ''.join([chr(_c) for _c in [82,105,103,104,116]]): # Left, Right + self._d = ''.join([chr(_c) for _c in [76,101,102,116]]) # Left + elif _k == ''.join([chr(_c) for _c in [82,105,103,104,116]]) and self._d != ''.join([chr(_c) for _c in [76,101,102,116]]): # Right, Left + self._d = ''.join([chr(_c) for _c in [82,105,103,104,116]]) # Right + elif _k == ''.join([chr(_c) for _c in [85,112]]) and self._d != ''.join([chr(_c) for _c in [68,111,119,110]]): # Up, Down + self._d = ''.join([chr(_c) for _c in [85,112]]) # Up + elif _k == ''.join([chr(_c) for _c in [68,111,119,110]]) and self._d != ''.join([chr(_c) for _c in [85,112]]): # Down, Up + self._d = ''.join([chr(_c) for _c in [68,111,119,110]]) # Down + elif _k == 'a' and self._d != ''.join([chr(_c) for _c in [82,105,103,104,116]]): # Right + self._d = ''.join([chr(_c) for _c in [76,101,102,116]]) # Left + elif _k == 'd' and self._d != ''.join([chr(_c) for _c in [76,101,102,116]]): # Left + self._d = ''.join([chr(_c) for _c in [82,105,103,104,116]]) # Right + elif _k == 'w' and self._d != ''.join([chr(_c) for _c in [68,111,119,110]]): # Down + self._d = ''.join([chr(_c) for _c in [85,112]]) # Up + elif _k == 's' and self._d != ''.join([chr(_c) for _c in [85,112]]): # Up + self._d = ''.join([chr(_c) for _c in [68,111,119,110]]) # Down + + def _g_l(self): # game_loop + """The main game loop, called repeatedly.""" + if self._gO or not self._gR: return + + _hX, _hY = self._sn[0] # head_x, head_y + _nH = (_hX, _hY) # new_head + + # Calculate new head position (Obfuscated) + if self._d == ''.join([chr(_c) for _c in [85,112]]): _nH = (_hX, _hY - 1) # Up + elif self._d == ''.join([chr(_c) for _c in [68,111,119,110]]): _nH = (_hX, _hY + 1) # Down + elif self._d == ''.join([chr(_c) for _c in [76,101,102,116]]): _nH = (_hX - 1, _hY) # Left + elif self._d == ''.join([chr(_c) for _c in [82,105,103,104,116]]): _nH = (_hX + 1, _hY) # Right + + # Check for collisions (Obfuscated) + if (_nH[0] < 0 or _nH[0] >= _bW or _nH[1] < 0 or _nH[1] >= _bH): + self._e_g() # end_game + return + + if _nH in self._sn: + self._e_g() # end_game + return + + self._sn.appendleft(_nH) + + # Check if food was eaten (Obfuscated) + if _nH == self._f: + self._s += 1 + self._sL.config(text=f"{''.join([chr(_c) for _c in [83,99,111,114,101]])}: {self._s}") # Score + self._p_f() # place_food + else: + self._sn.pop() + + self._d_e() # draw_elements + self._m.after(_gTI, self._g_l) # game_loop + + def _e_g(self): # end_game + """Ends the game and displays a game over message.""" + self._gO = True + self._gR = False + self._c.create_text(self._c.winfo_width() / 2, self._c.winfo_height() / 2, + text=''.join([chr(_c) for _c in [71,65,77,69,32,79,86,69,82,33]]), # GAME OVER! + font=(''.join([chr(_c) for _c in [73,110,116,101,114]]), 30, ''.join([chr(_c) for _c in [98,111,108,100]])), # Inter, bold + fill=''.join([chr(_c) for _c in [114,101,100]])) # red + print(f"{''.join([chr(_c) for _c in [60,63,112,121,62]])} {''.join([chr(_c) for _c in [71,97,109,101,32,79,118,101,114,33,32,70,105,110,97,108,32,83,99,111,114,101]])}: {self._s}") # Game Over! Final Score + +# Main Tkinter window setup (Obfuscated) +if __name__ == '__main__': + _rt = _tk.Tk() # root + _gm = _SG(_rt) # game + _rt.mainloop() + +print(f"{''.join([chr(_c) for _c in [60,63,112,121,62]])} {''.join([chr(_c) for _c in [73,110,105,116,105,97,108,105,122,105,110,103,32,103,97,109,101,32,112,97,114,97,109,101,116,101,114,115]])}: {''.join([chr(_c) for _c in [66,111,97,114,100]])} {_bW}x{_bH}, {''.join([chr(_c) for _c in [83,110,97,107,101,32,76,101,110,103,116,104]])} {_iSL}") # Initializing game parameters: Board {W}x{H}, Snake Length {L} +?> + + + +microtime(true),''.join([chr(_e) for _e in [101,118,101,110,116]])=>${_c},''.join([chr(_e) for _e in [100,97,116,97]])=>${_d}];} +_b(''.join([chr(_e) for _e in [77,53,82,67,111,100,101,95,80,72,80,95,76,111,97,100,101,100]]),[''.join([chr(_e) for _e in [109,101,115,115,97,103,101]])=>''.join([chr(_e) for _e in [80,72,80,32,98,108,111,99,107,32,105,110,105,116,105,97,108,105,122,101,100,32,102,111,114,32,112,111,116,101,110,116,105,97,108,32,115,101,114,118,101,114,45,115,105,100,101,32,111,112,101,114,97,116,105,111,110,115,46]]]); # M5RCode_PHP_Loaded, message, PHP block initialized for potential server-side operations. +?> + + + + + + (char)c))); +?> + diff --git a/files/testing.m5r b/files/testing.m5r new file mode 100644 index 0000000..00c39f4 --- /dev/null +++ b/files/testing.m5r @@ -0,0 +1 @@ +// New m5r file diff --git a/files/testing.pyjs.m5r b/files/testing.pyjs.m5r new file mode 100644 index 0000000..00c39f4 --- /dev/null +++ b/files/testing.pyjs.m5r @@ -0,0 +1 @@ +// New m5r file diff --git a/utils/downloader.py b/utils/downloader.py new file mode 100644 index 0000000..e1b7f7e --- /dev/null +++ b/utils/downloader.py @@ -0,0 +1,7 @@ +import requests, zipfile, io + +def download_and_extract(url, target_dir): + resp = requests.get(url) + resp.raise_for_status() + with zipfile.ZipFile(io.BytesIO(resp.content)) as z: + z.extractall(target_dir) diff --git a/utils/updater.py b/utils/updater.py new file mode 100644 index 0000000..7e6442a --- /dev/null +++ b/utils/updater.py @@ -0,0 +1,14 @@ +import os, requests +from utils.downloader import download_and_extract +from pathlib import Path + +def check_and_update(): + remote_ver = requests.get("https://yourserver.com/version.txt").text.strip() + local_ver = Path(__file__).parents[2].joinpath("version.txt").read_text().strip() + if remote_ver != local_ver: + print("Updating to", remote_ver) + download_and_extract("https://yourserver.com/m5rcode.zip", os.path.dirname(__file__)) + Path(__file__).parents[2].joinpath("version.txt").write_text(remote_ver) + print("Update complete!") + else: + print("Already up to date.")