|
14 | 14 | import net.minecraft.screen.ScreenHandlerListener; |
15 | 15 | import net.minecraft.util.math.BlockPos; |
16 | 16 | import net.wurstclient.clickgui.screens.ChestSearchScreen; |
| 17 | +import net.minecraft.enchantment.Enchantment; |
| 18 | +import net.minecraft.enchantment.EnchantmentHelper; |
| 19 | +import it.unimi.dsi.fastutil.objects.Object2IntMap; |
| 20 | +import net.minecraft.registry.entry.RegistryEntry; |
| 21 | +import java.util.Set; |
| 22 | +import net.minecraft.component.type.PotionContentsComponent; |
| 23 | +import net.minecraft.component.DataComponentTypes; |
| 24 | +import net.minecraft.entity.effect.StatusEffectInstance; |
| 25 | +import net.minecraft.entity.effect.StatusEffect; |
| 26 | +import net.minecraft.util.Identifier; |
17 | 27 |
|
18 | 28 | import java.io.File; |
19 | 29 | import java.util.ArrayList; |
|
23 | 33 | import java.util.Timer; |
24 | 34 | import java.util.TimerTask; |
25 | 35 |
|
26 | | -/** |
27 | | - * Captures chest contents whenever a container screen opens. |
28 | | - */ |
29 | 36 | public class ChestRecorder |
30 | 37 | { |
31 | 38 | private final ChestManager manager; |
@@ -347,6 +354,88 @@ private void recordFromStacksInternal(String serverIp, String dimension, |
347 | 354 | { |
348 | 355 | it.nbt = null; |
349 | 356 | } |
| 357 | + // Extract enchantment ids and potion/effect ids from the actual |
| 358 | + // ItemStack where possible. This allows searching by enchantment |
| 359 | + // or potion even if the textual NBT is not easily searchable. |
| 360 | + try |
| 361 | + { |
| 362 | + // Enchantments (including enchanted books) |
| 363 | + try |
| 364 | + { |
| 365 | + Set<Object2IntMap.Entry<RegistryEntry<Enchantment>>> enchSet = |
| 366 | + EnchantmentHelper.getEnchantments(copy) |
| 367 | + .getEnchantmentEntries(); |
| 368 | + if(enchSet != null && !enchSet.isEmpty()) |
| 369 | + { |
| 370 | + it.enchantments = new java.util.ArrayList<>(); |
| 371 | + it.enchantmentLevels = new java.util.ArrayList<>(); |
| 372 | + for(Object2IntMap.Entry<RegistryEntry<Enchantment>> e : enchSet) |
| 373 | + { |
| 374 | + RegistryEntry<Enchantment> ren = e.getKey(); |
| 375 | + if(ren == null) |
| 376 | + continue; |
| 377 | + Identifier id = ren.getKey().map(k -> k.getValue()) |
| 378 | + .orElse(null); |
| 379 | + String idStr = id != null ? id.toString() |
| 380 | + : ren.getIdAsString(); |
| 381 | + int lvl = e.getIntValue(); |
| 382 | + if(idStr != null && !idStr.isBlank()) |
| 383 | + { |
| 384 | + it.enchantments.add(idStr); |
| 385 | + it.enchantmentLevels.add(Integer.valueOf(lvl)); |
| 386 | + } |
| 387 | + } |
| 388 | + } |
| 389 | + }catch(Throwable ignored) |
| 390 | + {} |
| 391 | + |
| 392 | + // Potions / effects |
| 393 | + try |
| 394 | + { |
| 395 | + PotionContentsComponent potionContents = |
| 396 | + copy.getComponents().getOrDefault( |
| 397 | + DataComponentTypes.POTION_CONTENTS, |
| 398 | + PotionContentsComponent.DEFAULT); |
| 399 | + if(potionContents != null) |
| 400 | + { |
| 401 | + java.util.List<String> pe = new java.util.ArrayList<>(); |
| 402 | + for(StatusEffectInstance sei : potionContents |
| 403 | + .getEffects()) |
| 404 | + { |
| 405 | + RegistryEntry<StatusEffect> effEntry = |
| 406 | + sei.getEffectType(); |
| 407 | + Identifier id = effEntry.getKey() |
| 408 | + .map(k -> k.getValue()).orElse(null); |
| 409 | + String idStr = id != null ? id.toString() |
| 410 | + : effEntry.getIdAsString(); |
| 411 | + if(idStr != null && !idStr.isBlank()) |
| 412 | + pe.add(idStr); |
| 413 | + } |
| 414 | + if(!pe.isEmpty()) |
| 415 | + { |
| 416 | + it.potionEffects = pe; |
| 417 | + it.primaryPotion = pe.get(0); |
| 418 | + }else |
| 419 | + { |
| 420 | + // fallback to base potion id |
| 421 | + java.util.Optional<net.minecraft.registry.entry.RegistryEntry<net.minecraft.potion.Potion>> basePotion = |
| 422 | + potionContents.potion(); |
| 423 | + if(basePotion.isPresent()) |
| 424 | + { |
| 425 | + Identifier id = basePotion.get().getKey() |
| 426 | + .map(k -> k.getValue()).orElse(null); |
| 427 | + String idStr = id != null ? id.toString() |
| 428 | + : basePotion.get().getIdAsString(); |
| 429 | + it.primaryPotion = idStr; |
| 430 | + } |
| 431 | + } |
| 432 | + } |
| 433 | + }catch(Throwable ignored) |
| 434 | + {} |
| 435 | + }catch(Throwable ignored) |
| 436 | + { |
| 437 | + // ignore extraction errors |
| 438 | + } |
350 | 439 | items.add(it); |
351 | 440 | } |
352 | 441 |
|
@@ -414,4 +503,13 @@ private void recordFromStacksInternal(String serverIp, String dimension, |
414 | 503 | } |
415 | 504 | } |
416 | 505 |
|
| 506 | + private static String sanitizePath(String raw) |
| 507 | + { |
| 508 | + if(raw == null || raw.isEmpty()) |
| 509 | + return ""; |
| 510 | + int colon = raw.indexOf(':'); |
| 511 | + return colon >= 0 && colon + 1 < raw.length() ? raw.substring(colon + 1) |
| 512 | + : raw; |
| 513 | + } |
| 514 | + |
417 | 515 | } |
0 commit comments