VolumeUpdateObserver interface

Пакет: com.hypixel.hytale.builtin.triggervolumes.manager

Файл: com/hypixel/hytale/builtin/triggervolumes/manager/TriggerVolumeManager.java

Методы (2)

МодификаторыВозвратСигнатура
abstract void onVolumeRemovedvoid onVolumeRemoved(@Nonnull String var1)
abstract void onVolumeUpdatedvoid onVolumeUpdated(@Nonnull VolumeEntry var1)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.triggervolumes.manager;

class="kw">import com.hypixel.hytale.builtin.triggervolumes.EntityTargetType;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.component.TriggerVolumeGroup;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.SignalTag;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.TriggerEventType;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.TriggerRule;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.builtin.TaggedVolumeEffectUtil;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.builtin.rules.NoBuildRule;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.builtin.rules.NoDamageRule;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.builtin.rules.NoDestroyRule;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.builtin.rules.NoHarvestRule;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.builtin.rules.NoTickRule;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.builtin.rules.RuleEntityFilter;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.shape.BoxShape;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.shape.CylinderShape;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.shape.SphereShape;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.shape.TriggerVolumeShape;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.system.DelayedEffectScheduler;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.system.VolumeSpatialIndex;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.codec.codecs.map.MapCodec;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.Resource;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.protocol.InteractionType;
class="kw">import com.hypixel.hytale.protocol.packets.player.AddOrUpdateTriggerVolumeDisplay;
class="kw">import com.hypixel.hytale.protocol.packets.player.ClientRuleVolume;
class="kw">import com.hypixel.hytale.protocol.packets.player.RemoveTriggerVolumeDisplay;
class="kw">import com.hypixel.hytale.protocol.packets.player.TriggerVolumeConditionTiming;
class="kw">import com.hypixel.hytale.protocol.packets.player.TriggerVolumeDisplayEntry;
class="kw">import com.hypixel.hytale.protocol.packets.player.TriggerVolumeShapeType;
class="kw">import com.hypixel.hytale.protocol.packets.player.UpdateClientRuleVolumes;
class="kw">import com.hypixel.hytale.protocol.packets.player.UpdateTriggerVolumeDisplay;
class="kw">import com.hypixel.hytale.server.core.Message;
class="kw">import com.hypixel.hytale.server.core.universe.PlayerRef;
class="kw">import com.hypixel.hytale.server.core.universe.Universe;
class="kw">import com.hypixel.hytale.server.core.universe.world.TickSuppressionRegistry;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
class="kw">import java.util.ArrayDeque;
class="kw">import java.util.ArrayList;
class="kw">import java.util.Collection;
class="kw">import java.util.Collections;
class="kw">import java.util.Deque;
class="kw">import java.util.EnumSet;
class="kw">import java.util.HashMap;
class="kw">import java.util.HashSet;
class="kw">import java.util.Iterator;
class="kw">import java.util.LinkedHashMap;
class="kw">import java.util.LinkedHashSet;
class="kw">import java.util.List;
class="kw">import java.util.Locale;
class="kw">import java.util.Map;
class="kw">import java.util.Objects;
class="kw">import java.util.Set;
class="kw">import java.util.UUID;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.concurrent.ConcurrentHashMap;
class="kw">import java.util.concurrent.ThreadLocalRandom;
class="kw">import java.util.function.Predicate;
class="kw">import java.util.regex.Matcher;
class="kw">import java.util.regex.Pattern;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;
class="kw">import org.joml.Vector3f;

class="kw">public class TriggerVolumeManager class="kw">implements Resource<EntityStore> {
   @Nonnull
   class="kw">public class="kw">static class="kw">final UUID ENVIRONMENT_ACTOR_UUID = new UUID(0L, 0L);
   @Nonnull
   class="kw">public class="kw">static class="kw">final BuilderCodec<TriggerVolumeManager> CODEC = BuilderCodec.builder(TriggerVolumeManager.class, TriggerVolumeManager::new)
      .append(
         new KeyedCodec<>("Volumes", new MapCodec<>(VolumeEntry.CODEC, ConcurrentHashMap::new, false), false),
         (var0, var1) -> var0.volumes.putAll(var1),
         var0 -> var0.volumes.isEmpty() ? null : var0.volumes
      )
      .add()
      .append(
         new KeyedCodec<>("Groups", new MapCodec<>(GroupEntry.CODEC, ConcurrentHashMap::new, false), false),
         (var0, var1) -> var0.groups.putAll(var1),
         var0 -> var0.groups.isEmpty() ? null : var0.groups
      )
      .add()
      .afterDecode(TriggerVolumeManager::postDecode)
      .build();
   class="kw">private class="kw">static class="kw">final Vector3f COLOR_ENABLED = new Vector3f(0.0F, 0.8F, 0.8F);
   class="kw">private class="kw">static class="kw">final Vector3f COLOR_DISABLED = new Vector3f(0.8F, 0.2F, 0.2F);
   class="kw">private class="kw">static class="kw">final float OPACITY_ENABLED = 0.3F;
   class="kw">private class="kw">static class="kw">final float OPACITY_DISABLED = 0.15F;
   class="kw">private class="kw">static class="kw">final String NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789";
   class="kw">private class="kw">static class="kw">final int DEFAULT_NAME_LENGTH = 6;
   class="kw">private class="kw">static class="kw">final Pattern NUMBERED_SUFFIX = Pattern.compile("^(.+) \\(\\d+\\)$");
   class="kw">private class="kw">final Map<String, VolumeEntry> volumes = new ConcurrentHashMap<>();
   class="kw">private class="kw">final Map<String, GroupEntry> groups = new ConcurrentHashMap<>();
   class="kw">private class="kw">final ConcurrentHashMap<String, String> prefabGroupLinkRemap = new ConcurrentHashMap<>();
   class="kw">private class="kw">final Map<UUID, EnumSet<TriggerVolumeManager.ViewSource>> activeViewers = new ConcurrentHashMap<>();
   class="kw">private class="kw">final Map<UUID, String> playerSelections = new ConcurrentHashMap<>();
   class="kw">private class="kw">final class="kw">transient Map<UUID, TriggerVolumeManager.SelectionObserver> selectionObservers = new ConcurrentHashMap<>();
   class="kw">private class="kw">final class="kw">transient Map<UUID, TriggerVolumeManager.VolumeUpdateObserver> volumeUpdateObservers = new ConcurrentHashMap<>();
   @Nonnull
   class="kw">private class="kw">final class="kw">transient Deque<TriggerVolumeManager.PendingTriggerEvent> pendingEvents = new ArrayDeque<>();
   @Nonnull
   class="kw">private class="kw">final VolumeSpatialIndex spatialIndex = new VolumeSpatialIndex();
   @Nonnull
   class="kw">private class="kw">final class="kw">transient Set<VolumeEntry> activeVolumes = ConcurrentHashMap.newKeySet();
   @Nonnull
   class="kw">private class="kw">final class="kw">transient DelayedEffectScheduler delayedEffectScheduler = new DelayedEffectScheduler();
   @Nullable
   class="kw">private World world;
   class="kw">private class="kw">transient class="kw">volatile boolean clientRuleVolumesDirty;
   class="kw">private class="kw">transient class="kw">volatile boolean tickSuppressionDirty = true;
   class="kw">private class="kw">transient class="kw">volatile boolean entityTargetCounterDirty = true;
   class="kw">private class="kw">transient class="kw">volatile boolean hasEntityTargetVolumes;
   class="kw">private class="kw">static class="kw">final byte RULE_NO_BUILD = 1;
   class="kw">private class="kw">static class="kw">final byte RULE_NO_DESTROY = 2;
   class="kw">private class="kw">static class="kw">final byte RULE_NO_HARVEST = 4;
   class="kw">private class="kw">static class="kw">final byte RULE_NO_DAMAGE_ALL = 8;
   class="kw">private class="kw">static class="kw">final byte RULE_NO_DAMAGE_PLAYERS = 16;

