Skip to content

Commit dee4849

Browse files
authored
Merge pull request #1 from Zhou-Shilin/master
feat: Basic features
2 parents 1d561a7 + e0f8bfc commit dee4849

File tree

15 files changed

+264
-4
lines changed

15 files changed

+264
-4
lines changed

build.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from subprocess import Popen, PIPE, STDOUT
2+
from log_writer import logger
3+
4+
def build_plugin(artifact_name):
5+
project_path = f"codes/{artifact_name}"
6+
build_command = ["cd", project_path, "&&", "mvn", "-V", "-B", "clean", "package", "--file", "pom.xml"]
7+
8+
process = Popen(build_command, stdout=PIPE, stderr=STDOUT, shell=True)
9+
10+
def log_subprocess_output(pipe):
11+
output = ""
12+
for line in iter(pipe.readline, b''):
13+
str_line = str(line)
14+
output += str_line
15+
logger(f"building -> {str_line}")
16+
return output
17+
18+
with process.stdout:
19+
output = log_subprocess_output(process.stdout)
20+
21+
process.wait()
22+
23+
return output
24+
25+
if __name__ == "__main__":
26+
result = build_plugin("ExamplePlugin2")
27+
print(result)
28+
print(type(result))

codes/ExamplePlugin4/pom.xml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>org.cubegpt</groupId>
8+
<artifactId>ExamplePlugin4</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
<packaging>jar</packaging>
11+
12+
<dependencies>
13+
<dependency>
14+
<groupId>org.bukkit</groupId>
15+
<artifactId>bukkit</artifactId>
16+
<version>1.13.2-R0.1-SNAPSHOT</version>
17+
<scope>provided</scope>
18+
</dependency>
19+
</dependencies>
20+
21+
<build>
22+
<sourceDirectory>src/main/java</sourceDirectory>
23+
<resources>
24+
<resource>
25+
<directory>src/main/resources</directory>
26+
</resource>
27+
</resources>
28+
<plugins>
29+
<plugin>
30+
<groupId>org.apache.maven.plugins</groupId>
31+
<artifactId>maven-compiler-plugin</artifactId>
32+
<version>3.8.0</version>
33+
<configuration>
34+
<source>1.8</source>
35+
<target>1.8</target>
36+
</configuration>
37+
</plugin>
38+
</plugins>
39+
</build>
40+
</project>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.cubegpt._188eba63;
2+
3+
import org.bukkit.Bukkit;
4+
import org.bukkit.event.EventHandler;
5+
import org.bukkit.event.Listener;
6+
import org.bukkit.event.player.PlayerJoinEvent;
7+
import org.bukkit.plugin.java.JavaPlugin;
8+
9+
public class Main extends JavaPlugin implements Listener {
10+
11+
@Override
12+
public void onEnable() {
13+
Bukkit.getServer().getPluginManager().registerEvents(this, this);
14+
}
15+
16+
@EventHandler
17+
public void onPlayerJoin(PlayerJoinEvent event) {
18+
event.getPlayer().sendMessage("hello");
19+
}
20+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
message: "hello"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
name: ExamplePlugin4
2+
version: 1.0
3+
main: org.cubegpt._188eba63.Main
4+
api-version: 1.13
5+
author: CubeGPT
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
message: "hello"
Binary file not shown.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
name: ExamplePlugin4
2+
version: 1.0
3+
main: org.cubegpt._188eba63.Main
4+
api-version: 1.13
5+
author: CubeGPT
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
artifactId=ExamplePlugin4
2+
groupId=org.cubegpt
3+
version=1.0-SNAPSHOT
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org\cubegpt\_188eba63\Main.class
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
D:\zhousl\BukkitGPT\BukkitGPT-v3\codes\ExamplePlugin4\src\main\java\org\cubegpt\188eba63\Main.java

config.yaml

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,44 @@
88
API_KEY: "" # Free API Key with GPT-4 access: https://github.com/CubeGPT/.github/discussions/1
99
BASE_URL: "https://api.openai.com/v1/chat/completions"
1010

11-
# More config options here.
11+
GENERATION_MODEL: "gpt-4-turbo-2024-04-09"
12+
13+
# DEVELOPER SETTINGS #
14+
VERSION_NUMBER: "Beta 1.0"
15+
16+
# PROMPT SETTINGS #
17+
# If you don't know what it is, please don't touch it. Be sure to backup before editing.
18+
19+
## Code Generation ##
20+
SYS_GEN: |
21+
You're a minecraft bukkit plugin coder AI. Game Version: 1.13.2 (1.13.2-R0.1-SNAPSHOT)
22+
Write the code & choose a artifact name for the following files with the infomation which is also provided by the user:
23+
%WORKING_PATH%/Main.java
24+
src/main/resources/plugin.yml
25+
src/main/resources/config.yml
26+
pom.xml
27+
Response in json format:
28+
{
29+
\"codes\": [
30+
{
31+
\"file\": \"codes/%ARTIFACT_NAME%/src/main/java/%PKG_ID_LST%Main.java\",
32+
\"code\": \"package ...;\\nimport org.bukkit.Bukkit;\\npublic class Main extends JavaPlugin implements CommandExecutor {\\n... (The code you need to write)\"
33+
},
34+
{
35+
\"file\": \"codes/%ARTIFACT_NAME%/src/main/resources/plugin.yml\",
36+
\"code\": \"name: ...\\nversion: ...\\n...\"
37+
},
38+
{
39+
\"file\": \"codes/%ARTIFACT_NAME%/src/main/resources/config.yml\",
40+
\"code\": \"...\"
41+
},
42+
{
43+
\"file\": \"codes/%ARTIFACT_NAME%/pom.xml\",
44+
\"code\": \"...\"
45+
}
46+
]
47+
}
48+
You should never response anything else. Never use Markdown format. Use \n for line feed, and never forget to use \ before ". Never write uncompeleted codes, such as leave a comment that says "// Your codes here" or "// Uncompeleted".
49+
50+
USR_GEN: |
51+
%DESCRIPTION%

