split server #2

This commit is contained in:
Sen 2025-05-03 22:42:03 +02:00
parent 3ab017888b
commit 8f8abfa0d3
11 changed files with 419 additions and 44 deletions

View file

@ -440,6 +440,7 @@ public class Game implements IThreadListener {
}
public void connect(String address, int port, String user, String pass, String access) {
this.displayGuiScreen(GuiLoading.makeWaitTask("Verbinde zu " + (address == null ? "localhost" : address) + ":" + port + " ..."));
Log.JNI.info("Verbinde zu " + (address == null ? "localhost" : address) + ":" + port);
NetConnection connection = null;
try
@ -2353,9 +2354,9 @@ public class Game implements IThreadListener {
public void startServer(File dir) {
if(this.server != null)
return;
server = new ServerProcess(dir, 1024, 4096, this.port);
server = new ServerProcess(this, dir, 1024, 4096, this.port);
server.start();
this.displayGuiScreen(GuiLoading.makeLoadTask(server));
this.displayGuiScreen(GuiLoading.makeStartTask(server));
// while(server != null && !server.isStarted()) {
// try {
// Thread.sleep(10L);
@ -2371,7 +2372,7 @@ public class Game implements IThreadListener {
if(server != null) {
server.shutdown();
if(display) {
this.displayGuiScreen(GuiLoading.makeSaveTask(server));
this.displayGuiScreen(GuiLoading.makeStopTask(server));
}
else {
while(!server.isStopped()) {
@ -2893,6 +2894,11 @@ public class Game implements IThreadListener {
return;
}
}
else if(line.startsWith("!")) {
if(this.server != null)
this.server.runCommand(line.substring(1));
return;
}
if(this.thePlayer != null && this.getNetHandler() != null)
this.getNetHandler().addToSendQueue(new CPacketMessage(line.startsWith("/") ? CPacketMessage.Type.COMMAND : CPacketMessage.Type.CHAT, line.startsWith("/") ? line.substring(1) : line));
// Log.CONSOLE.user("%s", line);

View file

@ -27,6 +27,7 @@ import game.future.ThreadFactoryBuilder;
import game.color.TextColor;
import game.command.CommandEnvironment;
import game.command.FixedExecutor;
import game.dimension.Dimension;
import game.dimension.Space;
import game.entity.Entity;
@ -307,9 +308,9 @@ public final class Server implements IThreadListener {
}
WorldServer.loadWarps(dim, this.warps);
}
if(port >= 0)
this.bind(port);
}
if(port >= 0)
this.bind(port);
Thread con = new Thread(new Runnable() {
private final BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(System.in)));
@ -331,6 +332,12 @@ public final class Server implements IThreadListener {
Server.this.shutdown();
continue;
}
final String cmd = line;
Server.this.schedule(new Runnable() {
public void run() {
Server.this.scriptEnv.execute(cmd, new FixedExecutor(Server.this, "#con", "KONSOLE", null));
}
});
}
}
}, "Server console handler");
@ -1193,4 +1200,11 @@ public final class Server implements IThreadListener {
System.out.flush();
}
}
public void logConsole(String message) {
if(this.ipcpipe)
this.sendPipeIPC("console", message);
else
Log.CONSOLE.info(message);
}
}

View file

