VoiceRouter class

Пакет: com.hypixel.hytale.server.core.modules.voice

Файл: com/hypixel/hytale/server/core/modules/voice/VoiceRouter.java

Поля (42)

МодификаторыТипИмя
final int VERBOSE_LOG_PACKET_FREQUENCY
break
break
return
double var11
VoiceModule.PositionSnapshot var11
double var12
PacketHandler var14
ChannelConnection var15
VoiceConfig var2
Vector3dc var2
PlayerRef var2
Set var3
VoicePlayerState var3
UUID var3
int var3
boolean var4
VoiceRouter.SpeakerDescriptor var4
Vector3dc var4
VoiceModule.PositionSnapshot var5
VoiceRouter.SpeakerDescriptor var5
var5
RelayedVoiceData var5
List var5
UUID var5
VoiceRouter.SpeakerDescriptor var6
RelayedVoiceData var6
Vector3dc var6
int var6
PacketHandler var6
Set var6
PlayerVoiceFrame var7
RelayedVoiceData var7
double var7
ChannelConnection var7
float var7
UUID var8
List var8
var8
var8
VoiceModule.PositionSnapshot var9
double var9

Методы (30)

МодификаторыВозвратСигнатура
private record ListenerCandidaterecord ListenerCandidate(double distSq, ChannelConnection voiceChannel)
record SpeakerDescriptorrecord SpeakerDescriptor(@Nonnull UUID speakerId, @Nullable Vector3dc position, boolean isUnderwater, @Nonnull UUID worldId, int entityId)
private RelayedVoiceData buildRelayRelayedVoiceData buildRelay(@Nonnull VoiceRouter.SpeakerDescriptor var1, @Nonnull byte[] var2, short var3, int var4)
private void dispatchInterceptedFramevoid dispatchInterceptedFrame(@Nonnull PlayerVoiceFrame var1)
for for(VoiceRouter.ListenerCandidate var8 : var5)
for for(UUID var5 : var1)
for for(UUID var10 : var6)
private PacketHandler getPlayerHandlerPacketHandler getPlayerHandler(UUID var1)
if if(var2 == null || var3 == null)
if if(var6 != null)
if if(!this.loggedFirstCacheRoute && var3 > 0)
if if(var2 % 50 == 0)
if if(var5 == null)
if if(var5 != null)
if if(var6 != null)
if if(var4 == null)
if if(var14 != null)
if if(var8 == null)
private void logRoutevoid logRoute(@Nonnull VoiceRouter.SpeakerDescriptor var1, short var2, int var3)
void removePlayerFromWorldSetvoid removePlayerFromWorldSet(@Nonnull UUID var1, @Nonnull UUID var2)
public void removePlayerFromWorldSetsvoid removePlayerFromWorldSets(@Nonnull UUID var1)
private int routeByProximityint routeByProximity(@Nonnull VoiceRouter.SpeakerDescriptor var1, @Nonnull RelayedVoiceData var2, @Nullable Set<UUID> var3, @Nullable Set<UUID> var4)
void routeExplicitFramevoid routeExplicitFrame(@Nonnull VoiceRouter.SpeakerDescriptor var1, @Nonnull byte[] var2, short var3, int var4, @Nonnull Collection<UUID> var5)
void routeProximityFramevoid routeProximityFrame(@Nonnull VoiceRouter.SpeakerDescriptor var1, @Nonnull byte[] var2, short var3, int var4)
void routeProximityFramevoid routeProximityFrame(@Nonnull VoiceRouter.SpeakerDescriptor var1, @Nonnull byte[] var2, short var3, int var4, @Nullable Set<UUID> var5, @Nullable Set<UUID> var6)
private int routeToExplicitint routeToExplicit(@Nonnull Collection<UUID> var1, @Nonnull RelayedVoiceData var2)
public void routeVoiceFromCachevoid routeVoiceFromCache(@Nonnull PlayerRef var1, @Nonnull VoiceData var2)
private boolean sendRelayboolean sendRelay(@Nonnull ChannelConnection var1, @Nonnull RelayedVoiceData var2)
public void sendVoiceConfigvoid sendVoiceConfig(@Nonnull PlayerRef var1)
public void updateSpeakerPositionCachevoid updateSpeakerPositionCache(@Nonnull PlayerRef var1, @Nonnull Vector3d var2, float var3, boolean var4, @Nonnull UUID var5, int var6, boolean var7)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.modules.voice;

