diff --git a/VoiceCraft.Server/Data/VoiceCraftParticipant.cs b/VoiceCraft.Server/Data/VoiceCraftParticipant.cs index e339b162..dcd542ef 100644 --- a/VoiceCraft.Server/Data/VoiceCraftParticipant.cs +++ b/VoiceCraft.Server/Data/VoiceCraftParticipant.cs @@ -32,4 +32,26 @@ public static short GenerateKey() return (short)Random.Shared.Next(short.MinValue + 1, short.MaxValue); //short.MinValue is used to specify no Key. } } + + public enum ParticipantBitmask : ushort + { + DeathEnabled = 1, // 0000 0000 0000 0001 + ProximityEnabled = 2, // 0000 0000 0000 0010 + WaterEffectEnabled = 4, // 0000 0000 0000 0100 + EchoEffectEnabled = 8, // 0000 0000 0000 1000 + DirectionalEnabled = 16, // 0000 0000 0001 0000 + EnvironmentEnabled = 32, // 0000 0000 0010 0000 + + HearingBitmask1 = 64, // 0000 0000 0100 0000 + HearingBitmask2 = 128, // 0000 0000 1000 0000 + HearingBitmask3 = 256, // 0000 0001 0000 0000 + HearingBitmask4 = 512, // 0000 0010 0000 0000 + HearingBitmask5 = 1024, // 0000 0100 0000 0000 + + TalkingBitmask1 = 2048, // 0000 1000 0000 0000 + TalkingBitmask2 = 4096, // 0001 0000 0000 0000 + TalkingBitmask3 = 8192, // 0010 0000 0000 0000 + TalkingBitmask4 = 16384, // 0100 0000 0000 0000 + TalkingBitmask5 = 32768, // 1000 0000 0000 0000 + } } diff --git a/VoiceCraft.Server/VoiceCraftServer.cs b/VoiceCraft.Server/VoiceCraftServer.cs index 70766d59..2d10ea2f 100644 --- a/VoiceCraft.Server/VoiceCraftServer.cs +++ b/VoiceCraft.Server/VoiceCraftServer.cs @@ -141,7 +141,7 @@ public void MoveParticipantToChannel(NetPeer peer, VoiceCraftParticipant client, { ObjectDisposedException.ThrowIf(IsDisposed, nameof(VoiceCraftServer)); - if (client.Channel == ServerProperties.DefaultChannel) return; //Client is already in the only channel, do nothing. + if (client.Channel == channel) return; //Client is already in the channel, do nothing. //Tell the client to leave the previous channel/reset if hidden. peer.AddToSendBuffer(new Core.Packets.VoiceCraft.LeaveChannel()); @@ -463,35 +463,38 @@ private void OnClientAudio(Core.Packets.VoiceCraft.ClientAudio data, NetPeer pee Logger.LogToConsole(LogType.Error, $"Error, Default channel {ServerProperties.DefaultChannel.Name} has no override settings, voice calculations cannot execute!", nameof(VoiceCraftServer)); return; } - if (Participants.TryGetValue(peer, out var client) && client.Binded && !client.Muted && !client.Deafened && !client.ServerMuted) + if (Participants.TryGetValue(peer, out var client) && client.Binded && !client.Muted && !client.Deafened && !client.ServerMuted && !client.ServerDeafened) { client.LastSpoke = Environment.TickCount64; var defaultSettings = ServerProperties.DefaultChannel.OverrideSettings; var proximityToggle = client.Channel.OverrideSettings?.ProximityToggle ?? defaultSettings.ProximityToggle; if (proximityToggle) { - if (client.Dead || string.IsNullOrWhiteSpace(client.EnvironmentId)) return; //Bitmask Check - var proximityDistance = client.Channel.OverrideSettings?.ProximityDistance ?? defaultSettings.ProximityDistance; //Bitmask Check - var voiceEffects = client.Channel.OverrideSettings?.VoiceEffects ?? defaultSettings.VoiceEffects; //Bitmask Check + if ((client.ChecksBitmask & (ushort)ParticipantBitmask.DeathEnabled) != 0 && client.Dead || (client.ChecksBitmask & (ushort)ParticipantBitmask.EnvironmentEnabled) != 0 && string.IsNullOrWhiteSpace(client.EnvironmentId)) return; + var proximityDistance = client.Channel.OverrideSettings?.ProximityDistance ?? defaultSettings.ProximityDistance; + var voiceEffects = client.Channel.OverrideSettings?.VoiceEffects ?? defaultSettings.VoiceEffects; var list = Participants.Where(x => x.Value != client && x.Value.Binded && !x.Value.Deafened && - !x.Value.Dead && //Bitmask Check Here + !x.Value.ServerDeafened && x.Value.Channel == client.Channel && - !string.IsNullOrWhiteSpace(x.Value.EnvironmentId) && //Bitmask Check Here - x.Value.EnvironmentId == client.EnvironmentId && //Bitmask Check Here - Vector3.Distance(x.Value.Position, client.Position) <= proximityDistance //Bitmask Check Here + + //Bitmask Checks here + (((x.Value.ChecksBitmask | client.ChecksBitmask) & (ushort)ParticipantBitmask.DeathEnabled) == 0 || !x.Value.Dead) && + (((x.Value.ChecksBitmask | client.ChecksBitmask) & (ushort)ParticipantBitmask.EnvironmentEnabled) == 0 || !string.IsNullOrWhiteSpace(x.Value.EnvironmentId) && x.Value.EnvironmentId == client.EnvironmentId) && + (((x.Value.ChecksBitmask | client.ChecksBitmask) & (ushort)ParticipantBitmask.ProximityEnabled) == 0 || Vector3.Distance(x.Value.Position, client.Position) <= proximityDistance) && + (((x.Value.ChecksBitmask >> 6) & (client.ChecksBitmask >> 11)) != 0) ); //Get Participants for (ushort i = 0; i < list.Count(); i++) { var participant = list.ElementAt(i); - var volume = 1.0f - Math.Clamp(Vector3.Distance(participant.Value.Position, client.Position) / proximityDistance, 0.0f, 1.0f); //Bitmask Check Here - var echo = voiceEffects ? Math.Max(participant.Value.CaveDensity, client.CaveDensity) * (1.0f - volume) : 0.0f; //Bitmask Check Here - var muffled = voiceEffects && (participant.Value.InWater || client.InWater); //Bitmask Check Here - var rotation = (float)(Math.Atan2(participant.Value.Position.Z - client.Position.Z, participant.Value.Position.X - client.Position.X) - (participant.Value.Rotation * Math.PI / 180)); //Bitmask Check Here + var volume = ((participant.Value.ChecksBitmask | client.ChecksBitmask) & (ushort)ParticipantBitmask.ProximityEnabled) != 0 ? 1.0f - Math.Clamp(Vector3.Distance(participant.Value.Position, client.Position) / proximityDistance, 0.0f, 1.0f) : 1.0f; + var echo = ((participant.Value.ChecksBitmask | client.ChecksBitmask) & (ushort)ParticipantBitmask.EchoEffectEnabled) != 0 && voiceEffects ? Math.Max(participant.Value.CaveDensity, client.CaveDensity) * (1.0f - volume) : 0.0f; + var muffled = ((participant.Value.ChecksBitmask | client.ChecksBitmask) & (ushort)ParticipantBitmask.WaterEffectEnabled) != 0 && voiceEffects && (participant.Value.InWater || client.InWater); + var rotation = (participant.Value.ChecksBitmask & (ushort)ParticipantBitmask.DirectionalEnabled) != 0 ? (float)(Math.Atan2(participant.Value.Position.Z - client.Position.Z, participant.Value.Position.X - client.Position.X) - (participant.Value.Rotation * Math.PI / 180)) : 1.5f; participant.Key.AddToSendBuffer(new Core.Packets.VoiceCraft.ServerAudio() { @@ -507,12 +510,12 @@ private void OnClientAudio(Core.Packets.VoiceCraft.ClientAudio data, NetPeer pee } else { - //Custom Bitmask Checks Here. var list = Participants.Where(x => x.Value != client && x.Value.Binded && !x.Value.Deafened && - x.Value.Channel == client.Channel); + x.Value.Channel == client.Channel && + (((x.Value.ChecksBitmask >> 6) & (client.ChecksBitmask >> 11)) != 0)); for (ushort i = 0; i < list.Count(); i++) { @@ -585,7 +588,7 @@ private void MCCommBind(Core.Packets.MCComm.Bind packet, HttpListenerContext ctx IsMuted = client.Value.Muted, Key = client.Value.Key, Name = client.Value.Name - }, [client.Value], [client.Value.Channel]); //Broadcast to all other participants. + }, Participants.Values.Where(x => x == client.Value || !x.Binded).ToArray(), [client.Value.Channel]); //Broadcast to all other participants. var list = Participants.Where(x => x.Value != client.Value && x.Value.Binded && x.Value.Channel == client.Value.Channel); foreach (var participant in list)