console.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,58 @@
44
from log_writer import logger
55
import core
66
import config
7+
import build
78

89
if __name__ == "__main__":
910
core.initialize()
1011

11-
# Codes here.
12+
print("BukkitGPT v3 beta console running")
13+
14+
# Get user inputs
15+
name = input("Enter the plugin name: ")
16+
description = input("Enter the plugin description: ")
17+
18+
artifact_name = name.replace(" ", "")
19+
package_id = f"org.cubegpt.{uuid.uuid4().hex[:8]}"
20+
21+
pkg_id_path = ""
22+
for id in package_id.split("."):
23+
pkg_id_path += id + "/"
24+
25+
logger(f"user_input -> name: {name}")
26+
logger(f"user_input -> description: {description}")
27+
logger(f"random_generate -> package_id: {package_id}")
28+
logger(f"str_path -> pkg_id_path: {pkg_id_path}")
29+
30+
print("Generating plugin...")
31+
32+
codes = core.askgpt(config.SYS_GEN.replace("%ARTIFACT_NAME%", artifact_name).replace("%PKG_ID_LST%", pkg_id_path), config.USR_GEN.replace("%DESCRIPTION", description), config.GENERATION_MODEL)
33+
logger(f"codes: {codes}")
34+
35+
core.response_to_action(codes)
36+
37+
print("Code generated. Building now...")
38+
39+
40+
result = build.build_plugin(artifact_name)
41+
if "BUILD SUCCESS" in result:
42+
print(f"Build complete. Find your plugin at 'codes/{artifact_name}/target/{artifact_name}.jar'")
43+
elif "Compilation failure":
44+
print("Build failed. Passing the error to ChatGPT and let it to fix it?")
45+
fix = input("Y/n: ")
46+
if fix == "n":
47+
print("Exiting...")
48+
sys.exit(0)
49+
else:
50+
print("Fixing is a uncompleted feature.")
51+
print("Restart the program and retype the name & description, etc. to try again.")
52+
print("Exiting...")
53+
sys.exit(0)
54+
else:
55+
print("Unknown error. Please check the logs && send the log to @BaimoQilin on discord.")
56+
print("Exiting...")
57+
sys.exit(0)
58+
1259

1360
else:
1461
print("Error: Please run console.py as the main program instead of importing it from another program.")

core.py

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from openai import OpenAI
2-
import mcschematic
2+
import chardet
33
import sys
44
import json
55
import locale
6+
import os
67

78
from log_writer import logger
89
import config
@@ -83,7 +84,74 @@ def askgpt(system_prompt: str, user_prompt: str, model_name: str, disable_json_m
8384
logger(f"askgpt: extracted reply {assistant_reply}")
8485
return assistant_reply
8586

86-
# Core codes here.
87+
def response_to_action(msg):
88+
"""
89+
Converts a response from ChatGPT to an action.
90+
91+
Args:
92+
msg (str): The response from ChatGPT.
93+
94+
Returns:
95+
str: The action to take.
96+
"""
97+
text = json.loads(msg)
98+
99+
codes = text["codes"]
100+
101+
for section in codes:
102+
file = section["file"]
103+
code = section["code"]
104+
105+
paths = file.split("/")
106+
107+
# Join the list elements to form a path
108+
path = os.path.join(*paths)
109+
110+
# Get the directory path and the file name
111+
dir_path, file_name = os.path.split(path)
112+
113+
# Create directories, if they don't exist
114+
try:
115+
os.makedirs(dir_path, exist_ok=True)
116+
except FileNotFoundError:
117+
pass
118+
119+
# Create the file
120+
with open(path, 'w') as f:
121+
f.write(code) # Write an empty string to the file
122+
123+
def mixed_decode(text: str):
124+
"""
125+
Decode a mixed text containing both normal text and a byte sequence.
126+
127+
Args:
128+
text (str): The mixed text to be decoded.
129+
130+
Returns:
131+
str: The decoded text, where the byte sequence has been converted to its corresponding characters.
132+
133+
"""
134+
# Split the normal text and the byte sequence
135+
# Assuming the byte sequence is everything after the last colon and space ": "
136+
try:
137+
normal_text, byte_text = text.rsplit(": ", 1)
138+
except (TypeError, ValueError):
139+
# The text only contains normal text
140+
return text
141+
142+
# Convert the byte sequence to actual bytes
143+
byte_sequence = byte_text.encode('latin1') # latin1 encoding maps byte values directly to unicode code points
144+
145+
# Detect the encoding of the byte sequence
146+
detected_encoding = chardet.detect(byte_sequence)
147+
encoding = detected_encoding['encoding']
148+
149+
# Decode the byte sequence
150+
decoded_text = byte_sequence.decode(encoding)
151+
152+
# Combine the normal text with the decoded byte sequence
153+
final_text = normal_text + ": " + decoded_text
154+
return final_text
87155

88156
if __name__ == "__main__":
89157
print("This script is not meant to be run directly. Please run console.py instead.")

0 commit comments

Comments
 (0)