class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.protocol.Position;
class="kw">import com.hypixel.hytale.protocol.io.ChannelConnection;
class="kw">import com.hypixel.hytale.protocol.packets.stream.StreamType;
class="kw">import com.hypixel.hytale.protocol.packets.voice.RelayedVoiceData;
class="kw">import com.hypixel.hytale.protocol.packets.voice.VoiceCodec;
class="kw">import com.hypixel.hytale.protocol.packets.voice.VoiceConfig;
class="kw">import com.hypixel.hytale.protocol.packets.voice.VoiceData;
class="kw">import com.hypixel.hytale.server.core.io.PacketHandler;
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.util.UUIDUtil;
class="kw">import java.util.ArrayList;
class="kw">import java.util.Collection;
class="kw">import java.util.List;
class="kw">import java.util.Set;
class="kw">import java.util.UUID;
class="kw">import java.util.concurrent.ConcurrentHashMap;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;
class="kw">import org.joml.Vector3dc;

class="kw">public class VoiceRouter {
   class="kw">private class="kw">static class="kw">final int VERBOSE_LOG_PACKET_FREQUENCY = 50;
   class="kw">private class="kw">static class="kw">final int MAX_LISTENERS_PER_SPEAKER = 12;
   class="kw">private class="kw">final VoiceModule voiceModule;
   class="kw">private class="kw">final HytaleLogger logger;
   class="kw">private class="kw">final ConcurrentHashMap<UUID, Set<UUID>> worldPlayerSets = new ConcurrentHashMap<>();
   class="kw">private class="kw">volatile boolean loggedFirstCacheRoute = false;

   class="kw">public VoiceRouter(@Nonnull VoiceModule var1) {
      this.voiceModule = var1;
      this.logger = var1.getLogger();
   }

   class="kw">public void updateSpeakerPositionCache(@Nonnull PlayerRef var1, @Nonnull Vector3d var2, float var3, boolean var4, @Nonnull UUID var5, int var6, boolean var7) {
      UUID var8 = var1.getUuid();
      VoiceModule.PositionSnapshot var9 = this.voiceModule.getCachedPosition(var8);
      if (var9 != null && !var9.worldId().equals(var5)) {
         this.removePlayerFromWorldSet(var8, var9.worldId());
      }

      this.worldPlayerSets.compute(var5, (var1x, var2x) -> {
         Set var3 = var2x != null ? var2x : ConcurrentHashMap.newKeySet();
         var3.add(var8);
         class="kw">return var3;
      });
      this.voiceModule.updatePositionCache(var8, VoiceModule.PositionSnapshot.atEyeHeight(var2, var3, var4, var5, var6, var7));
   }

   class="kw">public void removePlayerFromWorldSets(@Nonnull UUID var1) {
      for (UUID var3 : this.worldPlayerSets.keySet()) {
         this.removePlayerFromWorldSet(var1, var3);
      }
   }

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

   class="kw">public void sendVoiceConfig(@Nonnull PlayerRef var1) {
      VoiceConfig var2 = new VoiceConfig();
      var2.voiceEnabled = this.voiceModule.isVoiceEnabled();
      var2.codec = VoiceCodec.Opus;
      var2.sampleRate = 48000;
      var2.channels = 1;
      var2.maxHearingDistance = this.voiceModule.getMaxHearingDistance();
      var2.referenceDistance = this.voiceModule.getReferenceDistance();
      var2.supportsVoiceStream = true;
      var2.maxPacketsPerSecond = (byte)this.voiceModule.getMaxPacketsPerSecond();
      var1.getPacketHandler().writeNoCache(var2);
      this.logger
         .at(Level.FINE)
         .log(
            "[VoiceConfig] Sent to %s: enabled=%s, codec=%s, sampleRate=%d, maxDistance=%.1f, refDistance=%.1f, supportsVoiceStream=true, maxPacketsPerSecond=%d",
            var1.getUsername(),
            var2.voiceEnabled,
            var2.codec,
            var2.sampleRate,
            var2.maxHearingDistance,
            var2.referenceDistance,
            var2.maxPacketsPerSecond
         );
   }

