VoiceStreamHandler class
Пакет: com.hypixel.hytale.server.core.modules.voice
Файл: com/hypixel/hytale/server/core/modules/voice/VoiceStreamHandler.java
implements: ConnectionHandler
Поля (4)
| Модификаторы | Тип | Имя |
|---|---|---|
final |
PacketHandler |
packetHandler |
|
PlayerRef |
var2 |
|
VoicePlayerState |
var3 |
|
int |
var5 |
Методы (11)
| Модификаторы | Возврат | Сигнатура |
|---|---|---|
private |
PlayerRef |
getPlayerRefPlayerRef getPlayerRef() |
private |
void |
handleVoiceDatavoid handleVoiceData(@Nonnull PlayerRef var1, @Nonnull VoiceData var2) |
|
|
if if(this.packetHandler instanceof GamePacketHandler var2) |
|
|
if if(!this.loggedFirstPacket) |
|
|
if if(var2 == null) |
|
|
if if(var1 instanceof VoiceData var3) |
|
|
if if(!this.loggedFirstVoiceData) |
|
|
if if(var3 != null) |
|
|
if if(var5 >= 10) |
|
|
if if(this.cachedPlayerRef != null) |
|
|
if if(this.packetHandler instanceof GamePacketHandler var1) |
Исходный код
Показать/скрыть
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.NetworkChannel;
class="kw">import com.hypixel.hytale.protocol.ToServerPacket;
class="kw">import com.hypixel.hytale.protocol.io.ChannelConnection;
class="kw">import com.hypixel.hytale.protocol.io.ConnectionHandler;
class="kw">import com.hypixel.hytale.protocol.packets.stream.StreamType;
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.io.handlers.game.GamePacketHandler;
class="kw">import com.hypixel.hytale.server.core.universe.PlayerRef;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">public class VoiceStreamHandler class="kw">implements ConnectionHandler {
class="kw">private class="kw">final PacketHandler packetHandler;
class="kw">private class="kw">final ChannelConnection channel;
class="kw">private class="kw">final VoiceModule voiceModule;
class="kw">private class="kw">final HytaleLogger logger;
class="kw">private class="kw">volatile PlayerRef cachedPlayerRef;
class="kw">private class="kw">volatile boolean loggedFirstPacket = false;
class="kw">private class="kw">volatile boolean loggedFirstVoiceData = false;
class="kw">public VoiceStreamHandler(@Nonnull PacketHandler var1, @Nonnull ChannelConnection var2) {
this.packetHandler = var1;
this.channel = var2;
this.voiceModule = VoiceModule.get();
this.logger = this.voiceModule.getLogger();
}
@Override
class="kw">public void registered(@Nullable ConnectionHandler var1) {
this.packetHandler.setChannel(StreamType.Voice, this.channel);
if (this.packetHandler class="kw">instanceof GamePacketHandler var2) {
this.cachedPlayerRef = var2.getPlayerRef();
}
this.logger
.at(Level.FINE)
.log(
"[VoiceStream] Voice stream registered for %s (channel active=%s, playerRef=%s)",
this.packetHandler.getIdentifier(),
this.channel.isActive(),
this.cachedPlayerRef != null ? this.cachedPlayerRef.getUsername() : "null"
);
}
@Override
class="kw">public void handle(@Nonnull ToServerPacket var1) {
if (!this.loggedFirstPacket) {
this.loggedFirstPacket = true;
this.logger.at(Level.FINE).log("[VoiceStream] First packet received from %s: %s", this.packetHandler.getIdentifier(), var1.getClass().getSimpleName());
}
PlayerRef var2 = this.getPlayerRef();
if (var2 == null) {
this.logger.at(Level.WARNING).log("[VoiceStream] No player ref for voice packet from %s", this.packetHandler.getIdentifier());
} else {
if (var1 class="kw">instanceof VoiceData var3) {
this.handleVoiceData(var2, var3);
} else {
this.logger
.at(Level.WARNING)
.log("[VoiceStream] Unexpected packet type %s from %s", var1.getClass().getSimpleName(), this.packetHandler.getIdentifier());
}
}
}
class="kw">private void handleVoiceData(@Nonnull PlayerRef var1, @Nonnull VoiceData var2) {
if (this.voiceModule.isVoiceEnabled()) {
if (!this.loggedFirstVoiceData) {
this.loggedFirstVoiceData = true;
this.logger
.at(Level.FINE)
.log(
"[VoiceStream] Routing first VoiceData from %s: seq=%d, dataSize=%d",
var1.getUsername(),
var2.sequenceNumber,
var2.opusData != null ? var2.opusData.length : 0
);
}
if (!this.voiceModule.isShutdown()) {
VoicePlayerState var3 = this.voiceModule.getPlayerState(var1.getUuid());
if (var3 != null) {
if (!var3.isRoutingDisabled()) {
if (!var3.isSilenced() || this.voiceModule.hasPlayerVoiceInterceptors()) {
if (!this.voiceModule.isPlayerMuted(var1.getUuid())) {
if (!var3.checkRateLimit(this.voiceModule.getMaxPacketsPerSecond(), this.voiceModule.getBurstCapacity())) {
if (var3.shouldLogRateLimit()) {
this.logger
.at(Level.WARNING)
.log(
"[VoiceStream] RATE_LIMITED: player=%s, tokens=%.2f, maxPps=%d, burstCapacity=%d",
var1.getUsername(),
var3.getTokenBucket(),
this.voiceModule.getMaxPacketsPerSecond(),
this.voiceModule.getBurstCapacity()
);
}
} else if (var2.opusData != null && var2.opusData.length != 0) {
if (var2.opusData.length > this.voiceModule.getMaxPacketSize()) {
this.logger
.at(Level.WARNING)
.log(
"[VoiceStream] REJECTED_OVERSIZE: player=%s, size=%d, maxSize=%d",
var1.getUsername(),
var2.opusData.length,
this.voiceModule.getMaxPacketSize()
);
} else {
this.voiceModule
.getVoiceExecutor(var1.getUuid())
.execute(
() -> {
try {
this.voiceModule.getVoiceRouter().routeVoiceFromCache(var1, var2);
var3.resetConsecutiveErrors();
} catch (Exception var6) {
int var5 = var3.incrementConsecutiveErrors();
if (var5 >= 10) {
this.logger
.at(Level.WARNING)
.log("[VoiceStream] Disabled voice routing for %s after %d consecutive errors", var1.getUuid(), var5);
var3.setRoutingDisabled(true);
} else {
((HytaleLogger.Api)this.logger.at(Level.SEVERE).withCause(var6))
.log("[VoiceStream] Exception in routeVoiceFromCache for %s (failure %d/%d)", var1.getUuid(), var5, 10);
}
}
}
);
}
} else {
this.logger.at(Level.FINE).log("[VoiceStream] REJECTED_EMPTY: player=%s, seq=%d", var1.getUsername(), var2.sequenceNumber);
}
}
}
}
}
}
}
}
class="kw">private PlayerRef getPlayerRef() {
if (this.cachedPlayerRef != null) {
class="kw">return this.cachedPlayerRef;
}
if (this.packetHandler class="kw">instanceof GamePacketHandler var1) {
this.cachedPlayerRef = var1.getPlayerRef();
}
class="kw">return this.cachedPlayerRef;
}
@Override
class="kw">public void closed(@Nullable NetworkChannel var1) {
this.packetHandler.compareAndSetChannel(StreamType.Voice, this.channel, null);
this.logger.at(Level.FINE).log("[VoiceStream] Voice stream closed for %s", this.packetHandler.getIdentifier());
}
@Override
class="kw">public void unregistered(@Nullable ConnectionHandler var1) {
this.packetHandler.compareAndSetChannel(StreamType.Voice, this.channel, null);
}
@Override
class="kw">public void logCloseMessage() {
}
}