   class="kw">public TriggerVolumeManager() {
   }

   class="kw">private void postDecode() {
      this.migrateLegacyIds();

      for (Entry var2 : this.volumes.entrySet()) {
         var2.getValue().setId(var2.getKey());
         var2.getValue().expandTags();
      }

      for (Entry var7 : this.groups.entrySet()) {
         var7.getValue().setId(var7.getKey());
         var7.getValue().expandTags();
      }

      for (VolumeEntry var8 : this.volumes.values()) {
         if (var8.getGroupId() != null) {
            GroupEntry var3 = this.groups.get(var8.getGroupId());
            if (var3 != null) {
               var3.addMember(var8.getId());
            }
         }
      }

      for (VolumeEntry var9 : this.volumes.values()) {
         var9.attachOwnerSilently(this);
      }

      this.spatialIndex.rebuild(this.volumes.values());
      this.entityTargetCounterDirty = true;
   }

   class="kw">private void migrateLegacyIds() {
      HashMap var1 = new HashMap<>();

      for (Entry var3 : new ArrayList<>(this.volumes.entrySet())) {
         String var4 = var3.getKey();
         VolumeEntry var5 = var3.getValue();
         if (!var5.isFromWorldGen() && !isUuid(var4)) {
            if (var5.getName() == null) {
               var5.setName(var4);
            }

            var1.put(var4, this.generateUniqueVolumeId());
         }
      }

      HashMap var7 = new HashMap<>();

      for (Entry var12 : new ArrayList<>(this.groups.entrySet())) {
         String var16 = var12.getKey();
         GroupEntry var6 = var12.getValue();
         if (!var16.startsWith("tvg_wg_") && !isUuid(var16)) {
            if (var6.getName() == null) {
               var6.setName(var16);
            }

            var7.put(var16, this.generateUniquePastedGroupId());
         }
      }

      if (!var1.isEmpty() || !var7.isEmpty()) {
         for (Entry var13 : var1.entrySet()) {
            VolumeEntry var17 = this.volumes.remove(var13.getKey());
            if (var17 != null) {
               this.volumes.put(var13.getValue(), var17);
            }
         }

         for (Entry var14 : var7.entrySet()) {
            GroupEntry var18 = this.groups.remove(var14.getKey());
            if (var18 != null) {
               this.groups.put(var14.getValue(), var18);
            }
         }

         for (VolumeEntry var15 : this.volumes.values()) {
            String var19 = var15.getGroupId() != null ? var7.get(var15.getGroupId()) : null;
            if (var19 != null) {
               var15.setGroupId(var19);
            }
         }
      }
   }

   class="kw">private class="kw">static boolean isUuid(@Nonnull String var0) {
      try {
         UUID.fromString(var0);
         class="kw">return true;
      } catch (IllegalArgumentException var2) {
         class="kw">return false;
      }
   }

   class="kw">public void register(@Nonnull String var1, @Nonnull VolumeEntry var2) {
      if (var2.getName() == null) {
         var2.setName(generateDefaultName("tv_"));
      }

      this.volumes.put(var1, var2);
      var2.attachOwner(this);
      this.updateTrackingState(var2);
      this.entityTargetCounterDirty = true;
      this.markClientRuleVolumesDirty();
   }

   class="kw">public void unregister(@Nonnull String var1) {
      VolumeEntry var2 = this.volumes.remove(var1);
      if (var2 != null) {
         var2.markPendingDestroy();
         this.spatialIndex.markRemoved(var2, SpatialSnapshot.of(var2));
         var2.detachOwner();
         this.activeVolumes.remove(var2);
         String var3 = var2.getGroupId();
         if (var3 != null) {
            GroupEntry var4 = this.groups.get(var3);
            if (var4 != null) {
               var4.removeMember(var1);
               if (var4.getMemberVolumeIds().isEmpty()) {
                  this.unregisterGroup(var3);
               }
            }
         }
      }

      this.entityTargetCounterDirty = true;
      this.markClientRuleVolumesDirty();
   }

   void onVolumeAttached(@Nonnull VolumeEntry var1) {
      this.spatialIndex.markChanged(var1, SpatialSnapshot.of(var1));
   }

   void onVolumeSpatialChanged(@Nonnull VolumeEntry var1, @Nullable SpatialSnapshot var2) {
      this.spatialIndex.markChanged(var1, var2 != null ? var2 : SpatialSnapshot.of(var1));
      this.markClientRuleVolumesDirty();
   }

   void onVolumeEnabledChanged(@Nonnull VolumeEntry var1, @Nullable SpatialSnapshot var2) {
      this.spatialIndex.markChanged(var1, var2 != null ? var2 : SpatialSnapshot.of(var1));
      this.entityTargetCounterDirty = true;
      this.markClientRuleVolumesDirty();
   }

   class="kw">public void updateTrackingState(@Nonnull VolumeEntry var1) {
      if (var1.getTrackedEntities().isEmpty()) {
         this.activeVolumes.remove(var1);
      } else {
         this.activeVolumes.add(var1);
      }
   }

   @Nonnull
   class="kw">public Set<VolumeEntry> getActiveVolumes() {
      class="kw">return this.activeVolumes;
   }

   class="kw">public boolean hasEntityTargetVolumes() {
      if (this.entityTargetCounterDirty) {
         this.entityTargetCounterDirty = false;
         boolean var1 = false;

         for (VolumeEntry var3 : this.volumes.values()) {
            if (var3.isEnabled() && usesEntitySpatial(var3)) {
               var1 = true;
               break;
            }
         }

         this.hasEntityTargetVolumes = var1;
      }

      class="kw">return this.hasEntityTargetVolumes;
   }

   class="kw">private class="kw">static boolean usesEntitySpatial(@Nonnull VolumeEntry var0) {
      Set var1 = var0.getTargetTypes();
      class="kw">return var1.contains(EntityTargetType.NPC) || var1.contains(EntityTargetType.ITEM_DROP) || var1.contains(EntityTargetType.PROJECTILE);
   }

   @Nullable
   class="kw">public VolumeEntry renameVolume(@Nonnull String var1, @Nonnull String var2) {
      if (var1.equals(var2)) {
         class="kw">return this.volumes.get(var1);
      }

      VolumeEntry var3 = this.volumes.remove(var1);
      if (var3 == null) {
         class="kw">return null;
      }

      if (this.volumes.putIfAbsent(var2, var3) != null) {
         this.volumes.put(var1, var3);
         class="kw">return null;
      }

