0

I'm trying to make my own launcher, but I'm getting an error in the output.

import os
import shutil
import json
import subprocess
import sys
import time
from PyQt5.QtWidgets import QApplication, QWidget, QPlainTextEdit, QLabel, QLineEdit, QPushButton, QComboBox, QMessageBox, QHBoxLayout, QVBoxLayout
from PyQt5.QtCore import QProcess, QUrl, QLocale
import minecraft_launcher_lib
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineProfile
CLIENT_ID = ""
REDIRECT_URL = ""
minecraft_directory = os.path.expandvars(r"%APPDATA%"+"\\D-Day")
if not os.path.isdir(minecraft_directory):
    os.mkdir(minecraft_directory)
if not os.path.isdir(minecraft_directory+"\\mods"):
    os.mkdir(minecraft_directory+"\\mods")
if not os.path.isdir(minecraft_directory + "\\resourcepacks"):
    os.mkdir(minecraft_directory + "\\resourcepacks")
refresh_token_file = minecraft_directory+"\\refresh_token.json"
useraccount = {}
vname = ""

def read_all_file(path):
    output = os.listdir(path)
    file_list = []
    for i in output:
        if os.path.isdir(path + "\\" + i):
            file_list.extend(read_all_file(path + "\\" + i))
        elif os.path.isfile(path + "\\" + i):
            file_list.append(path + "\\" + i)
    return file_list
def removeAllFile(filePath):
    if os.path.exists(filePath):
        for file in os.scandir(filePath):
            os.remove(file.path)
def copy_all_file(file_list, new_path):
    for src_path in file_list:
        file = src_path.split("\\")[-1]
        shutil.copyfile(src_path, new_path + "\\" + file)

class LoginWindow(QWebEngineView):
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        self.setWindowTitle("MS Login")
        # Set the path where the refresh token is saved
        # Login with refresh token, if it exists
        if os.path.isfile(refresh_token_file):
            with open(refresh_token_file, "r", encoding="utf-8") as f:
                refresh_token = json.load(f)
                # Do the login with refresh token
                try:
                    account_informaton = minecraft_launcher_lib.microsoft_account.complete_refresh(CLIENT_ID, None, REDIRECT_URL, refresh_token)
                    self.show_account_information(account_informaton)
                # Show the window if the refresh token is invalid
                except minecraft_launcher_lib.exceptions.InvalidRefreshToken:
                    pass
        # Open the login url
        login_url, self.state, self.code_verifier = minecraft_launcher_lib.microsoft_account.get_secure_login_data(CLIENT_ID, REDIRECT_URL)
        self.load(QUrl(login_url))
        # Connects a function that is called when the url changed
        self.urlChanged.connect(self.new_url)
        # self.show()
    def new_url(self, url: QUrl):
        try:
            # Get the code from the url
            auth_code = minecraft_launcher_lib.microsoft_account.parse_auth_code_url(url.toString(), self.state)
            # Do the login
            account_information = minecraft_launcher_lib.microsoft_account.complete_login(CLIENT_ID, None, REDIRECT_URL, auth_code, self.code_verifier)
            # Show the login information
            self.show_account_information(account_information)
        except AssertionError:
            print("States do not match!")
        except KeyError:
            print("Url not valid")

    def show_account_information(self, information_dict):
        global useraccount
        useraccount = information_dict
        with open(refresh_token_file, "w", encoding="utf-8") as f:
            json.dump(information_dict["refresh_token"], f, ensure_ascii=False, indent=4)
        self.parent.ms_login.setText("logout")
        self.close()
        time.sleep(1)
        self.parent.show()

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.version_select = QComboBox()
        self.ms_login = QPushButton("login")
        if os.path.isfile(refresh_token_file):
            self.ms_login.click()
        self.ms_login.clicked.connect(self.mslogin)
        launch_button = QPushButton("Launch")
        launch_button.clicked.connect(self.launch_minecraft)

        self.version_select.addItem("realeconomy")

        # Create the layouts
        bottom_layout = QHBoxLayout()
        bottom_layout.addWidget(QLabel("login stats:"))
        bottom_layout.addWidget(self.ms_login)
        bottom_layout.addWidget(QLabel("contect select:"))
        bottom_layout.addWidget(self.version_select)
        bottom_layout.addWidget(launch_button)

        main_layout = QVBoxLayout()
        main_layout.addLayout(bottom_layout)

        self.setLayout(main_layout)
        self.setGeometry(0, 0, 600, 200)
        self.setWindowTitle("D-Day Minecraft Launcher")


    def mslogin(self):
        global useraccount
        if self.ms_login.text() == "login":
            self.hide()
            QWebEngineProfile.defaultProfile().setHttpAcceptLanguage(QLocale.system().name().split("_")[0])
            self.logins = LoginWindow(self)
            self.logins.show()
        else:
            QWebEngineProfile.defaultProfile().cookieStore().deleteAllCookies()
            os.remove(refresh_token_file)
            useraccount = {}
            self.ms_login.setText("login")

    def launch_minecraft(self):
        global vname
        # Get the selected version
        version = self.version_select.currentText()
        if self.ms_login.text() == "login":
            QMessageBox.warning(self, "warn", "Plase login")
        else:
            removeAllFile(minecraft_directory + "\\mods")
            time.sleep(1)
            options = {}
            options["username"] = useraccount["name"]
            options["uuid"] = useraccount["id"]
            options["token"] = useraccount["access_token"]
            self.hide()
            if version == "realeconomy":
                shutil.copy(".\\data\\resourcepacks\\RealEconomy\\Amberstone 3.90 (1.16).zip", minecraft_directory + "\\resourcepacks")
                copy_all_file(read_all_file(".\\data\\mods\\RealEconomy"), minecraft_directory + "\\mods")
                time.sleep(1)
                vname = "1.16.5-forge-36.2.39"
                options["Resourcepacks"] = "Amberstone 3.90 (1.16).zip"
            elif version == "mini":
                vname = "1.16.5-forge-36.2.39"
            mcinstall(vname)
            minecraft_command = minecraft_launcher_lib.command.get_minecraft_command(vname, minecraft_directory, options)
            subprocess.call(minecraft_command)

def mcinstall(vname):
    if not os.path.isfile(minecraft_directory + "\\versions\\" + vname + "\\" + vname + ".jar"):
        if minecraft_launcher_lib.forge.supports_automatic_install(vname.replace("forge-")):
            callback = {
                "setStatus": lambda text: print(text)
            }
            minecraft_launcher_lib.forge.install_forge_version(vname.replace("forge-"), minecraft_directory, callback=callback)
        else:
            minecraft_launcher_lib.forge.run_forge_installer(vname.replace("forge-"))

def main():
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec())

if __name__ == "__main__":
    main()

The GUI run in PyCharm works without any errors.

when I create the output with pyinstaller -F main.py through pyinstaller to make the exe and run the exe, an error occurs.

enter image description here

I'm also curious as to why it's giving an error in exe when there is no problem in pycharm.

Y_Y
  • 25
  • 4
  • Welcome to Stack Overflow. I believe the issue is how you're creating your paths. I suggest using the ```os.path.join()``` or use Pathlib module. The way you're doing it right now is prone to errors and isn't cross-platform (if this is even an issue for you). – ewokx Aug 05 '22 at 02:31

1 Answers1

0

I solved the problem via os.path.join.

cottontail
  • 10,268
  • 18
  • 50
  • 51
Y_Y
  • 25
  • 4