@ -16,6 +16,7 @@ import game.util.Tuple;
import game.util.Util;
public class ServerProcess {
private final Game monitor;
private final ProcessBuilder builder;
private Process process;
@ -26,7 +27,8 @@ public class ServerProcess {
private int progress = -1;
private int lastTick;
public ServerProcess(File dir, int minMem, int maxMem, int port) {
public ServerProcess(Game monitor, File dir, int minMem, int maxMem, int port) {
this.monitor = monitor;
File jar = new File("game.jar");
String path;
if(jar.exists()) {
@ -87,6 +89,12 @@ public class ServerProcess {
ServerProcess.this.progress = Integer.parseInt(data.second);
else if(data.first.equals("tick"))
ServerProcess.this.lastTick = Integer.parseInt(data.second);
else if(data.first.equals("console"))
ServerProcess.this.monitor.schedule(new Runnable() {
public void run() {
ServerProcess.this.monitor.logConsole(data.second);
}
});
Log.SYSTEM.trace("server cmd %s -- %s", data.first, data.second);
continue;
}
@ -130,4 +138,12 @@ public class ServerProcess {
catch(Exception e) {
}
}
public void runCommand(String cmd) {
try {
this.writer.println(cmd);
}
catch(Exception e) {
}
}
}

View file

@ -0,0 +1,53 @@
package game.command;
import game.Server;
import game.entity.Entity;
import game.world.BlockPos;
import game.world.Position;
public class FixedExecutor implements Executor {
private final Server server;
private final String id;
private String name;
private Position position;
public FixedExecutor(Server server, String id, String name, Position pos) {
this.server = server;
this.id = id;
this.name = name;
this.position = pos;
}
public void setName(String name) {
this.name = name;
}
public void setPosition(Position pos) {
this.position = pos;
}
public void logConsole(String msg) {
this.server.logConsole(msg);
}
public String getExecId() {
return this.id;
}
public String getExecName() {
return this.name;
}
public Position getExecPos() {
return this.position;
}
public Entity getPointedEntity() {
return null;
}
public BlockPos getPointedPosition() {
return null;
}
}

View file

@ -14,9 +14,7 @@ public class CommandAdmin extends Command {
}
public void exec(CommandEnvironment env, Executor exec, Player player) {
if(!(exec instanceof Player))
throw new RunException("Dieser Befehl kann nur von Spielern ausgeführt werden");
else if(player == exec)
if(player == exec)
throw new RunException("Du kannst nicht deinen eigenen Admin-Status erneut setzen");
else if(player.getAdmin())
throw new RunException("%s ist bereits ein Admin", player.getUser());

View file

@ -16,8 +16,8 @@ public class CommandRevoke extends Command {
public void exec(CommandEnvironment env, Executor exec, Player player) {
if(exec instanceof Player)
throw new RunException("Dieser Befehl kann nur der Konsole ausgeführt werden");
else if(player == exec)
throw new RunException("Du kannst nicht deinen eigenen Admin-Status entfernen");
// else if(player == exec)
// throw new RunException("Du kannst nicht deinen eigenen Admin-Status entfernen");
else if(!player.getAdmin())
throw new RunException("%s ist kein Admin", player.getUser());
player.setAdmin(false);

View file

@ -18,7 +18,7 @@ public class GuiLoading extends Gui {
private Bar progressBar1;
private Bar progressBar2;
public static GuiLoading makeLoadTask(final ServerProcess server) {
public static GuiLoading makeStartTask(final ServerProcess server) {
return new GuiLoading("Starte Server ...", new Callback() {
boolean started = false;
@ -40,8 +40,8 @@ public class GuiLoading extends Gui {
});
}
public static GuiLoading makeSaveTask(final ServerProcess server) {
return new GuiLoading("Speichere Welt ...", new Callback() {
public static GuiLoading makeStopTask(final ServerProcess server) {
return new GuiLoading("Beende Server ...", new Callback() {
public void poll(Game gm, GuiLoading gui) {
if(server.isStopped()) {
gm.displayGuiScreen(GuiMenu.INSTANCE);

View file

@ -9,7 +9,7 @@ import game.gui.element.Label;
import game.gui.element.NavButton;
import game.gui.element.Textbox;
import game.gui.options.GuiOptions;
import game.gui.server.GuiConnect;
import game.gui.world.GuiServers;
import game.gui.world.GuiWorlds;
import game.init.Config;
import game.renderer.Drawing;
@ -74,7 +74,7 @@ public class GuiMenu extends Gui {
if(GuiMenu.this.hacked == 8)
GuiMenu.this.hacked++;
else
GuiMenu.this.gm.displayGuiScreen(GuiConnect.INSTANCE);
GuiMenu.this.gm.displayGuiScreen(GuiServers.INSTANCE);
}
}, "Server beitreten"));
this.infoButton = this.add(new ActButton(0, 56, 400, 24, new ActButton.Callback() {

View file

@ -2,33 +2,40 @@ package game.gui.server;
import game.color.TextColor;
import game.gui.Gui;
import game.gui.GuiMenu;
import game.gui.element.ActButton;
import game.gui.element.Label;
import game.gui.element.NavButton;
import game.gui.element.Textbox;
import game.gui.element.Textbox.Action;
import game.gui.world.GuiServers;
import game.gui.world.GuiServers.ServerInfo;
import game.init.Config;
import game.network.Player;
import game.vars.CVarCategory;
import game.vars.Variable;
public class GuiConnect extends Gui implements Textbox.Callback {
public static final GuiConnect INSTANCE = new GuiConnect();
public static final GuiConnect INSTANCE = new GuiConnect(null);
private GuiConnect() {
}
private final ServerInfo server;
private Textbox nameBox;
private Textbox addrBox;
private Textbox portBox;
private Textbox userBox;
private Textbox passBox;
private Textbox accBox;
private Label nameLabel;
private Label addrLabel;
private Label portLabel;
private Label userLabel;
private Label passLabel;
private Label accLabel;
public GuiConnect(ServerInfo server) {
this.server = server;
}
@Variable(name = "srv_last_address", category = CVarCategory.SYSTEM, min = 1, max = 128, display = "Letzte Server-Adresse")
private String lastAddr = "";
@Variable(name = "srv_last_port", category = CVarCategory.SYSTEM, min = 0, max = 65535, display = "Letzter Server-Port")
@ -41,21 +48,21 @@ public class GuiConnect extends Gui implements Textbox.Callback {
private String lastAcc = "";
public void init(int width, int height) {
this.addrBox = this.add(new Textbox(0, 20, 400, 24, 128, true, this, this.lastAddr));
this.portBox = this.add(new Textbox(404, 20, 76, 24, 5, true, this, "" + this.lastPort));
this.userBox = this.add(new Textbox(0, 70, 220, 24, Player.MAX_USER_LENGTH, true, this, Player.VALID_USER, this.lastUser));
this.passBox = this.add(new Textbox(0, 120, 480, 24, Player.MAX_PASS_LENGTH, true, this, this.lastPass));
this.accBox = this.add(new Textbox(0, 170, 480, 24, Player.MAX_PASS_LENGTH, true, this, this.lastAcc));
if(this.server != null)
this.nameBox = this.add(new Textbox(0, -50, 400, 24, 128, true, this, this.server.getName()));
this.addrBox = this.add(new Textbox(0, 20, 400, 24, 128, true, this, this.server == null ? this.lastAddr : this.server.getAddress()));
this.portBox = this.add(new Textbox(404, 20, 76, 24, 5, true, this, "" + (this.server == null ? this.lastPort : this.server.getPort())));
this.userBox = this.add(new Textbox(0, 70, 220, 24, Player.MAX_USER_LENGTH, true, this, Player.VALID_USER, this.server == null ? this.lastUser : this.server.getUser()));
this.passBox = this.add(new Textbox(0, 120, 480, 24, Player.MAX_PASS_LENGTH, true, this, this.server == null ? this.lastPass : this.server.getPassword()));
this.accBox = this.add(new Textbox(0, 170, 480, 24, Player.MAX_PASS_LENGTH, true, this, this.server == null ? this.lastAcc : this.server.getAccess()));
this.add(new ActButton(0, 220, 480, 24, new ActButton.Callback() {
public void use(ActButton elem, ActButton.Mode action) {
GuiConnect.this.connect();
}
}, "Verbinden"));
this.add(new ActButton(0, 250, 480, 24, new ActButton.Callback() {
public void use(ActButton elem, ActButton.Mode action) {
GuiConnect.this.gm.displayGuiScreen(GuiMenu.INSTANCE);
}
}, "Zurück"));
}, this.server == null ? "Verbinden" : (this.server.getName().isEmpty() ? "Hinzufügen" : "Übernehmen")));
this.add(new NavButton(0, 250, 480, 24, GuiServers.INSTANCE, "Zurück"));
if(this.server != null)
this.nameLabel = this.add(new Label(0, -70, 410, 20, "Name", true));
this.addrLabel = this.add(new Label(0, 0, 410, 20, "Adresse", true));
this.portLabel = this.add(new Label(414, 0, 66, 20, "Port", true));
this.userLabel = this.add(new Label(0, 50, 220, 20, "Nutzer", true));
@ -65,12 +72,20 @@ public class GuiConnect extends Gui implements Textbox.Callback {
}
public String getTitle() {
return "Mit Server verbinden";
return this.server == null ? "Mit Server verbinden" : (this.server.getName().isEmpty() ? "Server hinzufügen" : "Server bearbeiten");
}
private void connect() {
if(this.gm.theWorld != null)
return;
String name = null;
if(this.server != null) {
name = this.nameBox.getText();
if(name.isEmpty()) {
this.nameLabel.setText(TextColor.RED + "Name");
return;
}
}
String addr = this.addrBox.getText();
if(addr.isEmpty()) {
this.addrLabel.setText(TextColor.RED + "Adresse");
@ -99,13 +114,19 @@ public class GuiConnect extends Gui implements Textbox.Callback {
}
String pass = this.passBox.getText();
String acc = this.accBox.getText();
this.lastAddr = addr;
this.lastPort = port;
this.lastUser = user;
this.lastPass = pass;
this.lastAcc = acc;
this.gm.setDirty();
this.gm.connect(addr, port, user, pass, acc);
if(this.server == null) {
this.lastAddr = addr;
this.lastPort = port;
this.lastUser = user;
this.lastPass = pass;
this.lastAcc = acc;
this.gm.setDirty();
this.gm.connect(addr, port, user, pass, acc);
}
else {
this.server.setData(name, addr, port, user, pass, acc);
GuiServers.INSTANCE.applyServer(this.server);
}
}
public void use(Textbox elem, Action value) {
@ -120,10 +141,8 @@ public class GuiConnect extends Gui implements Textbox.Callback {
this.portLabel.setText("Port");
else if(elem == this.userBox)
this.userLabel.setText("Nutzer");
else if(this.server != null && elem == this.nameBox)
this.nameLabel.setText("Name");
}
}
// public void updateScreen() {
//
// }
}

View file

@ -0,0 +1,269 @@
package game.gui.world;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import game.color.TextColor;
import game.gui.GuiMenu;
import game.gui.element.ActButton;
import game.gui.element.ActButton.Mode;
import game.gui.element.GuiList;
import game.gui.element.ListEntry;
import game.gui.element.NavButton;
import game.gui.server.GuiConnect;
import game.init.Config;
import game.log.Log;
import game.network.Player;
import game.renderer.Drawing;
import game.util.FileUtils;
import game.util.Tuple;
import game.util.Util;
public class GuiServers extends GuiList<GuiServers.ServerInfo> implements ActButton.Callback {
public class ServerInfo implements Comparable<ServerInfo>, ListEntry {
private String name;
private String address;
private int port;
private String user;
private String password;
private String access;
private long lastConnected;
public ServerInfo(String name, String address, int port, String user, String password, String access, long lastConnected) {
this.name = name;
this.address = address;
this.port = port;
this.user = user;
this.password = password;
this.access = access;
this.lastConnected = lastConnected;
}
public String getName() {
return this.name;
}
public String getAddress() {
return this.address;
}
public int getPort() {
return this.port;
}
public String getUser() {
return this.user;
}
public String getPassword() {
return this.password;
}
public String getAccess() {
return this.access;
}
public long getLastConnected() {
return this.lastConnected;
}
public void setData(String name, String address, int port, String user, String password, String access) {
this.name = name;
this.address = address;
this.port = port;
this.user = user;
this.password = password;
this.access = access;
}
public void setLastConnected() {
this.lastConnected = System.currentTimeMillis();
}
public int compareTo(ServerInfo comp) {
return this.lastConnected < comp.lastConnected ? 1 : (this.lastConnected > comp.lastConnected ? -1 : this.name.compareTo(comp.name));
}
public void select(boolean isDoubleClick, int mouseX, int mouseY) {
GuiServers.this.selectButton.enabled = true;
GuiServers.this.deleteButton.enabled = true;
GuiServers.this.editButton.enabled = true;
GuiServers.this.copyButton.enabled = true;
if(isDoubleClick) {
GuiServers.this.use(GuiServers.this.selectButton, Mode.PRIMARY);
}
}
public void draw(int x, int y, int mouseXIn, int mouseYIn, boolean hover) {
Drawing.drawText(this.name + TextColor.GRAY + " - " + TextColor.RESET + this.user, x + 2, y, 0xffffffff);
Drawing.drawText(this.address + TextColor.GRAY + " Port " + TextColor.RESET + this.port, x + 2, y + 18, 0xff808080);
Drawing.drawText("Zuletzt verbunden: " + (this.lastConnected == -1L ? "nie" : DATE_FORMAT.format(new Date(this.lastConnected))), x + 2, y + 18 + 16, 0xff808080);
}
}
public static final GuiServers INSTANCE = new GuiServers();
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
private static final File SERVERS_FILE = new File("servers.cfg");
private ActButton deleteButton;
private ActButton selectButton;
private ActButton copyButton;
private ActButton editButton;
private ActButton createButton;
private GuiServers() {
}
public void init(int width, int height) {
super.init(width, height);
this.setDimensions(width, height, 32, height - 60);
this.elements.clear();
if(SERVERS_FILE.exists()) {
try {
String[] lines = FileUtils.read(SERVERS_FILE).split("\n");
String name = "";
String address = "";
int port = -1;
String user = "";
String password = "";
String access = "";
long time = -1L;
for(int z = 0; z <= lines.length; z++) {
String line = z == lines.length ? null : lines[z];
if(line == null || (line.startsWith("[") && line.endsWith("]"))) {
if(!name.isEmpty() && !address.isEmpty() && !user.isEmpty() && user.length() < Player.MAX_USER_LENGTH && Player.isValidUser(user) && password.length() < Player.MAX_PASS_LENGTH && access.length() < Player.MAX_PASS_LENGTH && address.length() < 128 && name.length() < 128 && port >= 0 && port < 65536)
this.elements.add(new ServerInfo(name, address, port, user, password, access, time));
if(line != null) {
address = "";
port = -1;
user = "";
password = "";
access = "";
time = -1L;
name = line.substring(1, line.length() - 1);
}
}
else {
Tuple<String, String> value = Util.getKeyValue(line);
if(value.first.equals("address"))
address = value.second;
else if(value.first.equals("port"))
try {
port = Integer.parseInt(value.second);
}
catch(NumberFormatException e) {
}
else if(value.first.equals("user"))
user = value.second;
else if(value.first.equals("password"))
password = value.second;
else if(value.first.equals("access"))
access = value.second;
else if(value.first.equals("connected"))
try {
time = Long.parseLong(value.second);
}
catch(NumberFormatException e) {
}
}
}
Collections.sort(this.elements);
}
catch(Exception e) {
Log.IO.error("Konnte Serverliste nicht laden", e);
this.elements.clear();
}
}
this.add(this.selectButton = new ActButton(width / 2 - 383, height - 56, 150, 24, this, "Verbinden"));
this.add(this.createButton = new ActButton(width / 2 + 233, height - 56, 150, 24, this, "Hinzufügen ..."));
this.add(this.deleteButton = new ActButton(width / 2 - 229, height - 28, 150, 24, this, "Löschen"));
this.add(this.editButton = new ActButton(width / 2 - 75, height - 28, 150, 24, this, "Bearbeiten"));
this.add(this.copyButton = new ActButton(width / 2 - 383, height - 28, 150, 24, this, "Kopieren"));
this.add(new NavButton(width / 2 - 75, height - 56, 150, 24, GuiConnect.INSTANCE, "Schnellverbdg."));
this.add(new NavButton(width / 2 + 233, height - 28, 150, 24, GuiMenu.INSTANCE, "Abbrechen"));
this.selectButton.enabled = false;
this.deleteButton.enabled = false;
this.editButton.enabled = false;
this.copyButton.enabled = false;
}
public void onGuiClosed() {
this.save();
}
public void applyServer(ServerInfo server) {
if(this.selectedElement < 0)
this.elements.add(server);
this.save();
this.gm.displayGuiScreen(this);
}
private void save() {
try {
StringBuilder sb = new StringBuilder();
for(ServerInfo server : this.elements) {
if(sb.length() > 0)
sb.append("\n");
sb.append("[" + server.getName() + "]\n");
sb.append("address " + server.getAddress() + "\n");
sb.append("port " + server.getPort() + "\n");
sb.append("user " + server.getUser() + "\n");
sb.append("password " + server.getPassword() + "\n");
sb.append("access " + server.getAccess() + "\n");
sb.append("connected " + server.getLastConnected());
}
FileUtils.write(SERVERS_FILE, sb.toString());
}
catch(Exception e) {
Log.IO.error("Konnte Serverliste nicht speichern", e);
}
}
public String getTitle() {
return "Server auswählen";
}
public int getListWidth() {
return 660;
}
public int getSlotHeight() {
return 56;
}
public void use(ActButton button, Mode mode) {
if(button == this.deleteButton) {
if(this.selectedElement >= 0) {
this.elements.remove(this.selectedElement);
this.gm.displayGuiScreen(this);
}
}
else if(button == this.selectButton) {
ServerInfo server = this.getSelected();
if(server != null) {
server.setLastConnected();
this.gm.connect(server.address, server.port, server.user, server.password, server.access);
}
}
else if(button == this.createButton) {
this.setSelected(-1);
this.gm.displayGuiScreen(new GuiConnect(new ServerInfo("", "", Config.PORT, "", "", "", -1L)));
}
else if(button == this.editButton) {
ServerInfo server = this.getSelected();
if(server != null)
this.gm.displayGuiScreen(new GuiConnect(server));
}
else if(button == this.copyButton) {
ServerInfo server = this.getSelected();
if(server != null) {
this.setSelected(-1);
this.gm.displayGuiScreen(new GuiConnect(new ServerInfo(server.name, server.address, server.port, server.user, server.address, server.access, -1L)));
}
}
}
}

View file

@ -42,7 +42,7 @@ public class PacketDecoder extends ByteToMessageDecoder
// if (Log.isTraceEnabled())
// {
// Log.SYSTEM.info("EIN: [" + p_decode_1_.channel().attr(NetConnection.ATTR_STATE).get() + ":" + i + "] " + packet.getClass().getName());
// Log.SYSTEM.info("EIN: [" + p_decode_1_.channel().attr(NetConnection.ATTR_STATE).get() + ":" + i + "] " + packet.getClass().getName());
// }
}
}