From 83082f4f3cdf2974b52100b8143e4e7d5961f2af Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 3 Aug 2025 14:33:45 +0200 Subject: [PATCH] add /tick, /freeze and variable overrides --- server/src/main/java/server/Server.java | 93 ++++++++++++++++++- .../server/command/CommandEnvironment.java | 2 + .../command/commands/CommandFreeze.java | 22 +++++ .../server/command/commands/CommandSv.java | 19 ++-- .../server/command/commands/CommandTick.java | 26 ++++++ 5 files changed, 153 insertions(+), 9 deletions(-) create mode 100644 server/src/main/java/server/command/commands/CommandFreeze.java create mode 100644 server/src/main/java/server/command/commands/CommandTick.java diff --git a/server/src/main/java/server/Server.java b/server/src/main/java/server/Server.java index 353b0762..1e8d8dd3 100755 --- a/server/src/main/java/server/Server.java +++ b/server/src/main/java/server/Server.java @@ -116,6 +116,7 @@ public final class Server implements IThreadListener, Executor { private final Thread thread = Thread.currentThread(); private final NioEventLoopGroup eventGroup = new NioEventLoopGroup(0, Util.getThreadFactory("Netty Server IO")); private final Map variables = Maps.newTreeMap(); + private final Map> overrides = Maps.newTreeMap(); private final List clients = Collections.synchronizedList(Lists.newArrayList()); private final List players = Lists.newArrayList(); private final Map online = Maps.newHashMap(); @@ -350,9 +351,10 @@ public final class Server implements IThreadListener, Executor { tag.setString("Version", Util.VERSION); TagObject cfg = new TagObject(); for(String cvar : this.variables.keySet()) { - SVar value = this.variables.get(cvar); - if(!value.noDef || !value.def.equals(value.get())) - cfg.setString(cvar, value.get()); + SVar sv = this.variables.get(cvar); + String value = this.getVariableOverrideValue(cvar); + if(!sv.noDef || !sv.def.equals(value)) + cfg.setString(cvar, value); } tag.setObject("Config", cfg); writeDimensions(tag); @@ -455,6 +457,91 @@ public final class Server implements IThreadListener, Executor { public Map getVariables() { return this.variables; } + + public boolean setVariableOverride(String id, Runnable func) { + Map map = Maps.newHashMap(); + for(Entry entry : this.variables.entrySet()) { + map.put(entry.getKey(), entry.getValue().getRaw()); + } + func.run(); + for(Iterator> iter = map.entrySet().iterator(); iter.hasNext();) { + Entry entry = iter.next(); + SVar sv = this.variables.get(entry.getKey()); + if(!sv.getRaw().equals(entry.getValue())) { + for(Iterator>> oiter = this.overrides.entrySet().iterator(); oiter.hasNext();) { + Entry> oentry = oiter.next(); + Object value = oentry.getValue().remove(entry.getKey()); + if(value == null) + continue; + if(oentry.getValue().isEmpty()) + oiter.remove(); + if(sv.getRaw().equals(value)) + iter.remove(); + break; + } + sv.set(sv.get(), false, true); + if(sv.sync) + this.sendPacket(new SPacketServerConfig(entry.getKey(), sv.getRaw())); + } + else { + iter.remove(); + } + } + if(!map.isEmpty()) + this.overrides.put(id, map); + return !map.isEmpty(); + } + + public boolean unsetVariableOverride(String id) { + Map map = this.overrides.remove(id); + if(map == null) + return false; + for(Entry entry : map.entrySet()) { + SVar sv = this.variables.get(entry.getKey()); + if(!sv.getRaw().equals(entry.getValue())) { + sv.set("" + entry.getValue(), false, true); + if(sv.sync) + this.sendPacket(new SPacketServerConfig(entry.getKey(), sv.getRaw())); + } + } + return true; + } + + public String removeVariableOverride(String var) { + for(Iterator>> iter = this.overrides.entrySet().iterator(); iter.hasNext();) { + Entry> entry = iter.next(); + Object value = entry.getValue().remove(var); + if(value == null) + continue; + String id = entry.getKey(); + if(entry.getValue().isEmpty()) + iter.remove(); + SVar sv = this.variables.get(var); + if(!sv.getRaw().equals(value)) { + sv.set("" + value, false, true); + if(sv.sync) + this.sendPacket(new SPacketServerConfig(var, sv.getRaw())); + } + return id; + } + return null; + } + + public String getVariableOverride(String var) { + for(Entry> entry : this.overrides.entrySet()) { + if(entry.getValue().containsKey(var)) + return entry.getKey(); + } + return null; + } + + public String getVariableOverrideValue(String var) { + for(Entry> entry : this.overrides.entrySet()) { + if(entry.getValue().containsKey(var)) + return "" + entry.getValue().get(var); + } + return this.variables.get(var).get(); + } private Server() { for(Class clazz : new Class[] {Vars.class, SVars.class}) { diff --git a/server/src/main/java/server/command/CommandEnvironment.java b/server/src/main/java/server/command/CommandEnvironment.java index 15c0c060..c53861e0 100644 --- a/server/src/main/java/server/command/CommandEnvironment.java +++ b/server/src/main/java/server/command/CommandEnvironment.java @@ -279,6 +279,8 @@ public class CommandEnvironment { this.registerExecutable(new CommandEffect()); this.registerExecutable(new CommandExterminatus()); this.registerExecutable(new CommandReset()); + this.registerExecutable(new CommandTick()); + this.registerExecutable(new CommandFreeze()); this.registerExecutable(new CommandSet()); } diff --git a/server/src/main/java/server/command/commands/CommandFreeze.java b/server/src/main/java/server/command/commands/CommandFreeze.java new file mode 100644 index 00000000..5953089a --- /dev/null +++ b/server/src/main/java/server/command/commands/CommandFreeze.java @@ -0,0 +1,22 @@ +package server.command.commands; + +import common.vars.Vars; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.vars.SVars; + +public class CommandFreeze extends Command { + public CommandFreeze() { + super("freeze"); + } + + public void exec(CommandEnvironment env, Executor exec) { + if(env.getServer().unsetVariableOverride("freeze")) { + exec.log("Die Welt ist jetzt nicht mehr eingefroren"); + return; + } + env.getServer().setVariableOverride("freeze", () -> {SVars.randomTick = 0; SVars.boltChance = 0; SVars.weatherTick = 0; SVars.weatherChance = 0; SVars.tickSpawn = false; Vars.dayCycle = false; Vars.mobTick = false; Vars.liquidPhysics = false; Vars.blockGravity = false; Vars.fire = false;}); + exec.log("Welt wurde eingefroren"); + } +} diff --git a/server/src/main/java/server/command/commands/CommandSv.java b/server/src/main/java/server/command/commands/CommandSv.java index 90c48db2..af993484 100644 --- a/server/src/main/java/server/command/commands/CommandSv.java +++ b/server/src/main/java/server/command/commands/CommandSv.java @@ -39,7 +39,7 @@ public class CommandSv extends Command { return null; } - private String formatVariable(String name, SVar sv, String separator, boolean censor) { + private String formatVariable(String name, SVar sv, String override, String separator, boolean censor) { String value = sv.get(); StringBuilder sb = new StringBuilder(Color.YELLOW + name + Color.GRAY + " " + separator + " "); if(sv.noDef && sv.def.equals(value)) @@ -52,6 +52,8 @@ public class CommandSv extends Command { sb.append(((sv.type == ValueType.BOOLEAN ? (value.equals("true") ? Color.GREEN : Color.RED) : Color.BLUE)) + value); if(!sv.def.equals(value)) sb.append(Color.GRAY + " (" + (sv.noDef ? Color.DARK_GRAY + "[ - ]" : Color.BROWN + sv.def) + Color.GRAY + ")"); + if(override != null) + sb.append(Color.GRAY + " [" + Color.RED + override + Color.GRAY + "]"); return sb.toString(); } @@ -60,7 +62,7 @@ public class CommandSv extends Command { if(value != null) throw new RunException("Kann keinen Wert ohne eine Variable angeben"); for(Entry entry : env.getServer().getVariables().entrySet()) { - exec.log(this.formatVariable(entry.getKey(), entry.getValue(), "=", true)); + exec.log(this.formatVariable(entry.getKey(), entry.getValue(), env.getServer().getVariableOverride(entry.getKey()), "=", true)); } exec.log(Color.GREEN + "SVARs insgesamt registriert: %d", env.getServer().getVariables().size()); return null; @@ -93,11 +95,16 @@ public class CommandSv extends Command { throw new RunException(Color.DARK_RED + "'%s' ist keine gültige Zahl", value); } } - sv.set(value, false, true); - if(sv.sync) - env.getServer().sendPacket(new SPacketServerConfig(variable, sv.getRaw())); + String override = env.getServer().removeVariableOverride(variable); + if(override != null) + exec.log(Color.YELLOW + "Überschreibung %s für %s entfernt", override, variable); + if(override == null || !value.equals(sv.get())) { + sv.set(value, false, true); + if(sv.sync) + env.getServer().sendPacket(new SPacketServerConfig(variable, sv.getRaw())); + } } - exec.log(this.formatVariable(variable, sv, value == null ? "=" : "->", false)); + exec.log(this.formatVariable(variable, sv, env.getServer().getVariableOverride(variable), value == null ? "=" : "->", false)); return sv.noDef && sv.def.equals(sv.get()) ? null : sv.get(); } } diff --git a/server/src/main/java/server/command/commands/CommandTick.java b/server/src/main/java/server/command/commands/CommandTick.java new file mode 100644 index 00000000..7cb41a05 --- /dev/null +++ b/server/src/main/java/server/command/commands/CommandTick.java @@ -0,0 +1,26 @@ +package server.command.commands; + +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; + +public class CommandTick extends Command { + public CommandTick() { + super("tick"); + + this.setParamsOptional(); + this.addDouble("target", 2.0, 10000.0); + } + + public void exec(CommandEnvironment env, Executor exec, Double target) { + if(target != null) { + float last = env.getServer().getTpsTarget(); + env.getServer().setTpsTarget(target.floatValue()); + exec.log("Soll-Tick-Geschwindigkeit von %.1f T/s auf %.1f T/s gesetzt", last, env.getServer().getTpsTarget()); + } + else { + float avg = env.getServer().getAverageTps(); + exec.log("Aktuelle Soll-Tick-Geschwindigkeit beträgt %.1f T/s, es werden %.2f T/s bei durchschnittlich %.2f ms erreicht (potenziell %.2f T/s)", env.getServer().getTpsTarget(), env.getServer().getTpsRate(), avg, avg > 0.0f ? 1000.0f / avg : Float.POSITIVE_INFINITY); + } + } +}