refactor progress
This commit is contained in:
232
fluxer_gateway/src/gateway/gateway_rpc_voice.erl
Normal file
232
fluxer_gateway/src/gateway/gateway_rpc_voice.erl
Normal file
@@ -0,0 +1,232 @@
|
||||
%% 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(gateway_rpc_voice).
|
||||
|
||||
-export([execute_method/2]).
|
||||
|
||||
-spec execute_method(binary(), map()) -> term().
|
||||
execute_method(<<"voice.confirm_connection">>, Params) ->
|
||||
ChannelIdBin = maps:get(<<"channel_id">>, Params),
|
||||
ConnectionId = maps:get(<<"connection_id">>, Params),
|
||||
case parse_optional_guild_id(Params) of
|
||||
undefined ->
|
||||
gateway_rpc_call:execute_method(
|
||||
<<"call.confirm_connection">>,
|
||||
#{
|
||||
<<"channel_id">> => ChannelIdBin,
|
||||
<<"connection_id">> => ConnectionId
|
||||
}
|
||||
);
|
||||
GuildId ->
|
||||
TokenNonce = maps:get(<<"token_nonce">>, Params, undefined),
|
||||
gateway_rpc_guild:execute_method(
|
||||
<<"guild.confirm_voice_connection_from_livekit">>,
|
||||
#{
|
||||
<<"guild_id">> => integer_to_binary(GuildId),
|
||||
<<"connection_id">> => ConnectionId,
|
||||
<<"token_nonce">> => TokenNonce
|
||||
}
|
||||
)
|
||||
end;
|
||||
execute_method(<<"voice.disconnect_user_if_in_channel">>, Params) ->
|
||||
ChannelIdBin = maps:get(<<"channel_id">>, Params),
|
||||
UserIdBin = maps:get(<<"user_id">>, Params),
|
||||
ConnectionId = maps:get(<<"connection_id">>, Params, undefined),
|
||||
case parse_optional_guild_id(Params) of
|
||||
undefined ->
|
||||
CallParams = #{
|
||||
<<"channel_id">> => ChannelIdBin,
|
||||
<<"user_id">> => UserIdBin
|
||||
},
|
||||
gateway_rpc_call:execute_method(
|
||||
<<"call.disconnect_user_if_in_channel">>,
|
||||
maybe_put_connection_id(ConnectionId, CallParams)
|
||||
);
|
||||
GuildId ->
|
||||
GuildParams = #{
|
||||
<<"guild_id">> => integer_to_binary(GuildId),
|
||||
<<"user_id">> => UserIdBin,
|
||||
<<"expected_channel_id">> => ChannelIdBin
|
||||
},
|
||||
gateway_rpc_guild:execute_method(
|
||||
<<"guild.disconnect_voice_user_if_in_channel">>,
|
||||
maybe_put_connection_id(ConnectionId, GuildParams)
|
||||
)
|
||||
end;
|
||||
execute_method(<<"voice.get_voice_states_for_channel">>, Params) ->
|
||||
ChannelIdBin = maps:get(<<"channel_id">>, Params),
|
||||
case parse_optional_guild_id(Params) of
|
||||
undefined ->
|
||||
build_dm_voice_states_response(ChannelIdBin);
|
||||
GuildId ->
|
||||
gateway_rpc_guild:execute_method(
|
||||
<<"guild.get_voice_states_for_channel">>,
|
||||
#{
|
||||
<<"guild_id">> => integer_to_binary(GuildId),
|
||||
<<"channel_id">> => ChannelIdBin
|
||||
}
|
||||
)
|
||||
end;
|
||||
execute_method(<<"voice.get_pending_joins_for_channel">>, Params) ->
|
||||
ChannelIdBin = maps:get(<<"channel_id">>, Params),
|
||||
case parse_optional_guild_id(Params) of
|
||||
undefined ->
|
||||
normalize_pending_joins_response(
|
||||
gateway_rpc_call:execute_method(
|
||||
<<"call.get_pending_joins">>,
|
||||
#{<<"channel_id">> => ChannelIdBin}
|
||||
)
|
||||
);
|
||||
GuildId ->
|
||||
gateway_rpc_guild:execute_method(
|
||||
<<"guild.get_pending_joins_for_channel">>,
|
||||
#{
|
||||
<<"guild_id">> => integer_to_binary(GuildId),
|
||||
<<"channel_id">> => ChannelIdBin
|
||||
}
|
||||
)
|
||||
end;
|
||||
execute_method(Method, _Params) ->
|
||||
throw({error, <<"Unknown method: ", Method/binary>>}).
|
||||
|
||||
-spec parse_optional_guild_id(map()) -> integer() | undefined.
|
||||
parse_optional_guild_id(Params) ->
|
||||
case maps:get(<<"guild_id">>, Params, undefined) of
|
||||
undefined ->
|
||||
undefined;
|
||||
null ->
|
||||
undefined;
|
||||
GuildIdBin ->
|
||||
validation:snowflake_or_throw(<<"guild_id">>, GuildIdBin)
|
||||
end.
|
||||
|
||||
-spec maybe_put_connection_id(binary() | undefined, map()) -> map().
|
||||
maybe_put_connection_id(undefined, Params) ->
|
||||
Params;
|
||||
maybe_put_connection_id(ConnectionId, Params) ->
|
||||
Params#{<<"connection_id">> => ConnectionId}.
|
||||
|
||||
-spec build_dm_voice_states_response(binary()) -> map().
|
||||
build_dm_voice_states_response(ChannelIdBin) ->
|
||||
case gateway_rpc_call:execute_method(<<"call.get">>, #{<<"channel_id">> => ChannelIdBin}) of
|
||||
null ->
|
||||
#{<<"voice_states">> => []};
|
||||
CallData when is_map(CallData) ->
|
||||
VoiceStates = get_map_value(CallData, [<<"voice_states">>, voice_states]),
|
||||
#{<<"voice_states">> => normalize_voice_states(VoiceStates)}
|
||||
end.
|
||||
|
||||
-spec normalize_voice_states(term()) -> [map()].
|
||||
normalize_voice_states(VoiceStates) when is_list(VoiceStates) ->
|
||||
lists:reverse(
|
||||
lists:foldl(fun normalize_voice_state_entry/2, [], VoiceStates)
|
||||
);
|
||||
normalize_voice_states(_) ->
|
||||
[].
|
||||
|
||||
-spec normalize_voice_state_entry(map(), [map()]) -> [map()].
|
||||
normalize_voice_state_entry(VoiceState, Acc) ->
|
||||
ConnectionId = normalize_id(get_map_value(VoiceState, [<<"connection_id">>, connection_id])),
|
||||
UserId = normalize_id(get_map_value(VoiceState, [<<"user_id">>, user_id])),
|
||||
ChannelId = normalize_id(get_map_value(VoiceState, [<<"channel_id">>, channel_id])),
|
||||
case {ConnectionId, UserId, ChannelId} of
|
||||
{undefined, _, _} ->
|
||||
Acc;
|
||||
{_, undefined, _} ->
|
||||
Acc;
|
||||
{_, _, undefined} ->
|
||||
Acc;
|
||||
_ ->
|
||||
[#{
|
||||
<<"connection_id">> => ConnectionId,
|
||||
<<"user_id">> => UserId,
|
||||
<<"channel_id">> => ChannelId
|
||||
} | Acc]
|
||||
end.
|
||||
|
||||
-spec normalize_pending_joins_response(term()) -> map().
|
||||
normalize_pending_joins_response(Response) when is_map(Response) ->
|
||||
PendingJoins = get_map_value(Response, [<<"pending_joins">>, pending_joins]),
|
||||
#{<<"pending_joins">> => normalize_pending_joins(PendingJoins)};
|
||||
normalize_pending_joins_response(_) ->
|
||||
#{<<"pending_joins">> => []}.
|
||||
|
||||
-spec normalize_pending_joins(term()) -> [map()].
|
||||
normalize_pending_joins(PendingJoins) when is_list(PendingJoins) ->
|
||||
lists:reverse(
|
||||
lists:foldl(fun normalize_pending_join_entry/2, [], PendingJoins)
|
||||
);
|
||||
normalize_pending_joins(_) ->
|
||||
[].
|
||||
|
||||
-spec normalize_pending_join_entry(map(), [map()]) -> [map()].
|
||||
normalize_pending_join_entry(PendingJoin, Acc) ->
|
||||
ConnectionId = normalize_id(get_map_value(PendingJoin, [<<"connection_id">>, connection_id])),
|
||||
UserId = normalize_id(get_map_value(PendingJoin, [<<"user_id">>, user_id])),
|
||||
TokenNonce = normalize_token_nonce(get_map_value(PendingJoin, [<<"token_nonce">>, token_nonce])),
|
||||
ExpiresAt = normalize_expiry(get_map_value(PendingJoin, [<<"expires_at">>, expires_at])),
|
||||
case {ConnectionId, UserId} of
|
||||
{undefined, _} ->
|
||||
Acc;
|
||||
{_, undefined} ->
|
||||
Acc;
|
||||
_ ->
|
||||
[#{
|
||||
<<"connection_id">> => ConnectionId,
|
||||
<<"user_id">> => UserId,
|
||||
<<"token_nonce">> => TokenNonce,
|
||||
<<"expires_at">> => ExpiresAt
|
||||
} | Acc]
|
||||
end.
|
||||
|
||||
-spec normalize_id(term()) -> binary() | undefined.
|
||||
normalize_id(undefined) ->
|
||||
undefined;
|
||||
normalize_id(Value) when is_binary(Value) ->
|
||||
Value;
|
||||
normalize_id(Value) when is_integer(Value) ->
|
||||
integer_to_binary(Value);
|
||||
normalize_id(_) ->
|
||||
undefined.
|
||||
|
||||
-spec normalize_token_nonce(term()) -> binary().
|
||||
normalize_token_nonce(undefined) ->
|
||||
<<>>;
|
||||
normalize_token_nonce(Value) when is_binary(Value) ->
|
||||
Value;
|
||||
normalize_token_nonce(Value) when is_integer(Value) ->
|
||||
integer_to_binary(Value);
|
||||
normalize_token_nonce(_) ->
|
||||
<<>>.
|
||||
|
||||
-spec normalize_expiry(term()) -> integer().
|
||||
normalize_expiry(Value) when is_integer(Value) ->
|
||||
Value;
|
||||
normalize_expiry(_) ->
|
||||
0.
|
||||
|
||||
-spec get_map_value(map(), [term()]) -> term().
|
||||
get_map_value(_Map, []) ->
|
||||
undefined;
|
||||
get_map_value(Map, [Key | Rest]) ->
|
||||
case maps:find(Key, Map) of
|
||||
{ok, Value} ->
|
||||
Value;
|
||||
error ->
|
||||
get_map_value(Map, Rest)
|
||||
end.
|
||||
Reference in New Issue
Block a user