MiLoader open source
GioWolffrom mcstatus.server import JavaServer
import tkinter as tk
from tkinter import filedialog, messagebox
import re
import base64
from io import BytesIO
from PIL import Image
def parse_motd(motd_data):
"""
Converts MOTD to a string, including color codes and gradients.
"""
if isinstance(motd_data, str):
return motd_data # If it's a string, return it as is.
elif isinstance(motd_data, dict):
# If it's a dictionary, process 'text' and 'extra'.
text = motd_data.get("text", "")
extra = motd_data.get("extra", [])
for part in extra:
text += part.get("text", "")
return text
return ""
def get_motd_with_colors(motd_raw):
"""
Converts color codes to & symbols or retains HEX codes.
"""
# Replacement of standard color codes
color_codes = {
"§0": "&0", "§1": "&1", "§2": "&2", "§3": "&3",
"§4": "&4", "§5": "&5", "§6": "&6", "§7": "&7",
"§8": "&8", "§9": "&9", "§a": "&a", "§b": "&b",
"§c": "&c", "§d": "&d", "§e": "&e", "§f": "&f",
"§k": "&k", "§l": "&l", "§m": "&m", "§n": "&n", "§o": "&o", "§r": "&r"
}
hex_pattern = r"§#[a-fA-F0-9]{6}" # HEX color codes
def replace_color(match):
code = match.group(0)
if code in color_codes:
return color_codes[code]
elif re.match(hex_pattern, code):
return code.replace("§", "&") # Replace HEX with the format &#rrggbb
return code
return re.sub(f"({'|'.join(color_codes.keys())}|{hex_pattern})", replace_color, motd_raw)
def fetch_motds(ip):
"""
Fetches MOTD from the server.
"""
try:
server = JavaServer.lookup(ip)
status = server.status()
motd_data = status.description # Fetch MOTD as data
motd_raw = parse_motd(motd_data) # Convert to string
motd_with_colors = get_motd_with_colors(motd_raw)
return [motd_with_colors]
except Exception as e:
return [f"Error: {e}"]
def save_motd_file(ip):
"""
Fetches MOTD and saves it to a text file.
"""
motds = fetch_motds(ip)
if not motds or "Error" in motds[0]:
messagebox.showerror("Error", motds[0] if motds else "Failed to fetch MOTD.")
return
file_path = filedialog.asksaveasfilename(
title="Save MOTD as",
defaultextension=".txt",
filetypes=[("Text Files", "*.txt")]
)
if file_path:
with open(file_path, "w", encoding="utf-8") as file:
for idx, motd in enumerate(motds, start=1):
file.write(f"MOTD {idx}:\n{motd}\n\n")
messagebox.showinfo("Done", "MOTD saved successfully!")
def save_server_icon(ip):
"""
Fetches the server icon and saves it as a PNG file.
"""
try:
server = JavaServer.lookup(ip)
status = server.status()
if status.icon: # Use the icon attribute instead of favicon
# Decode the base64 icon string
icon_data = status.icon.split(",")[1]
icon_bytes = base64.b64decode(icon_data)
icon = Image.open(BytesIO(icon_bytes))
# Ask the user where to save the icon
file_path = filedialog.asksaveasfilename(
title="Save Server Icon",
defaultextension=".png",
filetypes=[("PNG Image", "*.png")]
)
if file_path:
icon.save(file_path, "PNG")
messagebox.showinfo("Done", "Server icon saved successfully!")
else:
messagebox.showerror("Error", "No server icon found.")
except Exception as e:
messagebox.showerror("Error", f"Failed to fetch server icon: {e}")
# GUI creation
def main():
root = tk.Tk()
root.title("MiLoader by GioWolf")
root.geometry("400x250")
root.configure(bg="#2b2b2b")
root.resizable(False, False) # Make the window fixed size
# Get the screen width and height
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
# Calculate the position to center the window
window_width = 400
window_height = 250
position_top = int((screen_height - window_height) / 2)
position_left = int((screen_width - window_width) / 2)
# Set the window's position
root.geometry(f'{window_width}x{window_height}+{position_left}+{position_top}')
# Input field for IP
tk.Label(root, text="Minecraft Server IP:", fg="white", bg="#2b2b2b", font=("Arial", 12)).pack(pady=10)
ip_entry = tk.Entry(root, width=30, font=("Arial", 14))
ip_entry.pack(pady=5)
# Button to fetch MOTD
def on_fetch_motd():
ip = ip_entry.get().strip()
if not ip:
messagebox.showerror("Error", "Please enter the server IP.")
return
save_motd_file(ip)
# Button to fetch the server icon
def on_fetch_icon():
ip = ip_entry.get().strip()
if not ip:
messagebox.showerror("Error", "Please enter the server IP.")
return
save_server_icon(ip)
# Wider buttons with fixed width
tk.Button(
root,
text="Download MOTD",
command=on_fetch_motd,
bg="#4CAF50",
fg="white",
font=("Arial", 12),
activebackground="#45a049",
width=20
).pack(pady=10)
tk.Button(
root,
text="Download ICON",
command=on_fetch_icon,
bg="#2196F3",
fg="white",
font=("Arial", 12),
activebackground="#1E88E5",
width=20
).pack(pady=10)
root.mainloop()
if __name__ == "__main__":
main()