1
1
package dynamic_fps .impl .mixin ;
2
2
3
+ import java .util .ArrayList ;
4
+ import java .util .List ;
3
5
import java .util .Map ;
6
+ import java .util .Set ;
4
7
5
8
import dynamic_fps .impl .feature .volume .SmoothVolumeHandler ;
9
+ import dynamic_fps .impl .util .Logging ;
6
10
import net .minecraft .client .Minecraft ;
7
11
import org .jetbrains .annotations .Nullable ;
8
12
import org .spongepowered .asm .mixin .Final ;
@@ -66,9 +70,23 @@ private float calculateVolume(SoundInstance instance) {
66
70
// Also fixes this compat bug: https://github.com/juliand665/Dynamic-FPS/issues/55
67
71
boolean isMusic = source .equals (SoundSource .MUSIC ) || source .equals (SoundSource .RECORDS );
68
72
69
- this .instanceToChannel .forEach ((instance , handle ) -> {
70
- if (!instance .getSource ().equals (source )) {
71
- return ;
73
+ // Create a copy of all currently active sounds, as iterating over this collection
74
+ // Can throw if a sound instance stops playing while we are updating sound volumes
75
+ List <SoundInstance > sounds ;
76
+
77
+ try {
78
+ sounds = new ArrayList <>(this .instanceToChannel .keySet ());
79
+ } catch (Throwable e ) {
80
+ Logging .getLogger ().error ("Unable to update source volume!" , e );
81
+ return ;
82
+ }
83
+
84
+ // Using our copy should now be safe as long as we check the channel handle exists
85
+ for (SoundInstance instance : sounds ) {
86
+ ChannelAccess .ChannelHandle handle = this .instanceToChannel .get (instance );
87
+
88
+ if (handle == null || !instance .getSource ().equals (source )) {
89
+ continue ;
72
90
}
73
91
74
92
float volume = this .calculateVolume (instance );
@@ -93,7 +111,7 @@ private float calculateVolume(SoundInstance instance) {
93
111
channel .setVolume (volume );
94
112
}
95
113
});
96
- });
114
+ }
97
115
}
98
116
99
117
/**
0 commit comments