mirror of
https://codeberg.org/godmaire/sergei.git
synced 2024-09-20 00:08:25 +00:00
feat: stop if channel is empty
This commit is contained in:
parent
ffcc3f6b66
commit
0b4a52364e
2 changed files with 55 additions and 6 deletions
|
@ -4,13 +4,17 @@ defmodule Sergei.Player do
|
||||||
require Logger
|
require Logger
|
||||||
alias Nostrum.Voice
|
alias Nostrum.Voice
|
||||||
|
|
||||||
|
@check_repeat_interval 100
|
||||||
|
@check_empty_interval 30_000
|
||||||
|
|
||||||
def start_link(_) do
|
def start_link(_) do
|
||||||
GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
|
GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def init(state) do
|
def init(state) do
|
||||||
Process.send_after(self(), :tick, 100)
|
Process.send_after(self(), :check_repeat, @check_repeat_interval)
|
||||||
|
Process.send_after(self(), :check_empty, @check_empty_interval)
|
||||||
|
|
||||||
{:ok, state}
|
{:ok, state}
|
||||||
end
|
end
|
||||||
|
@ -42,7 +46,7 @@ defmodule Sergei.Player do
|
||||||
|
|
||||||
# Server
|
# Server
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info(:tick, state) do
|
def handle_info(:check_repeat, state) do
|
||||||
state
|
state
|
||||||
|> Enum.filter(fn {_id, %{paused: paused} = _state} -> not paused end)
|
|> Enum.filter(fn {_id, %{paused: paused} = _state} -> not paused end)
|
||||||
|> Enum.filter(fn {guild_id, _data} -> not Voice.playing?(guild_id) end)
|
|> Enum.filter(fn {guild_id, _data} -> not Voice.playing?(guild_id) end)
|
||||||
|
@ -50,7 +54,39 @@ defmodule Sergei.Player do
|
||||||
Voice.play(guild_id, url, :ytdl)
|
Voice.play(guild_id, url, :ytdl)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Process.send_after(self(), :tick, 100)
|
Process.send_after(self(), :check_repeat, @check_repeat_interval)
|
||||||
|
{:noreply, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_info(:check_empty, state) do
|
||||||
|
Logger.debug("Checking for empty channels")
|
||||||
|
%{id: self_id} = Nostrum.Cache.Me.get()
|
||||||
|
|
||||||
|
channel_to_guild =
|
||||||
|
state
|
||||||
|
|> Map.keys()
|
||||||
|
|> Map.new(fn guild_id -> {Voice.get_channel_id(guild_id), guild_id} end)
|
||||||
|
|
||||||
|
populated_channels =
|
||||||
|
Sergei.VoiceStateCache.get_state()
|
||||||
|
# Filter out self
|
||||||
|
|> Enum.filter(fn {user_id, _data} -> user_id != self_id end)
|
||||||
|
|> Enum.map(fn {_user_id, %{channel_id: channel_id}} -> channel_id end)
|
||||||
|
|> Enum.reduce(MapSet.new(), fn channel, set -> MapSet.put(set, channel) end)
|
||||||
|
|
||||||
|
state
|
||||||
|
|> Enum.map(fn {guild_id, _data} -> Voice.get_channel_id(guild_id) end)
|
||||||
|
|> Enum.reduce(MapSet.new(), fn channel, set -> MapSet.put(set, channel) end)
|
||||||
|
|> MapSet.difference(populated_channels)
|
||||||
|
|> Enum.map(fn channel_id ->
|
||||||
|
Logger.debug("Leaving channel #{channel_id}")
|
||||||
|
channel_id
|
||||||
|
end)
|
||||||
|
|> Enum.map(fn channel_id -> Map.get(channel_to_guild, channel_id) end)
|
||||||
|
|> Enum.each(fn guild_id -> stop(guild_id) end)
|
||||||
|
|
||||||
|
Process.send_after(self(), :check_empty, @check_empty_interval)
|
||||||
{:noreply, state}
|
{:noreply, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,11 @@ defmodule Sergei.VoiceStateCache do
|
||||||
GenServer.call(__MODULE__, {:get, user_id})
|
GenServer.call(__MODULE__, {:get, user_id})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_state() :: %{non_neg_integer() => %{guild_id: integer(), channel_id: integer()}}
|
||||||
|
def get_state() do
|
||||||
|
GenServer.call(__MODULE__, {:get})
|
||||||
|
end
|
||||||
|
|
||||||
# Server
|
# Server
|
||||||
@impl true
|
@impl true
|
||||||
def handle_cast({:update, state}, cache) do
|
def handle_cast({:update, state}, cache) do
|
||||||
|
@ -34,9 +39,12 @@ defmodule Sergei.VoiceStateCache do
|
||||||
}
|
}
|
||||||
} = state
|
} = state
|
||||||
|
|
||||||
entry =
|
entry = %{
|
||||||
Map.new()
|
user_id => %{
|
||||||
|> Map.put(user_id, %{guild_id: guild_id, channel_id: channel_id})
|
guild_id: guild_id,
|
||||||
|
channel_id: channel_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{:noreply, Map.merge(cache, entry)}
|
{:noreply, Map.merge(cache, entry)}
|
||||||
end
|
end
|
||||||
|
@ -45,4 +53,9 @@ defmodule Sergei.VoiceStateCache do
|
||||||
def handle_call({:get, user_id}, _from, cache) do
|
def handle_call({:get, user_id}, _from, cache) do
|
||||||
{:reply, Map.get(cache, user_id), cache}
|
{:reply, Map.get(cache, user_id), cache}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_call({:get}, _from, cache) do
|
||||||
|
{:reply, cache, cache}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue