initial commit
This commit is contained in:
150
fluxer_gateway/src/guild/voice/voice_utils.erl
Normal file
150
fluxer_gateway/src/guild/voice/voice_utils.erl
Normal file
@@ -0,0 +1,150 @@
|
||||
%% Copyright (C) 2026 Fluxer Contributors
|
||||
%%
|
||||
%% This file is part of Fluxer.
|
||||
%%
|
||||
%% Fluxer is free software: you can redistribute it and/or modify
|
||||
%% it under the terms of the GNU Affero General Public License as published by
|
||||
%% the Free Software Foundation, either version 3 of the License, or
|
||||
%% (at your option) any later version.
|
||||
%%
|
||||
%% Fluxer is distributed in the hope that it will be useful,
|
||||
%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
%% GNU Affero General Public License for more details.
|
||||
%%
|
||||
%% You should have received a copy of the GNU Affero General Public License
|
||||
%% along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
-module(voice_utils).
|
||||
|
||||
-export([
|
||||
build_voice_token_rpc_request/6,
|
||||
build_voice_token_rpc_request/7,
|
||||
build_force_disconnect_rpc_request/4,
|
||||
build_update_participant_rpc_request/5,
|
||||
build_update_participant_permissions_rpc_request/5,
|
||||
add_geolocation_to_request/3,
|
||||
compute_voice_permissions/3
|
||||
]).
|
||||
|
||||
build_voice_token_rpc_request(GuildId, ChannelId, UserId, ConnectionId, Latitude, Longitude) ->
|
||||
BaseReq =
|
||||
case GuildId of
|
||||
null ->
|
||||
#{
|
||||
<<"type">> => <<"voice_get_token">>,
|
||||
<<"channel_id">> => integer_to_binary(ChannelId),
|
||||
<<"user_id">> => integer_to_binary(UserId)
|
||||
};
|
||||
_ ->
|
||||
BaseMap = #{
|
||||
<<"type">> => <<"voice_get_token">>,
|
||||
<<"guild_id">> => integer_to_binary(GuildId),
|
||||
<<"channel_id">> => integer_to_binary(ChannelId),
|
||||
<<"user_id">> => integer_to_binary(UserId)
|
||||
},
|
||||
case ConnectionId of
|
||||
null ->
|
||||
BaseMap;
|
||||
ConnectionId when is_binary(ConnectionId) ->
|
||||
maps:put(<<"connection_id">>, ConnectionId, BaseMap);
|
||||
ConnectionId when is_integer(ConnectionId) ->
|
||||
maps:put(<<"connection_id">>, integer_to_binary(ConnectionId), BaseMap);
|
||||
_ ->
|
||||
BaseMap
|
||||
end
|
||||
end,
|
||||
|
||||
add_geolocation_to_request(BaseReq, Latitude, Longitude).
|
||||
|
||||
add_geolocation_to_request(RequestMap, Latitude, Longitude) ->
|
||||
case {Latitude, Longitude} of
|
||||
{Lat, Long} when is_binary(Lat) andalso is_binary(Long) ->
|
||||
maps:merge(RequestMap, #{
|
||||
<<"latitude">> => Lat,
|
||||
<<"longitude">> => Long
|
||||
});
|
||||
_ ->
|
||||
RequestMap
|
||||
end.
|
||||
|
||||
build_force_disconnect_rpc_request(GuildId, ChannelId, UserId, ConnectionId) ->
|
||||
BaseReq = #{
|
||||
<<"type">> => <<"voice_force_disconnect_participant">>,
|
||||
<<"channel_id">> => integer_to_binary(ChannelId),
|
||||
<<"user_id">> => integer_to_binary(UserId),
|
||||
<<"connection_id">> => ConnectionId
|
||||
},
|
||||
case GuildId of
|
||||
null ->
|
||||
BaseReq;
|
||||
_ ->
|
||||
maps:put(<<"guild_id">>, integer_to_binary(GuildId), BaseReq)
|
||||
end.
|
||||
|
||||
build_update_participant_rpc_request(GuildId, ChannelId, UserId, Mute, Deaf) ->
|
||||
BaseReq = #{
|
||||
<<"type">> => <<"voice_update_participant">>,
|
||||
<<"channel_id">> => integer_to_binary(ChannelId),
|
||||
<<"user_id">> => integer_to_binary(UserId),
|
||||
<<"mute">> => Mute,
|
||||
<<"deaf">> => Deaf
|
||||
},
|
||||
case GuildId of
|
||||
null ->
|
||||
BaseReq;
|
||||
_ ->
|
||||
maps:put(<<"guild_id">>, integer_to_binary(GuildId), BaseReq)
|
||||
end.
|
||||
|
||||
build_update_participant_permissions_rpc_request(
|
||||
GuildId, ChannelId, UserId, ConnectionId, VoicePermissions
|
||||
) ->
|
||||
BaseReq = #{
|
||||
<<"type">> => <<"voice_update_participant_permissions">>,
|
||||
<<"channel_id">> => integer_to_binary(ChannelId),
|
||||
<<"user_id">> => integer_to_binary(UserId),
|
||||
<<"connection_id">> => ConnectionId,
|
||||
<<"can_speak">> => maps:get(can_speak, VoicePermissions, true),
|
||||
<<"can_stream">> => maps:get(can_stream, VoicePermissions, true),
|
||||
<<"can_video">> => maps:get(can_video, VoicePermissions, true)
|
||||
},
|
||||
case GuildId of
|
||||
null ->
|
||||
BaseReq;
|
||||
_ ->
|
||||
maps:put(<<"guild_id">>, integer_to_binary(GuildId), BaseReq)
|
||||
end.
|
||||
|
||||
-spec compute_voice_permissions(integer(), integer(), map()) -> map().
|
||||
compute_voice_permissions(UserId, ChannelId, State) ->
|
||||
Permissions = guild_permissions:get_member_permissions(UserId, ChannelId, State),
|
||||
SpeakPerm = constants:speak_permission(),
|
||||
StreamPerm = constants:stream_permission(),
|
||||
AdminPerm = constants:administrator_permission(),
|
||||
|
||||
IsAdmin = (Permissions band AdminPerm) =:= AdminPerm,
|
||||
CanSpeak = IsAdmin orelse ((Permissions band SpeakPerm) =:= SpeakPerm),
|
||||
CanStream = IsAdmin orelse ((Permissions band StreamPerm) =:= StreamPerm),
|
||||
|
||||
HasVirtualAccess = guild_virtual_channel_access:has_virtual_access(UserId, ChannelId, State),
|
||||
FinalCanSpeak = CanSpeak orelse HasVirtualAccess,
|
||||
FinalCanStream = CanStream orelse HasVirtualAccess,
|
||||
|
||||
#{
|
||||
can_speak => FinalCanSpeak,
|
||||
can_stream => FinalCanStream,
|
||||
can_video => FinalCanStream
|
||||
}.
|
||||
|
||||
build_voice_token_rpc_request(
|
||||
GuildId, ChannelId, UserId, ConnectionId, Latitude, Longitude, VoicePermissions
|
||||
) ->
|
||||
BaseReq = build_voice_token_rpc_request(
|
||||
GuildId, ChannelId, UserId, ConnectionId, Latitude, Longitude
|
||||
),
|
||||
maps:merge(BaseReq, #{
|
||||
<<"can_speak">> => maps:get(can_speak, VoicePermissions, true),
|
||||
<<"can_stream">> => maps:get(can_stream, VoicePermissions, true),
|
||||
<<"can_video">> => maps:get(can_video, VoicePermissions, true)
|
||||
}).
|
||||
Reference in New Issue
Block a user