Skip to content

Commit 18758ba

Browse files
TiagoFar78cati-xf
andcommitted
Implement kits placing items in specific slots
Everytime you create a kit with gear (armor and offhand) equipped, the gear is placed in their respective slots once you retrieve the kit. For example, if you create the kit with a golden helmet equipped, it will be placed in your helmet slot when retrieving the kit. Co-authored-by: Catarina Freire <catarina.xie.freire@tecnico.ulisboa.pt>
1 parent cde7184 commit 18758ba

File tree

5 files changed

+217
-63
lines changed

5 files changed

+217
-63
lines changed

Essentials/src/main/java/com/earth2me/essentials/Kit.java

Lines changed: 124 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.List;
2727
import java.util.Map;
2828
import java.util.logging.Level;
29+
import java.util.stream.Collectors;
2930

3031
import 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
}

Essentials/src/main/java/com/earth2me/essentials/Kits.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,20 @@ public String matchKit(final String name) {
112112
return null;
113113
}
114114

115-
public void addKit(String name, final List<String> lines, final long delay) {
115+
public void addKit(String name, final List<String> basicLines, final List<String> gearLines, final long delay) {
116116
name = name.replace('.', '_').replace('/', '_').toLowerCase(Locale.ENGLISH);
117117
// Will overwrite but w/e
118118
rootConfig.setProperty("kits." + name + ".delay", delay);
119-
rootConfig.setProperty("kits." + name + ".items", lines);
119+
rootConfig.setProperty("kits." + name + ".items", basicLines);
120+
121+
final String[] gearConfigName = {"boots", "leggings", "chestplate", "helmet", "offhand"};
122+
for (int i = 0; i < gearLines.size(); i++) {
123+
final String gearLine = gearLines.get(i);
124+
if (gearLine != null) {
125+
rootConfig.setProperty("kits." + name + "." + gearConfigName[i], gearLine);
126+
}
127+
}
128+
120129
parseKits();
121130
rootConfig.save();
122131
}

Essentials/src/main/java/com/earth2me/essentials/commands/Commandcreatekit.java

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ public void run(final Server server, final User user, final String commandLabel,
3939
// Command handler will auto fail if this fails.
4040
final long delay = Long.parseLong(args[1]);
4141
final String kitname = args[0];
42-
final ItemStack[] items = Inventories.getInventory(user.getBase(), true);
42+
final ItemStack[] items = Inventories.getInventoryBasicContents(user.getBase());
43+
final ItemStack[] gear = Inventories.getInventoryGear(user.getBase());
4344
final List<String> list = new ArrayList<>();
45+
final List<String> gearList = new ArrayList<>();
4446

4547
boolean useSerializationProvider = ess.getSettings().isUseBetterKits();
4648

@@ -50,26 +52,43 @@ public void run(final Server server, final User user, final String commandLabel,
5052
}
5153

5254
for (ItemStack is : items) {
53-
if (is != null && is.getType() != null && is.getType() != Material.AIR) {
54-
final String serialized;
55-
if (useSerializationProvider) {
56-
serialized = "@" + Base64Coder.encodeLines(ess.getSerializationProvider().serializeItem(is));
57-
} else {
58-
serialized = ess.getItemDb().serialize(is);
59-
}
55+
final String serialized = serializeItem(is, useSerializationProvider);
56+
if (serialized != null) {
6057
list.add(serialized);
6158
}
6259
}
60+
61+
int gearItemsAmount = 0;
62+
for (ItemStack is : gear) {
63+
gearItemsAmount = is == null ? gearItemsAmount : gearItemsAmount + 1;
64+
gearList.add(serializeItem(is, useSerializationProvider));
65+
}
66+
6367
// Some users might want to directly write to config knowing the consequences. *shrug*
6468
if (!ess.getSettings().isPastebinCreateKit()) {
65-
ess.getKits().addKit(kitname, list, delay);
66-
user.sendTl("createdKit", kitname, list.size(), delay);
69+
ess.getKits().addKit(kitname, list, gearList, delay);
70+
user.sendTl("createdKit", kitname, list.size() + gearItemsAmount, delay);
6771
} else {
68-
uploadPaste(user.getSource(), kitname, delay, list);
72+
uploadPaste(user.getSource(), kitname, delay, list, gearList);
6973
}
7074
}
7175

72-
private void uploadPaste(final CommandSource sender, final String kitName, final long delay, final List<String> list) {
76+
private String serializeItem(ItemStack is, boolean useSerializationProvider) {
77+
if (is != null && is.getType() != null && is.getType() != Material.AIR) {
78+
final String serialized;
79+
if (useSerializationProvider) {
80+
serialized = "@" + Base64Coder.encodeLines(ess.getSerializationProvider().serializeItem(is));
81+
} else {
82+
serialized = ess.getItemDb().serialize(is);
83+
}
84+
85+
return serialized;
86+
}
87+
88+
return null;
89+
}
90+
91+
private void uploadPaste(final CommandSource sender, final String kitName, final long delay, final List<String> list, final List<String> gearList) {
7392
ess.runTaskAsynchronously(() -> {
7493
try {
7594
final StringWriter sw = new StringWriter();
@@ -79,6 +98,14 @@ private void uploadPaste(final CommandSource sender, final String kitName, final
7998
config.node("kits", kitName, "delay").set(delay);
8099
config.node("kits", kitName, "items").set(list);
81100

101+
final String[] gearConfigName = {"boots", "leggings", "chestplate", "helmet", "offhand"};
102+
for (int i = 0; i < gearList.size(); i++) {
103+
final String gearLine = gearList.get(i);
104+
if (gearLine != null) {
105+
config.node("kits", kitName, gearConfigName[i]).set(gearList.get(i));
106+
}
107+
}
108+
82109
sw.append("# Copy the kit code below into the kits section in your config.yml file\n");
83110
loader.save(config);
84111

Essentials/src/main/java/com/earth2me/essentials/commands/Commandshowkit.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.util.Collections;
99
import java.util.List;
1010
import java.util.Locale;
11+
import java.util.stream.Collectors;
1112

1213
public class Commandshowkit extends EssentialsCommand {
1314
public Commandshowkit() {
@@ -22,7 +23,11 @@ public void run(final Server server, final User user, final String commandLabel,
2223

2324
for (final String kitName : args[0].toLowerCase(Locale.ENGLISH).split(",")) {
2425
user.sendTl("kitContains", kitName);
25-
for (final String s : new Kit(kitName, ess).getItems()) {
26+
final Kit kit = new Kit(kitName, ess);
27+
for (final String s : kit.getBasicItems()) {
28+
user.sendTl("kitItem", s);
29+
}
30+
for (final String s : kit.getGearItems().stream().filter(is -> is != null).collect(Collectors.toList())) {
2631
user.sendTl("kitItem", s);
2732
}
2833
}

0 commit comments

Comments
 (0)