4
4
import com .mojang .brigadier .CommandDispatcher ;
5
5
import com .mojang .brigadier .arguments .StringArgumentType ;
6
6
import com .mojang .brigadier .exceptions .CommandSyntaxException ;
7
+ import com .mojang .brigadier .exceptions .DynamicCommandExceptionType ;
7
8
import com .mojang .brigadier .exceptions .SimpleCommandExceptionType ;
9
+ import com .mojang .brigadier .suggestion .Suggestions ;
10
+ import com .mojang .brigadier .suggestion .SuggestionsBuilder ;
8
11
import dev .ftb .mods .ftblibrary .snbt .SNBT ;
9
12
import dev .ftb .mods .ftbranks .api .FTBRanksAPI ;
10
13
import dev .ftb .mods .ftbranks .api .PermissionValue ;
18
21
import net .minecraft .ChatFormatting ;
19
22
import net .minecraft .commands .CommandSourceStack ;
20
23
import net .minecraft .commands .Commands ;
24
+ import net .minecraft .commands .SharedSuggestionProvider ;
21
25
import net .minecraft .commands .arguments .EntityArgument ;
22
26
import net .minecraft .commands .arguments .GameProfileArgument ;
23
27
import net .minecraft .nbt .StringTag ;
24
28
import net .minecraft .network .chat .Component ;
25
- import net .minecraft .network .chat .MutableComponent ;
26
29
import net .minecraft .network .chat .TextComponent ;
27
- import net .minecraft .network .chat .TranslatableComponent ;
28
30
import net .minecraft .server .level .ServerPlayer ;
29
31
import org .apache .commons .lang3 .math .NumberUtils ;
30
32
31
33
import java .io .IOException ;
32
34
import java .util .Collection ;
33
35
import java .util .Collections ;
36
+ import java .util .concurrent .CompletableFuture ;
34
37
35
38
/**
36
39
* @author LatvianModder
37
40
*/
38
41
public class FTBRanksCommands {
42
+ public static final DynamicCommandExceptionType ERROR_UNKNOWN_RANK = new DynamicCommandExceptionType ((object ) -> new TextComponent ("Unknown rank: " + object .toString ()));
43
+
39
44
public static void register (CommandDispatcher <CommandSourceStack > dispatcher , Commands .CommandSelection selection ) {
40
45
dispatcher .register (Commands .literal ("ftbranks" )
41
46
.requires (source -> source .getServer ().isSingleplayer () || source .hasPermission (2 ))
@@ -54,21 +59,24 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher, Co
54
59
)
55
60
)
56
61
.then (Commands .literal ("delete" )
57
- .then (Commands .argument ("rank" , RankArgumentType .rank ())
58
- .executes (context -> deleteRank (context .getSource (), RankArgumentType .getRank (context , "rank" )))
62
+ .then (Commands .argument ("rank" , StringArgumentType .word ())
63
+ .suggests ((context , builder ) -> suggestRanks (builder ))
64
+ .executes (context -> deleteRank (context .getSource (), StringArgumentType .getString (context , "rank" )))
59
65
)
60
66
)
61
67
.then (Commands .literal ("add" )
62
68
.then (Commands .argument ("players" , GameProfileArgument .gameProfile ())
63
- .then (Commands .argument ("rank" , RankArgumentType .rank ())
64
- .executes (context -> addRank (context .getSource (), GameProfileArgument .getGameProfiles (context , "players" ), RankArgumentType .getRank (context , "rank" )))
69
+ .then (Commands .argument ("rank" , StringArgumentType .word ())
70
+ .suggests ((context , builder ) -> suggestRanks (builder ))
71
+ .executes (context -> addRank (context .getSource (), GameProfileArgument .getGameProfiles (context , "players" ), StringArgumentType .getString (context , "rank" )))
65
72
)
66
73
)
67
74
)
68
75
.then (Commands .literal ("remove" )
69
76
.then (Commands .argument ("players" , GameProfileArgument .gameProfile ())
70
- .then (Commands .argument ("rank" , RankArgumentType .rank ())
71
- .executes (context -> removeRank (context .getSource (), GameProfileArgument .getGameProfiles (context , "players" ), RankArgumentType .getRank (context , "rank" )))
77
+ .then (Commands .argument ("rank" , StringArgumentType .word ())
78
+ .suggests ((context , builder ) -> suggestRanks (builder ))
79
+ .executes (context -> removeRank (context .getSource (), GameProfileArgument .getGameProfiles (context , "players" ), StringArgumentType .getString (context , "rank" )))
72
80
)
73
81
)
74
82
)
@@ -78,51 +86,60 @@ public static void register(CommandDispatcher<CommandSourceStack> dispatcher, Co
78
86
)
79
87
)
80
88
.then (Commands .literal ("list_players_with" )
81
- .then (Commands .argument ("rank" , RankArgumentType .rank ())
82
- .executes (context -> listPlayersWith (context .getSource (), RankArgumentType .getRank (context , "rank" )))
89
+ .then (Commands .argument ("rank" , StringArgumentType .word ())
90
+ .suggests ((context , builder ) -> suggestRanks (builder ))
91
+ .executes (context -> listPlayersWith (context .getSource (), StringArgumentType .getString (context , "rank" )))
83
92
)
84
93
)
85
94
.then (Commands .literal ("node" )
86
95
.then (Commands .literal ("add" )
87
- .then (Commands .argument ("rank" , RankArgumentType .rank ())
96
+ .then (Commands .argument ("rank" , StringArgumentType .word ())
97
+ .suggests ((context , builder ) -> suggestRanks (builder ))
88
98
.then (Commands .argument ("node" , StringArgumentType .word ())
89
99
.then (Commands .argument ("value" , StringArgumentType .greedyString ())
90
- .executes (context -> setNode (context .getSource (), RankArgumentType . getRank (context , "rank" ), StringArgumentType .getString (context , "node" ), StringArgumentType .getString (context , "value" )))
100
+ .executes (context -> setNode (context .getSource (), StringArgumentType . getString (context , "rank" ), StringArgumentType .getString (context , "node" ), StringArgumentType .getString (context , "value" )))
91
101
)
92
102
)
93
103
)
94
104
)
95
105
.then (Commands .literal ("remove" )
96
- .then (Commands .argument ("rank" , RankArgumentType .rank ())
106
+ .then (Commands .argument ("rank" , StringArgumentType .word ())
107
+ .suggests ((context , builder ) -> suggestRanks (builder ))
97
108
.then (Commands .argument ("node" , StringArgumentType .word ())
98
- .executes (context -> setNode (context .getSource (), RankArgumentType . getRank (context , "rank" ), StringArgumentType .getString (context , "node" ), null ))
109
+ .executes (context -> setNode (context .getSource (), StringArgumentType . getString (context , "rank" ), StringArgumentType .getString (context , "node" ), null ))
99
110
)
100
111
)
101
112
)
102
113
)
103
114
.then (Commands .literal ("condition" )
104
- .then (Commands .argument ("rank" , RankArgumentType .rank ())
115
+ .then (Commands .argument ("rank" , StringArgumentType .word ())
116
+ .suggests ((context , builder ) -> suggestRanks (builder ))
105
117
.then (Commands .argument ("value" , StringArgumentType .greedyString ())
106
- .executes (context -> setCondition (context .getSource (), RankArgumentType . getRank (context , "rank" ), StringArgumentType .getString (context , "value" )))
118
+ .executes (context -> setCondition (context .getSource (), StringArgumentType . getString (context , "rank" ), StringArgumentType .getString (context , "value" )))
107
119
)
108
120
)
109
121
)
110
122
.then (Commands .literal ("show_rank" )
111
- .then (Commands .argument ("rank" , RankArgumentType .rank ())
112
- .executes (context -> showRank (context .getSource (), RankArgumentType .getRank (context , "rank" )))
123
+ .then (Commands .argument ("rank" , StringArgumentType .word ())
124
+ .suggests ((context , builder ) -> suggestRanks (builder ))
125
+ .executes (context -> showRank (context .getSource (), StringArgumentType .getString (context , "rank" )))
113
126
)
114
127
)
115
128
);
116
129
}
117
130
131
+ private static CompletableFuture <Suggestions > suggestRanks (SuggestionsBuilder builder ) {
132
+ return SharedSuggestionProvider .suggest (FTBRanksAPI .INSTANCE .getManager ().getAllRanks ().stream ().map (Rank ::getId ), builder );
133
+ }
134
+
118
135
private static String normalizeRankName (String name ) {
119
136
return name .toLowerCase ().replace ("+" , "_plus" ).replaceAll ("[^a-z0-9_]" , "_" ).replaceAll ("_{2,}" , "_" );
120
137
}
121
138
122
139
private static int reloadRanks (CommandSourceStack source ) {
123
140
try {
124
141
FTBRanksAPIImpl .manager .reload ();
125
- source .sendSuccess (new TranslatableComponent ( "ftbranks.reload " ), true );
142
+ source .sendSuccess (new TextComponent ( "Ranks reloaded from disk! " ), true );
126
143
127
144
for (ServerPlayer p : source .getServer ().getPlayerList ().getPlayers ()) {
128
145
source .getServer ().getPlayerList ().sendPlayerPermissionLevel (p );
@@ -143,12 +160,12 @@ private static int refreshReadme(CommandSourceStack source) {
143
160
ex .printStackTrace ();
144
161
}
145
162
146
- source .sendSuccess (new TranslatableComponent ( "ftbranks.refresh_readme " ), false );
163
+ source .sendSuccess (new TextComponent ( "README file refreshed! " ), false );
147
164
return 1 ;
148
165
}
149
166
150
167
private static int listAllRanks (CommandSourceStack source ) {
151
- source .sendSuccess (new TranslatableComponent ( "ftbranks.ranks " ), false );
168
+ source .sendSuccess (new TextComponent ( "Ranks: " ), false );
152
169
153
170
for (Rank rank : FTBRanksAPIImpl .manager .getAllRanks ()) {
154
171
source .sendSuccess (new TextComponent ("- " + rank .getName ()).withStyle (rank .getCondition ().isDefaultCondition () ? ChatFormatting .AQUA : ChatFormatting .YELLOW ), false );
@@ -161,44 +178,47 @@ private static int createRank(CommandSourceStack source, String name) {
161
178
String id = normalizeRankName (name );
162
179
163
180
if (FTBRanksAPIImpl .manager .getRank (id ).isPresent ()) {
164
- source .sendFailure (new TranslatableComponent ( "ftbranks.rank_taken" , name ));
181
+ source .sendFailure (new TextComponent ( "Rank '" + name + "' is already taken!" ));
165
182
return 0 ;
166
183
}
167
184
168
185
FTBRanksAPIImpl .manager .createRank (id , name );
169
- source .sendSuccess (new TranslatableComponent ( "ftbranks.rank_created" , id ), false );
186
+ source .sendSuccess (new TextComponent ( "Rank '" + id + "' created!" ), false );
170
187
return 1 ;
171
188
}
172
189
173
- private static int deleteRank (CommandSourceStack source , Rank rank ) {
190
+ private static int deleteRank (CommandSourceStack source , String rankName ) throws CommandSyntaxException {
191
+ Rank rank = getRank (rankName );
174
192
FTBRanksAPI .INSTANCE .getManager ().deleteRank (rank .getId ());
175
- source .sendSuccess (new TranslatableComponent ( "ftbranks.rank_deleted" , rank .getName ()), false );
193
+ source .sendSuccess (new TextComponent ( "Rank '" + rank .getName () + "' deleted!" ), false );
176
194
177
195
return 1 ;
178
196
}
179
197
180
- private static int addRank (CommandSourceStack source , Collection <GameProfile > players , Rank rank ) {
198
+ private static int addRank (CommandSourceStack source , Collection <GameProfile > players , String rankName ) throws CommandSyntaxException {
199
+ Rank rank = getRank (rankName );
181
200
for (GameProfile profile : players ) {
182
201
if (rank .add (profile )) {
183
- source .sendSuccess (new TranslatableComponent ( "ftbranks.player_added" , profile .getName (), rank .getName ()), false );
202
+ source .sendSuccess (new TextComponent ( String . format ( "Player %s added to rank '%s'!" , profile .getName (), rank .getName () )), false );
184
203
}
185
204
}
186
205
187
206
return 1 ;
188
207
}
189
208
190
- private static int removeRank (CommandSourceStack source , Collection <GameProfile > players , Rank rank ) {
209
+ private static int removeRank (CommandSourceStack source , Collection <GameProfile > players , String rankName ) throws CommandSyntaxException {
210
+ Rank rank = getRank (rankName );
191
211
for (GameProfile profile : players ) {
192
212
if (rank .remove (profile )) {
193
- source .sendSuccess (new TranslatableComponent ( "ftbranks.player_removed" , profile .getName (), rank .getName ()), false );
213
+ source .sendSuccess (new TextComponent ( String . format ( "Player %s removed from rank '%s'!" , profile .getName (), rank .getName () )), false );
194
214
}
195
215
}
196
216
197
217
return 1 ;
198
218
}
199
219
200
220
private static int listRanksOf (CommandSourceStack source , ServerPlayer player ) {
201
- source .sendSuccess (new TranslatableComponent ( "ftbranks.list_ranks_of" , player .getGameProfile ().getName ()), false );
221
+ source .sendSuccess (new TextComponent ( String . format ( "Ranks added to player '%s':" , player .getGameProfile ().getName () )), false );
202
222
203
223
for (Rank rank : FTBRanksAPIImpl .manager .getAllRanks ()) {
204
224
if (rank .isActive (player )) {
@@ -208,9 +228,10 @@ private static int listRanksOf(CommandSourceStack source, ServerPlayer player) {
208
228
209
229
return 1 ;
210
230
}
231
+ private static int listPlayersWith (CommandSourceStack source , String rankName ) throws CommandSyntaxException {
232
+ Rank rank = getRank (rankName );
211
233
212
- private static int listPlayersWith (CommandSourceStack source , Rank rank ) {
213
- source .sendSuccess (new TranslatableComponent ("ftbranks.list_players_with" , rank .getName ()), false );
234
+ source .sendSuccess (new TextComponent (String .format ("Players with rank '%s':" , rank .getName ())), false );
214
235
215
236
for (ServerPlayer player : source .getServer ().getPlayerList ().getPlayers ()) {
216
237
if (rank .isActive (player )) {
@@ -221,13 +242,15 @@ private static int listPlayersWith(CommandSourceStack source, Rank rank) {
221
242
return 1 ;
222
243
}
223
244
224
- private static int setNode (CommandSourceStack source , Rank rank , String node , String value ) throws CommandSyntaxException {
245
+ private static int setNode (CommandSourceStack source , String rankName , String node , String value ) throws CommandSyntaxException {
246
+ Rank rank = getRank (rankName );
247
+
225
248
try {
226
249
rank .setPermission (node , strToPermissionValue (value ));
227
250
if (value != null ) {
228
- source .sendSuccess (new TranslatableComponent ( "ftbranks.node_added" , node , rank .getPermission (node ), rank ), false );
251
+ source .sendSuccess (new TextComponent ( String . format ( "Permission node '%s'='%s' added to rank '%s'" , node , rank .getPermission (node ), rank ) ), false );
229
252
} else {
230
- source .sendSuccess (new TranslatableComponent ( "ftbranks.node_removed" , node , rank ), false );
253
+ source .sendSuccess (new TextComponent ( String . format ( "Permission node '%s' removed from rank '%s'" , node , rank ) ), false );
231
254
}
232
255
} catch (IllegalArgumentException e ) {
233
256
throw new SimpleCommandExceptionType (new TextComponent (e .getMessage ())).create ();
@@ -236,7 +259,9 @@ private static int setNode(CommandSourceStack source, Rank rank, String node, St
236
259
return 1 ;
237
260
}
238
261
239
- private static int setCondition (CommandSourceStack source , Rank rank , String value ) throws CommandSyntaxException {
262
+ private static int setCondition (CommandSourceStack source , String rankName , String value ) throws CommandSyntaxException {
263
+ Rank rank = getRank (rankName );
264
+
240
265
try {
241
266
RankCondition condition ;
242
267
if (value .equals ("default" ) || value .equals ("\" \" " )) {
@@ -247,37 +272,34 @@ private static int setCondition(CommandSourceStack source, Rank rank, String val
247
272
condition = FTBRanksAPI .INSTANCE .getManager ().createCondition (rank , StringTag .valueOf (value ));
248
273
}
249
274
rank .setCondition (condition );
250
- source .sendSuccess (new TranslatableComponent ( "ftbranks.node_added" , "condition" , value , rank ), false );
275
+ source .sendSuccess (new TextComponent ( String . format ( "Condition '%s' added to rank '%s'" , value , rank ) ), false );
251
276
} catch (Exception e ) {
252
277
throw new SimpleCommandExceptionType (new TextComponent (e .getMessage ())).create ();
253
278
}
254
279
255
280
return 1 ;
256
281
}
257
282
258
- private static int showRank (CommandSourceStack source , Rank rank ) {
283
+ private static int showRank (CommandSourceStack source , String rankName ) throws CommandSyntaxException {
284
+ Rank rank = getRank (rankName );
285
+
259
286
source .sendSuccess (new TextComponent ("=" .repeat (50 )).withStyle (ChatFormatting .GREEN ), false );
260
287
261
- source .sendSuccess (new TranslatableComponent ( "ftbranks.show_rank.header" , col ( rank .getId (), ChatFormatting . WHITE ), col ( rank .getName (), ChatFormatting . WHITE ), col ( Integer . toString ( rank .getPower ()), ChatFormatting . WHITE )).withStyle (ChatFormatting .YELLOW ), false );
288
+ source .sendSuccess (new TextComponent ( String . format ( "Rank ID: %s, Rank Name: %s, Power: %d" , rank .getId (), rank .getName (), rank .getPower ())).withStyle (ChatFormatting .YELLOW ), false );
262
289
263
290
String condStr = rank .getCondition ().asString ();
264
291
Component c = condStr .isEmpty () ?
265
- new TranslatableComponent ("ftbranks.show_rank.condition.default" ).withStyle (ChatFormatting .WHITE , ChatFormatting .ITALIC ) :
266
- col (condStr , ChatFormatting .WHITE );
267
- source .sendSuccess (new TranslatableComponent ("ftbranks.show_rank.condition" , c ).withStyle (ChatFormatting .YELLOW ), false );
292
+ new TextComponent ("(none: players must be added)" ).withStyle (ChatFormatting .WHITE , ChatFormatting .ITALIC ) : new TextComponent (condStr );
293
+ source .sendSuccess (new TextComponent ("Condition: " ).append (c ).withStyle (ChatFormatting .YELLOW ), false );
268
294
269
- source .sendSuccess (new TranslatableComponent ( "ftbranks.show_rank. nodes" ).withStyle (ChatFormatting .YELLOW ), false );
295
+ source .sendSuccess (new TextComponent ( "Permission nodes: " ).withStyle (ChatFormatting .YELLOW ), false );
270
296
rank .getPermissions ().stream ().sorted ().forEach (node ->
271
- source .sendSuccess (new TranslatableComponent ( "ftbranks.show_rank.node" , col ( node , ChatFormatting . AQUA ), rank .getPermission (node )). withStyle ( ChatFormatting . WHITE ), false )
297
+ source .sendSuccess (new TextComponent ( " - " + node + ": " + rank .getPermission (node )), false )
272
298
);
273
299
274
300
return 0 ;
275
301
}
276
302
277
- private static MutableComponent col (String str , ChatFormatting color ) {
278
- return new TextComponent (str ).withStyle (color );
279
- }
280
-
281
303
private static PermissionValue strToPermissionValue (String str ) {
282
304
if (str == null ) {
283
305
return null ;
@@ -291,4 +313,8 @@ private static PermissionValue strToPermissionValue(String str) {
291
313
return StringPermissionValue .of (str );
292
314
}
293
315
}
294
- }
316
+
317
+ private static Rank getRank (String rankName ) throws CommandSyntaxException {
318
+ return FTBRanksAPI .INSTANCE .getManager ().getRank (rankName ).orElseThrow (() -> ERROR_UNKNOWN_RANK .create (rankName ));
319
+ }
320
+ }
0 commit comments