diff --git a/ResourceManager.py b/ResourceManager.py new file mode 100644 index 0000000..a7984fa --- /dev/null +++ b/ResourceManager.py @@ -0,0 +1,11 @@ +from PIL import ImageTk, Image +import os +import sys + +def resource_path(relative_path): + base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__))) + return os.path.join(base_path, relative_path) + +def get_image_and_resize(path_to_image, width, height): + image = Image.open(resource_path(path_to_image)).resize((width, height)) + return ImageTk.PhotoImage(image) diff --git a/UserData.py b/UserData.py new file mode 100644 index 0000000..1668b5c --- /dev/null +++ b/UserData.py @@ -0,0 +1,25 @@ +import os +import json +import appdirs + +app_name = 'FinnWarsLauncher' +author_name = 'NikkeDoy, NuffMan' +default_server_address = "23.88.63.235:14572" +default_username = "FinnWarsLauncher" +default_windowed = False + +def save_preferences(data): + config_dir = appdirs.user_config_dir(app_name, author_name) + os.makedirs(config_dir, exist_ok=True) + file_path = os.path.join(config_dir, 'config.json') + with open(file_path, 'w') as f: + json.dump(data, f) + +def get_preferences(): + config_dir = appdirs.user_config_dir(app_name, author_name) + file_path = os.path.join(config_dir, 'config.json') + if(os.path.isfile(file_path)): + with open(file_path, 'r') as f: + return json.load(f) + else: + return {"server": default_server_address, "username": default_username, "windowed": default_windowed} diff --git a/assets/icon.ico b/assets/icon.ico new file mode 100644 index 0000000..0cf553d Binary files /dev/null and b/assets/icon.ico differ diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 0000000..63df4a5 Binary files /dev/null and b/assets/icon.png differ diff --git a/main.py b/main.py index 11a0912..2a1713b 100644 --- a/main.py +++ b/main.py @@ -1,38 +1,36 @@ from tkinter import * -from PIL import ImageTk, Image -import time import re -import userdata -import asyncio import subprocess -import os -import sys +import pyautogui -def resource_path(relative_path): - base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__))) - return os.path.join(base_path, relative_path) +import UserData +import ResourceManager def save_preferences(): - userdata.save_preferences({"server": server_address_field.get(), "username": username_field.get()}) + UserData.save_preferences({"server": server_address_field.get(), "username": username_field.get(), "windowed": windowed.get()}) save_preferences_button.config(state=DISABLED, text="Saved!") root.after(5000, lambda: save_preferences_button.config(state=NORMAL, text="Save")) def launch_exe(): - # Check for valid server address (Currently only supports numerical addresses (not domains)) + # Check for valid server address (Currently only supports numerical addresses (not domains.)) if not validate_server_address(server_address_field.get()): print(f"Invalid address \"{server_address_field.get()}\", please use a proper one...") server_address_field.delete(0, END) - server_address_field.insert(0, userdata.default_server_address) + server_address_field.insert(0, UserData.default_server_address) return + # Validate username by checking if username length is reasonable. if not validate_username(username_field.get()): print(f"Username \"{username_field.get()}\" is too long, please use a shorter one...") username_field.delete(0, END) - username_field.insert(0, userdata.default_username) + username_field.insert(0, UserData.default_username) return - print("IP Address: " + server_address_field.get()) - print("Username: " + username_field.get()) + # If game needs to be windowed then we use BF42Plus provided "workaround." + if windowed.get(): + pyautogui.keyDown("shift") + root.after(5000, lambda: pyautogui.keyUp("shift")) + subprocess.call([ "./Battlefield 1942/Battlefield 1942/BF1942.exe", "+game", "FinnWars", @@ -61,7 +59,7 @@ def validate_server_address(server_address): def validate_username(username): return len(username) <= 16 -preferences = userdata.get_preferences() +preferences = UserData.get_preferences() # Create the main window root = Tk() @@ -75,12 +73,12 @@ window_width = int(720*scaling) window_height = int(360*scaling) root.geometry(str(window_width) + "x" + str(window_height)) -# Background image scaled correctly -image = Image.open(resource_path("assets/background.png")) -resized_image = image.resize((window_width, window_height)) -photo = ImageTk.PhotoImage(resized_image) +window_icon = ResourceManager.get_image_and_resize("assets/icon.png", 128, 128) +root.wm_iconphoto(False, window_icon) -background_label = Label(root, image=photo) +background_image = ResourceManager.get_image_and_resize("assets/background.png", window_width, window_height) + +background_label = Label(root, image=background_image) background_label.pack(fill=BOTH, expand = YES) # Create the text fields @@ -91,6 +89,10 @@ server_address_label = Label(root, text="Server Address:", font=font, fg="black" server_address_field = Entry(root, font=font, width=box_width) username_label = Label(root, text="Username:", font=font, fg="black", width=box_width) username_field = Entry(root, font=font, width=box_width) +windowed = BooleanVar() +windowed.set(preferences["windowed"]) +settings_label = Label(root, text="Settings", font=font, fg="black", width=int(window_width/11.3)) +windowed_checkbutton = Checkbutton(root, text="Windowed", variable=windowed, font=font, width=int(window_width/26)) if "server" in preferences: server_address_field.insert(0, preferences["server"]) @@ -108,28 +110,18 @@ button_width = int(window_width/48) save_preferences_button = Button(root, text="Save", command=save_preferences, width=button_width) launch_game = Button(root, text="Launch", command=launch_exe, width=button_width) -menu_bar = Menu(root) -root.config(menu=menu_bar) - -file_menu = Menu(root, tearoff=0) -file_menu.add_command(label="Settings") -file_menu.add_command(label="Exit", command=root.quit) -menu_bar.add_cascade(label="File", menu=file_menu) # Place the widgets on the window server_address_label.place(x=window_width/72, y=window_height/36) server_address_field.place(x=window_width/72, y=int(window_height/7.2)) username_label.place(x=int(window_width/1.95), y=window_height/36) username_field.place(x=int(window_width/1.95), y=int(window_height/7.2)) + +settings_label.place(x=int(window_width/72), y=int(window_height/3.2)) +windowed_checkbutton.place(x=int(window_width/72), y=int(window_height/2.4)) + save_preferences_button.place(x=int(window_width/2.4), y=int(window_height/1.16)) launch_game.place(x=int(window_width/1.4), y=int(window_height/1.16)) -#server_address_label.place(x=10, y=20) -#server_address_field.place(x=10, y=50) -#username_label.place(x=370, y=20) -#username_field.place(x=370, y=50) -#save_preferences_button.place(x=300, y=310) -#launch_game.place(x=510, y=310) - # Start the main event loop root.mainloop() diff --git a/requirements.txt b/requirements.txt index 2794044..7556be2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,20 @@ altgraph==0.17.4 appdirs==1.4.4 asyncio==3.4.3 +MouseInfo==0.1.3 packaging==24.2 pillow==11.0.0 pyasn1==0.6.1 +PyAutoGUI==0.9.54 +PyGetWindow==0.0.9 pyinstaller==6.11.1 pyinstaller-hooks-contrib==2024.10 +PyMsgBox==1.0.9 +pyperclip==1.9.0 +PyRect==0.2.0 +PyScreeze==1.0.1 +python3-xlib==0.15 +pytweening==1.2.0 rsa==4.9 setuptools==75.6.0 tk==0.1.0