private OutgoingUDPPackets GenerateOutgoingPacket(UDPVoicePacket udpVoice, PendingPacket pendingPacket, SRClient fromClient) { var outgoingList = new HashSet <IPEndPoint>(); var coalitionSecurity = _serverSettings.GetGeneralSetting(ServerSettingsKeys.COALITION_AUDIO_SECURITY).BoolValue; var guid = fromClient.ClientGuid; foreach (var client in _clientsList) { if (!client.Key.Equals(guid)) { var ip = client.Value.VoipPort; bool global = false; if (ip != null) { for (int i = 0; i < udpVoice.Frequencies.Length; i++) { foreach (var testFrequency in _globalFrequencies) { if (PlayerGameState.FreqCloseEnough(testFrequency, udpVoice.Frequencies[i])) { //ignore everything as its global frequency global = true; break; } } } if (global) { outgoingList.Add(ip); } // check that either coalition radio security is disabled OR the coalitions match else if ((!coalitionSecurity || (client.Value.Coalition == fromClient.Coalition))) { var radioInfo = client.Value.GameState; if (radioInfo != null) { for (int i = 0; i < udpVoice.Frequencies.Length; i++) { RadioReceivingState radioReceivingState = null; var receivingRadio = radioInfo.CanHearTransmission(udpVoice.Frequencies[i], (RadioInformation.Modulation)udpVoice.Modulations[i], udpVoice.UnitId, radioInfo.vehicleId, _emptyBlockedRadios, out radioReceivingState); //only send if we can hear! if (receivingRadio != null) { outgoingList.Add(ip); } } } } } } else { #if DEBUG //TODO - test outgoingList.Add(client.Value.VoipPort); #endif } } if (outgoingList.Count > 0) { return(new OutgoingUDPPackets { OutgoingEndPoints = outgoingList.ToList(), ReceivedPacket = pendingPacket.RawBytes }); } else { return(null); } }
private void ProcessPackets() { while (!_stop) { try { PendingPacket udpPacket = null; _pendingProcessingPackets.TryTake(out udpPacket, 100000, _pendingProcessingCancellationToken.Token); if (udpPacket != null) { //last 22 bytes are guid! var guid = Encoding.ASCII.GetString( udpPacket.RawBytes, udpPacket.RawBytes.Length - 22, 22); if (_clientsList.ContainsKey(guid)) { var client = _clientsList[guid]; client.VoipPort = udpPacket.ReceivedFrom; var spectatorAudioDisabled = _serverSettings.GetGeneralSetting(ServerSettingsKeys.SPECTATORS_AUDIO_DISABLED).BoolValue; if ((client.Coalition == 0 && spectatorAudioDisabled) || client.Muted) { // IGNORE THE AUDIO } else { try { //decode var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(udpPacket.RawBytes); if (udpVoicePacket != null) //magical ping ignore message 4 - its an empty voip packet to intialise VoIP if //someone doesnt transmit { var outgoingVoice = GenerateOutgoingPacket(udpVoicePacket, udpPacket, client); if (outgoingVoice != null) { //Add to the processing queue _outGoing.Add(outgoingVoice); //mark as transmitting for the UI double mainFrequency = udpVoicePacket.Frequencies.FirstOrDefault(); // Only trigger transmitting frequency update for "proper" packets (excluding invalid frequencies and magic ping packets with modulation 4) if (mainFrequency > 0) { RadioInformation.Modulation mainModulation = (RadioInformation.Modulation)udpVoicePacket.Modulations[0]; if (mainModulation == RadioInformation.Modulation.INTERCOM) { client.TransmittingFrequency = "INTERCOM"; } else { client.TransmittingFrequency = $"{(mainFrequency / 1000000).ToString("0.000", CultureInfo.InvariantCulture)} {mainModulation}"; } client.LastTransmissionReceived = DateTime.Now; } } } } catch (Exception) { //Hide for now, slows down loop to much.... } } } } } catch (Exception ex) { Logger.Info("Failed to Process UDP Packet: " + ex.Message); } } }