      var3.setId(var2);

      for (GroupEntry var5 : this.groups.values()) {
         if (var5.getMemberVolumeIds().remove(var1)) {
            var5.addMember(var2);
         }
      }

      for (Entry var7 : this.playerSelections.entrySet()) {
         if (var1.equals(var7.getValue())) {
            var7.setValue(var2);
         }
      }

      this.markClientRuleVolumesDirty();
      class="kw">return var3;
   }

   class="kw">public void removeWorldGenVolumesInChunk(long var1) {
      ArrayList var3 = new ArrayList<>();
      boolean var4 = false;
      Iterator var5 = this.volumes.values().iterator();

      while (var5.hasNext()) {
         VolumeEntry var6 = var5.next();
         if (var6.isFromWorldGen()) {
            Vector3d var7 = var6.getPosition();
            if (ChunkUtil.indexChunkFromBlock(var7.x(), var7.z()) == var1) {
               String var8 = var6.getGroupId();
               if (var8 != null) {
                  GroupEntry var9 = this.groups.get(var8);
                  if (var9 != null) {
                     var9.removeMember(var6.getId());
                     if (var9.getMemberVolumeIds().isEmpty()) {
                        var3.add(var8);
                     }
                  }
               }

               var6.markPendingDestroy();
               this.spatialIndex.markRemoved(var6, SpatialSnapshot.of(var6));
               var6.detachOwner();
               this.activeVolumes.remove(var6);
               var5.remove();
               this.notifyViewersRemove(var6.getId());
               var4 = true;
            }
         }
      }

      for (String var11 : var3) {
         this.unregisterGroup(var11);
      }

      if (var4) {
         this.entityTargetCounterDirty = true;
         this.markClientRuleVolumesDirty();
      }
   }

   class="kw">public int removeAllVolumes() {
      int var1 = this.volumes.size();
      if (var1 == 0 && this.groups.isEmpty()) {
         class="kw">return 0;
      }

      for (VolumeEntry var3 : this.volumes.values()) {
         var3.markPendingDestroy();
         var3.detachOwner();
         this.notifyViewersRemove(var3.getId());
      }

      this.volumes.clear();
      this.groups.clear();
      this.spatialIndex.clear();
      this.activeVolumes.clear();
      this.entityTargetCounterDirty = true;
      this.markClientRuleVolumesDirty();
      class="kw">return var1;
   }

   @Nullable
   class="kw">public VolumeEntry getVolume(@Nonnull String var1) {
      class="kw">return this.volumes.get(var1);
   }

   @Nonnull
   class="kw">public Collection<VolumeEntry> getVolumes() {
      class="kw">return Collections.unmodifiableCollection(this.volumes.values());
   }

   class="kw">public boolean hasVolumes() {
      class="kw">return !this.volumes.isEmpty();
   }

   @Nonnull
   class="kw">public Map<String, VolumeEntry> getVolumesMap() {
      class="kw">return Collections.unmodifiableMap(this.volumes);
   }

   class="kw">public boolean hasVolume(@Nonnull String var1) {
      class="kw">return this.volumes.containsKey(var1);
   }

   class="kw">public void markSpatialDirty() {
      this.entityTargetCounterDirty = true;
   }

   class="kw">public boolean hasActiveRule(@Nonnull Vector3d var1, @Nonnull Class<? class="kw">extends TriggerRule> var2) {
      this.spatialIndex.applyPendingChanges();
      ArrayList var3 = new ArrayList<>();
      this.spatialIndex.collectCandidates(var1, var3);

      for (VolumeEntry var5 : var3) {
         if (isRuleCandidate(var5, var1)) {
            if (containsRule(var5.getRules(), var2)) {
               class="kw">return true;
            }

            GroupEntry var6 = var5.getGroupId() != null ? this.groups.get(var5.getGroupId()) : null;
            if (var6 != null && var6.isEnabled() && containsRule(var6.getRules(), var2)) {
               class="kw">return true;
            }
         }
      }

      class="kw">return false;
   }

   @Nonnull
   class="kw">public <T class="kw">extends TriggerRule> List<T> getActiveRules(@Nonnull Vector3d var1, @Nonnull Class<T> var2) {
      this.spatialIndex.applyPendingChanges();
      ArrayList var3 = new ArrayList<>();
      this.spatialIndex.collectCandidates(var1, var3);
      ArrayList var4 = new ArrayList<>();

      for (VolumeEntry var6 : var3) {
         if (isRuleCandidate(var6, var1)) {
            collectRules(var6.getRules(), var2, var4);
            GroupEntry var7 = var6.getGroupId() != null ? this.groups.get(var6.getGroupId()) : null;
            if (var7 != null && var7.isEnabled()) {
               collectRules(var7.getRules(), var2, var4);
            }
         }
      }

      class="kw">return var4;
   }

   @Nonnull
   class="kw">public <T class="kw">extends TriggerRule> List<TriggerVolumeManager.ActiveRule<T>> getActiveRulesWithVolume(@Nonnull Vector3d var1, @Nonnull Class<T> var2) {
      this.spatialIndex.applyPendingChanges();
      ArrayList var3 = new ArrayList<>();
      this.spatialIndex.collectCandidates(var1, var3);
      ArrayList var4 = new ArrayList<>();

      for (VolumeEntry var6 : var3) {
         if (isRuleCandidate(var6, var1)) {
            collectRulesWithVolume(var6.getRules(), var2, var6, var4);
            GroupEntry var7 = var6.getGroupId() != null ? this.groups.get(var6.getGroupId()) : null;
            if (var7 != null && var7.isEnabled()) {
               collectRulesWithVolume(var7.getRules(), var2, var6, var4);
            }
         }
      }

      class="kw">return var4;
   }

   class="kw">private class="kw">static <T class="kw">extends TriggerRule> void collectRulesWithVolume(
      @Nonnull List<TriggerRule> var0, @Nonnull Class<T> var1, @Nonnull VolumeEntry var2, @Nonnull List<TriggerVolumeManager.ActiveRule<T>> var3
   ) {
      for (TriggerRule var5 : var0) {
         if (var5.isEnabled() && var1.isInstance(var5)) {
            var3.add(new TriggerVolumeManager.ActiveRule<>(var1.cast(var5), var2));
         }
      }
   }

   class="kw">private class="kw">static boolean isRuleCandidate(@Nonnull VolumeEntry var0, @Nonnull Vector3d var1) {
      class="kw">return var0.isEnabled() && var0.isRulesActive() && var0.getShape().contains(var0.getPosition(), var1);
   }

   class="kw">private class="kw">static boolean containsRule(@Nonnull List<TriggerRule> var0, @Nonnull Class<? class="kw">extends TriggerRule> var1) {
      for (TriggerRule var3 : var0) {
         if (var3.isEnabled() && var1.isInstance(var3)) {
            class="kw">return true;
         }
      }

      class="kw">return false;
   }

   class="kw">private class="kw">static <T class="kw">extends TriggerRule> void collectRules(@Nonnull List<TriggerRule> var0, @Nonnull Class<T> var1, @Nonnull List<T> var2) {
      for (TriggerRule var4 : var0) {
         if (var4.isEnabled() && var1.isInstance(var4)) {
            var2.add(var1.cast(var4));
         }
      }
   }

