diff --git a/.gitignore b/.gitignore index 55ef229..ade67b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ -projects/* -!projects/template/ +generated/* logs/* test.py diff --git a/README.md b/README.md index 8799043..19e479e 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ "> +
+Join our discord
@@ -40,9 +42,8 @@ After the user enters a requirement, the program causes `gpt-4-preview` to gener ```json { "materials": [ - "A": "minecraft:air", - "S": "minecraft:stone", - "G": "minecraft:glass" + "A: \"minecraft:air\"", + "S: \"minecraft:stone\"" ], "structures": [ { diff --git a/config.yaml b/config.yaml index f3ca695..0b60e19 100644 --- a/config.yaml +++ b/config.yaml @@ -16,39 +16,38 @@ SYS_GEN: | You are a minecraft structure builder bot. You should design a building or a structure based on user's instructions. Response in json like this: { - \"materials\": [ - \"A\": \"minecraft:air\", - \"S\": \"minecraft:stone\", - \"G\": \"minecraft:glass\" + "materials": [ + "A: \"minecraft:air\"", + "S: \"minecraft:stone\"" ], - \"structures\": [ + "structures": [ { - \"floor\": 0, - \"structure\": \"SSSSSSSS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSSSSSSSS\" + "floor": 0, + "structure": "SSSSSSSS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSSSSSSSS" }, { - \"floor\": 1, - \"structure\": \"SSGGGGSS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSSSSSSSS\" + "floor": 1, + "structure": "SSGGGGSS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSSSSSSSS" }, { - \"floor\": 2, - \"structure\": \"SSGGGGSS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSSSSSSSS\" + "floor": 2, + "structure": "SSGGGGSS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSSSSSSSS" }, { - \"floor\": 3, - \"structure\": \"SSSSSSSS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSSSSSSSS\" + "floor": 3, + "structure": "SSSSSSSS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSAAAAAAS\nSSSSSSSS" }, { - \"floor\": 4, - \"structure\": \"SSSSSSSS\nSSSSSSSS\nSSSSSSSS\nSSSSSSSS\nSSSSSSSS\nSSSSSSSS\nSSSSSSSS\nSSSSSSSS\nSSSSSSSS\nSSSSSSSS\n\" + "floor": 4, + "structure": "SSSSSSSS\nSSSSSSSS\nSSSSSSSS\nSSSSSSSS\nSSSSSSSS\nSSSSSSSS\nSSSSSSSS\nSSSSSSSS\nSSSSSSSS\nSSSSSSSS\n" } ] } - Never response anything else. Do not design a building which is too large (more than 10 floors). Never use markdown format. Use \n for line feed. And for example , if there's a "t" before \", use \\t. + Never response anything else. Do not design a building which is too large (more than 10 floors). Never use markdown format. Use \n for line feed. USR_GEN: | %DESCRIPTION% # Developer Settings # -DEBUG_MODE: False +DEBUG_MODE: True VERSION_NUMBER: "Alpha-1.0" #NEVER EDIT THIS IF YOU DON'T KNOW WHAT ARE YOU DOING \ No newline at end of file diff --git a/console.py b/console.py index df66807..4f7baa2 100644 --- a/console.py +++ b/console.py @@ -58,6 +58,13 @@ def generate_plugin(description): logger(f"console: Saving {name}.schem to generated/ folder.") version_tag = core.input_version_to_mcs_tag(version) + + # Check if the version is valid. If not, ask the user to retype the version number. + while version_tag is None: + print("Error: Invalid version number. Please retype the version number.") + version = input("[re-0/0] What's your minecraft version? (eg. 1.20.1): ") + version_tag = core.input_version_to_mcs_tag(version) + schem.save("generated", name, version_tag) print("Generated. Get your schem file in folder generated.") diff --git a/core.py b/core.py index e506dda..4ce1c10 100644 --- a/core.py +++ b/core.py @@ -97,7 +97,11 @@ def text_to_schem(text: str): return schematic except (json.decoder.JSONDecodeError, KeyError, TypeError, ValueError, AttributeError, IndexError) as e: - logger(f"text_to_command: failed to load JSON data. Error: {e}") + logger(f"text_to_command: failed to load JSON data. Error message: {e}") + + if config.DEBUG_MODE: + raise e + return None def input_version_to_mcs_tag(input_version): @@ -114,8 +118,13 @@ def input_version_to_mcs_tag(input_version): >>> input_version_to_mcs_tag("1.20.1") 'JE_1_20_1' """ - version = input_version.split(".") - return getattr(mcschematic.Version, f"JE_{version[0]}_{version[1]}_{version[2]}") + try: + version = input_version.split(".") + result = getattr(mcschematic.Version, f"JE_{version[0]}_{version[1]}_{version[2]}") + except (AttributeError, IndexError) as e: + logger(f"input_version_to_mcs_tag: failed to convert version {input_version}; {e}") + return None + return result if __name__ == "__main__": print("This script is not meant to be run directly. Please run console.py instead.") \ No newline at end of file diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..3012081 Binary files /dev/null and b/logo.png differ diff --git a/ui.py b/ui.py new file mode 100644 index 0000000..239e4ef --- /dev/null +++ b/ui.py @@ -0,0 +1,104 @@ +import sys +import tkinter as tk +import tkinter.messagebox as msgbox + +from log_writer import logger +import core +import config + +def get_schematic(description): + """ + Generates a schematic based on the given description. + + Args: + description (str): The description of the schematic. + + Returns: + str: The generated schematic. + + Raises: + SystemExit: If the schematic generation fails. + """ + response = core.askgpt(config.SYS_GEN, config.USR_GEN.replace("%DESCRIPTION%", description), config.GENERATE_MODEL) + + schem = core.text_to_schem(response) + + if schem is None: + msgbox.showerror("Error", "Failed to generate the schematic. We recommend you to change the generating model to gpt-4-turbo-preview or other smarter models.") + sys.exit(1) + + return schem + +def generate_schematic(): + """ + Generates a schematic file based on user input. + + This function retrieves the version, name, and description from the user interface, + initializes the core functionality, and generates a plugin based on the provided description. + It then saves the generated schematic file in the 'generated' folder. + + Returns: + None + """ + generate_button.config(state=tk.DISABLED, text="Generating...") + + version = version_entry.get() + name = name_entry.get() + description = description_entry.get() + + logger(f"console: input version {version}") + logger(f"console: input name {name}") + logger(f"console: input description {description}") + + schem = get_schematic(description) + + logger(f"console: Saving {name}.schem to generated/ folder.") + version_tag = core.input_version_to_mcs_tag(version) + + while version_tag is None: + msgbox.showerror("Error", "Invalid version number. Please retype the version number.") + version = version_entry.get() + version_tag = core.input_version_to_mcs_tag(version) + + schem.save("generated", name, version_tag) + + msgbox.showinfo("Success", "Generated. Get your schem file in folder generated.") + + generate_button.config(state=tk.NORMAL, text="Generate") + +def Application(): + global version_entry, name_entry, description_entry, generate_button + + window = tk.Tk() + window.title("BuilderGPT") + + logo = tk.PhotoImage(file="logo.png") + logo = logo.subsample(4) + logo_label = tk.Label(window, image=logo) + logo_label.pack() + + version_label = tk.Label(window, text="What's your minecraft version? (eg. 1.20.1):") + version_label.pack() + version_entry = tk.Entry(window) + version_entry.pack() + + name_label = tk.Label(window, text="What's the name of your structure? It will be the name of the generated *.schem file:") + name_label.pack() + name_entry = tk.Entry(window) + name_entry.pack() + + description_label = tk.Label(window, text="What kind of structure would you like to generate? Describe as clear as possible:") + description_label.pack() + description_entry = tk.Entry(window) + description_entry.pack() + + generate_button = tk.Button(window, text="Generate", command=generate_schematic) + generate_button.pack() + + window.mainloop() + +if __name__ == "__main__": + core.initialize() + Application() +else: + print("Error: Please run ui.py as the main program instead of importing it from another program.") \ No newline at end of file