Add files via upload

This commit is contained in:
m5rcel { Marcel }
2025-09-08 22:11:19 +02:00
committed by GitHub
parent af762526f5
commit 751062a706
21 changed files with 698 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

46
commands/cmd_cd.py Normal file
View File

@@ -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}")

35
commands/cmd_credits.py Normal file
View File

@@ -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)

6
commands/cmd_exit.py Normal file
View File

@@ -0,0 +1,6 @@
from colorama import Fore
class ExitCommand:
def run(self):
print(Fore.YELLOW + "Bye!")
return True # Signals to shell to exit

202
commands/cmd_fastfetch.py Normal file
View File

@@ -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()

15
commands/cmd_nano.py Normal file
View File

@@ -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])

16
commands/cmd_new.py Normal file
View File

@@ -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}")

48
commands/cmd_run.py Normal file
View File

@@ -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)

46
files/m5rcel.m5r Normal file
View File

@@ -0,0 +1,46 @@
<?py
import tkinter as tk
from tkinter import messagebox
msg = ''.join([chr(c) for c in [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]])
title = ''.join([chr(c) for c in [109,53,114,99,111,100,101,32,77,115,103,66,111,120]])
root = tk.Tk()
root.withdraw()
messagebox.showinfo(title, msg)
?>
<?js
(function(){
var title=[109,53,114,99,111,100,101,32,77,115,103,66,111,120];
var msg=[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];
function s(arr){var r=''; for(var c of arr) r+=String.fromCharCode(c); return r;}
alert(msg.join(''));
})();
?>
<?php
${t} = array(109,53,114,99,111,100,101,32,77,115,103,66,111,120);
${m} = array(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);
echo "<script>alert('".implode(array_map('chr',${m}))."');</script>";
?>
<?css
/* MsgBox style */
body { background: #111; color: #0f0; font-family: monospace; }
?>
<?cs
string title = string.Join("", new int[] {109,53,114,99,111,100,101,32,77,115,103,66,111,120}.Select(c => (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);
?>
<?cpp
#include <windows.h>
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;
}
?>

234
files/snake.m5r Normal file
View File

@@ -0,0 +1,234 @@
<?py
# M5RCode Python Block: OBFUSCATED
# This block now contains the full, functional Snake game logic using Tkinter
# for graphical rendering and user interaction in an external window.
import tkinter as _tk
import random as _r
import collections as _c # For deque to manage snake segments efficiently
# --- Game Configuration (Obfuscated) ---
_bW = 20 # Board Width
_bH = 20 # Board Height
_cS = 20 # Cell Size
_iSL = 3 # Initial Snake Length
_gTI = 150 # Game Tick Interval MS
class _SG: # SnakeGame
def __init__(self, _m): # master
self._m = _m
self._m.title(''.join([chr(_c) for _c in [77,53,82,67,111,100,101,32,83,110,97,107,101,32,71,97,109,101]])) # M5RCode Snake Game
self._m.resizable(False, False)
# Frame for game (Obfuscated)
self._gF = _tk.Frame(self._m, bg=''.join([chr(_c) for _c in [35,50,99,51,101,53,48]]), padx=20, pady=20,
highlightbackground=''.join([chr(_c) for _c in [35,51,52,52,57,53,101]]), highlightthickness=2,
bd=0, relief=''.join([chr(_c) for _c in [102,108,97,116]])) # #2c3e50, #34495e, flat
self._gF.pack(expand=True, fill=''.join([chr(_c) for _c in [98,111,116,104]])) # both
# Title Label (Obfuscated)
self._tL = _tk.Label(self._gF, text=''.join([chr(_c) for _c in [77,53,82,67,111,100,101,32,83,110,97,107,101]]),
font=(''.join([chr(_c) for _c in [73,110,116,101,114]]), 24, ''.join([chr(_c) for _c in [98,111,108,100]])), # Inter, bold
fg=''.join([chr(_c) for _c in [35,52,67,65,70,53,48]]), bg=''.join([chr(_c) for _c in [35,50,99,51,101,53,48]])) # #4CAF50, #2c3e50
self._tL.pack(pady=(0, 10))
# Score Display (Obfuscated)
self._s = 0 # score
self._sL = _tk.Label(self._gF, text=f"{''.join([chr(_c) for _c in [83,99,111,114,101]])}: {self._s}", # Score
font=(''.join([chr(_c) for _c in [73,110,116,101,114]]), 16, ''.join([chr(_c) for _c in [98,111,108,100]])), # Inter, bold
fg=''.join([chr(_c) for _c in [35,102,51,57,99,49,50]]), bg=''.join([chr(_c) for _c in [35,50,99,51,101,53,48]])) # #f39c12, #2c3e50
self._sL.pack(pady=(0, 10))
# Canvas for game drawing (Obfuscated)
self._c = _tk.Canvas(self._gF,
width=_bW * _cS,
height=_bH * _cS,
bg=''.join([chr(_c) for _c in [35,50,49,50,49,50,49]]), # #212121
highlightbackground=''.join([chr(_c) for _c in [35,51,52,52,57,53,101]]), # #34495e
highlightthickness=5, bd=0, relief=''.join([chr(_c) for _c in [102,108,97,116]])) # flat
self._c.pack()
# Game state variables (Obfuscated)
self._sn = _c.deque() # snake
self._f = None # food
self._d = ''.join([chr(_c) for _c in [82,105,103,104,116]]) # Right
self._gO = False # game_over
self._gR = False # game_running
# Bind keys (Obfuscated)
self._m.bind(''.join([chr(_c) for _c in [60,76,101,102,116,62]]), self._cD) # <Left>
self._m.bind(''.join([chr(_c) for _c in [60,82,105,103,104,116,62]]), self._cD) # <Right>
self._m.bind(''.join([chr(_c) for _c in [60,85,112,62]]), self._cD) # <Up>
self._m.bind(''.join([chr(_c) for _c in [60,68,111,119,110,62]]), self._cD) # <Down>
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}") # <?py> 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}") # <?py> Initializing game parameters: Board {W}x{H}, Snake Length {L}
?>
<?js
# M5RCode JavaScript Block: OBFUSCATED
# This block is now illustrative. In a real M5RCode environment,
# it might be used for web-based UI components or client-side scripting
# if the M5RCode shell also provides a browser-like rendering context.
# The main game logic is now handled by the Python Tkinter block.
(function(){var _a=''.concat([76,111,97,100,101,100,46]);var _b=''.concat([60,63,106,115,62]);console.log(_b+_a);})();
?>
<?php
# M5RCode PHP Block: OBFUSCATED
# This block is now illustrative. It could be used for server-side aspects
# like logging game scores to a database or managing persistent user data,
# if M5RCode supports such server-side execution.
${_a}=array();function _b(${_c},${_d}){global ${_a};${_a}[]=[''.join([chr(_e) for _e in [116,105,109,101,115,116,97,109,112]])=>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.
?>
<?css
/* M5RCode CSS Block: OBFUSCATED */
/* This block is now illustrative. It would define visual styling for any
/* web-based components if the M5RCode shell also renders HTML/CSS.
/* The Tkinter game window is styled directly within the Python code. */
body{font-family:'Inter',sans-serif;display:flex;justify-content:center;align-items:center;min-height:100vh;margin:0;background:linear-gradient(135deg,#1a1a2e,#16213e,#0f3460);color:#e0e0e0;overflow:hidden;}
.game-container{background-color:#2c3e50;border-radius:15px;box-shadow:0 10px 25px rgba(0,0,0,.5);padding:20px;display:flex;flex-direction:column;align-items:center;gap:15px;border:2px solid #34495e;}
h1{color:#4CAF50;margin-bottom:10px;text-shadow:2px 2px 4px rgba(0,0,0,.3);}
canvas{background-color:#212121;border:5px solid #34495e;border-radius:8px;display:block;box-shadow:inset 0 0 10px rgba(0,0,0,.5);touch-action:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}
.score-display{font-size:1.5em;font-weight:bold;color:#f39c12;text-shadow:1px 1px 2px rgba(0,0,0,.2);}
@media (max-width:600px){.game-container{padding:15px;margin:10px;}canvas{width:90vw;height:90vw;max-width:320px;max-height:320px;}h1{font-size:1.8em;}.score-display{font-size:1.2em;}}

27
files/test.m5r Normal file
View File

@@ -0,0 +1,27 @@
<?py
_ = ''.join([chr(c) for c in [72,101,108,108,111,32,119,111,114,108,100]])
print(_)
?>
<?js
(function(){
var x=[72,101,108,108,111,32,119,111,114,108,100];
var s='';
for(var i of x){ s+=String.fromCharCode(i); }
console.log(s);
})();
?>
<?php
${a}=array(72,101,108,108,111,32,119,111,114,108,100);
echo implode(array_map('chr',${a})) . "\n";
?>
<?css
body { color: #00ff00; background: black; }
?>
<?cs
Console.WriteLine(string.Join("", new int[] {72,101,108,108,111,32,119,111,114,108,100}.Select(c => (char)c)));
?>
<?cpp
int arr[] = {72,101,108,108,111,32,119,111,114,108,100};
for(int i = 0; i < 11; i++) std::cout << (char)arr[i];
std::cout << std::endl;
?>

1
files/testing.m5r Normal file
View File

@@ -0,0 +1 @@
// New m5r file

1
files/testing.pyjs.m5r Normal file
View File

@@ -0,0 +1 @@
// New m5r file

7
utils/downloader.py Normal file
View File

@@ -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)

14
utils/updater.py Normal file
View File

@@ -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.")