   @Nonnull
   class="kw">public VolumeSpatialIndex getSpatialIndex() {
      class="kw">return this.spatialIndex;
   }

   @Nonnull
   class="kw">public DelayedEffectScheduler getDelayedEffectScheduler() {
      class="kw">return this.delayedEffectScheduler;
   }

   class="kw">public void setWorld(@Nullable World var1) {
      this.world = var1;
   }

   @Nullable
   class="kw">public World getWorld() {
      class="kw">return this.world;
   }

   class="kw">public void registerGroup(@Nonnull String var1, @Nonnull GroupEntry var2) {
      if (var2.getName() == null) {
         var2.setName(generateDefaultName("tvg_"));
      }

      this.groups.put(var1, var2);
   }

   class="kw">private class="kw">static String generateDefaultName(@Nonnull String var0) {
      ThreadLocalRandom var1 = ThreadLocalRandom.current();
      StringBuilder var2 = new StringBuilder(var0);

      for (int var3 = 0; var3 < 6; var3++) {
         var2.append("abcdefghijklmnopqrstuvwxyz0123456789".charAt(var1.nextInt("abcdefghijklmnopqrstuvwxyz0123456789".length())));
      }

      class="kw">return var2.toString();
   }

   @Nonnull
   class="kw">public String makeUniqueVolumeName(@Nullable String var1, @Nullable String var2) {
      class="kw">return this.makeUniqueName(var1, "tv_", var2x -> this.isVolumeNameFree(var2x, var2));
   }

   class="kw">private boolean isVolumeNameFree(@Nonnull String var1, @Nullable String var2) {
      for (Entry var4 : this.volumes.entrySet()) {
         if (!var4.getKey().equals(var2) && var1.equals(var4.getValue().getName())) {
            class="kw">return false;
         }
      }

      class="kw">return true;
   }

   @Nonnull
   class="kw">public String makeUniqueGroupName(@Nullable String var1, @Nullable String var2) {
      class="kw">return this.makeUniqueName(var1, "tvg_", var2x -> this.isGroupNameFree(var2x, var2));
   }

   @Nonnull
   class="kw">private String makeUniqueName(@Nullable String var1, @Nonnull String var2, @Nonnull Predicate<String> var3) {
      String var4 = var1 != null ? var1.trim() : "";
      if (var4.isEmpty()) {
         class="kw">return generateDefaultName(var2);
      }

      if (var3.test(var4)) {
         class="kw">return var4;
      }

      Matcher var5 = NUMBERED_SUFFIX.matcher(var4);
      String var6 = var5.matches() ? var5.group(1) : var4;
      int var7 = 2;

      while (true) {
         String var8 = var6 + " (" + var7 + ")";
         if (var3.test(var8)) {
            class="kw">return var8;
         }

         var7++;
      }
   }

   class="kw">private boolean isGroupNameFree(@Nonnull String var1, @Nullable String var2) {
      for (Entry var4 : this.groups.entrySet()) {
         if (!var4.getKey().equals(var2) && var1.equals(var4.getValue().getName())) {
            class="kw">return false;
         }
      }

      class="kw">return true;
   }

   class="kw">public void unregisterGroup(@Nonnull String var1) {
      this.groups.remove(var1);
   }

   @Nullable
   class="kw">public GroupEntry getGroup(@Nonnull String var1) {
      class="kw">return this.groups.get(var1);
   }

   class="kw">public boolean hasGroup(@Nonnull String var1) {
      class="kw">return this.groups.containsKey(var1);
   }

   class="kw">public void clearPrefabGroupLinkRemap() {
      this.prefabGroupLinkRemap.clear();
   }

   @Nonnull
   class="kw">public String ensureGroupForPrefabLink(@Nonnull String var1, @Nonnull VolumeEntry var2, @Nonnull String var3) {
      class="kw">return this.prefabGroupLinkRemap
         .computeIfAbsent(
            var1,
            var3x -> {
               String var4 = this.generateUniquePastedGroupId();
               int var5 = var2.getColor() != null
                  ? packRgb(var2.getColor())
                  : (int)(COLOR_ENABLED.x() * 255.0F) << 16 | (int)(COLOR_ENABLED.y() * 255.0F) << 8 | (int)(COLOR_ENABLED.z() * 255.0F);
               GroupEntry var6 = new GroupEntry(
                  var4, var3, new Vector3d(var2.getPosition()), new ArrayList<>(), EnumSet.copyOf(var2.getTargetTypes()), var2.isEnabled(), var5
               );
               this.registerGroup(var4, var6);
               class="kw">return var4;
            }
         );
   }

   @Nonnull
   class="kw">public String upsertGroupForPrefabLink(@Nonnull String var1, @Nonnull TriggerVolumeGroup var2, @Nonnull String var3, @Nonnull Vector3d var4, float var5) {
      String var6 = this.prefabGroupLinkRemap.computeIfAbsent(var1, var1x -> this.generateUniquePastedGroupId());
      GroupEntry var7 = this.groups.get(var6);
      if (var7 == null) {
         GroupEntry var8 = var2.toGroupEntry(var6, var3, new Vector3d(var4), var5);
         var8.setName(this.makeUniqueGroupName(var8.getName(), var6));
         this.registerGroup(var6, var8);
      } else {
         var2.applyTo(var7, new Vector3d(var4), var5);
         var7.setName(this.makeUniqueGroupName(var7.getName(), var6));
      }

      class="kw">return var6;
   }

   @Nullable
   class="kw">public String ensureWorldGenGroup(int var1, @Nonnull String var2, @Nonnull VolumeEntry var3, @Nonnull String var4) {
      String var5 = getWorldGenGroupId(var1, var2);
      if (var5 == null) {
         class="kw">return null;
      }

      if (this.groups.containsKey(var5)) {
         class="kw">return var5;
      }

      int var6 = var3.getColor() != null
         ? packRgb(var3.getColor())
         : (int)(COLOR_ENABLED.x() * 255.0F) << 16 | (int)(COLOR_ENABLED.y() * 255.0F) << 8 | (int)(COLOR_ENABLED.z() * 255.0F);
      GroupEntry var7 = new GroupEntry(
         var5, var4, new Vector3d(var3.getPosition()), new ArrayList<>(), EnumSet.copyOf(var3.getTargetTypes()), var3.isEnabled(), var6
      );
      this.registerGroup(var5, var7);
      class="kw">return var5;
   }

   @Nullable
   class="kw">public String upsertWorldGenGroup(int var1, @Nonnull String var2, @Nonnull TriggerVolumeGroup var3, @Nonnull String var4, @Nonnull Vector3d var5, float var6) {
      String var7 = getWorldGenGroupId(var1, var2);
      if (var7 == null) {
         class="kw">return null;
      }

      GroupEntry var8 = this.groups.get(var7);
      if (var8 == null) {
         this.registerGroup(var7, var3.toGroupEntry(var7, var4, new Vector3d(var5), var6));
      } else {
         var3.applyTo(var8, new Vector3d(var5), var6);
      }

      class="kw">return var7;
   }

