diff --git a/client/events.lua b/client/events.lua index 7f8b769..438ea10 100644 --- a/client/events.lua +++ b/client/events.lua @@ -3,14 +3,14 @@ function handleInitialState() MumbleSetTalkerProximity(voiceModeData[1] + 0.0) MumbleClearVoiceTarget(voiceTarget) MumbleSetVoiceTarget(voiceTarget) - MumbleSetVoiceChannel(playerServerId) + MumbleSetVoiceChannel(LocalPlayer.state.assignedChannel) - while MumbleGetVoiceChannelFromServerId(playerServerId) ~= playerServerId do + while MumbleGetVoiceChannelFromServerId(playerServerId) ~= LocalPlayer.state.assignedChannel do Wait(250) - MumbleSetVoiceChannel(playerServerId) + MumbleSetVoiceChannel(LocalPlayer.state.assignedChannel) end - MumbleAddVoiceTargetChannel(voiceTarget, playerServerId) + MumbleAddVoiceTargetChannel(voiceTarget, LocalPlayer.state.assignedChannel) addNearbyPlayers() end diff --git a/client/init/proximity.lua b/client/init/proximity.lua index 0dc4ccb..0ce44e2 100644 --- a/client/init/proximity.lua +++ b/client/init/proximity.lua @@ -9,7 +9,7 @@ function orig_addProximityCheck(ply) local tgtPed = GetPlayerPed(ply) local voiceRange = GetConvar('voice_useNativeAudio', 'false') == 'true' and proximity * 3 or proximity local distance = #(plyCoords - GetEntityCoords(tgtPed)) - return distance < voiceRange, distance + return distance < voiceRange, distance end local addProximityCheck = orig_addProximityCheck @@ -29,14 +29,14 @@ function addNearbyPlayers() currentTargets = {} MumbleClearVoiceTargetChannels(voiceTarget) if LocalPlayer.state.disableProximity then return end - MumbleAddVoiceChannelListen(playerServerId) - MumbleAddVoiceTargetChannel(voiceTarget, playerServerId) + MumbleAddVoiceChannelListen(LocalPlayer.state.assignedChannel) + MumbleAddVoiceTargetChannel(voiceTarget, LocalPlayer.state.assignedChannel) - for source, _ in pairs(callData) do - if source ~= playerServerId then - MumbleAddVoiceTargetChannel(voiceTarget, source) + for source, _ in pairs(callData) do + if source ~= playerServerId then + MumbleAddVoiceTargetChannel(voiceTarget, MumbleGetVoiceChannelFromServerId(source)) end - end + end local players = GetActivePlayers() @@ -48,11 +48,11 @@ function addNearbyPlayers() -- if distance then -- currentTargets[serverId] = distance -- else - -- -- backwards compat, maybe remove in v7 + -- -- backwards compat, maybe remove in v7 -- currentTargets[serverId] = 15.0 -- end -- logger.verbose('Added %s as a voice target', serverId) - MumbleAddVoiceTargetChannel(voiceTarget, serverId) + MumbleAddVoiceTargetChannel(voiceTarget, MumbleGetVoiceChannelFromServerId(serverId)) end end end @@ -67,7 +67,7 @@ function setSpectatorMode(enabled) local serverId = GetPlayerServerId(ply) if serverId == playerServerId then goto skip_loop end logger.verbose("Adding %s to listen table", serverId) - MumbleAddVoiceChannelListen(serverId) + MumbleAddVoiceChannelListen(MumbleGetVoiceChannelFromServerId(serverId)) ::skip_loop:: end else @@ -76,7 +76,7 @@ function setSpectatorMode(enabled) local serverId = GetPlayerServerId(ply) if serverId == playerServerId then goto skip_loop end logger.verbose("Removing %s from listen table", serverId) - MumbleRemoveVoiceChannelListen(serverId) + MumbleRemoveVoiceChannelListen(MumbleGetVoiceChannelFromServerId(serverId)) ::skip_loop:: end end @@ -84,14 +84,14 @@ end RegisterNetEvent('onPlayerJoining', function(serverId) if isListenerEnabled then - MumbleAddVoiceChannelListen(serverId) + MumbleAddVoiceChannelListen(MumbleGetVoiceChannelFromServerId(serverId)) logger.verbose("Adding %s to listen table", serverId) end end) RegisterNetEvent('onPlayerDropped', function(serverId) if isListenerEnabled then - MumbleRemoveVoiceChannelListen(serverId) + MumbleRemoveVoiceChannelListen(MumbleGetVoiceChannelFromServerId(serverId)) logger.verbose("Removing %s from listen table", serverId) end end) @@ -116,7 +116,7 @@ CreateThread(function() while not MumbleIsConnected() do Wait(100) end - -- Leave the check here as we don't want to do any of this logic + -- Leave the check here as we don't want to do any of this logic if GetConvarInt('voice_enableUi', 1) == 1 then local curTalkingStatus = MumbleIsPlayerTalking(PlayerId()) == 1 if lastRadioStatus ~= radioPressed or lastTalkingStatus ~= curTalkingStatus then diff --git a/server/main.lua b/server/main.lua index 69f3733..d61a0be 100644 --- a/server/main.lua +++ b/server/main.lua @@ -2,6 +2,21 @@ voiceData = {} radioData = {} callData = {} +local maxChannels = GetConvarInt('sv_maxclients', 32) + 10 +local mappedChannels = {} +function firstFreeChannel() + local newMax = GetConvarInt('sv_maxclients', 32) + 10 + if newMax > maxChannels then maxChannels = newMax end + + for i = 1, maxChannels do + if not mappedChannels[i] then + return i + end + end + + return 0 +end + function defaultTable(source) handleStateBagInitilization(source) return { @@ -14,7 +29,7 @@ end function handleStateBagInitilization(source) local plyState = Player(source).state - if not plyState.pmaVoiceInit then + if not plyState.pmaVoiceInit then plyState:set('radio', GetConvarInt('voice_defaultRadioVolume', 30), true) plyState:set('call', GetConvarInt('voice_defaultCallVolume', 60), true) plyState:set('submix', nil, true) @@ -25,6 +40,15 @@ function handleStateBagInitilization(source) -- We want to save voice inits because we'll automatically reinitalize calls and channels plyState:set('pmaVoiceInit', true, false) end + + local assignedChannel = firstFreeChannel() + plyState:set('assignedChannel', assignedChannel, true) + if assignedChannel ~= 0 then + mappedChannels[assignedChannel] = source + logger.verbose('[reuse] Assigned %s to channel %s', source, assignedChannel) + else + logger.error('[reuse] Failed to find a free channel for %s', source) + end end CreateThread(function() @@ -55,7 +79,7 @@ CreateThread(function() logger.info('No convars detected for voice mode, defaulting to \'setr voice_useNativeAudio true\' and \'setr voice_useSendingRangeOnly true\'') end elseif sendingRangeOnly == 'false' then - logger.warn('It\'s recommended to have \'voice_useSendingRangeOnly\' set to true you can do that with \'setr voice_useSendingRangeOnly true\', this prevents players who directly join the mumble server from broadcasting to players.') + logger.warn("It's recommended to have 'voice_useSendingRangeOnly' set to true you can do that with 'setr voice_useSendingRangeOnly true', this prevents players who directly join the mumble server from broadcasting to players.") end local radioVolume = GetConvarInt("voice_defaultRadioVolume", 30) @@ -83,6 +107,8 @@ end) AddEventHandler("playerDropped", function() local source = source + local mappedChannel = Player(source).state.assignedChannel + if voiceData[source] then local plyData = voiceData[source] @@ -96,6 +122,11 @@ AddEventHandler("playerDropped", function() voiceData[source] = nil end + + if mappedChannel then + mappedChannels[mappedChannel] = nil + logger.verbose('[reuse] Unassigned %s from channel %s', source, mappedChannel) + end end) if GetConvarInt('voice_externalDisallowJoin', 0) == 1 then