   class="kw">public void routeVoiceFromCache(@Nonnull PlayerRef var1, @Nonnull VoiceData var2) {
      if (!this.voiceModule.isShutdown()) {
         if (this.voiceModule.isVoiceEnabled()) {
            if (!this.voiceModule.isPlayerMuted(var1.getUuid())) {
               if (var2.opusData != null && var2.opusData.length <= this.voiceModule.getMaxPacketSize()) {
                  VoicePlayerState var3 = this.voiceModule.getPlayerState(var1.getUuid());
                  boolean var4 = var3 != null && var3.isSilenced();
                  VoiceModule.PositionSnapshot var5 = this.voiceModule.getCachedPosition(var1.getUuid());
                  if (this.voiceModule.hasPlayerVoiceInterceptors()) {
                     PlayerVoiceFrame var7 = new PlayerVoiceFrame(var1, var5, var4, var2.opusData, var2.sequenceNumber, var2.timestamp);
                     this.voiceModule.runPlayerVoiceInterceptors(var7);
                     this.dispatchInterceptedFrame(var7);
                  } else if (!var4 && var5 != null) {
                     VoiceRouter.SpeakerDescriptor var6 = new VoiceRouter.SpeakerDescriptor(
                        var1.getUuid(), var5.position(), var5.isUnderwater(), var5.worldId(), var5.networkId()
                     );
                     this.routeProximityFrame(var6, var2.opusData, var2.sequenceNumber, var2.timestamp);
                  }
               }
            }
         }
      }
   }

   class="kw">private void dispatchInterceptedFrame(@Nonnull PlayerVoiceFrame var1) {
      class="kw">switch (var1.delivery()) {
         case NONE:
         class="kw">default:
            break;
         case EXPLICIT: {
            VoiceRouter.SpeakerDescriptor var5 = new VoiceRouter.SpeakerDescriptor(var1.speakerId(), null, false, UUIDUtil.EMPTY_UUID, var1.entityNetworkId());
            this.routeExplicitFrame(var5, var1.opus(), var1.sequenceNumber(), var1.timestamp(), var1.explicitListeners());
            break;
         }
         case PROXIMITY: {
            Vector3dc var2 = var1.position();
            UUID var3 = var1.worldId();
            if (var2 == null || var3 == null) {
               class="kw">return;
            }

            VoiceRouter.SpeakerDescriptor var4 = new VoiceRouter.SpeakerDescriptor(var1.speakerId(), var2, var1.underwater(), var3, var1.entityNetworkId());
            this.routeProximityFrame(var4, var1.opus(), var1.sequenceNumber(), var1.timestamp(), var1.allowedListeners(), var1.excludedListeners());
         }
      }
   }

   void routeProximityFrame(@Nonnull VoiceRouter.SpeakerDescriptor var1, @Nonnull byte[] var2, short var3, int var4) {
      this.routeProximityFrame(var1, var2, var3, var4, null, null);
   }

   void routeProximityFrame(
      @Nonnull VoiceRouter.SpeakerDescriptor var1, @Nonnull byte[] var2, short var3, int var4, @Nullable Set<UUID> var5, @Nullable Set<UUID> var6
   ) {
      var5 = this.voiceModule.getVoiceChannels().restrictAllowed(var1.speakerId(), var5);
      if (var5 == null || !var5.isEmpty()) {
         RelayedVoiceData var7 = this.buildRelay(var1, var2, var3, var4);
         this.logRoute(var1, var3, this.routeByProximity(var1, var7, var5, var6));
      }
   }

   void routeExplicitFrame(@Nonnull VoiceRouter.SpeakerDescriptor var1, @Nonnull byte[] var2, short var3, int var4, @Nonnull Collection<UUID> var5) {
      RelayedVoiceData var6 = this.buildRelay(var1, var2, var3, var4);
      this.logRoute(var1, var3, this.routeToExplicit(var5, var6));
   }

   class="kw">private RelayedVoiceData buildRelay(@Nonnull VoiceRouter.SpeakerDescriptor var1, @Nonnull byte[] var2, short var3, int var4) {
      RelayedVoiceData var5 = new RelayedVoiceData();
      var5.speakerId = var1.speakerId();
      var5.entityId = var1.entityId();
      var5.sequenceNumber = var3;
      var5.timestamp = var4;
      var5.speakerIsUnderwater = var1.isUnderwater();
      var5.opusData = var2;
      Vector3dc var6 = var1.position();
      if (var6 != null) {
         double var7 = Math.round(var6.x() * 2.0) / 2.0;
         double var9 = Math.round(var6.y() * 2.0) / 2.0;
         double var11 = Math.round(var6.z() * 2.0) / 2.0;
         var5.speakerPosition = new Position(var7, var9, var11);
      }

      class="kw">return var5;
   }