   @Nullable
   class="kw">private class="kw">static String getWorldGenGroupId(int var0, @Nonnull String var1) {
      String var2 = sanitizeWorldGenLinkId(var1);
      class="kw">return var2.isEmpty() ? null : "tvg_wg_" + Integer.toUnsignedString(var0, 36) + "_" + var2;
   }

   @Nonnull
   class="kw">private class="kw">static String sanitizeWorldGenLinkId(@Nonnull String var0) {
      String var1 = var0.toLowerCase(Locale.ROOT);
      StringBuilder var2 = new StringBuilder(var1.length());

      for (int var3 = 0; var3 < var1.length(); var3++) {
         char var4 = var1.charAt(var3);
         if (var4 >= 'a' && var4 <= 'z' || var4 >= '0' && var4 <= '9' || var4 == '_') {
            var2.append(var4);
         }
      }

      class="kw">return var2.toString();
   }

   @Nonnull
   class="kw">public String generateUniqueVolumeId() {
      String var1;
      do {
         var1 = UUID.randomUUID().toString();
      } while (this.hasVolume(var1));

      class="kw">return var1;
   }

   @Nonnull
   class="kw">private String generateUniquePastedGroupId() {
      String var1;
      do {
         var1 = UUID.randomUUID().toString();
      } while (this.hasGroup(var1));

      class="kw">return var1;
   }

   class="kw">private class="kw">static int packRgb(@Nonnull Vector3f var0) {
      int var1 = Math.min(255, Math.max(0, Math.round(var0.x() * 255.0F))) & 0xFF;
      int var2 = Math.min(255, Math.max(0, Math.round(var0.y() * 255.0F))) & 0xFF;
      int var3 = Math.min(255, Math.max(0, Math.round(var0.z() * 255.0F))) & 0xFF;
      class="kw">return var1 << 16 | var2 << 8 | var3;
   }

   @Nonnull
   class="kw">public Map<String, GroupEntry> getGroupsMap() {
      class="kw">return Collections.unmodifiableMap(this.groups);
   }

   @Nonnull
   class="kw">public List<VolumeEntry> getGroupMembers(@Nonnull String var1) {
      ArrayList var2 = new ArrayList<>();

      for (VolumeEntry var4 : this.volumes.values()) {
         if (var1.equals(var4.getGroupId())) {
            var2.add(var4);
         }
      }

      class="kw">return var2;
   }

   @Nonnull
   class="kw">public List<VolumeEntry> getVolumesByTag(int var1) {
      ArrayList var2 = new ArrayList<>();

      for (VolumeEntry var4 : this.volumes.values()) {
         if (var4.hasTag(var1)) {
            var2.add(var4);
         }
      }

      class="kw">return var2;
   }

   @Nonnull
   class="kw">public List<GroupEntry> getGroupsByTag(int var1) {
      ArrayList var2 = new ArrayList<>();

      for (GroupEntry var4 : this.groups.values()) {
         if (var4.hasTag(var1)) {
            var2.add(var4);
         }
      }

      class="kw">return var2;
   }

   class="kw">public boolean setTag(@Nonnull String var1, @Nonnull String var2, @Nullable String var3, @Nullable Ref<EntityStore> var4, @Nonnull UUID var5) {
      VolumeEntry var6 = this.volumes.get(var1);
      if (var6 == null) {
         class="kw">return false;
      }

      String var7 = var2.trim();
      if (var7.isEmpty()) {
         class="kw">return false;
      }

      String var8 = TaggedVolumeEffectUtil.normalizeTagValue(var3);
      String var9 = var6.getRawTags().get(var7);
      if (Objects.equals(var9, var8)) {
         class="kw">return false;
      }

      LinkedHashMap var10 = new LinkedHashMap<>(var6.getRawTags());
      var10.put(var7, var8);
      var6.setTags(var10);
      this.enqueuePendingEvent(
         new TriggerVolumeManager.PendingTriggerEvent(TriggerEventType.TAG_ADDED, var4, var5, var1, null, null, List.of(new SignalTag(var7, var8)), null)
      );
      class="kw">return true;
   }

   class="kw">public boolean removeTag(@Nonnull String var1, @Nonnull String var2, @Nullable Ref<EntityStore> var3, @Nonnull UUID var4) {
      class="kw">return this.removeTag(var1, var2, null, var3, var4);
   }

   class="kw">public boolean removeTag(@Nonnull String var1, @Nonnull String var2, @Nullable String var3, @Nullable Ref<EntityStore> var4, @Nonnull UUID var5) {
      VolumeEntry var6 = this.volumes.get(var1);
      if (var6 == null) {
         class="kw">return false;
      }

      String var7 = var2.trim();
      if (!var7.isEmpty() && var6.getRawTags().containsKey(var7)) {
         String var8 = var6.getRawTags().get(var7);
         String var9 = TaggedVolumeEffectUtil.blankToNull(var3);
         if (var9 != null && !Objects.equals(var8, var9)) {
            class="kw">return false;
         }

         LinkedHashMap var10 = new LinkedHashMap<>(var6.getRawTags());
         var10.remove(var7);
         var6.setTags(var10);
         this.enqueuePendingEvent(
            new TriggerVolumeManager.PendingTriggerEvent(TriggerEventType.TAG_REMOVED, var4, var5, var1, null, null, List.of(new SignalTag(var7, var8)), null)
         );
         class="kw">return true;
      } else {
         class="kw">return false;
      }
   }

   class="kw">public void enqueueBlockEvent(
      @Nonnull TriggerEventType var1, @Nonnull Ref<EntityStore> var2, @Nonnull UUID var3, @Nonnull Vector3d var4, @Nonnull String var5
   ) {
      this.enqueueBlockEvent(var1, var2, var3, var4, var5, null);
   }

   class="kw">public void enqueueBlockEvent(
      @Nonnull TriggerEventType var1,
      @Nonnull Ref<EntityStore> var2,
      @Nonnull UUID var3,
      @Nonnull Vector3d var4,
      @Nonnull String var5,
      @Nullable InteractionType var6
   ) {
      this.enqueuePendingEvent(new TriggerVolumeManager.PendingTriggerEvent(var1, var2, var3, null, new Vector3d(var4), var5, List.of(), var6));
   }

   class="kw">public void enqueueEntityUseEvent(
      @Nonnull Ref<EntityStore> var1, @Nonnull UUID var2, @Nonnull Vector3d var3, @Nullable String var4, @Nullable InteractionType var5
   ) {
      this.enqueuePendingEvent(
         new TriggerVolumeManager.PendingTriggerEvent(TriggerEventType.BLOCK_USED, var1, var2, null, new Vector3d(var3), var4, List.of(), var5)
      );
   }

   class="kw">public void enqueueEnvironmentBlockEvent(@Nonnull TriggerEventType var1, @Nonnull Vector3d var2, @Nonnull String var3) {
      this.enqueuePendingEvent(
         new TriggerVolumeManager.PendingTriggerEvent(var1, null, ENVIRONMENT_ACTOR_UUID, null, new Vector3d(var2), var3, List.of(), null)
      );
   }

   class="kw">public void enqueuePositionalEvent(@Nonnull TriggerEventType var1, @Nonnull Ref<EntityStore> var2, @Nonnull UUID var3, @Nonnull Vector3d var4) {
      this.enqueuePendingEvent(new TriggerVolumeManager.PendingTriggerEvent(var1, var2, var3, null, new Vector3d(var4), null, List.of(), null));
   }

