SteamWar/BauSystem
Archiviert
13
0

Script Turing Completeness #152

Manuell gemergt
YoyoNow hat 14 Commits von ScriptBranches nach master 2021-01-09 20:40:17 +01:00 zusammengeführt
Nur Änderungen aus Commit a8e6edefb8 werden angezeigt - Alle Commits anzeigen

Datei anzeigen

@ -83,11 +83,9 @@ public class ScriptListener implements Listener {
private final Player player; private final Player player;
private final List<String> commands = new ArrayList<>(); private final List<String> commands = new ArrayList<>();
private final Map<String, Integer> jumpPoints = new HashMap<>(); private final Map<String, Integer> jumpPoints = new HashMap<>();
private final VariableHolder variableHolder = new VariableHolder(); private Map<String, Integer> variables = new HashMap<>();
private boolean lastCommandWasSleep = false;
private int index = 0; private int index = 0;
Veraltet
Review

Mach das System nicht komplexer als nötig.

Mach das System nicht komplexer als nötig.
private int executionPoints = 0;
public ScriptExecutor(BookMeta bookMeta, Player player) { public ScriptExecutor(BookMeta bookMeta, Player player) {
Veraltet
Review

Wenn jemand mehr als 200 Befehle in ein Skriptbuch packt, dann werden eben mehr als 200 Befehle ausgeführt. Du kannst damit nicht Serverabstürze verhindern.

Wenn jemand mehr als 200 Befehle in ein Skriptbuch packt, dann werden eben mehr als 200 Befehle ausgeführt. Du kannst damit nicht Serverabstürze verhindern.
Veraltet
Review

Ich will damit auch verhindern, dass du unendlich schleifen machst. Aber ich habe es nun rausgenommen.

Ich will damit auch verhindern, dass du unendlich schleifen machst. Aber ich habe es nun rausgenommen.
this.player = player; this.player = player;
@ -114,51 +112,36 @@ public class ScriptListener implements Listener {
while (index < commands.size()) { while (index < commands.size()) {
String command = commands.get(index++); String command = commands.get(index++);
executionPoints++; String firstArg = command;
if (executionPoints > 200) { if (command.contains(" ")) {
player.sendMessage(BauSystem.PREFIX + "§cBitte füge ein sleep in dein Script ein."); firstArg = command.substring(0, command.indexOf(' '));
return;
} }
if (executionPoints < 0) { switch (firstArg.toLowerCase()) {
executionPoints = 0; case "sleep":
} ScriptListener.sleepCommand(this, generateArgumentArray("sleep", command));
return;
if (command.toLowerCase().startsWith("sleep")) { case "exit":
ScriptListener.sleepCommand(this, generateArgumentArray("sleep", command)); return;
lastCommandWasSleep = true; case "jump":
return; int jumpIndex = ScriptListener.jumpCommand(this, generateArgumentArray("jump", command));
} if (jumpIndex != -1) {
lastCommandWasSleep = false; index = jumpIndex;
if (command.toLowerCase().startsWith("exit")) { } else {
return; player.sendMessage(BauSystem.PREFIX + "§cUnbekannter Jump Punkt: " + command);
} }
if (command.toLowerCase().startsWith("jump")) { continue;
int jumpIndex = ScriptListener.jumpCommand(this, generateArgumentArray("jump", command)); case "info":
if (jumpIndex != -1) { ScriptListener.infoCommand(this, generateArgumentArray("info", command));
executionPoints += 2; continue;
Veraltet
Review

Wenn du hier mit so vielen Extracommands anfängst: Mach ein switch case draus.

Wenn du hier mit so vielen Extracommands anfängst: Mach ein switch case draus.
index = jumpIndex; case "var":
} else { ScriptListener.variableCommand(this, generateArgumentArray("var", command));
player.sendMessage(BauSystem.PREFIX + "§cUnbekannter Jump Punkt: " + command); continue;
} case "if":
continue; int ifJumpIndex = ScriptListener.ifCommand(this, generateArgumentArray("if", command));
} if (ifJumpIndex != -1) {
if (command.toLowerCase().startsWith("info")) { index = ifJumpIndex;
executionPoints -= 1; }
ScriptListener.infoCommand(this, generateArgumentArray("info", command)); continue;
continue;
}
if (command.toLowerCase().startsWith("var")) {
executionPoints -= 1;
ScriptListener.variableCommand(this, generateArgumentArray("var", command));
continue;
}
if (command.toLowerCase().startsWith("if")) {
int jumpIndex = ScriptListener.ifCommand(this, generateArgumentArray("if", command));
if (jumpIndex != -1) {
executionPoints += 2;
index = jumpIndex;
}
continue;
} }
PlayerCommandPreprocessEvent preprocessEvent = new PlayerCommandPreprocessEvent(player, "/" + command); PlayerCommandPreprocessEvent preprocessEvent = new PlayerCommandPreprocessEvent(player, "/" + command);
@ -191,9 +174,6 @@ public class ScriptListener implements Listener {
scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cDie Zeit darf nur aus Zahlen bestehen."); scriptExecutor.player.sendMessage(BauSystem.PREFIX + "§cDie Zeit darf nur aus Zahlen bestehen.");
} }
} }
if (!scriptExecutor.lastCommandWasSleep) {
scriptExecutor.executionPoints -= sleepTime - 1;
}
Bukkit.getScheduler().runTaskLater(BauSystem.getPlugin(), scriptExecutor::resume, sleepTime); Bukkit.getScheduler().runTaskLater(BauSystem.getPlugin(), scriptExecutor::resume, sleepTime);
} }
@ -207,8 +187,8 @@ public class ScriptListener implements Listener {
private static void infoCommand(ScriptExecutor scriptExecutor, String[] args) { private static void infoCommand(ScriptExecutor scriptExecutor, String[] args) {
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
if (args[i].startsWith("$") && scriptExecutor.variableHolder.isVariable(args[i].substring(1))) { if (args[i].startsWith("$") && isVariable(scriptExecutor, args[i].substring(1))) {
args[i] = scriptExecutor.variableHolder.getValue(args[i].substring(1)) + ""; args[i] = getValue(scriptExecutor, args[i].substring(1)) + "";
} }
} }
scriptExecutor.player.sendMessage("§eInfo§8» §7" + ChatColor.translateAlternateColorCodes('&', String.join(" ", args))); scriptExecutor.player.sendMessage("§eInfo§8» §7" + ChatColor.translateAlternateColorCodes('&', String.join(" ", args)));
@ -227,15 +207,15 @@ public class ScriptListener implements Listener {
case "inc": case "inc":
case "increment": case "increment":
Veraltet
Review

Den Info-Befehl finde ich etwas unnötig, sicherlich wird er interessant zum Debuggen sein, aber wir wollen die Leute nicht dazu ermuntern, horrend aufwändige Skripte zu schreiben, und wenn, dann soll es eine Herausforderung sein. Der Info-Command bläst das System nur ohne nennenswerten Mehrwert auf.

Den Info-Befehl finde ich etwas unnötig, sicherlich wird er interessant zum Debuggen sein, aber wir wollen die Leute nicht dazu ermuntern, horrend aufwändige Skripte zu schreiben, und wenn, dann soll es eine Herausforderung sein. Der Info-Command bläst das System nur ohne nennenswerten Mehrwert auf.
Veraltet
Review

Mit diesem Command soll man, besonders, wenn man einem anderen sein eigenes Skript gibt, So dass er weiß wie man diesen verwendet? Bzw auch um user Rückgaben zu machen.

Mit diesem Command soll man, besonders, wenn man einem anderen sein eigenes Skript gibt, So dass er weiß wie man diesen verwendet? Bzw auch um user Rückgaben zu machen.
case "++": case "++":
scriptExecutor.variableHolder.add(args[0], 1); add(scriptExecutor, args[0], 1);
return; return;
case "dec": case "dec":
case "decrement": case "decrement":
case "--": case "--":
scriptExecutor.variableHolder.add(args[0], -1); add(scriptExecutor, args[0], -1);
return; return;
} }
Veraltet
Review

Bislang sind keine freien Variablen außer den 4 Konstanten fire, tnt, trace & freeze nötig. Das Programm hat so wenige Input- und Outputmöglichkeiten (Man kann Variablen schließlich nur in ifs verwenden), dass man es daher immer auf die Konstanten zurückgreifen kann und einfach keine freien Variablen benötigt. Entweder das System wird mächtiger, oder Variablen sind sinnlos.

Bislang sind keine freien Variablen außer den 4 Konstanten fire, tnt, trace & freeze nötig. Das Programm hat so wenige Input- und Outputmöglichkeiten (Man kann Variablen schließlich nur in ifs verwenden), dass man es daher immer auf die Konstanten zurückgreifen kann und einfach keine freien Variablen benötigt. Entweder das System wird mächtiger, oder Variablen sind sinnlos.
Veraltet
Review

Du kannst mit variablen schleifenabbrüche und sonstige Sachen machen. Ich glaube das das doch sinnvoll wäre.

Du kannst mit variablen schleifenabbrüche und sonstige Sachen machen. Ich glaube das das doch sinnvoll wäre.
Veraltet
Review

Du hast aber nix, wofür Schleifen sinnvoll wären. Variablen kannst du letztendlich nur für ifs verwenden. Und eine "Schleife" kannst du ohne variablen Input auch einfach entrollen, da die Länge schon während des Schreibens des Skriptes bekannt ist, d.h besteht dafür keine Notwendigkeit.

Du hast aber nix, wofür Schleifen sinnvoll wären. Variablen kannst du letztendlich nur für ifs verwenden. Und eine "Schleife" kannst du ohne variablen Input auch einfach entrollen, da die Länge schon während des Schreibens des Skriptes bekannt ist, d.h besteht dafür keine Notwendigkeit.
Veraltet
Review

Jedoch ist es einfacher, wenn man diese als Schleife darstellen kann. Außerdem welche Output/Input Systeme kann man noch einbauen?

Jedoch ist es einfacher, wenn man diese als Schleife darstellen kann. Außerdem welche Output/Input Systeme kann man noch einbauen?
Veraltet
Review

Nein, das ist nicht mal einfacher. Die Variablen fügen dem Skriptsystem derzeit nix hinzu.

Anders würde es aussehen, wenn man die Befehle auch für andere Befehle als für info verwenden könnte...., dann würde ich allerdings info umbenennen in echo und in einen normalen Befehl umwandeln.

Nein, das ist nicht mal einfacher. Die Variablen fügen dem Skriptsystem derzeit nix hinzu. Anders würde es aussehen, wenn man die Befehle auch für andere Befehle als für info verwenden könnte...., dann würde ich allerdings info umbenennen in echo und in einen normalen Befehl umwandeln.
Veraltet
Review

Welche Befehle soll man für andere Befehle verwenden? Meinst du variablen soll man für andere Befehle verwenden können sollen. Und das umwandeln könnte ich. Ich weiß halt nicht wie man das mit den Variablen dann sinnvoll machen sollte. Weil es dann ja scheinbar globale und nicht globale variablen geben sollte?

Welche Befehle soll man für andere Befehle verwenden? Meinst du variablen soll man für andere Befehle verwenden können sollen. Und das umwandeln könnte ich. Ich weiß halt nicht wie man das mit den Variablen dann sinnvoll machen sollte. Weil es dann ja scheinbar globale und nicht globale variablen geben sollte?
Veraltet
Review

Nein, ich habe nix von globalen und nicht globalen Variablen geschrieben. Ich habe etwas von der Einsetzbarkeit von Variablen geschrieben. Ich möchte die Variablen innerhalb eines Skripts für nahezu jeden Befehl verwenden können, z.B. für ein //pos1 X,Y,Z

Nein, ich habe nix von globalen und nicht globalen Variablen geschrieben. Ich habe etwas von der Einsetzbarkeit von Variablen geschrieben. Ich möchte die Variablen innerhalb eines Skripts für nahezu jeden Befehl verwenden können, z.B. für ein //pos1 X,Y,Z
Veraltet
Review

Achso. Ich glaube das lässt sich einrichten.

Achso. Ich glaube das lässt sich einrichten.
scriptExecutor.variableHolder.setValue(args[0], args[1]); setValue(scriptExecutor, args[0], args[1]);
} }
private static int ifCommand(ScriptExecutor scriptExecutor, String[] args) { private static int ifCommand(ScriptExecutor scriptExecutor, String[] args) {
@ -249,15 +229,15 @@ public class ScriptListener implements Listener {
int firstValue; int firstValue;
int secondValue; int secondValue;
if (scriptExecutor.variableHolder.isVariable(args[0])) { if (isVariable(scriptExecutor, args[0])) {
firstValue = scriptExecutor.variableHolder.getValue(args[0]); firstValue = getValue(scriptExecutor, args[0]);
} else { } else {
firstValue = scriptExecutor.variableHolder.parseValue(args[0]); firstValue = parseValue(args[0]);
} }
if (scriptExecutor.variableHolder.isVariable(args[1])) { if (isVariable(scriptExecutor, args[1])) {
secondValue = scriptExecutor.variableHolder.getValue(args[1]); secondValue = getValue(scriptExecutor, args[1]);
} else { } else {
secondValue = scriptExecutor.variableHolder.parseValue(args[1]); secondValue = parseValue(args[1]);
} }
if (firstValue == secondValue) { if (firstValue == secondValue) {
@ -267,60 +247,54 @@ public class ScriptListener implements Listener {
} }
} }
private static class VariableHolder { private static void setValue(ScriptExecutor scriptExecutor, String key, String value) {
scriptExecutor.variables.put(key, parseValue(value));
}
private Map<String, Integer> variables = new HashMap<>(); private static void add(ScriptExecutor scriptExecutor, String key, int value) {
if (!isVariable(scriptExecutor, key)) {
public void setValue(String key, String value) { scriptExecutor.variables.put(key, 0);
variables.put(key, parseValue(value));
} }
scriptExecutor.variables.put(key, scriptExecutor.variables.get(key) + value);
}
public void add(String key, int value) { private static int getValue(ScriptExecutor scriptExecutor, String key) {
if (!isVariable(key)) { switch (key) {
variables.put(key, 0); case "trace":
} return RecordManager.getStatus().isTracing() ? 1 : 0;
variables.put(key, variables.get(key) + value); case "tnt":
return CommandTNT.getInstance().isOn() ? 1 : 0;
case "freeze":
return CommandFreeze.getInstance().isOn() ? 1 : 0;
case "fire":
return CommandFire.getInstance().isOn() ? 1 : 0;
Veraltet
Review

Das System ist viel zu aufwändig für das wenige, dass es kann. Einfach eine Map<String, Integer> statt einem "VariableHolder". Es gibt nur Integer, keine Boolean. Alles außer 0 wird true bewertet. Die Konstanten "trace", "tnt", "freeze" und "fire" kannst du als solche extra behandeln wie hier in getValue().

Das System ist viel zu aufwändig für das wenige, dass es kann. Einfach eine Map<String, Integer> statt einem "VariableHolder". Es gibt nur Integer, keine Boolean. Alles außer 0 wird true bewertet. Die Konstanten "trace", "tnt", "freeze" und "fire" kannst du als solche extra behandeln wie hier in getValue().
} }
return scriptExecutor.variables.getOrDefault(key, 0);
}
public int getValue(String key) { private static boolean isVariable(ScriptExecutor scriptExecutor, String key) {
switch (key) { switch (key) {
case "trace": case "trace":
return RecordManager.getStatus().isTracing() ? 1 : 0; case "tnt":
case "tnt": case "freeze":
return CommandTNT.getInstance().isOn() ? 1 : 0; case "fire":
case "freeze": return true;
return CommandFreeze.getInstance().isOn() ? 1 : 0; default:
case "fire": return scriptExecutor.variables.containsKey(key);
return CommandFire.getInstance().isOn() ? 1 : 0;
}
return variables.getOrDefault(key, 0);
} }
}
public boolean isVariable(String key) { private static int parseValue(String value) {
switch (key) { if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes")) {
case "trace": return 1;
case "tnt": } else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no")) {
case "freeze": return 0;
case "fire":
return true;
default:
return variables.containsKey(key);
}
} }
try {
public int parseValue(String value) { return Integer.parseInt(value);
if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes")) { } catch (NumberFormatException e) {
return 1; return 0;
} else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no")) {
return 0;
}
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
return 0;
}
} }
} }
} }