Skip to content

Commit bf8d3b2

Browse files
committed
新版本
1 parent 36f43f2 commit bf8d3b2

File tree

2 files changed

+181
-1
lines changed

2 files changed

+181
-1
lines changed

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
# Xiaofeishu Python Minecraft Server Launcher
22

3-
## 进度
43
开服器正在开发中,请各位耐心等待。
54

5+
## 进度
6+
2023/9/1 大概的样子有了
7+
8+
69
## 计划
710
- [x] 界面简洁
811
- [ ] 动态规则

source code/app.py

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import tkinter as tk
2+
from tkinter import ttk
3+
import subprocess
4+
import os
5+
import yaml
6+
import threading
7+
8+
# 创建主窗口
9+
root = tk.Tk()
10+
root.title("Minecraft 服务器启动器")
11+
12+
# 创建标签框架
13+
frame = ttk.LabelFrame(root, text="服务器配置")
14+
frame.grid(row=0, column=0, padx=10, pady=10, sticky="nsew")
15+
16+
# 创建标签
17+
java_label = ttk.Label(frame, text="选择Java版本:")
18+
java_label.grid(row=0, column=0, padx=10, pady=5, sticky="w")
19+
20+
jar_file_label = ttk.Label(frame, text="Minecraft服务器JAR文件名:")
21+
jar_file_label.grid(row=1, column=0, padx=10, pady=5, sticky="w")
22+
23+
# 创建下拉列表框和输入框
24+
java_var = tk.StringVar()
25+
java_dropdown = ttk.Combobox(frame, textvariable=java_var)
26+
java_dropdown.grid(row=0, column=1, padx=10, pady=5)
27+
java_dropdown.state(["readonly"]) # 禁止手动输入
28+
29+
jar_file_entry = ttk.Entry(frame, width=40)
30+
jar_file_entry.grid(row=1, column=1, padx=10, pady=5)
31+
32+
# 创建启动按钮
33+
def start_minecraft_server():
34+
def run_server():
35+
selected_java_version = java_var.get()
36+
new_jar_file_name = jar_file_entry.get()
37+
38+
# 进入Minecraft服务器目录
39+
os.chdir("XPMSL\\server")
40+
41+
# 启动Minecraft服务器命令
42+
cmd_command = f'"{java_executables[java_versions.index(selected_java_version)]}" -Xmx2G -Xms1G -jar {new_jar_file_name} nogui'
43+
44+
# 使用subprocess启动服务器进程,使用PIPE连接输入和输出
45+
global server_process
46+
server_process = subprocess.Popen(cmd_command, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
47+
48+
# 清空输出框
49+
output_text.delete("1.0", tk.END)
50+
51+
# 在输出框中显示输出
52+
output_text.config(state="normal") # 设置输出框为可编辑状态
53+
output_text.insert(tk.END, f"启动Minecraft服务器:\n")
54+
while True:
55+
line = server_process.stdout.readline()
56+
if not line:
57+
break
58+
output_text.insert(tk.END, line)
59+
output_text.see(tk.END) # 滚动到最新输出
60+
root.update_idletasks() # 更新界面以响应用户操作
61+
output_text.insert(tk.END, f"标准错误:\n")
62+
while True:
63+
line = server_process.stderr.readline()
64+
if not line:
65+
break
66+
output_text.insert(tk.END, line)
67+
output_text.see(tk.END)
68+
root.update_idletasks()
69+
output_text.config(state="disabled") # 设置输出框为只读状态
70+
71+
# 使用线程运行服务器启动函数
72+
server_thread = threading.Thread(target=run_server)
73+
server_thread.start()
74+
75+
start_button = ttk.Button(frame, text="启动Minecraft服务器", command=start_minecraft_server)
76+
start_button.grid(row=2, column=0, columnspan=2, padx=10, pady=10)
77+
78+
# 创建关闭服务器按钮
79+
def stop_minecraft_server():
80+
# 向Minecraft服务器发送关闭命令,例如使用"stop"命令
81+
if server_process:
82+
server_process.stdin.write("stop\n")
83+
server_process.stdin.flush()
84+
85+
stop_button = ttk.Button(frame, text="关闭Minecraft服务器", command=stop_minecraft_server)
86+
stop_button.grid(row=3, column=0, columnspan=2, padx=10, pady=5)
87+
88+
# 创建文本框用于输入命令
89+
command_entry = ttk.Entry(frame, width=40)
90+
command_entry.grid(row=4, column=0, columnspan=2, padx=10, pady=5)
91+
92+
# 创建发送命令按钮
93+
def send_command():
94+
command = command_entry.get()
95+
if server_process:
96+
server_process.stdin.write(command + "\n")
97+
server_process.stdin.flush()
98+
command_entry.delete(0, "end")
99+
100+
send_button = ttk.Button(frame, text="发送命令", command=send_command)
101+
send_button.grid(row=4, column=2, padx=5, pady=5)
102+
103+
# 创建文本框
104+
output_text = tk.Text(root, height=15, width=50, state="disabled")
105+
output_text.grid(row=1, column=0, padx=10, pady=10, sticky="nsew")
106+
107+
# 创建垂直和水平滚动条
108+
v_scrollbar = tk.Scrollbar(root, orient="vertical", command=output_text.yview)
109+
v_scrollbar.grid(row=1, column=1, sticky="ns")
110+
output_text.config(yscrollcommand=v_scrollbar.set)
111+
112+
h_scrollbar = tk.Scrollbar(root, orient="horizontal", command=output_text.xview)
113+
h_scrollbar.grid(row=2, column=0, columnspan=2, sticky="ew")
114+
output_text.config(xscrollcommand=h_scrollbar.set)
115+
116+
# 读取配置文件
117+
def read_config():
118+
with open("XPMSL\\config.yaml", "r") as config_file:
119+
config = yaml.load(config_file, Loader=yaml.FullLoader)
120+
return config
121+
122+
# 搜索Java可执行文件并获取版本信息
123+
def find_java_executables():
124+
java_executables = []
125+
program_files_path = os.path.join("C:\\", "Program Files", "Java")
126+
127+
if os.path.exists(program_files_path):
128+
for root, dirs, files in os.walk(program_files_path):
129+
for dir in dirs:
130+
if dir.lower().startswith("jdk"):
131+
jdk_path = os.path.join(root, dir, "bin", "java.exe")
132+
if os.path.exists(jdk_path):
133+
java_executables.append(jdk_path)
134+
135+
return java_executables
136+
137+
# 获取Java版本
138+
def get_java_version(java_executable):
139+
try:
140+
output = subprocess.check_output([java_executable, "-version"], stderr=subprocess.STDOUT, text=True)
141+
lines = output.splitlines()
142+
for line in lines:
143+
if "version" in line:
144+
return line.strip()
145+
except subprocess.CalledProcessError:
146+
pass
147+
return "无法获取版本信息"
148+
149+
# 检查并创建配置文件
150+
def create_config_if_not_exists():
151+
if not os.path.exists("XPMSL\\config.yaml"):
152+
default_config = {"jar_file": "server.jar"}
153+
with open("XPMSL\\config.yaml", "w") as config_file:
154+
yaml.dump(default_config, config_file)
155+
156+
# 读取配置文件中的JAR文件名
157+
config = read_config()
158+
jar_file_name = config.get("jar_file", "server.jar")
159+
160+
# 搜索Java可执行文件并获取版本信息
161+
java_executables = find_java_executables()
162+
java_versions = [get_java_version(java_exe) for java_exe in java_executables]
163+
164+
# 将Java版本列表设置为下拉列表框的选项
165+
java_dropdown["values"] = java_versions
166+
167+
# 设置默认选中的Java版本
168+
if java_versions:
169+
java_var.set(java_versions[0])
170+
else:
171+
java_var.set("未找到Java")
172+
173+
# 设置默认的JAR文件名
174+
jar_file_entry.insert(0, jar_file_name)
175+
176+
# 启动主事件循环
177+
root.mainloop()

0 commit comments

Comments
 (0)