   class="kw">public void enqueueVolumeCreateEvent(@Nonnull VolumeEntry var1, @Nullable Ref<EntityStore> var2, @Nonnull UUID var3) {
      this.enqueuePendingEvent(
         new TriggerVolumeManager.PendingTriggerEvent(TriggerEventType.VOLUME_CREATE, var2, var3, var1.getId(), null, null, List.of(), null)
      );
   }

   class="kw">public void enqueueVolumeEvent(
      @Nonnull TriggerEventType var1, @Nonnull Ref<EntityStore> var2, @Nonnull UUID var3, @Nonnull String var4, @Nullable String var5, @Nullable String var6
   ) {
      this.enqueueVolumeEvent(var1, var2, var3, var4, var5 == null ? List.of() : List.of(new SignalTag(var5, var6)));
   }

   class="kw">public void enqueueVolumeEvent(
      @Nonnull TriggerEventType var1, @Nullable Ref<EntityStore> var2, @Nonnull UUID var3, @Nonnull String var4, @Nonnull List<SignalTag> var5
   ) {
      this.enqueueVolumeEvent(var1, var2, var3, var4, var5, null, null);
   }

   class="kw">public void enqueueVolumeEvent(
      @Nonnull TriggerEventType var1,
      @Nullable Ref<EntityStore> var2,
      @Nonnull UUID var3,
      @Nonnull String var4,
      @Nonnull List<SignalTag> var5,
      @Nullable Vector3d var6,
      @Nullable String var7
   ) {
      this.enqueuePendingEvent(new TriggerVolumeManager.PendingTriggerEvent(var1, var2, var3, var4, var6 != null ? new Vector3d(var6) : null, var7, var5, null));
   }

   @Nullable
   class="kw">public TriggerVolumeManager.PendingTriggerEvent pollPendingEvent() {
      class="kw">return this.pendingEvents.pollFirst();
   }

   class="kw">public boolean hasPendingEvents() {
      class="kw">return !this.pendingEvents.isEmpty();
   }

   class="kw">private void enqueuePendingEvent(@Nonnull TriggerVolumeManager.PendingTriggerEvent var1) {
      this.pendingEvents.addLast(var1);
   }

   class="kw">public boolean isViewing(@Nonnull UUID var1) {
      EnumSet var2 = this.activeViewers.get(var1);
      class="kw">return var2 != null && !var2.isEmpty();
   }

   class="kw">public boolean isViewing(@Nonnull UUID var1, @Nonnull TriggerVolumeManager.ViewSource var2) {
      EnumSet var3 = this.activeViewers.get(var1);
      class="kw">return var3 != null && var3.contains(var2);
   }

   @Nullable
   class="kw">public EnumSet<TriggerVolumeManager.ViewSource> peekViewerSources(@Nonnull UUID var1) {
      EnumSet var2 = this.activeViewers.get(var1);
      class="kw">return var2 != null ? EnumSet.copyOf(var2) : null;
   }

   class="kw">public void addViewer(@Nonnull UUID var1, @Nonnull TriggerVolumeManager.ViewSource var2) {
      this.activeViewers.computeIfAbsent(var1, var0 -> EnumSet.noneOf(TriggerVolumeManager.ViewSource.class)).add(var2);
   }

   class="kw">public void removeViewer(@Nonnull UUID var1, @Nonnull TriggerVolumeManager.ViewSource var2) {
      this.activeViewers.computeIfPresent(var1, (var1x, var2x) -> {
         var2x.remove(var2);
         class="kw">return var2x.isEmpty() ? null : var2x;
      });
   }

   class="kw">public void setPlayerSelection(@Nonnull UUID var1, @Nullable String var2) {
      if (var2 == null) {
         this.playerSelections.remove(var1);
      } else {
         this.playerSelections.put(var1, var2);
      }

      TriggerVolumeManager.SelectionObserver var3 = this.selectionObservers.get(var1);
      if (var3 != null) {
         var3.onSelectionChanged(var2);
      }
   }

   @Nullable
   class="kw">public String getPlayerSelection(@Nonnull UUID var1) {
      class="kw">return this.playerSelections.get(var1);
   }

   class="kw">public void setSelectionObserver(@Nonnull UUID var1, @Nonnull TriggerVolumeManager.SelectionObserver var2) {
      this.selectionObservers.put(var1, var2);
   }

   class="kw">public void clearSelectionObserver(@Nonnull UUID var1, @Nonnull TriggerVolumeManager.SelectionObserver var2) {
      this.selectionObservers.remove(var1, var2);
   }

   class="kw">public void setVolumeUpdateObserver(@Nonnull UUID var1, @Nonnull TriggerVolumeManager.VolumeUpdateObserver var2) {
      this.volumeUpdateObservers.put(var1, var2);
   }

   class="kw">public void clearVolumeUpdateObserver(@Nonnull UUID var1, @Nonnull TriggerVolumeManager.VolumeUpdateObserver var2) {
      this.volumeUpdateObservers.remove(var1, var2);
   }

   class="kw">public void notifyViewers() {
      this.markClientRuleVolumesDirty();
      if (!this.activeViewers.isEmpty()) {
         TriggerVolumeDisplayEntry[] var1 = this.buildDisplayEntries();
         UpdateTriggerVolumeDisplay var2 = new UpdateTriggerVolumeDisplay(var1);

         for (UUID var4 : this.activeViewers.keySet()) {
            PlayerRef var5 = Universe.get().getPlayer(var4);
            if (var5 != null) {
               var5.getPacketHandler().write(var2);
            }
         }
      }
   }

   class="kw">public int getViewerCount() {
      class="kw">return this.activeViewers.size();
   }

   @Nonnull
   class="kw">public Set<UUID> getViewerUuids() {
      class="kw">return new HashSet<>(this.activeViewers.keySet());
   }

   class="kw">public void clearViewers() {
      this.activeViewers.clear();
      this.playerSelections.clear();
   }

   class="kw">public void notifyViewersAdd(@Nonnull VolumeEntry var1) {
      this.markClientRuleVolumesDirty();
      if (!this.activeViewers.isEmpty()) {
         AddOrUpdateTriggerVolumeDisplay var2 = new AddOrUpdateTriggerVolumeDisplay(var1.getId(), this.buildDisplayEntry(var1));

         for (UUID var4 : this.activeViewers.keySet()) {
            PlayerRef var5 = Universe.get().getPlayer(var4);
            if (var5 != null) {
               var5.getPacketHandler().write(var2);
            }
         }
      }

      for (TriggerVolumeManager.VolumeUpdateObserver var7 : this.volumeUpdateObservers.values()) {
         var7.onVolumeUpdated(var1);
      }
   }

   class="kw">public void notifyViewersRemove(@Nonnull String var1) {
      this.markClientRuleVolumesDirty();
      if (!this.activeViewers.isEmpty()) {
         RemoveTriggerVolumeDisplay var2 = new RemoveTriggerVolumeDisplay(var1);

         for (UUID var4 : this.activeViewers.keySet()) {
            PlayerRef var5 = Universe.get().getPlayer(var4);
            if (var5 != null) {
               var5.getPacketHandler().write(var2);
            }
         }
      }

