@Ghostplayer: Da ist dreimal ``global`` drin und eine globale Variable ohne dieses Schlüsselwort — das ist keine Lösung, sondern ein Problem. Und das ist nichts was man irgendwann mal gerade biegt, so einen Unsinn sollte man gar nicht erst anfangen. Denn entweder macht man das dann am Ende doch nie ordentlich, oder stellt *dann* erst fest was für ein Chaos man da angerichtet hat, das sich gar nicht mehr so einfach ordentlich machen lässt.
Wenn man `os.path.join()` verwendet und dann doch wieder in Teile hart einen Pfadtrenner schreibt, macht das irgendwie keinen Sinn. Und `pathlib` hatte ich ja schon erwähnt.
Man prüft nicht ob eine Datei existiert bevor man sie öffnet. Dieser Test ist im öffnen schon enthalten, und zwischen dem unnötigen Extratext und dem Öffnen kann es sich das ja schon wieder geändert haben. Du löst ja sogar genau die Ausnahme aus die sowieso schon ausgelöst wird.
Und das hatte ich ja auch schon erwähnt: Man behandelt keine Ausnahmen in dem man sie einfach durch Print-Ausgaben ersetzt und dann so weitermacht als wäre nix passiert. Das führt doch dann nur zu Folgeausnahmen und Aufrufer haben gar keine Möglichkeit auf Ausnahmefälle zu reagieren.
Beim öffnen von Textdateien sollte man die Kodierung angeben.
Ein `strip()` vor einem ``split()`` ist unnötig:
Code: Alles auswählen
In [15]: " a b c d \n".split()
Out[15]: ['a', 'b', 'c', 'd']
``for line in iter(file.readline, "")`` ist recht umständlich für ``for line in file:``.
Bei Threads möchte man in der Regel die `daemon`-Option haben.
Zum stoppen möchte man nicht einfach nur den "stop"-Befehl senden, denn man muss ja auch den Prozess sauber abräumen und den anderen Zustand entsprechend setzen.
Zwischenstand (ungetestet):
Code: Alles auswählen
import subprocess
from pathlib import Path
from threading import Thread
class Server:
def __init__(self, name, install_path=Path("servers")):
self.path = install_path / name
self.process = None
self.log_entries = []
self.is_on = False
def _process_output(self, file):
with file:
for line in file:
self.log_entries.append(line)
if "Done (" in line:
self.is_on = True
def start(self, min_memory="4G", max_memory="7G"):
arguments = (
(
self.path
/ "libraries"
/ "net"
/ "minecraftforge"
/ "forge"
/ "1.20.2-48.1.0"
/ "win_args.txt"
)
.read_text(encoding="utf-8")
.split()
)
self.process = subprocess.Popen(
[
"java",
f"-Xms{min_memory}",
f"-Xmx{max_memory}",
*arguments,
"nogui",
],
cwd=self.path,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
for file in [self.process.stdout, self.process.stderr]:
Thread(
target=self._process_output, args=[file], daemon=True
).start()
def send_command(self, command):
self.process.stdin.write(command + "\n")
self.process.stdin.flush()
def stop(self):
self.send_command("stop") # ???
return_code = self.process.wait()
self.process = None
self.is_on = False
return return_code
Wird `log_entries` nicht recht schnell unschön gross?