2626import java .util .List ;
2727import java .util .Map ;
2828import java .util .logging .Level ;
29+ import java .util .stream .Collectors ;
2930
3031import static com .earth2me .essentials .I18n .tlLiteral ;
3132
@@ -127,10 +128,10 @@ public long getNextUse(final User user) throws Exception {
127128
128129 @ Deprecated
129130 public List <String > getItems (final User user ) throws Exception {
130- return getItems ();
131+ return getBasicItems ();
131132 }
132133
133- public List <String > getItems () throws Exception {
134+ public List <String > getBasicItems () throws Exception {
134135 if (kit == null ) {
135136 throw new TranslatableException ("kitNotFound" );
136137 }
@@ -154,14 +155,46 @@ public List<String> getItems() throws Exception {
154155 }
155156 }
156157
158+ public List <String > getGearItems () throws Exception {
159+ if (kit == null ) {
160+ throw new TranslatableException ("kitNotFound" );
161+ }
162+ try {
163+ final List <String > itemList = new ArrayList <>();
164+ final String [] gearConfigName = {"boots" , "leggings" , "chestplate" , "helmet" , "offhand" };
165+ for (String itemName : gearConfigName ) {
166+ final Object item = kit .get (itemName );
167+ if (item == null ) {
168+ itemList .add (null );
169+ continue ;
170+ }
171+
172+ if (item instanceof String ) {
173+ itemList .add (item .toString ());
174+ continue ;
175+ }
176+ throw new Exception ("Invalid kit item: " + item .toString ());
177+ }
178+
179+ return itemList ;
180+ } catch (final Exception e ) {
181+ ess .getLogger ().log (Level .WARNING , "Error parsing kit " + kitName + ": " + e .getMessage ());
182+ throw new TranslatableException (e ,"kitError2" );
183+ }
184+ }
185+
157186 public boolean expandItems (final User user ) throws Exception {
158- return expandItems (user , getItems (user ));
187+ return expandItems (user , getItems (user ), getGearItems () );
159188 }
160189
161- public boolean expandItems (final User user , final List <String > items ) throws Exception {
190+ public boolean expandItems (final User user , final List <String > items , final List < String > gearItems ) throws Exception {
162191 try {
163- final IText input = new SimpleTextInput (items );
164- final IText output = new KeywordReplacer (input , user .getSource (), ess , true , true );
192+ final IText basicInput = new SimpleTextInput (items );
193+ final IText basicOutput = new KeywordReplacer (basicInput , user .getSource (), ess , true , true );
194+
195+ final List <String > nonNullGearItems = gearItems .stream ().filter (is -> is != null ).collect (Collectors .toList ());
196+ final IText gearInput = new SimpleTextInput (nonNullGearItems );
197+ final IText gearOutput = new KeywordReplacer (gearInput , user .getSource (), ess , true , true );
165198
166199 final KitClaimEvent event = new KitClaimEvent (user , this );
167200 Bukkit .getPluginManager ().callEvent (event );
@@ -173,58 +206,29 @@ public boolean expandItems(final User user, final List<String> items) throws Exc
173206 final boolean allowUnsafe = ess .getSettings ().allowUnsafeEnchantments ();
174207 final boolean autoEquip = ess .getSettings ().isKitAutoEquip ();
175208 final List <ItemStack > itemList = new ArrayList <>();
209+ final List <ItemStack > gearList = new ArrayList <>();
176210 final List <String > commandQueue = new ArrayList <>();
177211 final List <String > moneyQueue = new ArrayList <>();
178212 final String currencySymbol = ess .getSettings ().getCurrencySymbol ().isEmpty () ? "$" : ess .getSettings ().getCurrencySymbol ();
179- for (final String kitItem : output .getLines ()) {
180- if (kitItem .startsWith ("$" ) || kitItem .startsWith (currencySymbol )) {
181- moneyQueue .add (NumberUtil .sanitizeCurrencyString (kitItem , ess ));
182- continue ;
183- }
184-
185- if (kitItem .startsWith ("/" )) {
186- String command = kitItem .substring (1 );
187- final String name = user .getName ();
188- command = command .replace ("{player}" , name );
189- commandQueue .add (command );
190- continue ;
191- }
192-
193- final ItemStack stack ;
194-
195- if (kitItem .startsWith ("@" )) {
196- if (ess .getSerializationProvider () == null ) {
197- ess .getLogger ().log (Level .WARNING , AdventureUtil .miniToLegacy (tlLiteral ("kitError3" , kitName , user .getName ())));
198- continue ;
199- }
200- stack = ess .getSerializationProvider ().deserializeItem (Base64Coder .decodeLines (kitItem .substring (1 )));
201- } else {
202- final String [] parts = kitItem .split (" +" );
203- final ItemStack parseStack = ess .getItemDb ().get (parts [0 ], parts .length > 1 ? Integer .parseInt (parts [1 ]) : 1 );
204213
205- if (parseStack .getType () == Material .AIR ) {
206- continue ;
207- }
208-
209- final MetaItemStack metaStack = new MetaItemStack (parseStack );
210-
211- if (parts .length > 2 ) {
212- // We pass a null sender here because kits should not do perm checks
213- metaStack .parseStringMeta (null , allowUnsafe , parts , 2 , ess );
214- }
215-
216- stack = metaStack .getItemStack ();
217- }
218-
219- itemList .add (stack );
220- }
214+ populateKitLists (user , basicOutput , moneyQueue , commandQueue , itemList , allowUnsafe , currencySymbol );
215+ populateKitLists (user , gearOutput , moneyQueue , commandQueue , gearList , allowUnsafe , currencySymbol );
221216
222217 final int maxStackSize = user .isAuthorized ("essentials.oversizedstacks" ) ? ess .getSettings ().getOversizedStackSize () : 0 ;
223218 final boolean isDropItemsIfFull = ess .getSettings ().isDropItemsIfFull ();
224219
225- final KitPreExpandItemsEvent itemsEvent = new KitPreExpandItemsEvent (user , kitName , itemList );
220+ final List <ItemStack > totalItems = new ArrayList <>(itemList );
221+ totalItems .addAll (gearList .stream ().filter (is -> is != null ).collect (Collectors .toList ()));
222+ final KitPreExpandItemsEvent itemsEvent = new KitPreExpandItemsEvent (user , kitName , totalItems );
226223 Bukkit .getPluginManager ().callEvent (itemsEvent );
227224
225+ final List <Integer > nullGearItemsIndexes = findNullIndexes (gearItems );
226+
227+ final ItemStack [] gearArray = addNullIndexes (gearList , nullGearItemsIndexes ).toArray (new ItemStack [0 ]);
228+ final List <ItemStack > leftovers = Inventories .addGear (user .getBase (), gearArray );
229+
230+ itemList .addAll (leftovers );
231+
228232 final ItemStack [] itemArray = itemList .toArray (new ItemStack [0 ]);
229233
230234 if (!isDropItemsIfFull && !Inventories .hasSpace (user .getBase (), maxStackSize , autoEquip , itemArray )) {
@@ -274,4 +278,76 @@ public boolean expandItems(final User user, final List<String> items) throws Exc
274278 }
275279 return true ;
276280 }
281+
282+ private void populateKitLists (User user , IText output , List <String > moneyQueue , List <String > commandQueue , List <ItemStack > itemList , boolean allowUnsafe , String currencySymbol ) throws Exception {
283+ for (final String kitItem : output .getLines ()) {
284+ if (kitItem .startsWith (currencySymbol )) {
285+ moneyQueue .add (NumberUtil .sanitizeCurrencyString (kitItem , ess ));
286+ continue ;
287+ }
288+
289+ if (kitItem .startsWith ("/" )) {
290+ String command = kitItem .substring (1 );
291+ final String name = user .getName ();
292+ command = command .replace ("{player}" , name );
293+ commandQueue .add (command );
294+ continue ;
295+ }
296+
297+ final ItemStack stack = parseItemStack (kitItem , user , allowUnsafe );
298+ if (stack == null ) {
299+ continue ;
300+ }
301+
302+ itemList .add (stack );
303+ }
304+ }
305+
306+ private ItemStack parseItemStack (String kitItem , User user , boolean allowUnsafe ) throws Exception {
307+ if (kitItem .startsWith ("@" )) {
308+ if (ess .getSerializationProvider () == null ) {
309+ ess .getLogger ().log (Level .WARNING , AdventureUtil .miniToLegacy (tlLiteral ("kitError3" , kitName , user .getName ())));
310+ return null ;
311+ }
312+ return ess .getSerializationProvider ().deserializeItem (Base64Coder .decodeLines (kitItem .substring (1 )));
313+ } else {
314+ final String [] parts = kitItem .split (" +" );
315+ final ItemStack parseStack = ess .getItemDb ().get (parts [0 ], parts .length > 1 ? Integer .parseInt (parts [1 ]) : 1 );
316+
317+ if (parseStack .getType () == Material .AIR ) {
318+ return null ;
319+ }
320+
321+ final MetaItemStack metaStack = new MetaItemStack (parseStack );
322+
323+ if (parts .length > 2 ) {
324+ // We pass a null sender here because kits should not do perm checks
325+ metaStack .parseStringMeta (null , allowUnsafe , parts , 2 , ess );
326+ }
327+
328+ return metaStack .getItemStack ();
329+ }
330+ }
331+
332+ private List <Integer > findNullIndexes (List <String > list ) {
333+ final List <Integer > nullIndexes = new ArrayList <>();
334+
335+ for (int i = 0 ; i < list .size (); i ++) {
336+ if (list .get (i ) == null ) {
337+ nullIndexes .add (i );
338+ }
339+ }
340+
341+ return nullIndexes ;
342+ }
343+
344+ private List <ItemStack > addNullIndexes (List <ItemStack > list , List <Integer > nullIndexes ) {
345+ final List <ItemStack > newList = new ArrayList <>(list );
346+
347+ for (int nullIndex : nullIndexes ) {
348+ newList .add (nullIndex , null );
349+ }
350+
351+ return newList ;
352+ }
277353}
0 commit comments