      for (TriggerVolumeManager.VolumeUpdateObserver var7 : this.volumeUpdateObservers.values()) {
         var7.onVolumeRemoved(var1);
      }
   }

   class="kw">public void notifyViewersLegacyVolumeSkipped() {
      if (!this.activeViewers.isEmpty()) {
         Message var1 = Message.translation("server.triggervolumes.legacyVolumeSkipped");

         for (UUID var3 : this.activeViewers.keySet()) {
            PlayerRef var4 = Universe.get().getPlayer(var3);
            if (var4 != null) {
               var4.sendMessage(var1);
            }
         }
      }
   }

   class="kw">public void sendVolumeDisplay(@Nonnull PlayerRef var1) {
      var1.getPacketHandler().write(new UpdateTriggerVolumeDisplay(this.buildDisplayEntries()));
   }

   @Nonnull
   class="kw">private TriggerVolumeDisplayEntry[] buildDisplayEntries() {
      Collection var1 = this.volumes.values();
      TriggerVolumeDisplayEntry[] var2 = new TriggerVolumeDisplayEntry[var1.size()];
      int var3 = 0;

      for (VolumeEntry var5 : var1) {
         var2[var3++] = this.buildDisplayEntry(var5);
      }

      class="kw">return var2;
   }

   @Nonnull
   class="kw">public TriggerVolumeDisplayEntry buildDisplayEntry(@Nonnull VolumeEntry var1) {
      TriggerVolumeDisplayEntry var2 = new TriggerVolumeDisplayEntry();
      TriggerVolumeManager.VolumeGeometry var3 = computeGeometry(var1);
      var2.shapeType = var3.shapeType();
      var2.position = var3.position();
      var2.dimensions = var3.dimensions();
      if (var3.rotation() != null) {
         var2.rotation = var3.rotation();
      }

      var2.color = var1.getColor() != null ? var1.getColor() : (var1.isEnabled() ? COLOR_ENABLED : COLOR_DISABLED);
      var2.opacity = var1.isEnabled() ? 0.3F : 0.15F;
      var2.volumeId = var1.getId();
      var2.name = var1.getName();
      var2.effectAssetRef = var1.getEffectAssetRef();
      int var4 = 0;

      for (EntityTargetType var6 : var1.getTargetTypes()) {
         var4 |= class="kw">switch (var6) {
            case PLAYER -> 1;
            case NPC -> 2;
            case ITEM_DROP -> 4;
            case PROJECTILE -> 8;
         };
      }

      var2.targetTypes = (byte)var4;
      var2.keepLoaded = var1.isKeepLoaded();
      var2.cancelDelayedOnExit = var1.isCancelDelayedEffectsOnExit();
      var2.cooldown = var1.getCooldown();
      var2.cooldownMode = (byte)var1.getCooldownMode().ordinal();
      var2.activationDelay = var1.getActivationDelay();
      var2.conditionTiming = var1.getConditionTiming() == ConditionTiming.BEFORE_VOLUME_DELAY
         ? TriggerVolumeConditionTiming.BeforeVolumeDelay
         : TriggerVolumeConditionTiming.AfterVolumeDelay;
      if (var1.getGroupId() != null) {
         var2.groupId = var1.getGroupId();
         GroupEntry var9 = this.groups.get(var1.getGroupId());
         if (var9 != null) {
            var2.groupColor = var9.getColor();
            float var10 = (var9.getColor() >> 16 & 0xFF) / 255.0F;
            float var7 = (var9.getColor() >> 8 & 0xFF) / 255.0F;
            float var8 = (var9.getColor() & 0xFF) / 255.0F;
            var2.color = new Vector3f(var10, var7, var8);
         }
      }

      class="kw">return var2;
   }

   @Nonnull
   class="kw">private class="kw">static TriggerVolumeManager.VolumeGeometry computeGeometry(@Nonnull VolumeEntry var0) {
      Vector3d var1 = var0.getPosition();
      TriggerVolumeShape var2 = var0.getShape();
      if (var2 class="kw">instanceof BoxShape var12) {
         Vector3d var14 = var12.getMin();
         Vector3d var15 = var12.getMax();
         Vector3f var8 = new Vector3f(
            (float)(var1.x() + (var14.x() + var15.x()) * 0.5),
            (float)(var1.y() + (var14.y() + var15.y()) * 0.5),
            (float)(var1.z() + (var14.z() + var15.z()) * 0.5)
         );
         Vector3f var9 = new Vector3f((float)((var15.x() - var14.x()) * 0.5), (float)((var15.y() - var14.y()) * 0.5), (float)((var15.z() - var14.z()) * 0.5));
         Vector3d var10 = var12.getRotation();
         Vector3f var11 = var10 != null ? new Vector3f((float)var10.x(), (float)var10.y(), (float)var10.z()) : null;
         class="kw">return new TriggerVolumeManager.VolumeGeometry(TriggerVolumeShapeType.Box, var8, var9, var11);
      } else if (var2 class="kw">instanceof SphereShape var4) {
         Vector3d var13 = var4.getCenter();
         class="kw">return new TriggerVolumeManager.VolumeGeometry(
            TriggerVolumeShapeType.Sphere,
            new Vector3f((float)(var1.x() + var13.x()), (float)(var1.y() + var13.y()), (float)(var1.z() + var13.z())),
            new Vector3f((float)var4.getRadius(), 0.0F, 0.0F),
            null
         );
      } else if (var2 class="kw">instanceof CylinderShape var5) {
         Vector3d var6 = var5.getCenter();
         double var7 = var5.getHeight() * 0.5;
         class="kw">return new TriggerVolumeManager.VolumeGeometry(
            TriggerVolumeShapeType.Cylinder,
            new Vector3f((float)(var1.x() + var6.x()), (float)(var1.y() + var6.y() + var7), (float)(var1.z() + var6.z())),
            new Vector3f((float)var5.getRadius(), (float)var5.getHeight(), 0.0F),
            null
         );
      } else {
         double var3 = var2.getBoundingRadius();
         class="kw">return new TriggerVolumeManager.VolumeGeometry(
            TriggerVolumeShapeType.Sphere, new Vector3f((float)var1.x(), (float)var1.y(), (float)var1.z()), new Vector3f((float)var3, 0.0F, 0.0F), null
         );
      }
   }

   class="kw">public void markClientRuleVolumesDirty() {
      this.clientRuleVolumesDirty = true;
      this.tickSuppressionDirty = true;
   }

   class="kw">public void flushTickSuppressionIfDirty(@Nonnull TickSuppressionRegistry var1) {
      if (this.tickSuppressionDirty) {
         this.tickSuppressionDirty = false;
         TickSuppressionSnapshot var2 = this.buildTickSuppressionSnapshot();
         var1.setSnapshot(var2, var2 == null ? 0 : var2.activeKinds());
      }
   }

   @Nullable
   class="kw">private TickSuppressionSnapshot buildTickSuppressionSnapshot() {
      ArrayList var1 = new ArrayList<>();

