6
6
import com .google .gson .*;
7
7
import net .minecraft .client .MinecraftClient ;
8
8
import net .minecraft .util .Pair ;
9
+ import oshi .util .tuples .Triplet ;
9
10
10
11
import java .io .*;
11
12
import java .text .DecimalFormat ;
@@ -16,7 +17,7 @@ public class Config {
16
17
public static final JsonObject JSON ;
17
18
public static final Gson GSON ;
18
19
public static final File CONFIG_FILE ;
19
- public static final Map <String , Pair <List <Token >, String >> FUNCTIONS ;
20
+ public static final Map <String , Pair <List <Token >, String [] >> FUNCTIONS ;
20
21
public static final ImmutableMap <String , String > DEFAULTS ;
21
22
22
23
static {
@@ -71,7 +72,7 @@ public static boolean logExceptions() {
71
72
public static void refreshJson () {
72
73
try {
73
74
FileWriter writer = new FileWriter (CONFIG_FILE );
74
- JSON .add ("functions" , FUNCTIONS .entrySet ().stream ().map (x -> x .getKey () + "(" + x .getValue ().getRight () + ")=" + x .getValue ().getLeft ().stream ().map (Object ::toString ).collect (Collectors .joining ())).collect (JsonArray ::new , JsonArray ::add , JsonArray ::addAll ));
75
+ JSON .add ("functions" , FUNCTIONS .entrySet ().stream ().map (x -> x .getKey () + "(" + String . join ( ChatCalc . SEPARATOR , x .getValue ().getRight () ) + ")=" + x .getValue ().getLeft ().stream ().map (Object ::toString ).collect (Collectors .joining ())).collect (JsonArray ::new , JsonArray ::add , JsonArray ::addAll ));
75
76
writer .write (GSON .toJson (JSON ));
76
77
JSON .remove ("functions" );
77
78
writer .close ();
@@ -89,11 +90,38 @@ public static void readJson() {
89
90
JsonObject json = tempJson ; // annoying lambda requirement
90
91
DEFAULTS .forEach ((key , defaultValue ) -> JSON .add (key , json .get (key ) instanceof JsonPrimitive primitive && primitive .isString () ? primitive : new JsonPrimitive (defaultValue )));
91
92
if (json .get ("functions" ) instanceof JsonArray array ) {
92
- array .forEach (e -> FUNCTIONS .put (e .getAsString ().split ("\\ (" )[0 ], new Pair <>(MathEngine .tokenize (e .getAsString ().split ("=" )[1 ]), e .getAsString ().split ("[()]" )[1 ])));
93
+ array .forEach (e -> {
94
+ if (e instanceof JsonPrimitive primitive && primitive .isString ()) {
95
+ parseFunction (e .getAsString ()).ifPresent (parsedFunction -> FUNCTIONS .put (parsedFunction .getA (), new Pair <>(parsedFunction .getB (), parsedFunction .getC ())));
96
+ }
97
+ });
93
98
}
94
99
} catch (Exception ignored ) { }
95
100
}
96
101
102
+ public static Optional <Triplet <String , List <Token >, String []>> parseFunction (String function ) {
103
+ int functionNameEnd = function .indexOf ('(' );
104
+ if (functionNameEnd > 0 ) {
105
+ String functionName = function .substring (0 , functionNameEnd );
106
+ int paramsEnd = function .substring (functionNameEnd ).indexOf (')' ) + functionNameEnd ;
107
+ if (functionName .matches ("[A-Za-z]+" ) && paramsEnd > 0 && function .substring (paramsEnd + 1 ).startsWith ("=" ) && function .length () > paramsEnd + 2 ) { // I'm not commenting why this works, I know it, It's just hard to explain
108
+ String [] params = function .substring (functionNameEnd + 1 , paramsEnd ).split (ChatCalc .SEPARATOR );
109
+ for (String param : params ) {
110
+ if (!param .matches ("[A-Za-z]" )) {
111
+ return Optional .empty ();
112
+ }
113
+ }
114
+ String rest = function .substring (paramsEnd + 2 );
115
+ try {
116
+ List <Token > tokens = MathEngine .tokenize (rest );
117
+ return Optional .of (new Triplet <>(functionName , tokens , params ));
118
+ // System.out.printf("fn: %s, params: %s, rest: %s%n", functionName, params, rest);
119
+ } catch (Exception ignored ) { }
120
+ }
121
+ }
122
+ return Optional .empty ();
123
+ }
124
+
97
125
public static boolean debugTokens () {
98
126
return Boolean .parseBoolean (JSON .get ("debug_tokens" ).getAsString ());
99
127
}
@@ -105,13 +133,26 @@ public static void saveToChatHud(String input) {
105
133
}
106
134
}
107
135
108
- public static double func (String name , double value ) {
136
+ public static double func (String name , double ... values ) {
109
137
if (FUNCTIONS .containsKey (name )) {
138
+ if (values .length != FUNCTIONS .get (name ).getRight ().length ) {
139
+ throw new IllegalArgumentException ();
140
+ }
110
141
List <Token > tokens = new ArrayList <>(FUNCTIONS .get (name ).getLeft ());
111
- MathEngine .simplify (tokens , false , Optional .of (new Pair <>(FUNCTIONS .get (name ).getRight (), value )));
112
- return ((NumberToken ) tokens .get (0 )).val ;
142
+ FunctionParameter [] parameters = new FunctionParameter [values .length ];
143
+ for (int i = 0 ; i < parameters .length ; i ++) {
144
+ parameters [i ] = new FunctionParameter (FUNCTIONS .get (name ).getRight ()[i ], values [i ]);
145
+ }
146
+ MathEngine .simplify (tokens , false , Optional .of (parameters ));
147
+ if (tokens .get (0 ) instanceof NumberToken numberToken ) {
148
+ return numberToken .val ;
149
+ }
150
+ throw new IllegalArgumentException ();
113
151
} else {
114
- return value ;
152
+ if (values .length == 0 ) {
153
+ throw new IllegalArgumentException ();
154
+ }
155
+ return values [0 ];
115
156
}
116
157
}
117
158
0 commit comments