   class="kw">private void logRoute(@Nonnull VoiceRouter.SpeakerDescriptor var1, short var2, int var3) {
      if (!this.loggedFirstCacheRoute && var3 > 0) {
         this.loggedFirstCacheRoute = true;
         this.logger.at(Level.INFO).log("[VoiceRouter] First voice packet routed: speaker=%s, seq=%d, recipientCount=%d", var1.speakerId(), var2, var3);
      }

      if (var2 % 50 == 0) {
         this.logger.at(Level.FINE).log("[VoiceRouter] Route seq=%d, recipients=%d", var2, var3);
      }
   }

   class="kw">private int routeByProximity(@Nonnull VoiceRouter.SpeakerDescriptor var1, @Nonnull RelayedVoiceData var2, @Nullable Set<UUID> var3, @Nullable Set<UUID> var4) {
      List var5 = this.selectNearbyListeners(var1, var3, var4);
      if (var5 == null) {
         class="kw">return 0;
      }

      int var6 = 0;

      for (VoiceRouter.ListenerCandidate var8 : var5) {
         if (this.sendRelay(var8.voiceChannel(), var2)) {
            var6++;
         }
      }

      class="kw">return var6;
   }

   class="kw">private int routeToExplicit(@Nonnull Collection<UUID> var1, @Nonnull RelayedVoiceData var2) {
      int var3 = 0;

      for (UUID var5 : var1) {
         if (var5 != null) {
            PacketHandler var6 = this.getPlayerHandler(var5);
            if (var6 != null) {
               ChannelConnection var7 = var6.getChannel(StreamType.Voice);
               if (var7 != null && this.sendRelay(var7, var2)) {
                  var3++;
               }
            }
         }
      }

      class="kw">return var3;
   }

   class="kw">private boolean sendRelay(@Nonnull ChannelConnection var1, @Nonnull RelayedVoiceData var2) {
      if (!var1.isActive()) {
         class="kw">return false;
      }

      var1.writeAndFlush(var2);
      class="kw">return true;
   }

   @Nullable
   class="kw">private List<VoiceRouter.ListenerCandidate> selectNearbyListeners(
      @Nonnull VoiceRouter.SpeakerDescriptor var1, @Nullable Set<UUID> var2, @Nullable Set<UUID> var3
   ) {
      Vector3dc var4 = var1.position();
      if (var4 == null) {
         class="kw">return null;
      }

      UUID var5 = var1.worldId();
      Set var6 = this.worldPlayerSets.get(var5);
      if (var6 != null && !var6.isEmpty()) {
         float var7 = this.voiceModule.getMaxHearingDistance() * this.voiceModule.getMaxHearingDistance();
         List var8 = null;

         for (UUID var10 : var6) {
            if (!var10.equals(var1.speakerId()) && (var2 == null || var2.contains(var10)) && (var3 == null || !var3.contains(var10))) {
               VoiceModule.PositionSnapshot var11 = this.voiceModule.getCachedPosition(var10);
               if (var11 != null && var11.worldId().equals(var5) && (this.voiceModule.isDeadPlayersCanHear() || !var11.isDead())) {
                  double var12 = var4.distanceSquared(var11.position());
                  if (Double.isFinite(var12) && !(var12 > var7)) {
                     PacketHandler var14 = this.getPlayerHandler(var10);
                     if (var14 != null) {
                        ChannelConnection var15 = var14.getChannel(StreamType.Voice);
                        if (var15 != null && var15.isActive()) {
                           if (var8 == null) {
                              var8 = new ArrayList<>();
                           }

                           var8.add(new VoiceRouter.ListenerCandidate(var12, var15));
                        }
                     }
                  }
               }
            }
         }

         if (var8 != null && var8.size() > 12) {
            var8.sort((var0, var1x) -> Double.compare(var0.distSq(), var1x.distSq()));
            var8 = var8.subList(0, 12);
         }

         class="kw">return var8;
      } else {
         class="kw">return null;
      }
   }

   class="kw">private PacketHandler getPlayerHandler(UUID var1) {
      PlayerRef var2 = Universe.get().getPlayer(var1);
      class="kw">return var2 != null ? var2.getPacketHandler() : null;
   }

   class="kw">private record ListenerCandidate(double distSq, ChannelConnection voiceChannel) {
      class="kw">private ListenerCandidate {
      }
   }

   record SpeakerDescriptor(@Nonnull UUID speakerId, @Nullable Vector3dc position, boolean isUnderwater, @Nonnull UUID worldId, int entityId) {
      SpeakerDescriptor {
      }
   }
}