      for (VolumeEntry var3 : this.volumes.values()) {
         if (var3.isEnabled() && var3.isRulesActive()) {
            NoTickRule var4 = this.findActiveNoTickRule(var3);
            if (var4 != null) {
               int var5 = (var4.suppressesScheduled() ? 1 : 0) | (var4.suppressesRandom() ? 2 : 0);
               if (var5 != 0) {
                  var1.add(new TickSuppressionSnapshot.Region(new Vector3d(var3.getPosition()), var3.getShape(), var5));
               }
            }
         }
      }

      class="kw">return var1.isEmpty() ? null : new TickSuppressionSnapshot(var1);
   }

   @Nullable
   class="kw">private NoTickRule findActiveNoTickRule(@Nonnull VolumeEntry var1) {
      for (TriggerRule var3 : var1.getRules()) {
         if (var3.isEnabled() && var3 class="kw">instanceof NoTickRule var4) {
            class="kw">return var4;
         }
      }

      GroupEntry var6 = var1.getGroupId() != null ? this.groups.get(var1.getGroupId()) : null;
      if (var6 != null && var6.isEnabled()) {
         for (TriggerRule var8 : var6.getRules()) {
            if (var8.isEnabled() && var8 class="kw">instanceof NoTickRule var5) {
               class="kw">return var5;
            }
         }
      }

      class="kw">return null;
   }

   class="kw">public void flushClientRuleVolumesIfDirty() {
      if (this.clientRuleVolumesDirty) {
         this.clientRuleVolumesDirty = false;
         this.broadcastClientRuleVolumes();
      }
   }

   class="kw">public void broadcastClientRuleVolumes() {
      if (this.world != null) {
         UpdateClientRuleVolumes var1 = new UpdateClientRuleVolumes(this.buildClientRuleVolumes());

         for (PlayerRef var3 : this.world.getPlayerRefs()) {
            var3.getPacketHandler().write(var1);
         }
      }
   }

   class="kw">public void sendClientRuleVolumes(@Nonnull PlayerRef var1) {
      var1.getPacketHandler().write(new UpdateClientRuleVolumes(this.buildClientRuleVolumes()));
   }

   @Nonnull
   class="kw">private ClientRuleVolume[] buildClientRuleVolumes() {
      ArrayList var1 = new ArrayList<>();

      for (VolumeEntry var3 : this.volumes.values()) {
         ClientRuleVolume var4 = this.buildClientRuleVolume(var3);
         if (var4 != null) {
            var1.add(var4);
         }
      }

      class="kw">return var1.toArray(new ClientRuleVolume[0]);
   }

   @Nullable
   class="kw">private ClientRuleVolume buildClientRuleVolume(@Nonnull VolumeEntry var1) {
      if (var1.isEnabled() && var1.isRulesActive()) {
         byte var2 = 0;
         IntOpenHashSet var3 = new IntOpenHashSet();
         IntOpenHashSet var4 = new IntOpenHashSet();
         IntOpenHashSet var5 = new IntOpenHashSet();
         LinkedHashSet var6 = new LinkedHashSet<>();

         for (TriggerRule var8 : var1.getRules()) {
            var2 = accumulateRule(var8, var2, var3, var4, var5, var6);
         }

         if (var1.getGroupId() != null) {
            GroupEntry var10 = this.groups.get(var1.getGroupId());
            if (var10 != null && var10.isEnabled()) {
               for (TriggerRule var9 : var10.getRules()) {
                  var2 = accumulateRule(var9, var2, var3, var4, var5, var6);
               }
            }
         }

         if (var2 == 0) {
            class="kw">return null;
         }

         TriggerVolumeManager.VolumeGeometry var11 = computeGeometry(var1);
         ClientRuleVolume var13 = new ClientRuleVolume();
         var13.rules = var2;
         var13.shapeType = var11.shapeType();
         var13.position = var11.position();
         var13.dimensions = var11.dimensions();
         var13.rotation = var11.rotation() != null ? var11.rotation() : new Vector3f();
         var13.buildExceptBlocks = toIntArrayOrNull(var3);
         var13.destroyExceptBlocks = toIntArrayOrNull(var4);
         var13.harvestExceptBlocks = toIntArrayOrNull(var5);
         var13.destroyExceptTools = var6.isEmpty() ? null : var6.toArray(new String[0]);
         class="kw">return var13;
      } else {
         class="kw">return null;
      }
   }

   class="kw">private class="kw">static byte accumulateRule(
      @Nonnull TriggerRule var0, byte var1, @Nonnull IntOpenHashSet var2, @Nonnull IntOpenHashSet var3, @Nonnull IntOpenHashSet var4, @Nonnull Set<String> var5
   ) {
      if (!var0.isEnabled()) {
         class="kw">return var1;
      }

      if (var0 class="kw">instanceof NoBuildRule var6) {
         var1 = (byte)(var1 | 1);
         var6.collectExceptBlockIds(var2);
      } else if (var0 class="kw">instanceof NoDestroyRule var7) {
         var1 = (byte)(var1 | 2);
         var7.collectExceptBlockIds(var3);
         var7.collectExceptToolKeys(var5);
      } else if (var0 class="kw">instanceof NoHarvestRule var8) {
         var1 = (byte)(var1 | 4);
         var8.collectExceptBlockIds(var4);
      } else if (var0 class="kw">instanceof NoDamageRule var9 && var9.getEntityFilter() == RuleEntityFilter.ALL) {
         var1 = (byte)(var1 | (var9.isPvpOnly() ? 16 : 8));
      }

      class="kw">return var1;
   }

   @Nullable
   class="kw">private class="kw">static int[] toIntArrayOrNull(@Nonnull IntOpenHashSet var0) {
      class="kw">return var0.isEmpty() ? null : var0.toIntArray();
   }

   @Nonnull
   @Override
   class="kw">public Resource<EntityStore> clone() {
      throw new UnsupportedOperationException("TriggerVolumeManager cannot be cloned");
   }

   class="kw">public record ActiveRule<T class="kw">extends TriggerRule>(@Nonnull T rule, @Nonnull VolumeEntry volume) {
      class="kw">public ActiveRule {
      }
   }

   class="kw">public record PendingTriggerEvent(
      @Nonnull TriggerEventType eventType,
      @Nullable Ref<EntityStore> actorRef,
      @Nonnull UUID actorUuid,
      @Nullable String volumeId,
      @Nullable Vector3d blockPosition,
      @Nullable String blockId,
      @Nonnull List<SignalTag> signalTags,
      @Nullable InteractionType interactionType
   ) {
      class="kw">public PendingTriggerEvent {
      }
   }

   class="kw">public class="kw">interface SelectionObserver {
      void onSelectionChanged(@Nullable String var1);
   }

   class="kw">public enum ViewSource {
      COMMAND,
      TOOL,
      SELECTION_TOOL;

      ViewSource() {
      }
   }

   class="kw">private record VolumeGeometry(
      @Nonnull TriggerVolumeShapeType shapeType, @Nonnull Vector3f position, @Nonnull Vector3f dimensions, @Nullable Vector3f rotation
   ) {
      class="kw">private VolumeGeometry {
      }
   }

   class="kw">public class="kw">interface VolumeUpdateObserver {
      void onVolumeUpdated(@Nonnull VolumeEntry var1);

      void onVolumeRemoved(@Nonnull String var1);
   }
}