Change Language to Lua #1
@ -11,6 +11,7 @@ version = project.mod_version
|
|||||||
group = project.maven_group
|
group = project.maven_group
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -9,6 +9,6 @@ org.gradle.parallel=true
|
|||||||
loader_version=0.14.11
|
loader_version=0.14.11
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version = 1.0.0
|
mod_version = 2.0.0
|
||||||
maven_group = de.zonlykroks
|
maven_group = de.zonlykroks
|
||||||
archives_base_name = AdvancedScripts
|
archives_base_name = AdvancedScripts
|
@ -1,13 +0,0 @@
|
|||||||
package de.zonlykroks.advancedscripts.lexer;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Command {
|
|
||||||
public final boolean repeatable;
|
|
||||||
public final List<List<TokenType>> arguments;
|
|
||||||
|
|
||||||
public Command(boolean repeatable, List<List<TokenType>> arguments) {
|
|
||||||
this.repeatable = repeatable;
|
|
||||||
this.arguments = arguments;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package de.zonlykroks.advancedscripts.lexer;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Commands {
|
|
||||||
|
|
||||||
private Commands() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map<String, Command> COMMANDS = new HashMap<>();
|
|
||||||
}
|
|
@ -1,134 +0,0 @@
|
|||||||
package de.zonlykroks.advancedscripts.lexer;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ExpressionColorizer {
|
|
||||||
|
|
||||||
private ExpressionColorizer() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Token> colorize(String expression) {
|
|
||||||
List<String> parts = tokenize(expression);
|
|
||||||
List<Token> tokens = new ArrayList<>();
|
|
||||||
for (int i = 0; i < parts.size(); i++) {
|
|
||||||
String part = parts.get(i);
|
|
||||||
if ("{".equals(part) || "}".equals(part)) {
|
|
||||||
tokens.add(new Token(part, TokenTypeColors.OTHER));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ("true".equalsIgnoreCase(part) || "false".equalsIgnoreCase(part)) {
|
|
||||||
tokens.add(new Token(part, TokenTypeColors.BOOLEAN));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Double.parseDouble(part);
|
|
||||||
tokens.add(new Token(part, TokenTypeColors.NUMBER));
|
|
||||||
continue;
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Long.parseLong(part);
|
|
||||||
tokens.add(new Token(part, TokenTypeColors.NUMBER));
|
|
||||||
continue;
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
}
|
|
||||||
if (part.contains(".")) {
|
|
||||||
String[] split = part.split("\\.");
|
|
||||||
if (split.length == 1) {
|
|
||||||
tokens.add(new Token(part, TokenTypeColors.VARIABLE));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (VariablePrefixes.RPEFIXES.contains(split[0])) {
|
|
||||||
tokens.add(new Token(split[0], TokenTypeColors.OTHER));
|
|
||||||
tokens.add(new Token(".", TokenTypeColors.OTHER));
|
|
||||||
split = Arrays.copyOfRange(split, 1, split.length);
|
|
||||||
}
|
|
||||||
tokens.add(new Token(split[0], TokenTypeColors.VARIABLE));
|
|
||||||
for (int j = 1; j < split.length; j++) {
|
|
||||||
String s = split[j];
|
|
||||||
tokens.add(new Token(".", TokenTypeColors.OTHER));
|
|
||||||
if (VariableSuffixes.SUFFIXES.contains(s)) {
|
|
||||||
tokens.add(new Token(s, TokenTypeColors.OTHER));
|
|
||||||
} else {
|
|
||||||
tokens.add(new Token(s, TokenTypeColors.ERROR));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (Operators.OPERATORS.contains(part)) {
|
|
||||||
String previous = get(parts, i, -1);
|
|
||||||
String next = get(parts, i, 1);
|
|
||||||
if (previous == null || next == null) {
|
|
||||||
tokens.add(new Token(part, TokenTypeColors.ERROR));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (Operators.OPERATORS.contains(previous) || Operators.OPERATORS.contains(next)) {
|
|
||||||
tokens.add(new Token(part, TokenTypeColors.ERROR));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ("{".equals(previous) || "}".equals(next)) {
|
|
||||||
tokens.add(new Token(part, TokenTypeColors.ERROR));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
tokens.add(new Token(part, TokenTypeColors.OTHER));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (part.matches("[+\\-*/%^&|<>=!]+")) {
|
|
||||||
tokens.add(new Token(part, TokenTypeColors.ERROR));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
tokens.add(new Token(part, TokenTypeColors.VARIABLE));
|
|
||||||
}
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String get(List<String> parts, int index, int direction) {
|
|
||||||
for (int i = index + direction; i >= 0 && i < parts.size(); i += direction) {
|
|
||||||
String part = parts.get(i);
|
|
||||||
if (!part.isBlank()) return part;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<String> tokenize(String s) {
|
|
||||||
List<String> tokens = new ArrayList<>();
|
|
||||||
StringBuilder token = new StringBuilder();
|
|
||||||
for (int i = 0; i < s.length(); i++) {
|
|
||||||
char c = s.charAt(i);
|
|
||||||
if (c == '{' || c == '}' || c == ' ') {
|
|
||||||
if (token.length() > 0) {
|
|
||||||
tokens.add(token.toString());
|
|
||||||
token = new StringBuilder();
|
|
||||||
}
|
|
||||||
tokens.add(c + "");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
StringBuilder op = new StringBuilder();
|
|
||||||
for (int j = i; j < s.length(); j++) {
|
|
||||||
char k = s.charAt(j);
|
|
||||||
if (k == '+' || k == '-' || k == '*' || k == '/' || k == '%' || k == '^' || k == '&' || k == '|' || k == '>' || k == '<' || k == '=' || k == '!') {
|
|
||||||
op.append(k);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (op.length() > 0) {
|
|
||||||
if (token.length() > 0) {
|
|
||||||
tokens.add(token.toString());
|
|
||||||
token = new StringBuilder();
|
|
||||||
}
|
|
||||||
tokens.add(op.toString());
|
|
||||||
i += op.length() - 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
token.append(c);
|
|
||||||
}
|
|
||||||
if (token.length() > 0) {
|
|
||||||
tokens.add(token.toString());
|
|
||||||
}
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package de.zonlykroks.advancedscripts.lexer;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class Headers {
|
|
||||||
|
|
||||||
private Headers() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Set<String> HEADERS = new HashSet<>();
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package de.zonlykroks.advancedscripts.lexer;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class Operators {
|
|
||||||
|
|
||||||
private Operators() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Set<String> OPERATORS = new HashSet<>();
|
|
||||||
}
|
|
@ -2,277 +2,115 @@ package de.zonlykroks.advancedscripts.lexer;
|
|||||||
|
|
||||||
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class ScriptColorizer {
|
public class ScriptColorizer {
|
||||||
|
|
||||||
|
private static final Set<String> KEYWORDS = Set.of(
|
||||||
|
"and", "break", "do", "else", "elseif", "end", "for", "function", "goto", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "until", "while"
|
||||||
|
);
|
||||||
|
|
||||||
private ScriptColorizer() {
|
private ScriptColorizer() {
|
||||||
throw new IllegalStateException("Utility class");
|
throw new IllegalStateException("Utility class");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Token> colorize(int lineNumber, String line) {
|
public static List<Token> colorize(String line) {
|
||||||
Lixfel
hat
Könnte man das Einfärben nicht auch Serverseitig machen? Könnte man das Einfärben nicht auch Serverseitig machen?
Chaoscaot
hat
Eher weniger, der Highlighter ist ziemlich generell geschrieben und kann somit auch als outdated Version auf neuen Script laufen. Das auf den Server auszulagern macht einfach nur ziemlich hässlichen Async und Netcode. Eher weniger, der Highlighter ist ziemlich generell geschrieben und kann somit auch als outdated Version auf neuen Script laufen. Das auf den Server auszulagern macht einfach nur ziemlich hässlichen Async und Netcode.
|
|||||||
if (lineNumber == 0) {
|
List<Token> tokens = colorizeComment(line);
|
||||||
List<Token> tokens = colorizeHeader(line);
|
|
||||||
if (tokens != null) return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Token> tokens;
|
|
||||||
tokens = colorizeComment(line);
|
|
||||||
if (tokens != null) return tokens;
|
|
||||||
tokens = colorizeJumpPoint(line);
|
|
||||||
if (tokens != null) return tokens;
|
if (tokens != null) return tokens;
|
||||||
return colorizeLine(line);
|
return colorizeLine(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Token> colorizeHeader(String line) {
|
|
||||||
if (!line.startsWith("#!")) return null;
|
|
||||||
List<Token> tokens = new ArrayList<>();
|
|
||||||
tokens.add(new Token("#!", TokenTypeColors.COMMENT));
|
|
||||||
String s = line.substring(2);
|
|
||||||
|
|
||||||
for (String pattern : Headers.HEADERS) {
|
|
||||||
if (s.matches(pattern)) {
|
|
||||||
tokens.add(new Token(s, TokenTypeColors.OTHER));
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tokens.add(new Token(s, TokenTypeColors.ERROR));
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Token> colorizeComment(String line) {
|
private static List<Token> colorizeComment(String line) {
|
||||||
if (!line.startsWith("#")) return null;
|
if (!line.startsWith("--")) return null;
|
||||||
return List.of(new Token(line, TokenTypeColors.COMMENT));
|
return List.of(new Token(line, TokenTypeColors.COMMENT));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Token> colorizeJumpPoint(String line) {
|
|
||||||
if (!line.startsWith(".")) return null;
|
|
||||||
return List.of(new Token(line, TokenTypeColors.JUMP_POINT));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Token> colorizeLine(String line) {
|
private static List<Token> colorizeLine(String line) {
|
||||||
List<Token> tokens = new ArrayList<>();
|
List<Token> tokens = new ArrayList<>();
|
||||||
|
|
||||||
String command = line;
|
StringBuilder currentToken = new StringBuilder();
|
||||||
if (line.indexOf(' ') != -1) {
|
|
||||||
command = line.substring(0, line.indexOf(' '));
|
boolean inString = false;
|
||||||
}
|
boolean doubleQuoteString = false;
|
||||||
boolean repeatable = false;
|
|
||||||
List<List<TokenType>> argumentTypes = null;
|
System.out.println('"' + line + '"');
|
||||||
if (Commands.COMMANDS.containsKey(command)) {
|
|
||||||
Command c = Commands.COMMANDS.get(command);
|
for (char c : line.toCharArray()) {
|
||||||
repeatable = c.repeatable;
|
switch (c) {
|
||||||
argumentTypes = c.arguments;
|
case '"' -> {
|
||||||
tokens.add(new Token(command, TokenTypeColors.LITERAL));
|
if (inString) {
|
||||||
} else {
|
currentToken.append(c);
|
||||||
repeatable = true;
|
if (doubleQuoteString) {
|
||||||
argumentTypes = new ArrayList<>();
|
tokens.add(new Token(currentToken.toString(), TokenTypeColors.STRING));
|
||||||
argumentTypes.add(List.of(TokenType.any));
|
currentToken = new StringBuilder();
|
||||||
tokens.add(new Token(command, TokenTypeColors.OTHER));
|
inString = false;
|
||||||
}
|
doubleQuoteString = false;
|
||||||
if (command.equals(line)) return tokens;
|
}
|
||||||
tokens.add(Token.SPACE);
|
} else {
|
||||||
|
inString = true;
|
||||||
|
doubleQuoteString = true;
|
||||||
|
if (currentToken.length() > 0) {
|
||||||
|
tokens.add(toToken(currentToken.toString()));
|
||||||
|
currentToken = new StringBuilder();
|
||||||
|
}
|
||||||
|
currentToken.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case '\'' -> {
|
||||||
|
if (inString) {
|
||||||
|
currentToken.append(c);
|
||||||
|
if (!doubleQuoteString) {
|
||||||
|
tokens.add(new Token(currentToken.toString(), TokenTypeColors.STRING));
|
||||||
|
currentToken = new StringBuilder();
|
||||||
|
inString = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inString = true;
|
||||||
|
doubleQuoteString = false;
|
||||||
|
if (currentToken.length() > 0) {
|
||||||
|
tokens.add(toToken(currentToken.toString()));
|
||||||
|
currentToken = new StringBuilder();
|
||||||
|
}
|
||||||
|
currentToken.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case '-', ';', '(', ')', ',', ' ', '{', '\t' -> {
|
||||||
|
if (inString) {
|
||||||
|
currentToken.append(c);
|
||||||
|
} else {
|
||||||
|
if(currentToken.length() > 0) {
|
||||||
|
tokens.add(toToken(currentToken.toString()));
|
||||||
|
}
|
||||||
|
tokens.add(new Token(String.valueOf(c), TokenTypeColors.OTHER));
|
||||||
|
currentToken = new StringBuilder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default -> currentToken.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentToken.length() > 0) {
|
||||||
|
tokens.add(toToken(currentToken.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(tokens);
|
||||||
|
|
||||||
String args = line.substring(command.length() + 1);
|
|
||||||
tokens.addAll(colorizeArgs(args, repeatable, argumentTypes));
|
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Token> colorizeArgs(String args, boolean repeatable, List<List<TokenType>> argumentTypes) {
|
private static Token toToken(String text) {
|
||||||
List<Token> tokens = new ArrayList<>();
|
if (text.length() > 0) {
|
||||||
|
if (KEYWORDS.contains(text)) {
|
||||||
for (List<TokenType> tokenTypes : argumentTypes) {
|
return new Token(text, TokenTypeColors.CONSTANT);
|
||||||
List<Token> temp = new ArrayList<>();
|
} else if ("true".contentEquals(text) || "false".contentEquals(text)) {
|
||||||
int index = 0;
|
return new Token(text, TokenTypeColors.BOOLEAN);
|
||||||
int argIndex = 0;
|
} else if (text.matches("[0-9]+")) {
|
||||||
try {
|
return new Token(text, TokenTypeColors.NUMBER);
|
||||||
while (argIndex < args.length()) {
|
|
||||||
if (args.charAt(argIndex) == ' ') {
|
|
||||||
argIndex++;
|
|
||||||
temp.add(Token.SPACE);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
List<Token> current = parse(tokenTypes.get(index), args.substring(argIndex));
|
|
||||||
if (current.isEmpty()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
temp.addAll(current);
|
|
||||||
argIndex += current.stream().mapToInt(t -> t.text.length()).sum();
|
|
||||||
index++;
|
|
||||||
if (repeatable && index == tokenTypes.size()) {
|
|
||||||
index--;
|
|
||||||
}
|
|
||||||
if (index == tokenTypes.size()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
if (argIndex != args.length()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (index != tokenTypes.size() - (repeatable ? 1 : 0)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!temp.isEmpty()) {
|
|
||||||
tokens.addAll(temp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tokens.isEmpty()) {
|
|
||||||
tokens.add(new Token(args, TokenTypeColors.OTHER));
|
|
||||||
}
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Token> parse(TokenType type, String current) {
|
|
||||||
return switch (type) {
|
|
||||||
case any -> parseAny(current);
|
|
||||||
case expression -> parseExpression(current);
|
|
||||||
case jump_point -> parseJumpPoint(current);
|
|
||||||
case variable -> parseVariable(current);
|
|
||||||
case text_type -> parseText(current);
|
|
||||||
case number_type -> parseNumber(current);
|
|
||||||
case floating_number_type -> parseFloatingNumber(current);
|
|
||||||
case boolean_type -> parseBoolean(current);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Token> parseAny(String current) {
|
|
||||||
List<Token> tokens = parseExpression(current);
|
|
||||||
if (!tokens.isEmpty()) return tokens;
|
|
||||||
tokens = parseFloatingNumber(current);
|
|
||||||
if (!tokens.isEmpty()) return tokens;
|
|
||||||
tokens = parseNumber(current);
|
|
||||||
if (!tokens.isEmpty()) return tokens;
|
|
||||||
tokens = parseBoolean(current);
|
|
||||||
if (!tokens.isEmpty()) return tokens;
|
|
||||||
return parseText(current);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Token> parseExpression(String current) {
|
|
||||||
if (!current.startsWith("{")) return new ArrayList<>();
|
|
||||||
int depth = 0;
|
|
||||||
int index = 0;
|
|
||||||
do {
|
|
||||||
if (current.charAt(index) == '{') {
|
|
||||||
depth++;
|
|
||||||
} else if (current.charAt(index) == '}') {
|
|
||||||
depth--;
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
} while (depth != 0 && index < current.length());
|
|
||||||
if (depth != 0) return List.of(new Token(current, TokenTypeColors.ERROR));
|
|
||||||
return ExpressionColorizer.colorize(current.substring(0, index));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Token> parseJumpPoint(String current) {
|
|
||||||
int index = current.indexOf(' ');
|
|
||||||
if (index == -1) {
|
|
||||||
return List.of(new Token(current, TokenTypeColors.JUMP_POINT));
|
|
||||||
} else {
|
|
||||||
return List.of(new Token(current.substring(0, index), TokenTypeColors.JUMP_POINT));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Token> parseVariable(String current) {
|
|
||||||
int index = current.indexOf(' ');
|
|
||||||
if (index == -1) {
|
|
||||||
return List.of(new Token(current, TokenTypeColors.VARIABLE));
|
|
||||||
} else {
|
|
||||||
return List.of(new Token(current.substring(0, index), TokenTypeColors.VARIABLE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Token> parseText(String current) {
|
|
||||||
int index = current.indexOf(' ');
|
|
||||||
if (index != -1) {
|
|
||||||
current = current.substring(0, index);
|
|
||||||
}
|
|
||||||
List<Token> tokens = new ArrayList<>();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (int i = 0; i < current.length(); i++) {
|
|
||||||
char c = current.charAt(i);
|
|
||||||
if (c == '&' && i + 1 < current.length()) {
|
|
||||||
char color = current.charAt(i + 1);
|
|
||||||
if (color >= '0' && color <= '9' || color >= 'a' && color <= 'f' || color >= 'A' && color <= 'F') {
|
|
||||||
if (sb.length() > 0) {
|
|
||||||
tokens.add(new Token(sb.toString(), TokenTypeColors.TEXT));
|
|
||||||
sb = new StringBuilder();
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
switch (color) {
|
|
||||||
case '0' -> tokens.add(new Token("&0", 0xFF000000));
|
|
||||||
case '1' -> tokens.add(new Token("&1", 0xFF0000AA));
|
|
||||||
case '2' -> tokens.add(new Token("&2", 0xFF00AA00));
|
|
||||||
case '3' -> tokens.add(new Token("&3", 0xFF00AAAA));
|
|
||||||
case '4' -> tokens.add(new Token("&4", 0xFFAA0000));
|
|
||||||
case '5' -> tokens.add(new Token("&5", 0xFFAA00AA));
|
|
||||||
case '6' -> tokens.add(new Token("&6", 0xFFFFAA00));
|
|
||||||
case '7' -> tokens.add(new Token("&7", 0xFFAAAAAA));
|
|
||||||
case '8' -> tokens.add(new Token("&8", 0xFF555555));
|
|
||||||
case '9' -> tokens.add(new Token("&9", 0xFF5555FF));
|
|
||||||
case 'a', 'A' -> tokens.add(new Token("&a", 0xFF55FF55));
|
|
||||||
case 'b', 'B' -> tokens.add(new Token("&b", 0xFF55FFFF));
|
|
||||||
case 'c', 'C' -> tokens.add(new Token("&c", 0xFFFF5555));
|
|
||||||
case 'd', 'D' -> tokens.add(new Token("&d", 0xFFFF55FF));
|
|
||||||
case 'e', 'E' -> tokens.add(new Token("&e", 0xFFFFFF55));
|
|
||||||
case 'f', 'F' -> tokens.add(new Token("&f", 0xFFFFFFFF));
|
|
||||||
default -> tokens.add(new Token("&" + color, TokenTypeColors.TEXT));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sb.append(c);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
sb.append(c);
|
return new Token(text, TokenTypeColors.OTHER);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (sb.length() > 0) {
|
|
||||||
tokens.add(new Token(sb.toString(), TokenTypeColors.TEXT));
|
|
||||||
}
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Token> parseNumber(String current) {
|
|
||||||
int index = current.indexOf(' ');
|
|
||||||
String number = current;
|
|
||||||
if (index != -1) {
|
|
||||||
number = current.substring(0, index);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Long.parseLong(number);
|
|
||||||
return List.of(new Token(number, TokenTypeColors.NUMBER));
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Token> parseFloatingNumber(String current) {
|
|
||||||
int index = current.indexOf(' ');
|
|
||||||
String number = current;
|
|
||||||
if (index != -1) {
|
|
||||||
number = current.substring(0, index);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Double.parseDouble(number);
|
|
||||||
return List.of(new Token(number, TokenTypeColors.NUMBER));
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Token> parseBoolean(String current) {
|
|
||||||
int index = current.indexOf(' ');
|
|
||||||
String bool = current;
|
|
||||||
if (index != -1) {
|
|
||||||
bool = current.substring(0, index);
|
|
||||||
}
|
|
||||||
if ("true".equalsIgnoreCase(bool) || "false".equalsIgnoreCase(bool)) {
|
|
||||||
return List.of(new Token(bool, TokenTypeColors.BOOLEAN));
|
|
||||||
} else {
|
} else {
|
||||||
return new ArrayList<>();
|
return Token.SPACE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
package de.zonlykroks.advancedscripts.lexer;
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class ScriptSyntaxPacketParser {
|
|
||||||
|
|
||||||
private ScriptSyntaxPacketParser() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final TokenType[] TOKEN_TYPES = TokenType.values();
|
|
||||||
|
|
||||||
private static void reset() {
|
|
||||||
Operators.OPERATORS.clear();
|
|
||||||
Headers.HEADERS.clear();
|
|
||||||
VariablePrefixes.RPEFIXES.clear();
|
|
||||||
VariableSuffixes.SUFFIXES.clear();
|
|
||||||
Commands.COMMANDS.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static synchronized void parse(String scriptSyntax) {
|
|
||||||
reset();
|
|
||||||
|
|
||||||
JsonObject jsonObject = JsonParser.parseString(scriptSyntax).getAsJsonObject();
|
|
||||||
for (String key : jsonObject.keySet()) {
|
|
||||||
JsonArray jsonElements = jsonObject.get(key).getAsJsonArray();
|
|
||||||
if (key.startsWith("@")) {
|
|
||||||
parseSpecial(key, jsonElements);
|
|
||||||
} else {
|
|
||||||
parseCommand(key, jsonElements);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void parseCommand(String key, JsonArray value) {
|
|
||||||
boolean repeating = value.get(0).getAsBoolean();
|
|
||||||
List<List<TokenType>> validArgumentTypes = new ArrayList<>();
|
|
||||||
for (int i = 1; i < value.size(); i++) {
|
|
||||||
JsonArray parameters = value.get(i).getAsJsonArray();
|
|
||||||
List<TokenType> parameterTypes = new ArrayList<>();
|
|
||||||
for (JsonElement parameter : parameters) {
|
|
||||||
parameterTypes.add(TOKEN_TYPES[parameter.getAsInt()]);
|
|
||||||
}
|
|
||||||
validArgumentTypes.add(parameterTypes);
|
|
||||||
}
|
|
||||||
Commands.COMMANDS.put(key, new Command(repeating, validArgumentTypes));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void parseSpecial(String key, JsonArray value) {
|
|
||||||
Set<String> set;
|
|
||||||
switch (key) {
|
|
||||||
case "@operators":
|
|
||||||
set = Operators.OPERATORS;
|
|
||||||
break;
|
|
||||||
case "@headers":
|
|
||||||
set = Headers.HEADERS;
|
|
||||||
break;
|
|
||||||
case "@prefixes":
|
|
||||||
set = VariablePrefixes.RPEFIXES;
|
|
||||||
break;
|
|
||||||
case "@suffixes":
|
|
||||||
set = VariableSuffixes.SUFFIXES;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (JsonElement element : value) {
|
|
||||||
set.add(element.getAsString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,4 +10,12 @@ public class Token {
|
|||||||
this.text = text;
|
this.text = text;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Token{" +
|
||||||
|
"text='" + text + '\'' +
|
||||||
|
", color=" + color +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
package de.zonlykroks.advancedscripts.lexer;
|
|
||||||
|
|
||||||
public enum TokenType { // This is copied from the BauSystem2.0 sources.
|
|
||||||
any, // This does not include jump_point and variable
|
|
||||||
expression,
|
|
||||||
jump_point,
|
|
||||||
variable,
|
|
||||||
|
|
||||||
text_type,
|
|
||||||
number_type,
|
|
||||||
floating_number_type,
|
|
||||||
boolean_type,
|
|
||||||
}
|
|
@ -1,5 +1,7 @@
|
|||||||
package de.zonlykroks.advancedscripts.lexer;
|
package de.zonlykroks.advancedscripts.lexer;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
Lixfel
hat
AWT für ein HSBtoRGB zu importieren... muss nicht unbedingt sein. AWT für ein HSBtoRGB zu importieren... muss nicht unbedingt sein.
|
|||||||
|
|
||||||
public class TokenTypeColors {
|
public class TokenTypeColors {
|
||||||
|
|
||||||
private TokenTypeColors() {
|
private TokenTypeColors() {
|
||||||
@ -13,11 +15,10 @@ public class TokenTypeColors {
|
|||||||
public static final int ERROR = 0xFFAA0000;
|
public static final int ERROR = 0xFFAA0000;
|
||||||
|
|
||||||
public static final int VARIABLE = 0xFFFFFFFF;
|
public static final int VARIABLE = 0xFFFFFFFF;
|
||||||
public static final int LITERAL = 0xFF925F35;
|
|
||||||
public static final int COMMENT = 0xFF656565;
|
public static final int COMMENT = 0xFF656565;
|
||||||
public static final int JUMP_POINT = 0xFFFFa500;
|
public static final int CONSTANT = Color.HSBtoRGB(219, 0.54f, 0.51f);
|
||||||
|
|
||||||
public static final int NUMBER = 0xFF61839F;
|
public static final int NUMBER = 0xFF61839F;
|
||||||
public static final int BOOLEAN = 0xFF925F35;
|
public static final int BOOLEAN = 0xFF925F35;
|
||||||
public static final int TEXT = 0xFF6F855D;
|
public static final int STRING = Color.HSBtoRGB(150, 0.63f, 0.3f);
|
||||||
}
|
}
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
package de.zonlykroks.advancedscripts.lexer;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class VariablePrefixes {
|
|
||||||
|
|
||||||
private VariablePrefixes() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Set<String> RPEFIXES = new HashSet<>();
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package de.zonlykroks.advancedscripts.lexer;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class VariableSuffixes {
|
|
||||||
|
|
||||||
private VariableSuffixes() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Set<String> SUFFIXES = new HashSet<>();
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
package de.zonlykroks.advancedscripts.mixin;
|
|
||||||
|
|
||||||
import de.zonlykroks.advancedscripts.lexer.ScriptSyntaxPacketParser;
|
|
||||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
|
||||||
import net.minecraft.network.PacketByteBuf;
|
|
||||||
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
@Mixin(ClientPlayNetworkHandler.class)
|
|
||||||
public class ClientPlayNetworkHandlerMixin {
|
|
||||||
|
|
||||||
private static final Identifier CHANNEL = new Identifier("sw:script_syntax");
|
|
||||||
|
|
||||||
@Inject(method = "onCustomPayload", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/play/CustomPayloadS2CPacket;getData()Lnet/minecraft/network/PacketByteBuf;"), cancellable = true)
|
|
||||||
public void onCustomPayload(CustomPayloadS2CPacket packet, CallbackInfo ci) {
|
|
||||||
if (CHANNEL.equals(packet.getChannel())) {
|
|
||||||
PacketByteBuf buf = packet.getData();
|
|
||||||
int readableBytes = buf.readableBytes();
|
|
||||||
StringBuilder st = new StringBuilder();
|
|
||||||
for (int i = 0; i < readableBytes; i++) {
|
|
||||||
st.append((char) buf.readByte());
|
|
||||||
}
|
|
||||||
ScriptSyntaxPacketParser.parse(st.toString());
|
|
||||||
ci.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,6 +6,8 @@ import de.zonlykroks.advancedscripts.lexer.Token;
|
|||||||
import de.zonlykroks.advancedscripts.lexer.TokenTypeColors;
|
import de.zonlykroks.advancedscripts.lexer.TokenTypeColors;
|
||||||
import net.minecraft.client.font.TextHandler;
|
import net.minecraft.client.font.TextHandler;
|
||||||
import net.minecraft.client.gui.DrawableHelper;
|
import net.minecraft.client.gui.DrawableHelper;
|
||||||
|
import net.minecraft.client.gui.Element;
|
||||||
|
import net.minecraft.client.gui.Selectable;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
import net.minecraft.client.gui.screen.ingame.BookEditScreen;
|
import net.minecraft.client.gui.screen.ingame.BookEditScreen;
|
||||||
import net.minecraft.client.gui.screen.ingame.BookScreen;
|
import net.minecraft.client.gui.screen.ingame.BookScreen;
|
||||||
@ -25,7 +27,12 @@ import net.minecraft.text.Style;
|
|||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import org.apache.commons.lang3.mutable.MutableInt;
|
import org.apache.commons.lang3.mutable.MutableInt;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.luaj.vm2.ast.Chunk;
|
||||||
|
import org.luaj.vm2.parser.LuaParser;
|
||||||
|
import org.luaj.vm2.parser.ParseException;
|
||||||
|
|
||||||
|
import java.io.StringReader;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@ -137,6 +144,7 @@ public class ScriptEditScreen extends Screen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||||
|
setFocused(null);
|
||||||
this.renderBackground(matrices);
|
this.renderBackground(matrices);
|
||||||
RenderSystem.setShader(GameRenderer::getPositionTexProgram);
|
RenderSystem.setShader(GameRenderer::getPositionTexProgram);
|
||||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||||
@ -169,11 +177,11 @@ public class ScriptEditScreen extends Screen {
|
|||||||
if (lineTooLong(s)) {
|
if (lineTooLong(s)) {
|
||||||
fill(matrices, 25 + lineNumberLength + 2, 25 + lineNumber.getValue() * 9, 25 + lineNumberLength + 3, 25 + lineNumber.getValue() * 9 + height, TokenTypeColors.ERROR);
|
fill(matrices, 25 + lineNumberLength + 2, 25 + lineNumber.getValue() * 9, 25 + lineNumberLength + 3, 25 + lineNumber.getValue() * 9 + height, TokenTypeColors.ERROR);
|
||||||
}
|
}
|
||||||
this.textRenderer.draw(matrices, lineNumberText + "", 25 + lineNumberLength - textRenderer.getWidth(lineNumberText + ""), 25 + lineNumber.getValue() * 9, 0xFFFFFF);
|
this.textRenderer.draw(matrices, String.valueOf(lineNumberText), 25f + lineNumberLength - textRenderer.getWidth(String.valueOf(lineNumberText)), 25f + lineNumber.getValue() * 9f, 0xFFFFFF);
|
||||||
lineNumberText++;
|
lineNumberText++;
|
||||||
|
|
||||||
// Line text
|
// Line text
|
||||||
List<Token> tokens = ScriptColorizer.colorize(lineNumber.getValue(), s);
|
List<Token> tokens = ScriptColorizer.colorize(s);
|
||||||
AtomicInteger x = new AtomicInteger(25 + lineNumberLength + 5);
|
AtomicInteger x = new AtomicInteger(25 + lineNumberLength + 5);
|
||||||
AtomicInteger currentXIndex = new AtomicInteger(0);
|
AtomicInteger currentXIndex = new AtomicInteger(0);
|
||||||
for (Token token : tokens) {
|
for (Token token : tokens) {
|
||||||
@ -252,6 +260,7 @@ public class ScriptEditScreen extends Screen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void key(int keyCode) {
|
private void key(int keyCode) {
|
||||||
|
setFocused(null);
|
||||||
if (Screen.isSelectAll(keyCode)) {
|
if (Screen.isSelectAll(keyCode)) {
|
||||||
this.cursorX = 0;
|
this.cursorX = 0;
|
||||||
this.cursorY = 0;
|
this.cursorY = 0;
|
||||||
@ -282,46 +291,49 @@ public class ScriptEditScreen extends Screen {
|
|||||||
int previousCursorX = cursorX;
|
int previousCursorX = cursorX;
|
||||||
int previousCursorY = cursorY;
|
int previousCursorY = cursorY;
|
||||||
switch (keyCode) {
|
switch (keyCode) {
|
||||||
case 257:
|
case 258 -> {
|
||||||
case 335:
|
insert(" ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 257, 335 -> {
|
||||||
selection(true);
|
selection(true);
|
||||||
newLine();
|
newLine();
|
||||||
valid = false;
|
valid = false;
|
||||||
break;
|
}
|
||||||
case 259:
|
case 259 -> {
|
||||||
if (selection(true) == null) backspace(selectionType);
|
if (selection(true) == null) backspace(selectionType);
|
||||||
valid = false;
|
valid = false;
|
||||||
break;
|
}
|
||||||
case 261:
|
case 261 -> {
|
||||||
if (selection(true) == null) delete(selectionType);
|
if (selection(true) == null) delete(selectionType);
|
||||||
valid = false;
|
valid = false;
|
||||||
break;
|
}
|
||||||
case 262:
|
case 262 -> {
|
||||||
moveCursor(1, selectionType);
|
moveCursor(1, selectionType);
|
||||||
valid = Screen.hasShiftDown();
|
valid = Screen.hasShiftDown();
|
||||||
break;
|
}
|
||||||
case 263:
|
case 263 -> {
|
||||||
moveCursor(-1, selectionType);
|
moveCursor(-1, selectionType);
|
||||||
valid = Screen.hasShiftDown();
|
valid = Screen.hasShiftDown();
|
||||||
break;
|
}
|
||||||
case 264:
|
case 264 -> {
|
||||||
moveDown();
|
moveDown();
|
||||||
valid = Screen.hasShiftDown();
|
valid = Screen.hasShiftDown();
|
||||||
break;
|
}
|
||||||
case 265:
|
case 265 -> {
|
||||||
moveUp();
|
moveUp();
|
||||||
valid = Screen.hasShiftDown();
|
valid = Screen.hasShiftDown();
|
||||||
break;
|
}
|
||||||
case 268:
|
case 268 -> {
|
||||||
cursorX = 0;
|
cursorX = 0;
|
||||||
valid = Screen.hasShiftDown();
|
valid = Screen.hasShiftDown();
|
||||||
break;
|
}
|
||||||
case 269:
|
case 269 -> {
|
||||||
cursorX = lines.get(cursorY).length();
|
cursorX = lines.get(cursorY).length();
|
||||||
valid = Screen.hasShiftDown();
|
valid = Screen.hasShiftDown();
|
||||||
break;
|
}
|
||||||
default:
|
default -> {
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (Screen.hasShiftDown() && savedCursorX == -1 && savedCursorY == -1) {
|
if (Screen.hasShiftDown() && savedCursorX == -1 && savedCursorY == -1) {
|
||||||
@ -337,6 +349,7 @@ public class ScriptEditScreen extends Screen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||||
|
setFocused(null);
|
||||||
if (super.keyPressed(keyCode, scanCode, modifiers)) {
|
if (super.keyPressed(keyCode, scanCode, modifiers)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -348,17 +361,19 @@ public class ScriptEditScreen extends Screen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
|
public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
|
||||||
|
setFocused(null);
|
||||||
this.keyCode = -1;
|
this.keyCode = -1;
|
||||||
return super.keyReleased(keyCode, scanCode, modifiers);
|
return super.keyReleased(keyCode, scanCode, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean charTyped(char chr, int modifiers) {
|
public boolean charTyped(char chr, int modifiers) {
|
||||||
|
setFocused(null);
|
||||||
if (super.charTyped(chr, modifiers)) {
|
if (super.charTyped(chr, modifiers)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
selection(true);
|
selection(true);
|
||||||
boolean valid = insert(chr + "");
|
boolean valid = insert(String.valueOf(chr));
|
||||||
savedCursorY = -1;
|
savedCursorY = -1;
|
||||||
savedCursorX = -1;
|
savedCursorX = -1;
|
||||||
autoScroll();
|
autoScroll();
|
||||||
|
@ -7,8 +7,7 @@
|
|||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"KeyboardMixin",
|
"KeyboardMixin",
|
||||||
"ClientPlayerEntityMixin",
|
"ClientPlayerEntityMixin"
|
||||||
"ClientPlayNetworkHandlerMixin"
|
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
"name": "Advanced Scripts",
|
"name": "Advanced Scripts",
|
||||||
"description": "An addition to the Steamwar script system!",
|
"description": "An addition to the Steamwar script system!",
|
||||||
"authors": [
|
"authors": [
|
||||||
"zOnlyKroks"
|
"zOnlyKroks",
|
||||||
|
"Chaoscaot"
|
||||||
],
|
],
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"environment": "client",
|
"environment": "client",
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren
Kein License-Header, falsches package
Ich habe da nichts geändert...