Skip to content

Commit 3e2c2e2

Browse files
committed
/ch mute_non_OP
1 parent b243559 commit 3e2c2e2

27 files changed

Lines changed: 235 additions & 80 deletions

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ mod_name=Channel
3030
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
3131
mod_license=GNU GPL 3.0
3232
# The mod version. See https://semver.org/
33-
mod_version=26.1.2-7+alpha
33+
mod_version=26.1.2-8+alpha
3434
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
3535
# This should match the base package used for the mod sources.
3636
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html

src/main/java/cn/ussshenzhou/channel/audio/OpusManager.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ public static byte[] encode(byte[] audio, int sampleRate) throws OpusException {
3434
return Arrays.copyOf(result, length);
3535
}
3636

37-
public static short[] decode(byte[] opus, int sampleRate, UUID from) throws OpusException {
38-
var length = OpusPacketInfo.getNumSamples(opus, 0, opus.length, sampleRate);
37+
public static short[] decode(byte[] opus, UUID from) throws OpusException {
38+
var length = OpusPacketInfo.getNumSamples(opus, 0, opus.length, 48000);
3939
var outArray = new short[length];
40-
if (!decoders.containsKey(from) || decoders.get(from).sampleRate != sampleRate) {
40+
if (!decoders.containsKey(from)) {
4141
try {
42-
decoders.put(from, new Decoder(sampleRate, new OpusDecoder(sampleRate, 1)));
42+
decoders.put(from, new Decoder(48000, new OpusDecoder(48000, 1)));
4343
} catch (Exception e) {
4444
LogUtils.getLogger().error(e.getMessage());
4545
}

src/main/java/cn/ussshenzhou/channel/audio/client/receive/AudioReceiveHandler.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import cn.ussshenzhou.channel.util.AudioHelper;
1010
import com.google.common.collect.MapMaker;
1111
import com.mojang.logging.LogUtils;
12+
import it.unimi.dsi.fastutil.ints.IntArraySet;
1213
import net.minecraft.client.Minecraft;
1314
import net.minecraft.world.level.Level;
1415
import net.minecraft.world.level.block.Block;
@@ -72,22 +73,28 @@ private static void handleInternal(AudioPacket2C packet, Level level) throws Exc
7273
return;
7374
}
7475
var earPos = AudioHelper.getEarPos();
75-
var decoded = OpusManager.decode(packet.opus, packet.sampleRate, packet.from);
76-
if (Minecraft.getInstance().player != null && earPos.distanceToSqr(x, y, z) <= 64 * 64) {
76+
var decoded = OpusManager.decode(packet.opus, packet.from);
77+
if (Minecraft.getInstance().player != null && !Minecraft.getInstance().player.getUUID().equals(packet.from) && earPos.distanceToSqr(x, y, z) <= 64 * 64) {
7778
// direct talking sound always apply
78-
var audio = getDirectAudioAndCheckSampleRate(packet.from, packet.sampleRate);
79+
var audio = getDirectAudioAndCheckSampleRate(packet.from, 48000);
7980
audio.push(decoded);
8081
audio.setPos(x, y, z);
8182
}
8283
// through speaker
83-
var resampled = WebRTCHelper.resample(decoded, packet.sampleRate, 48000);
84+
if (packet.channels.length == 0) {
85+
return;
86+
}
87+
var channels = IntArraySet.of(packet.channels);
8488
for (var speaker : CHANNELED_BLOCK_CACHE_C) {
89+
if (!channels.contains(speaker.getChannel())) {
90+
continue;
91+
}
8592
var pos = speaker.getBlockPos();
8693
if (earPos.distanceToSqr(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5) > 64 * 64) {
8794
return;
8895
}
8996
var audio = getSpeakerAudioAndCheckSampleRate(speaker, 48000);
90-
audio.push(packet.from, resampled);
97+
audio.push(packet.from, decoded);
9198
}
9299
}
93100

src/main/java/cn/ussshenzhou/channel/audio/client/receive/SpeakerAudio.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ public void updateSourceParameters(SourceAudioData data, int auxSlot) {
5858
double extraDecay = 1;
5959
if (distance >= 32) {
6060
extraDecay = 1 - (distance - 32) / 32;
61-
correctedGain *= extraDecay;
6261
}
63-
alFilterf(this.alDirectFilter, AL_LOWPASS_GAIN, (float) (correctedGain / REVERB_ENHANCE));
62+
double wallDecay = Math.pow(0.5, data.wallThickness());
63+
alFilterf(this.alDirectFilter, AL_LOWPASS_GAIN, (float) (extraDecay * correctedGain * wallDecay / REVERB_ENHANCE));
6464
alFilterf(this.alDirectFilter, AL_LOWPASS_GAINHF, data.directHF());
6565
alSourcei(this.alSource, AL_DIRECT_FILTER, this.alDirectFilter);
6666

67-
alFilterf(this.alReverbFilter, AL_LOWPASS_GAIN, (float) extraDecay);
67+
alFilterf(this.alReverbFilter, AL_LOWPASS_GAIN, (float) (extraDecay * wallDecay));
6868
alFilterf(this.alReverbFilter, AL_LOWPASS_GAINHF, 1);
6969
alSource3i(this.alSource, AL_AUXILIARY_SEND_FILTER, auxSlot, 0, this.alReverbFilter);
7070

src/main/java/cn/ussshenzhou/channel/audio/client/rt/RayTraceCalculator.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ public static void run() {
6666
});
6767
post(() -> {
6868
journeyStandardDeviation = (float) Math.sqrt(journeySquaredDiffSum / pointTotalAmount);
69-
density = Mth.clamp(journeyStandardDeviation / (MAX_DISTANCE / 2f) + (inWater ? 0.6f : 0), 0, 1);
69+
float targetDensity = Mth.clamp(journeyStandardDeviation / (MAX_DISTANCE / 2f) + (inWater ? 0.6f : 0), 0, 1);
70+
float delta = Mth.clamp(targetDensity - density, -0.01f, 0.01f);
71+
//noinspection NonAtomicOperationOnVolatileField
72+
density += delta;
7073
});
7174
}
7275

@@ -390,12 +393,12 @@ static SourceAudioData calculateSourceAudioData(Vec3 sourcePos) {
390393
var cameraPos = AudioHelper.getEarPos();
391394
var tuple = calculateVirtualDirection(sourcePos);
392395
double meanReverbWeight = tuple.getA();
393-
var hitA = shoot(sourcePos, cameraPos, ClipContext.Block.OUTLINE);
396+
var hitA = shoot(sourcePos, cameraPos, CHANNEL_OUTLINE);
394397
float wallThickness;
395398
if (hitA.getType() == HitResult.Type.MISS) {
396399
wallThickness = 0;
397400
} else {
398-
var hitB = shoot(cameraPos, sourcePos, ClipContext.Block.OUTLINE);
401+
var hitB = shoot(cameraPos, sourcePos, CHANNEL_OUTLINE);
399402
wallThickness = (float) hitA.getLocation().distanceTo(hitB.getLocation());
400403
}
401404
double wallDecay = Math.pow(inWater ? 0.5 : 0.25, wallThickness);
@@ -410,7 +413,7 @@ static SourceAudioData calculateSourceAudioData(Vec3 sourcePos) {
410413
directHF *= 0.15f;
411414
reverbGain = Mth.clamp(reverbGain * 1.3f, 0, 1);
412415
}
413-
return new SourceAudioData(directGain, directHF, reverbGain, finalPos);
416+
return new SourceAudioData(directGain, wallThickness, directHF, reverbGain, finalPos);
414417
}
415418

416419
private static Tuple<Double, Vec3> calculateVirtualDirection(Vec3 sourcePos) {

src/main/java/cn/ussshenzhou/channel/audio/client/rt/RayTraceManager.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public class RayTraceManager {
4343
private static int AUX_SLOT = -1, REVERB_EFFECT;
4444
private static final ConcurrentHashMap<Vec3, SourceAudioData> SOURCE_AUDIO_DATA_CACHE = new ConcurrentHashMap<>();
4545
static boolean inWater = false;
46+
public static ClipContext.Block CHANNEL_OUTLINE = ClipContext.Block.valueOf("CHANNEL_OUTLINE");
47+
public static ClipContext.Block CHANNEL_VISUAL = ClipContext.Block.valueOf("CHANNEL_VISUAL");
4648

4749
public static int getSlot() {
4850
if (AUX_SLOT == -1) {
@@ -101,12 +103,13 @@ private static void generateHitPoints() {
101103
boolean debug = ChannelClientConfig.get().showRaytrace;
102104
var earPos = AudioHelper.getEarPos();
103105
for (var ray : generateRays(getRayAmount(), 0)) {
106+
//TODO IExtensibleEnum
104107
//noinspection DataFlowIssue
105-
generateOneRay(earPos, ray, level, debug, ClipContext.Block.OUTLINE, 0x80ffffff);
108+
generateOneRay(earPos, ray, level, debug, CHANNEL_OUTLINE, 0x80ffffff);
106109
}
107110
for (var ray : generateRays(getRayAmount(), 0.5)) {
108111
//noinspection DataFlowIssue
109-
generateOneRay(earPos, ray, level, debug, ClipContext.Block.VISUAL, 0x8000ff00);
112+
generateOneRay(earPos, ray, level, debug, CHANNEL_VISUAL, 0x8000ff00);
110113
}
111114
}
112115
}
@@ -174,8 +177,8 @@ private static void setEaxReverb() {
174177
alEffectf(REVERB_EFFECT, AL_EAXREVERB_LATE_REVERB_GAIN, lateRefGain);
175178
alEffectf(REVERB_EFFECT, AL_EAXREVERB_LATE_REVERB_DELAY, lateRefDelay);
176179
//-----Echo-----
177-
alEffectf(REVERB_EFFECT, AL_EAXREVERB_ECHO_TIME, echoTime);
178-
alEffectf(REVERB_EFFECT, AL_EAXREVERB_ECHO_DEPTH, echoDepth);
180+
alEffectf(REVERB_EFFECT, AL_EAXREVERB_ECHO_TIME, Float.isNaN(echoTime) ? 0.25f : echoTime);
181+
alEffectf(REVERB_EFFECT, AL_EAXREVERB_ECHO_DEPTH, Float.isNaN(echoDepth) ? 0.05f : echoDepth);
179182
//-----Modulation-----
180183
alEffectf(REVERB_EFFECT, AL_EAXREVERB_MODULATION_TIME, 0.4f);
181184
alEffectf(REVERB_EFFECT, AL_EAXREVERB_MODULATION_DEPTH, 0.025f);
@@ -240,6 +243,6 @@ public static BlockHitResult shoot(Vec3 from, Vec3 to, ClipContext.Block blockCo
240243
}
241244

242245
public static boolean canSee(Vec3 from, Vec3 to) {
243-
return shoot(from, to, ClipContext.Block.OUTLINE).getType() == HitResult.Type.MISS;
246+
return shoot(from, to, CHANNEL_OUTLINE).getType() == HitResult.Type.MISS;
244247
}
245248
}

src/main/java/cn/ussshenzhou/channel/audio/client/rt/SourceAudioData.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
public record SourceAudioData(
66
float directGain,
7+
float wallThickness,
78
float directHF,
89
float reverbGain,
910
Vec3 virtualPos

src/main/java/cn/ussshenzhou/channel/audio/client/send/MicReader.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public static synchronized void frameLengthChange() {
4646
}
4747

4848
private static synchronized void read() {
49-
if (Minecraft.getInstance().getConnection() == null || MicrophoneHud.getStatus() == MicrophoneHud.Status.SUBSPACE) {
49+
if (Minecraft.getInstance().getConnection() == null || MicrophoneHud.getStatus() == MicrophoneHud.Status.SUBSPACE || MicrophoneHud.getStatus() == MicrophoneHud.Status.OP) {
5050
return;
5151
}
5252
var cfg = ChannelClientConfig.get();
@@ -91,7 +91,7 @@ private static synchronized void read() {
9191
}
9292
//-----encode-----
9393
var opus = OpusManager.encode(audio, networkSampleRate);
94-
var packet = new TalkPacket2S(networkSampleRate, opus);
94+
var packet = new TalkPacket2S(opus);
9595
if (SubspaceConnection.using()) {
9696
SubspaceConnection.send(packet);
9797
} else {

src/main/java/cn/ussshenzhou/channel/audio/client/send/WebRTCHelper.java

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -183,33 +183,6 @@ private static byte[] resample(byte[] raw, int sampleRateIn, int sampleRateOut)
183183
}
184184
}
185185

186-
@SuppressWarnings("IntegerMultiplicationImplicitCastToLong")
187-
public static short[] resample(short[] raw, int sampleRateIn, int sampleRateOut) {
188-
var resampler = CreateResampler(sampleRateIn, sampleRateOut, ModConstant.MIC_CHANNEL);
189-
var segAmount = MicReader.getFrameLength() / 10;
190-
var inStepSamples = raw.length / segAmount;
191-
var outStepSamples = (int) ((float) raw.length / sampleRateIn * sampleRateOut / segAmount);
192-
int totalOutSamples = (int) ((float) raw.length / sampleRateIn * sampleRateOut);
193-
try (var arena = Arena.ofConfined()) {
194-
var src = arena.allocate(raw.length * 2);
195-
var dst = arena.allocate(totalOutSamples * 2);
196-
MemorySegment.copy(raw, 0, src, ValueLayout.JAVA_SHORT, 0, raw.length);
197-
for (int i = 0; i < segAmount; i++) {
198-
long srcOffset = (long) i * inStepSamples * 2;
199-
long destOffset = (long) i * outStepSamples * 2;
200-
var subSrc = src.asSlice(srcOffset, inStepSamples * 2);
201-
var subDest = dst.asSlice(destOffset, outStepSamples * 2);
202-
Resample(resampler,
203-
subSrc, sampleRateIn / 100,
204-
subDest, sampleRateOut / 100);
205-
}
206-
short[] result = new short[totalOutSamples];
207-
MemorySegment.copy(dst, ValueLayout.JAVA_SHORT, 0, result, 0, totalOutSamples);
208-
FreeResampler(resampler);
209-
return result;
210-
}
211-
}
212-
213186
private static boolean vad(MemorySegment audio, int sampleRate, int samplesPerChannel) {
214187
if (ChannelClientConfig.get().trigger != Trigger.VAD) {
215188
return true;

src/main/java/cn/ussshenzhou/channel/audio/server/RelayHandler.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import cn.ussshenzhou.channel.blockentity.ChanneledBlockEntity;
66
import cn.ussshenzhou.channel.blockentity.MicBlockEntity;
77
import cn.ussshenzhou.channel.blockentity.SpeakerBlockEntity;
8+
import cn.ussshenzhou.channel.config.ChannelServerConfig;
89
import cn.ussshenzhou.channel.network.AudioPacket2C;
910
import cn.ussshenzhou.t88.network.NetworkHelper;
1011
import com.google.common.collect.MapMaker;
@@ -15,6 +16,7 @@
1516
import net.minecraft.SharedConstants;
1617
import net.minecraft.resources.ResourceKey;
1718
import net.minecraft.server.level.ServerPlayer;
19+
import net.minecraft.server.permissions.Permissions;
1820
import net.minecraft.world.InteractionHand;
1921
import net.minecraft.world.level.Level;
2022
import net.minecraft.world.level.block.entity.BlockEntity;
@@ -144,18 +146,21 @@ private static IntArraySet findNearbyReceivingDeviceChannels(ServerPlayer to) {
144146
.setDaemon(true)
145147
.build());
146148

147-
public static void process(ServerPlayer from, byte[] opusAudio, int sampleRate) {
149+
public static void process(ServerPlayer from, byte[] opusAudio) {
150+
if (ChannelServerConfig.get().muteNoneOP && !from.permissions().hasPermission(Permissions.COMMANDS_GAMEMASTER)) {
151+
return;
152+
}
148153
SERVER_RELAY_THREAD.execute(() -> {
149154
try {
150-
talking(from, opusAudio, sampleRate);
155+
talking(from, opusAudio);
151156
} catch (Exception e) {
152157
LogUtils.getLogger().error("Something went wrong, but it should be okay. You can ignore this if nothing else went wrong.");
153158
LogUtils.getLogger().error(e.getMessage(), e);
154159
}
155160
});
156161
}
157162

158-
public static void talking(ServerPlayer from, byte[] opusAudio, int sampleRate) {
163+
public static void talking(ServerPlayer from, byte[] opusAudio) {
159164
HashSet<ServerPlayer> tos = new HashSet<>();
160165
for (var p : from.level().players()) {
161166
if (closeHear(from, p)) {
@@ -171,7 +176,7 @@ public static void talking(ServerPlayer from, byte[] opusAudio, int sampleRate)
171176
}
172177
}
173178
}
174-
tos.forEach(to -> NetworkHelper.sendToPlayer(to, new AudioPacket2C(sampleRate, from.getUUID(), opusAudio, channels)));
179+
tos.forEach(to -> NetworkHelper.sendToPlayer(to, new AudioPacket2C(from.getUUID(), opusAudio, channels)));
175180
}
176181

177182
public static boolean closeHear(ServerPlayer from, ServerPlayer to) {

0 commit comments

Comments
 (0)