Skip to content

Commit 35d06c1

Browse files
committed
more debug info
1 parent f8f98d1 commit 35d06c1

14 files changed

Lines changed: 420 additions & 24 deletions

File tree

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-30+beta
33+
mod_version=26.1.2-31+beta
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
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package cn.ussshenzhou.channel.audio;
2+
3+
import cn.ussshenzhou.channel.config.ChannelClientConfig;
4+
import cn.ussshenzhou.channel.subspace.client.SubspaceConnection;
5+
import cn.ussshenzhou.channel.util.IntervalCounter;
6+
import cn.ussshenzhou.channel.util.TimeCounter;
7+
import com.google.common.util.concurrent.ThreadFactoryBuilder;
8+
import it.unimi.dsi.fastutil.ints.Int2LongOpenHashMap;
9+
import net.minecraft.client.Minecraft;
10+
import net.minecraft.util.Util;
11+
import net.neoforged.fml.loading.FMLEnvironment;
12+
import net.neoforged.fml.util.thread.EffectiveSide;
13+
14+
import java.io.IOException;
15+
import java.net.InetAddress;
16+
import java.net.InetSocketAddress;
17+
import java.util.Arrays;
18+
import java.util.HashMap;
19+
import java.util.UUID;
20+
import java.util.concurrent.Executors;
21+
import java.util.concurrent.ScheduledExecutorService;
22+
import java.util.concurrent.TimeUnit;
23+
24+
25+
public class DebugManager {
26+
public static final int MEASURE_WINDOW_MS = 2000;
27+
public static final int LONG_MEASURE_WINDOW_MS = 5000;
28+
public static final IntervalCounter MIC_SEND_COUNTER = new IntervalCounter(ChannelClientConfig.get().frameLengthMs, MEASURE_WINDOW_MS);
29+
public static final IntervalCounter PLAY_COUNTER = new IntervalCounter(10, MEASURE_WINDOW_MS);
30+
public static final HashMap<UUID, IntervalCounter> RECEIVE_COUNTER = new HashMap<>();
31+
public static final TimeCounter PLAY_RESET_COUNTER = new TimeCounter(LONG_MEASURE_WINDOW_MS);
32+
public static final TimeCounter OPENAL_REPLAY_COUNTER = new TimeCounter(LONG_MEASURE_WINDOW_MS);
33+
public static final TimeCounter ICMP_PING = new TimeCounter(LONG_MEASURE_WINDOW_MS);
34+
private static final ScheduledExecutorService SCHEDULER = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryBuilder()
35+
.setNameFormat("Channel-Mic-Debug-Thread-%d")
36+
.setDaemon(true)
37+
.build());
38+
private static final Int2LongOpenHashMap OPUS_SEND_CACHE = new Int2LongOpenHashMap();
39+
public static final TimeCounter RELAY_PING = new TimeCounter(LONG_MEASURE_WINDOW_MS);
40+
41+
static {
42+
if (EffectiveSide.get().isClient()) {
43+
SCHEDULER.scheduleAtFixedRate(DebugManager::ping, 0, 500, TimeUnit.MILLISECONDS);
44+
}
45+
}
46+
47+
public static void refresh() {
48+
MIC_SEND_COUNTER.setIdealIntervalMs(ChannelClientConfig.get().frameLengthMs);
49+
PLAY_COUNTER.reset();
50+
RECEIVE_COUNTER.clear();
51+
}
52+
53+
public static void sending(byte[] opus) {
54+
OPUS_SEND_CACHE.put(Arrays.hashCode(opus), Util.getMillis());
55+
}
56+
57+
public static void receiving(byte[] opus) {
58+
var hashcode = Arrays.hashCode(opus);
59+
if (OPUS_SEND_CACHE.containsKey(hashcode)) {
60+
RELAY_PING.put((int) (Util.getMillis() - OPUS_SEND_CACHE.get(hashcode)) * 1000);
61+
OPUS_SEND_CACHE.remove(hashcode);
62+
}
63+
if (OPUS_SEND_CACHE.size() > 500) {
64+
OPUS_SEND_CACHE.clear();
65+
}
66+
}
67+
68+
private static void ping() {
69+
Thread.startVirtualThread(() -> {
70+
String host = null;
71+
if (SubspaceConnection.using() && SubspaceConnection.getChannel().remoteAddress() instanceof InetSocketAddress inetSocketAddress) {
72+
host = inetSocketAddress.getHostString();
73+
} else {
74+
var connection = Minecraft.getInstance().getConnection();
75+
if (connection != null) {
76+
var con = connection.getConnection();
77+
if (con.isConnected() && con.getRemoteAddress() instanceof InetSocketAddress inetSocketAddress) {
78+
host = inetSocketAddress.getHostString();
79+
}
80+
}
81+
}
82+
if (host == null) {
83+
return;
84+
}
85+
long start = Util.getNanos();
86+
try {
87+
boolean reachable = InetAddress.getByName(host).isReachable(LONG_MEASURE_WINDOW_MS);
88+
if (reachable) {
89+
ICMP_PING.put((int) ((Util.getNanos() - start) / 1000));
90+
} else {
91+
ICMP_PING.put(LONG_MEASURE_WINDOW_MS);
92+
}
93+
} catch (IOException ignored) {
94+
}
95+
});
96+
}
97+
98+
99+
//TODO leave world clear
100+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ private record Decoder(int sampleRate, OpusDecoder decoder) {
2222

2323
private static Encoder encoder;
2424
private static HashMap<UUID, Decoder> decoders = new HashMap<>();
25-
public static final TimeCounter SEND_SPEED = new TimeCounter(1000);
25+
public static final TimeCounter SEND_SPEED = new TimeCounter(2000);
2626

2727
public static byte[] encode(byte[] audio, int sampleRate) throws OpusException {
2828
if (encoder == null || encoder.sampleRate != sampleRate) {

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package cn.ussshenzhou.channel.audio.client.receive;
22

3+
import cn.ussshenzhou.channel.audio.DebugManager;
34
import cn.ussshenzhou.channel.audio.client.rt.RayTraceManager;
45
import cn.ussshenzhou.channel.audio.client.rt.SourceAudioData;
56
import cn.ussshenzhou.channel.config.ChannelClientConfig;
@@ -87,6 +88,7 @@ public boolean play() {
8788
int threshold = (state == AL_INITIAL) ? ChannelClientConfig.get().networkTolerance : ChannelClientConfig.get().networkTolerance / 5;
8889
if (readyBufferMs > threshold) {
8990
alSourcePlay(alSource);
91+
DebugManager.OPENAL_REPLAY_COUNTER.add(1);
9092
}
9193
}
9294
return false;

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package cn.ussshenzhou.channel.audio.client.receive;
22

3+
import cn.ussshenzhou.channel.audio.DebugManager;
34
import cn.ussshenzhou.channel.audio.client.rt.RayTraceManager;
45
import cn.ussshenzhou.channel.config.ChannelClientConfig;
56
import cn.ussshenzhou.channel.subspace.client.SubspaceConnection;
@@ -75,6 +76,7 @@ protected static void playing() {
7576
reset();
7677
initAL();
7778
}
79+
DebugManager.PLAY_COUNTER.update();
7880
audios.entrySet().removeIf(e -> play(level, e.getValue()));
7981
} catch (Throwable e) {
8082
LogUtils.getLogger().error("Something went wrong, but it should be okay. You can ignore this if nothing else went wrong.");
@@ -83,6 +85,7 @@ protected static void playing() {
8385
}
8486

8587
public static void reset() {
88+
DebugManager.PLAY_RESET_COUNTER.add(1);
8689
audios.values().forEach(Audio::close);
8790
audios.clear();
8891
}

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cn.ussshenzhou.channel.audio.client.receive;
22

33
import cn.ussshenzhou.channel.Item.ModItems;
4+
import cn.ussshenzhou.channel.audio.DebugManager;
45
import cn.ussshenzhou.channel.audio.client.send.WebRTCHelper;
56
import cn.ussshenzhou.channel.blockentity.SpeakerBlockEntity;
67
import cn.ussshenzhou.channel.config.ChannelClientConfig;
@@ -12,6 +13,7 @@
1213
import cn.ussshenzhou.channel.subspace.packet;
1314
import cn.ussshenzhou.channel.util.AudioHelper;
1415
import cn.ussshenzhou.channel.util.CompatHelper;
16+
import cn.ussshenzhou.channel.util.IntervalCounter;
1517
import com.google.common.collect.MapMaker;
1618
import com.mojang.logging.LogUtils;
1719
import it.unimi.dsi.fastutil.ints.IntArraySet;
@@ -76,6 +78,7 @@ public static void handle(AudioPacket2C packet) {
7678
}
7779

7880
private static void handleInternal(AudioPacket2C packet) throws Exception {
81+
DebugManager.RECEIVE_COUNTER.computeIfAbsent(packet.from, _ -> new IntervalCounter(DebugManager.MEASURE_WINDOW_MS)).update();
7982
double x = 0, y = 0, z = 0;
8083
//noinspection DataFlowIssue
8184
var from = Minecraft.getInstance().level.getPlayerByUUID(packet.from);
@@ -118,8 +121,12 @@ private static void handleInternal(AudioPacket2C packet) throws Exception {
118121
if (localPlayer == null) {
119122
return;
120123
}
121-
boolean hearingSelf = ChannelClientConfig.get().hearMyself && localPlayer.getUUID().equals(packet.from);
122-
boolean hearingOther = !localPlayer.getUUID().equals(packet.from) && earPos.distanceToSqr(x, y, z) <= 64 * 64;
124+
var self = localPlayer.getUUID().equals(packet.from);
125+
if (self) {
126+
DebugManager.receiving(packet.opus);
127+
}
128+
boolean hearingSelf = ChannelClientConfig.get().hearMyself && self;
129+
boolean hearingOther = !self && earPos.distanceToSqr(x, y, z) <= 64 * 64;
123130
if (hearingSelf || hearingOther) {
124131
// direct talking sound always apply
125132
var audio = (DirectAudio) AudioManager.audios.compute(packet.from.hashCode(), (_, old) -> old == null ? new DirectAudio(packet.from) : old);

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package cn.ussshenzhou.channel.audio.client.send;
22

3+
import cn.ussshenzhou.channel.audio.DebugManager;
34
import cn.ussshenzhou.channel.audio.Trigger;
45
import cn.ussshenzhou.channel.audio.nativ.NvidiaHelper;
56
import cn.ussshenzhou.channel.config.ChannelClientConfig;
@@ -47,7 +48,7 @@ public static synchronized void frameLengthChange() {
4748

4849
private static synchronized void read() {
4950
if (Minecraft.getInstance().getConnection() == null ||
50-
CompatHelper.isClientLevelValid() ||
51+
!CompatHelper.isClientLevelValid() ||
5152
MicrophoneHud.getStatus() == MicrophoneHud.Status.SUBSPACE ||
5253
MicrophoneHud.getStatus() == MicrophoneHud.Status.OP) {
5354
return;

src/main/java/cn/ussshenzhou/channel/gui/TransmitConfigPanel.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package cn.ussshenzhou.channel.gui;
22

3+
import cn.ussshenzhou.channel.audio.DebugManager;
34
import cn.ussshenzhou.channel.audio.OpusManager;
45
import cn.ussshenzhou.channel.audio.client.send.MicReader;
56
import cn.ussshenzhou.channel.config.ChannelClientConfig;
@@ -40,6 +41,7 @@ public TransmitConfigPanel() {
4041
length -> _ -> {
4142
ChannelClientConfig.write(c -> c.frameLengthMs = length);
4243
MicReader.frameLengthChange();
44+
DebugManager.refresh();
4345
},
4446
entry -> entry.getContent() == cfg.frameLengthMs
4547
).getB().setTooltip(Tooltip.create(Component.translatable("channel.config.net.length.tooltip")));

src/main/java/cn/ussshenzhou/channel/gui/hud/DebugHud.java

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,38 @@
11
package cn.ussshenzhou.channel.gui.hud;
22

3+
import cn.ussshenzhou.channel.audio.DebugManager;
34
import cn.ussshenzhou.t88.gui.util.HorizontalAlignment;
45
import cn.ussshenzhou.t88.gui.widegt.TLabel;
56
import cn.ussshenzhou.t88.gui.widegt.TPanel;
7+
import net.minecraft.client.Minecraft;
68
import net.minecraft.client.gui.GuiGraphicsExtractor;
79
import net.minecraft.network.chat.Component;
810

911
import static cn.ussshenzhou.channel.audio.client.rt.RayTraceCalculator.*;
1012

1113
public class DebugHud extends TPanel {
12-
private final TLabel raytraceData = new TLabel();
14+
private final TLabel textData = new TLabel();
1315

1416
public DebugHud() {
15-
this.add(raytraceData);
16-
raytraceData.setHorizontalAlignment(HorizontalAlignment.LEFT);
17+
this.add(textData);
18+
textData.setHorizontalAlignment(HorizontalAlignment.LEFT);
1719
}
1820

1921
@Override
2022
public void layout() {
21-
raytraceData.setBounds(0, 0, 200, 100);
23+
textData.setBounds(0, 0, width, height);
2224
super.layout();
2325
}
2426

2527
@Override
2628
public void resizeAsHud(int screenWidth, int screenHeight) {
27-
this.setAbsBounds(50, 50, 200, 100);
29+
this.setAbsBounds(10, 10, screenWidth - 10, screenHeight);
2830
super.resizeAsHud(screenWidth, screenHeight);
2931
}
3032

3133
@Override
3234
public void tickT() {
33-
raytraceData.setText(Component.literal(String.format("""
35+
textData.setText(Component.literal(String.format("""
3436
Density: %.3f
3537
Diffusion: %.3f
3638
HF Gain: %.3f
@@ -42,7 +44,17 @@ public void tickT() {
4244
Echo Time: %.3f
4345
Echo Depth: %.3f
4446
45-
Open Space Correction: %.3f""",
47+
Open Space Correction: %.3f
48+
49+
Sending Interval: %s
50+
ICMP Ping: %s
51+
Playing Interval: %s
52+
Playing Hard Reset: §b%d
53+
OpenAL Re-play: §b%d
54+
Relay Ping: %s
55+
56+
Receive Interval:
57+
%s""",
4658
getDensity(),
4759
getDiffusion(),
4860
getHfGain(),
@@ -54,11 +66,35 @@ public void tickT() {
5466
getEchoTime(),
5567
getEchoDepth(),
5668

57-
getOpenSpaceCorrection()
69+
getOpenSpaceCorrection(),
70+
71+
DebugManager.MIC_SEND_COUNTER.toString(),
72+
DebugManager.ICMP_PING.getStringAsMs(),
73+
DebugManager.PLAY_COUNTER.toString(),
74+
DebugManager.PLAY_RESET_COUNTER.count(),
75+
DebugManager.OPENAL_REPLAY_COUNTER.count(),
76+
DebugManager.RELAY_PING.getStringAsMs(),
77+
78+
getReceiveText()
5879
)));
5980
super.tickT();
6081
}
6182

83+
private String getReceiveText() {
84+
StringBuilder text = new StringBuilder();
85+
DebugManager.RECEIVE_COUNTER.forEach((uuid, counter) -> {
86+
text.append(" ");
87+
var player = Minecraft.getInstance().level.getPlayerByUUID(uuid);
88+
if (player != null) {
89+
text.append(player.getScoreboardName());
90+
} else {
91+
text.append(uuid.toString());
92+
}
93+
text.append(" ").append(counter.toString());
94+
});
95+
return text.toString();
96+
}
97+
6298
@Override
6399
public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float pPartialTick) {
64100
super.extractRenderState(graphics, mouseX, mouseY, pPartialTick);

src/main/java/cn/ussshenzhou/channel/network/TalkPacket2S.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package cn.ussshenzhou.channel.network;
22

3+
import cn.ussshenzhou.channel.audio.DebugManager;
34
import cn.ussshenzhou.channel.audio.server.RelayHandler;
45
import cn.ussshenzhou.channel.subspace.SubspacePacket;
56
import cn.ussshenzhou.channel.util.ModConstant;
@@ -31,6 +32,8 @@ public TalkPacket2S(FriendlyByteBuf buf) {
3132
@Encoder
3233
public void encode(FriendlyByteBuf buf) {
3334
buf.writeByteArray(this.opus);
35+
DebugManager.MIC_SEND_COUNTER.update();
36+
DebugManager.sending(opus);
3437
}
3538

3639
@Override

0 commit comments

Comments
 (0)