Skip to content

Commit 3643cc9

Browse files
ryanbarlow97claude
andcommitted
fix: require the full skill(amount) format for xp values
Values like smithing(5)(x) were read as smithing(5). They are now skipped with a warning, and only a plain skill name can reach the console exp command. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent b72c0b4 commit 3643cc9

1 file changed

Lines changed: 19 additions & 19 deletions

File tree

‎src/main/java/net/tfminecraft/advancedcrafting/objects/crafting/CraftingStation.java‎

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import java.util.List;
88
import java.util.Map;
99
import java.util.Optional;
10+
import java.util.regex.Matcher;
11+
import java.util.regex.Pattern;
1012

1113
import org.apache.commons.lang.WordUtils;
1214
import org.bukkit.Bukkit;
@@ -261,6 +263,9 @@ public StationFeedback craft(Player p, Double forcedQualityPercent) {
261263
return f;
262264
}
263265

266+
// skill(amount), e.g. crafter(2.0)
267+
private static final Pattern XP_FORMAT = Pattern.compile("([A-Za-z0-9_-]+)\\((\\d+(?:\\.\\d+)?)\\)");
268+
264269
private void giveXP(Player p) {
265270
// Map of skill name -> total XP to give
266271
Map<String, Double> xpBySkill = new HashMap<>();
@@ -271,26 +276,31 @@ private void giveXP(Player p) {
271276
String mId = split[1];
272277
int amount = currentMaterials.get(s);
273278

274-
double xpPerUnit = 0.0;
275-
String skill = null;
279+
String raw = null;
276280

277281
if (type.equalsIgnoreCase("ingredient")) {
278282
Ingredient ingredient = IngredientLoader.getByString(mId); // Assuming you have a method like this
279283
if (ingredient != null && ingredient.getIngredientData().hasXP()) {
280-
String raw = ingredient.getIngredientData().getXP();
281-
xpPerUnit = parseXPAmount(raw);
282-
skill = raw.split("\\(")[0]; // Assuming you store "agriculturist" here
284+
raw = ingredient.getIngredientData().getXP();
283285
}
284286
} else if (type.equalsIgnoreCase("alloy")) {
285287
Alloy alloy = AlloyManager.getAlloyById(mId); // Likewise for alloy
286288
if (alloy != null && alloy.getData().hasXP()) {
287-
String raw = alloy.getData().getXP();
288-
xpPerUnit = parseXPAmount(raw);
289-
skill = raw.split("\\(")[0]; // Assuming you store "agriculturist" here
289+
raw = alloy.getData().getXP();
290290
}
291291
}
292+
if (raw == null) continue;
293+
294+
// XP is paid after the item drops, so a bad value must be skipped rather than throw and leave the station uncleared.
295+
Matcher m = XP_FORMAT.matcher(raw.trim());
296+
if (!m.matches()) {
297+
Bukkit.getLogger().warning("AC: Invalid xp value '" + raw + "', expected skill(amount)");
298+
continue;
299+
}
300+
String skill = m.group(1);
301+
double xpPerUnit = Double.parseDouble(m.group(2));
292302

293-
if (skill != null && xpPerUnit > 0) {
303+
if (xpPerUnit > 0) {
294304
double totalXP = xpPerUnit * amount;
295305
xpBySkill.put(skill, xpBySkill.getOrDefault(skill, 0.0) + totalXP);
296306
}
@@ -307,16 +317,6 @@ private void giveXP(Player p) {
307317
}
308318

309319

310-
// XP is paid after the item drops, so a bad value must not throw and leave the station uncleared.
311-
private double parseXPAmount(String raw) {
312-
try {
313-
return Double.parseDouble(raw.split("\\(")[1].replace(")", ""));
314-
} catch (RuntimeException e) {
315-
Bukkit.getLogger().warning("AC: Invalid xp value '" + raw + "', expected skill(amount)");
316-
return 0.0;
317-
}
318-
}
319-
320320
private boolean checkItems(Player p) {
321321
boolean complete = true;
322322
for(IngredientType t : types.keySet()) {

0 commit comments

Comments
 (0)