diff --git a/.dialyzer_ignore.exs b/.dialyzer_ignore.exs
index 9ae13a0f6..dbb9c8904 100644
--- a/.dialyzer_ignore.exs
+++ b/.dialyzer_ignore.exs
@@ -11,7 +11,6 @@
{"lib/teiserver/account/reports/population_report.ex", :unused_fun},
{"lib/teiserver/account/reports/time_compare_report.ex", :invalid_contract},
{"lib/teiserver/account/reports/time_compare_report.ex", :call},
- {"lib/teiserver/account/reports/tournament_report.ex", :invalid_contract},
{"lib/teiserver/account/servers/party_server.ex", :no_return},
{"lib/teiserver/account/servers/party_server.ex", :call},
{"lib/teiserver/battle.ex", :call},
@@ -29,7 +28,6 @@
{"lib/teiserver/battle/tasks/post_match_process_task.ex", :call},
{"lib/teiserver/battle/tasks/post_match_process_task.ex", :unused_fun},
{"lib/teiserver/bridge/chat_commands.ex", :call},
- {"lib/teiserver/bridge/commands/findreports_command.ex", :pattern_match},
{"lib/teiserver/bridge/discord_bridge_bot.ex", :guard_fail},
{"lib/teiserver/bridge/discord_bridge_bot.ex", :no_return},
{"lib/teiserver/bridge/discord_bridge_bot.ex", :call},
@@ -97,8 +95,6 @@
{"lib/teiserver/mix_tasks/fake_data.ex", :no_return},
{"lib/teiserver/mix_tasks/fake_data.ex", :unused_fun},
{"lib/teiserver/moderation.ex", :unknown_type},
- {"lib/teiserver/moderation.ex", :invalid_contract},
- {"lib/teiserver/moderation/libs/report_group_lib.ex", :call},
{"lib/teiserver/moderation/libs/test_lib.ex", :invalid_contract},
{"lib/teiserver/protocols/spring/spring.ex", :unknown_type},
{"lib/teiserver/protocols/spring/spring_battle_in.ex", :call},
diff --git a/documents/planned_designs/clustering.md b/documents/planned_designs/clustering.md
index 7bfe39ba1..4f38cc975 100644
--- a/documents/planned_designs/clustering.md
+++ b/documents/planned_designs/clustering.md
@@ -93,7 +93,6 @@ Note: This ties in with the "Per node process" item.
- List of per ID processes (1 per id in entire cluster):
- ConsulServer
- LobbyThrottleServer
- - AccoladeChatServer
- QueueServer
- Per cluster processes that might need to be changed to use pooled resources (e.g. worker pool):
- CoordinatorServer
diff --git a/documents/planned_designs/tournaments.md b/documents/planned_designs/tournaments.md
deleted file mode 100644
index 1732257bb..000000000
--- a/documents/planned_designs/tournaments.md
+++ /dev/null
@@ -1,133 +0,0 @@
-### Ideas - Core
-- Bracket designs
-- Tourney types (bracket, round robin etc)
-- Ability to connect one tourney to another (e.g. TI group stages -> main event)
-- Signup process, might need to be linked to discord
-- Track bat
-- Admin functionality, maybe something like they temporarily have "friends list" like interactions with all players?
-- Challonge API https://api.challonge.com/v1
-- Don't allow spectators in tourney games except mods/organisers (as an option)
-
-### Ideas - Extra
-- Predicitons
-- Ability for people to sign up as standins should people drop out
-- Ability to jump to spectate a player's game
-- Automatically pull people into their game if ready
-- Alerts of when a game should be starting and warnings to admins regarding late starts
-- Online checker for specific players
-
-### Extensive ideas from Dubhdara
-- Signup within client
-- Signup within discord
-- Signup on website
-- Tourney rules page (specific to the tourney)
-- Support for single elimination
-- Match scheduling (automatic and manual)
-- Score reporting (Challonge API?)
-- Async and Synchronous support in terms of player (un)availability
-- Tourney page should have indicators of maps and settings for each game played and to-play
-- "Flake score" for players to indicate those that signup for and leave tourneys
-
-### API suggestion from Dubhdara
-```
-data Competition = Tournament | League # Interface
- teams :: [[Player]]
- matches :: [Match]
- startDate :: UTCTime
- rules :: [String]
-}
-
-data Tournament = inherits Competition {
- startTime :: UTCTime
- bracket = Tree Matches
- activePlayers :: Players
-}
-
-data League = League inherits Competition {
- roundDurationDays :: Int
- scoreBoard :: [(Player, Int)]
-}
-
-data Player | Player {
- id :: String
- scores :: Map(Tournament, Int)
- availibleTimes :: [(UTCTime, UTCTime)]
-}
-
-data Match = Match {
- startTime :: UTCTime
- isScheduled :: Bool
- players :: [Player]
- map :: String
-}
-
-CompetetionRunner {
- getNextMatches :: ([Player, Matches]) -> [Matches]
- displayMatches :: [Matches]
-
-TournamentRunner {
- randomizeBrackets :: Tree Matches
- setBrackets :: Tree Matches -> Tree Matches
- displayBrackets :: [Matches]
- setActivePlayers :: [Player] -> ()
-}
-
-LeagueRunner {
- scheduleNextMatch ([Match], [Player]) -> Match
- displayScores ([Player] -> Map(Player, Int)
- advanceRound :: [Player] -> [Player, Match]
-}
-
-PlayerAction {
- forfitMatch :: Match -> ()
- reportScore :: (Int, Int, [Player]) -> () # Team1Score, Team2Score, Winners
- signUpForCompetition :: Competition -> ()
- }
-
-AdminAction {
- startCompetition :: Tournament -> ()
- sendAnnoucement :: String -> ()
-}
-```
-
-### Schema
-Tournament
-- name
-- description
-- rules {:array, String()}
-- type (1v1, 3v3, 5v5, FFA etc)
-- format (swiss, round robin etc)
-- start date
-- discord_event_id
-- challonge_id
-- configs (e.g. allow spectators, welcome-messages)
-- brackets (maps per bracket etc)
-- stream_urls {:array, String()}
-
-TournamentMember # This tracks membership and role in a tourney
-- userid (discord_id is tracked against user)
-- role (organiser, caster, player, coach etc)
-- noshow (boolean)
-
-TournamentTeam
-- name
-- tournament_id
-- position (int)
-- eliminated (boolean)
-
-TournamentTeamMember # This tracks membership of a team
-- userid (discord_id is tracked against user)
-- team_id
-
-TournamentSeries
-- tournament_id
-
-TournamentGame
-- series_id
-- match_id
-- tournament_id
-
-TournamentPrediction
-- userid
-- tournament_id
-- prediction_data (map)
diff --git a/lib/teiserver.ex b/lib/teiserver.ex
index a85c7460c..2f39b0e0f 100644
--- a/lib/teiserver.ex
+++ b/lib/teiserver.ex
@@ -1,6 +1,5 @@
defmodule Teiserver do
@moduledoc false
- alias Teiserver.Account.AccoladeLib
alias Teiserver.Admin.DeleteUserTask
alias Teiserver.Data.Types, as: T
alias Teiserver.Helpers.CacheHelper
@@ -27,12 +26,6 @@ defmodule Teiserver do
:code.load_file(module)
end
- @spec accolade_status :: nil | :ok
- def accolade_status do
- Application.put_env(:elixir, :ansi_enabled, true)
- AccoladeLib.live_debug()
- end
-
@spec manually_delete_user(T.userid()) :: :ok
def manually_delete_user(id) do
Application.put_env(:elixir, :ansi_enabled, true)
diff --git a/lib/teiserver/account/accolades/accolade_bot_server.ex b/lib/teiserver/account/accolades/accolade_bot_server.ex
deleted file mode 100644
index bc95562b1..000000000
--- a/lib/teiserver/account/accolades/accolade_bot_server.ex
+++ /dev/null
@@ -1,247 +0,0 @@
-defmodule Teiserver.Account.AccoladeBotServer do
- @moduledoc """
- The accolade server is the interface point for the Accolade system.
- """
-
- alias Phoenix.PubSub
- alias Teiserver.Account
- alias Teiserver.Account.AccoladeLib
- alias Teiserver.Account.Auth
- alias Teiserver.Battle
- alias Teiserver.CacheUser
- alias Teiserver.Config
- alias Teiserver.Coordinator.CoordinatorCommands
- alias Teiserver.Coordinator.Parser
- alias Teiserver.Room
- use GenServer
- require Logger
-
- @spec max_miss_count :: float
- def max_miss_count do
- AccoladeLib.miss_count_limit() * 1.5
- end
-
- @spec start_link(list()) :: :ignore | {:error, any} | {:ok, pid}
- def start_link(opts) do
- GenServer.start_link(__MODULE__, opts[:data], [])
- end
-
- @impl GenServer
- def handle_call(:client_state, _from, state) do
- {:reply, state.client, state}
- end
-
- @impl GenServer
- def handle_cast({:update_client, new_client}, state) do
- {:noreply, %{state | client: new_client}}
- end
-
- def handle_cast({:merge_client, partial_client}, state) do
- {:noreply, %{state | client: Map.merge(state.client, partial_client)}}
- end
-
- @impl GenServer
- def handle_info(:begin, _state) do
- Logger.debug("Starting up Accolade server")
- account = get_accolade_account()
- Teiserver.cache_put(:application_metadata_cache, "teiserver_accolade_userid", account.id)
-
- {user, client} =
- case CacheUser.internal_client_login(account.id) do
- {:ok, user, client} -> {user, client}
- :error -> raise "No accolade user found"
- end
-
- state = %{
- ip: "127.0.0.1",
- userid: user.id,
- username: user.name,
- client: client
- }
-
- ~w(main accolades)
- |> Enum.each(fn room_name ->
- Room.get_or_make_room(room_name, user.id)
- Room.add_user_to_room(user.id, room_name)
- :ok = PubSub.subscribe(Teiserver.PubSub, "room:#{room_name}")
- end)
-
- :ok = PubSub.subscribe(Teiserver.PubSub, "legacy_user_updates:#{user.id}")
-
- # We only subscribe to this if we're not in test, if
- # we are it'll generate a bunch of SQL errors
- # without actually breaking anything
- if not Application.get_env(:teiserver, Teiserver)[:test_mode] do
- :ok = PubSub.subscribe(Teiserver.PubSub, "global_match_updates")
- end
-
- {:noreply, state}
- end
-
- # Match ending
- def handle_info(
- %{channel: "global_match_updates", event: :match_completed, match_id: match_id},
- state
- ) do
- case Battle.get_match(match_id) do
- nil ->
- nil
-
- match ->
- duration = Timex.diff(match.finished, match.started, :second)
-
- if duration > 600 do
- if Config.get_site_config_cache("teiserver.Enable accolades") do
- post_match_messages(match)
- end
- else
- :ok
- end
- end
-
- {:noreply, state}
- end
-
- def handle_info(%{channel: "global_match_updates"}, state) do
- {:noreply, state}
- end
-
- # Direct/Room messaging
- def handle_info({:add_user_to_room, _userid, _room_name}, state), do: {:noreply, state}
- def handle_info({:remove_user_from_room, _userid, _room_name}, state), do: {:noreply, state}
-
- def handle_info({:new_message, _userid, _room_name, _message}, state), do: {:noreply, state}
- def handle_info({:new_message_ex, _userid, _room_name, _message}, state), do: {:noreply, state}
-
- def handle_info({:direct_message, from_id, parts}, state) when is_list(parts) do
- new_state =
- parts
- |> Enum.reduce(state, fn part, acc_state ->
- {_reply, new_state} = handle_info({:direct_message, from_id, part}, acc_state)
- new_state
- end)
-
- {:noreply, new_state}
- end
-
- def handle_info({:direct_message, sender_id, "$" <> command}, state) do
- cmd = Parser.parse_command(sender_id, "$#{command}")
- new_state = CoordinatorCommands.handle_command(cmd, state)
-
- {:noreply, new_state}
- end
-
- def handle_info({:direct_message, userid, message}, state) do
- if not Auth.is_bot?(userid) do
- case AccoladeLib.cast_accolade_chat(userid, {:user_message, message}) do
- nil ->
- CacheUser.send_direct_message(
- state.userid,
- userid,
- "I'm not currently awaiting feedback for a player"
- )
-
- _result ->
- :ok
- end
- end
-
- {:noreply, state}
- end
-
- def handle_info({:new_accolade, userid}, state) do
- CacheUser.send_direct_message(
- state.userid,
- userid,
- "You have been awarded a new accolade send $whoami to myself to see your collection."
- )
-
- {:noreply, state}
- end
-
- # Client inout
- def handle_info(%{channel: "client_inout", event: :login, userid: userid}, state) do
- :timer.send_after(500, {:do_client_inout, :login, userid})
- {:noreply, state}
- end
-
- # Catchall handle_info
- def handle_info(msg, state) do
- Logger.error(
- "Accolade server handle_info error. No handler for msg of #{Kernel.inspect(msg)}"
- )
-
- {:noreply, state}
- end
-
- @spec get_accolade_account() :: Teiserver.Account.User.t()
- def get_accolade_account do
- user =
- Account.get_user(nil,
- search: [
- email: "accolades_bot@teiserver.local"
- ]
- )
-
- case user do
- nil ->
- # Make account
- {:ok, account} =
- Account.script_create_user(%{
- name: "AccoladesBot",
- email: "accolades_bot@teiserver.local",
- icon: "fa-solid #{AccoladeLib.icon()}" |> String.replace(" far ", " "),
- colour: "#0066AA",
- password: Account.make_bot_password(),
- roles: ["Bot", "Verified"],
- data: %{
- bot: true,
- moderator: false,
- lobby_client: "Teiserver Internal Process"
- }
- })
-
- Account.update_user_stat(account.id, %{
- country_override: Application.get_env(:teiserver, Teiserver)[:server_flag]
- })
-
- CacheUser.recache_user(account.id)
- account
-
- account ->
- account
- end
- end
-
- defp post_match_messages(%{id: match_id} = _match) do
- Logger.info("AccoladeBotServer post match messages for #{match_id}")
-
- # Get a list of all the players, then check if there are possible ratings for them
- memberships = Battle.list_match_memberships(search: [match_id: match_id])
-
- memberships
- |> Enum.each(fn %{user_id: userid} ->
- case AccoladeLib.get_possible_ratings(userid, memberships) do
- [] ->
- :ok
-
- possibles ->
- chosen = Enum.random(possibles)
- AccoladeLib.start_accolade_process(userid, chosen, match_id)
- end
- end)
- end
-
- @impl GenServer
- @spec init(map()) :: {:ok, map()}
- def init(_opts) do
- Horde.Registry.register(
- Teiserver.AccoladesRegistry,
- "AccoladeBotServer",
- :accolade_bot
- )
-
- send(self(), :begin)
- {:ok, %{}}
- end
-end
diff --git a/lib/teiserver/account/accolades/accolade_chat_server.ex b/lib/teiserver/account/accolades/accolade_chat_server.ex
deleted file mode 100644
index 39bbf2b2e..000000000
--- a/lib/teiserver/account/accolades/accolade_chat_server.ex
+++ /dev/null
@@ -1,229 +0,0 @@
-defmodule Teiserver.Account.AccoladeChatServer do
- @moduledoc """
- Each chat server is for a specific user, when the chat server has done it's job it self-terminates.
- """
-
- alias Teiserver.Account
- alias Teiserver.Account.AccoladeBotServer
- alias Teiserver.Account.AccoladeLib
- alias Teiserver.CacheUser
- alias Teiserver.Config
- alias Teiserver.Data.Types, as: T
-
- use GenServer
-
- @line_break "-------------------------------------------------"
- @chat_timeout 600_000
-
- def start_link(opts) do
- GenServer.start_link(__MODULE__, opts[:data], [])
- end
-
- @spec empty_state(T.userid(), T.userid(), T.lobby_id()) :: map()
- def empty_state(userid, recipient_id, match_id) do
- badge_types = AccoladeLib.get_badge_types()
-
- %{
- bot_id: AccoladeLib.get_accolade_bot_userid(),
- badge_types: badge_types,
- userid: userid,
- user: Account.get_user_by_id(userid),
- recipient_id: recipient_id,
- recipient: Account.get_user_by_id(recipient_id),
- match_id: match_id,
- stage: :not_started
- }
- end
-
- def handle_call(:ping, _from, state) do
- {:reply, :ok, state}
- end
-
- # Doesn't do anything at this stage
- def handle_info(:startup, state) do
- new_state = do_tick(state)
- :timer.send_after(@chat_timeout, :self_terminate)
- {:noreply, new_state}
- end
-
- # Handling user messages
- def handle_info({:user_message, message}, %{stage: :awaiting_choice} = state) do
- integer_choice =
- case message |> String.trim() |> Integer.parse() do
- :error -> :error
- {v, _rest} -> v
- end
-
- new_state =
- cond do
- String.downcase(message) == "n" ->
- Account.create_accolade(%{
- recipient_id: state.recipient_id,
- giver_id: state.userid,
- match_id: state.match_id,
- inserted_at: Timex.now()
- })
-
- increment_miss_count(state.userid, 3)
-
- CacheUser.send_direct_message(
- state.bot_id,
- state.userid,
- "Thank you for your feedback, no Accolade will be bestowed."
- )
-
- send(self(), :terminate)
- %{state | stage: :completed}
-
- integer_choice == 0 ->
- increment_miss_count(state.userid, 3)
-
- CacheUser.send_direct_message(
- state.bot_id,
- state.userid,
- "Thank you for your feedback, no Accolade will be bestowed."
- )
-
- send(self(), :terminate)
- %{state | stage: :completed}
-
- integer_choice != :error ->
- badge_type =
- state.badge_types
- |> Enum.filter(fn {i, _badge_type} -> i == integer_choice end)
-
- case badge_type do
- [] ->
- CacheUser.send_direct_message(
- state.bot_id,
- state.userid,
- "None of the listed Accolades match that option"
- )
-
- state
-
- [{_index, selected_type}] ->
- Account.create_accolade(%{
- recipient_id: state.recipient_id,
- giver_id: state.userid,
- badge_type_id: selected_type.id,
- match_id: state.match_id,
- inserted_at: Timex.now()
- })
-
- if Config.get_site_config_cache("teiserver.Inform of new accolades") do
- bot_pid = AccoladeLib.get_accolade_bot_pid()
- :timer.send_after(30_000, bot_pid, {:new_accolade, state.recipient_id})
- end
-
- decrement_miss_count(state.userid, 5)
-
- CacheUser.send_direct_message(
- state.bot_id,
- state.userid,
- "Thank you for your feedback, this Accolade will be bestowed."
- )
-
- send(self(), :terminate)
- %{state | stage: :completed}
- end
-
- :error ->
- CacheUser.send_direct_message(
- state.bot_id,
- state.userid,
- "I'm sorry but I can't pick an Accolade based on that value"
- )
-
- state
- end
-
- {:noreply, new_state}
- end
-
- def handle_info(:self_terminate, state) do
- increment_miss_count(state.userid, 10)
-
- send(self(), :terminate)
- {:noreply, state}
- end
-
- def handle_info(:terminate, state) do
- DynamicSupervisor.terminate_child(Teiserver.Account.AccoladeSupervisor, self())
- {:stop, :normal, %{state | userid: nil}}
- end
-
- def terminate(_reason, _state) do
- :ok
- end
-
- @spec do_tick(map()) :: map()
- defp do_tick(state) do
- case state.stage do
- :not_started -> send_initial_message(state)
- end
- end
-
- defp decrement_miss_count(userid, amount) do
- stats = Account.get_user_stat_data(userid)
- accolade_miss_count = Map.get(stats, "accolade_miss_count", 0)
-
- Account.update_user_stat(userid, %{
- "accolade_miss_count" => max(accolade_miss_count - amount, 0)
- })
- end
-
- defp increment_miss_count(userid, amount) do
- stats = Account.get_user_stat_data(userid)
- accolade_miss_count = Map.get(stats, "accolade_miss_count", 0)
-
- Account.update_user_stat(userid, %{
- "accolade_miss_count" =>
- min(max(accolade_miss_count + amount, 0), AccoladeBotServer.max_miss_count())
- })
- end
-
- @spec send_initial_message(map()) :: map()
- defp send_initial_message(state) do
- badge_lines =
- state.badge_types
- |> Enum.map(fn {i, bt} -> "#{i} - #{bt.name}, #{bt.description}" end)
-
- CacheUser.send_direct_message(
- state.bot_id,
- state.userid,
- [
- @line_break,
- "You have an opportunity to leave feedback on one of the players in your last game. We have selected #{state.recipient.name}",
- "Which of the following accolades do you feel they most deserve (if any)?",
- "N - No accolade for this player at all",
- "0 - No accolade this time, ask again later"
- ] ++
- badge_lines ++
- [
- ".",
- "Reply to this message with the number corresponding to the Accolade you feel is most appropriate for this player for this match."
- ]
- )
-
- %{state | stage: :awaiting_choice}
- end
-
- @spec init(map()) :: {:ok, map()}
- def init(opts) do
- userid = opts[:userid]
- recipient_id = opts[:recipient_id]
- match_id = opts[:match_id]
-
- # Update the queue pids cache to point to this process
- Horde.Registry.register(
- Teiserver.AccoladesRegistry,
- "AccoladeChatServer:#{userid}",
- userid
- )
-
- # :timer.send_interval(10_000, :tick)
- send(self(), :startup)
- {:ok, empty_state(userid, recipient_id, match_id)}
- end
-end
diff --git a/lib/teiserver/account/libs/accolade_lib.ex b/lib/teiserver/account/libs/accolade_lib.ex
index 5f81a0732..e622e84d0 100644
--- a/lib/teiserver/account/libs/accolade_lib.ex
+++ b/lib/teiserver/account/libs/accolade_lib.ex
@@ -4,8 +4,6 @@ defmodule Teiserver.Account.AccoladeLib do
alias Ecto.Adapters.SQL
alias Teiserver.Account
alias Teiserver.Account.Accolade
- alias Teiserver.Account.AccoladeBotServer
- alias Teiserver.Account.AccoladeChatServer
alias Teiserver.CacheUser
alias Teiserver.Data.Types, as: T
use TeiserverWeb, :library
@@ -195,88 +193,6 @@ defmodule Teiserver.Account.AccoladeLib do
preload: [giver: givers]
end
- @spec do_start() :: :ok
- defp do_start do
- # Start the supervisor server
- {:ok, _accolade_server_pid} =
- DynamicSupervisor.start_child(Teiserver.Account.AccoladeSupervisor, {
- AccoladeBotServer,
- name: Teiserver.Account.AccoladeBotServer, data: %{}
- })
-
- :ok
- end
-
- @spec start_accolade_server() :: :ok | {:failure, String.t()}
- def start_accolade_server do
- if is_nil(get_accolade_bot_userid()) do
- do_start()
- else
- {:failure, "Already started"}
- end
- end
-
- @spec cast_accolade_bot(any) :: any
- def cast_accolade_bot(msg) do
- case get_accolade_bot_pid() do
- nil -> nil
- pid -> send(pid, msg)
- end
- end
-
- @spec call_accolade_bot(any) :: any
- def call_accolade_bot(msg) do
- case get_accolade_bot_pid() do
- nil ->
- nil
-
- pid ->
- try do
- GenServer.call(pid, msg)
-
- # If the process has somehow died, we just return nil
- catch
- :exit, _reason ->
- nil
- end
- end
- end
-
- @spec get_accolade_bot_userid() :: T.userid() | nil
- def get_accolade_bot_userid do
- Teiserver.cache_get(:application_metadata_cache, "teiserver_accolade_userid")
- end
-
- @spec get_accolade_bot_pid() :: pid() | nil
- def get_accolade_bot_pid do
- case Horde.Registry.lookup(Teiserver.AccoladesRegistry, "AccoladeBotServer") do
- [{pid, _value}] ->
- pid
-
- _other ->
- nil
- end
- end
-
- @spec get_accolade_chat_pid(T.userid()) :: pid() | nil
- def get_accolade_chat_pid(userid) do
- case Horde.Registry.lookup(Teiserver.AccoladesRegistry, "AccoladeChatServer:#{userid}") do
- [{pid, _value}] ->
- pid
-
- _other ->
- nil
- end
- end
-
- @spec cast_accolade_chat(T.userid(), any) :: any
- def cast_accolade_chat(userid, msg) do
- case get_accolade_chat_pid(userid) do
- nil -> nil
- pid -> send(pid, msg)
- end
- end
-
@spec get_possible_ratings(T.userid(), [map()]) :: any
def get_possible_ratings(userid, memberships) do
their_membership = Enum.filter(memberships, fn m -> m.user_id == userid end) |> hd()
@@ -317,33 +233,6 @@ defmodule Teiserver.Account.AccoladeLib do
end
end
- @spec start_chat_server(T.userid(), T.userid(), T.lobby_id()) :: pid()
- def start_chat_server(userid, recipient_id, match_id) do
- {:ok, chat_server_pid} =
- DynamicSupervisor.start_child(Teiserver.Account.AccoladeSupervisor, {
- AccoladeChatServer,
- name: "accolade_chat_#{userid}",
- data: %{
- userid: userid,
- recipient_id: recipient_id,
- match_id: match_id
- }
- })
-
- chat_server_pid
- end
-
- @spec start_accolade_process(T.userid(), T.userid(), T.lobby_id()) :: :ok | :existing
- def start_accolade_process(userid, recipient_id, match_id) do
- case get_accolade_chat_pid(userid) do
- nil ->
- start_chat_server(userid, recipient_id, match_id)
-
- _pid ->
- :existing
- end
- end
-
@spec get_badge_types() :: [{non_neg_integer(), map()}]
def get_badge_types do
Teiserver.cache_get_or_store(:application_temp_cache, "accolade_badges", fn ->
@@ -388,46 +277,6 @@ order by name;"
|> Map.new(fn {k, v} -> {k, Enum.count(v)} end)
end
- @spec live_debug :: nil | :ok
- def live_debug do
- case get_accolade_bot_pid() do
- nil ->
- Logger.error("Error, no accolade bot pid")
-
- pid ->
- state = :sys.get_state(pid)
- children = DynamicSupervisor.which_children(Teiserver.Account.AccoladeSupervisor)
- child_count = Enum.count(children) - 1
-
- Logger.info("Accolade bot found, state is:")
- Logger.info("#{Kernel.inspect(state)}")
- Logger.info("Accolade chat count: #{child_count}")
-
- if Enum.count(children) > 1 do
- Logger.info("Pinging all chat servers...")
-
- pings =
- children
- |> ParallelStream.filter(fn {_id, _child, _type, [module]} ->
- module == Teiserver.Account.AccoladeChatServer
- end)
- |> ParallelStream.map(fn {_id, pid, _type, _modules} ->
- case GenServer.call(pid, :ping, 5000) do
- :ok -> :ok
- _other -> :not_okay
- end
- end)
- |> Enum.filter(fn p -> p == :ok end)
-
- rate = (Enum.count(pings) / child_count * 100) |> round()
-
- Logger.info(
- "Out of #{child_count} children, #{Enum.count(pings)} respond to ping (#{rate}%)"
- )
- end
- end
- end
-
def get_number_of_gifted_accolades(user_id, window_days) do
query = """
select count(*) from teiserver_account_accolades taa
diff --git a/lib/teiserver/account/libs/role_lib.ex b/lib/teiserver/account/libs/role_lib.ex
index 83988fff6..91f5c6e94 100644
--- a/lib/teiserver/account/libs/role_lib.ex
+++ b/lib/teiserver/account/libs/role_lib.ex
@@ -97,12 +97,11 @@ defmodule Teiserver.Account.RoleLib do
# Privileged
%{name: "VIP", colour: "#AA8833", icon: "fa-solid fa-sparkles", contains: ~w()},
%{name: "Streamer", colour: "#660066", icon: "fa-brands fa-twitch", contains: ~w()},
- %{name: "Tournament", colour: "#0000AA", icon: "fa-solid fa-trophy", contains: ~w()},
%{
name: "Caster",
colour: "#660066",
icon: "fa-solid fa-microphone-lines",
- contains: ~w(Streamer Tournament),
+ contains: ~w(Streamer),
badge: true
},
%{name: "Donor", colour: "#0066AA", icon: "fa-solid fa-euro", contains: ~w(), badge: true},
@@ -277,7 +276,7 @@ defmodule Teiserver.Account.RoleLib do
@spec privileged_roles :: [String.t()]
def privileged_roles do
- ~w(Bot VIP Caster Donor Tournament)
+ ~w(Bot VIP Caster Donor)
end
@spec property_roles :: [String.t()]
diff --git a/lib/teiserver/account/queries/user_queries.ex b/lib/teiserver/account/queries/user_queries.ex
index 8bfd64807..1a38a0052 100644
--- a/lib/teiserver/account/queries/user_queries.ex
+++ b/lib/teiserver/account/queries/user_queries.ex
@@ -354,16 +354,6 @@ defmodule Teiserver.Account.UserQueries do
where: fragment("not ? -> ? @> ?", users.data, "roles", "\"Caster\"")
end
- def _where(query, :tournament_player, "Player") do
- from users in query,
- where: fragment("? -> ? @> ?", users.data, "roles", "\"Tournament player\"")
- end
-
- def _where(query, :tournament_player, "Normal") do
- from users in query,
- where: fragment("not ? -> ? @> ?", users.data, "roles", "\"Tournament player\"")
- end
-
def _where(query, :vip, "VIP") do
from users in query,
where: fragment("? -> ? @> ?", users.data, "roles", "\"VIP\"")
diff --git a/lib/teiserver/account/reports/tournament_report.ex b/lib/teiserver/account/reports/tournament_report.ex
deleted file mode 100644
index 0c45da552..000000000
--- a/lib/teiserver/account/reports/tournament_report.ex
+++ /dev/null
@@ -1,268 +0,0 @@
-defmodule Teiserver.Account.TournamentReport do
- @moduledoc false
- alias Teiserver.Account
- alias Teiserver.Account.RatingLib
- alias Teiserver.Game.MatchRatingLib
- alias Teiserver.Helper.TimexHelper
- import Teiserver.Helper.NumberHelper, only: [round: 2]
-
- @spec icon() :: String.t()
- def icon, do: RatingLib.icon()
-
- @spec permissions() :: String.t()
- def permissions, do: "Moderator"
-
- defp get_player_id("#" <> id_str), do: String.to_integer(id_str)
-
- defp get_player_id(name) do
- Account.get_userid_from_name(name)
- end
-
- @spec make_split_data(String.t()) :: %{non_neg_integer => {String.t(), non_neg_integer()}}
- defp make_split_data(data) do
- data
- |> String.trim()
- |> String.split("\n")
- |> Enum.with_index()
- |> Map.new(fn {row, team_idx} ->
- id_map =
- row
- |> String.split(",")
- |> Enum.map(&String.trim/1)
- |> Enum.filter(fn
- "" -> false
- _name -> true
- end)
- |> Enum.map(fn name ->
- {String.trim(name), get_player_id(name)}
- end)
- |> Enum.reject(fn {_name, n} -> n == nil end)
-
- {team_idx, id_map}
- end)
- end
-
- @spec run(Plug.Conn.t(), map()) :: {nil, map()}
- def run(_conn, params) do
- params = apply_defaults(params)
-
- # First we take our lines and break them into teams
- split_data = make_split_data(params["names"] || "")
-
- name_to_id_map =
- split_data
- |> Map.values()
- |> List.flatten()
- |> Map.new()
-
- missing_names =
- (params["names"] || "")
- |> String.trim()
- |> String.replace(",", "\n")
- |> String.split("\n")
- |> Enum.map(&String.trim/1)
- |> Enum.reject(fn name ->
- Map.has_key?(name_to_id_map, name)
- end)
-
- if params["make_players"] == "true" do
- id_list = name_to_id_map |> Map.values() |> Enum.reject(&(&1 == nil))
-
- Account.list_users(
- search: [id_in: id_list],
- limit: Enum.count(id_list)
- )
- |> Enum.each(fn user ->
- new_roles = ["Tournament" | user.roles || []] |> Enum.uniq()
- new_data = user.data |> Map.put("roles", new_roles)
-
- Account.update_user(user, %{"data" => new_data})
- Account.recache_user(user.id)
- end)
-
- :timer.sleep(500)
- end
-
- type_name = params["game_type"]
-
- {type_id, _type_name} =
- case MatchRatingLib.rating_type_name_lookup()[type_name] do
- nil ->
- type_name = hd(MatchRatingLib.rating_type_list())
- {MatchRatingLib.rating_type_name_lookup()[type_name], type_name}
-
- v ->
- {v, type_name}
- end
-
- order_by =
- case params["value_type"] do
- "Leaderboard rating" -> "Leaderboard rating high to low"
- "Game rating" -> "Rating value high to low"
- "Skill value" -> "Skill high to low"
- end
-
- ratings =
- Account.list_ratings(
- search: [
- rating_type_id: type_id,
- user_id_in: Map.values(name_to_id_map),
- season: MatchRatingLib.active_season()
- ],
- order_by: order_by,
- preload: [:user],
- limit: Enum.count(name_to_id_map)
- )
-
- found_ids =
- ratings
- |> Enum.map(fn r -> r.user_id end)
-
- no_ratings =
- name_to_id_map
- |> Enum.reject(fn {_name, id} -> id == nil or Enum.member?(found_ids, id) end)
- |> Map.new()
- |> Map.keys()
-
- teams_as_ids =
- split_data
- |> Map.values()
- |> Enum.map_join("\n", fn team_data ->
- team_data
- |> Enum.map_join(", ", fn {_name, id} -> "##{id}" end)
- end)
-
- rating_values =
- ratings
- |> Map.new(fn rating ->
- value =
- case params["value_type"] do
- "Leaderboard rating" -> rating.leaderboard_rating
- "Game rating" -> rating.rating_value
- "Skill value" -> rating.skill
- end
-
- {rating.user_id, value}
- end)
-
- %{
- params: params,
- name_to_id_map: name_to_id_map,
- game_types: MatchRatingLib.rating_type_list(),
- no_ratings: no_ratings,
- ratings: ratings,
- missing_names: missing_names,
- teams_as_ids: teams_as_ids,
- team_data: make_team_data(split_data, rating_values),
- csv_data: make_csv_data(ratings, params["value_type"])
- }
- end
-
- defp make_team_data(split_data, rating_values) do
- split_data
- |> Map.new(fn {team_id, members} ->
- name_rating_pairs =
- members
- |> Enum.map(fn {name, userid} -> {name, rating_values[userid]} end)
- |> Enum.reject(fn {_name, rating} -> rating == nil end)
-
- aggregate_data =
- name_rating_pairs
- |> Enum.map(fn {_name, rating} -> rating end)
- |> aggregate_team_ratings()
-
- captain =
- name_rating_pairs
- |> Enum.sort_by(fn {_name, rating} -> rating end, &>=/2)
- |> Enum.take(1)
-
- aggregate_data =
- case captain do
- [{name, rating}] ->
- Map.merge(aggregate_data, %{
- captain_name: name,
- captain_rating: rating |> round(2)
- })
-
- _other ->
- aggregate_data
- end
-
- {team_id, aggregate_data}
- end)
- end
-
- defp aggregate_team_ratings([]) do
- %{
- mean: 0,
- median: 0,
- stdev: 0,
- count: 0,
- max: 0,
- min: 0,
- captain_name: "",
- captain_rating: 0
- }
- end
-
- defp aggregate_team_ratings(ratings) do
- %{
- mean: Statistics.mean(ratings) |> round(2),
- median: Statistics.median(ratings) |> round(2),
- stdev: Statistics.stdev(ratings) |> round(2),
- count: Enum.count(ratings),
- max: Enum.max(ratings) |> round(2),
- min: Enum.min(ratings) |> round(2),
- captain_name: "",
- captain_rating: 0
- }
- end
-
- defp add_csv_headings(output, value_type) do
- headings = [
- [
- "Position",
- "UserId",
- "Player",
- "Registration date",
- value_type
- ]
- ]
-
- headings ++ output
- end
-
- defp make_csv_data(ratings, value_type) do
- ratings
- |> Enum.with_index()
- |> Enum.map(fn {rating, index} ->
- value =
- case value_type do
- "Leaderboard rating" -> rating.leaderboard_rating
- "Game rating" -> rating.rating_value
- "Skill value" -> rating.skill
- end
-
- [
- index + 1,
- rating.user.id,
- rating.user.name,
- TimexHelper.date_to_str(rating.user.inserted_at, format: :ymd),
- value
- ]
- end)
- |> add_csv_headings(value_type)
- |> CSV.encode(separator: ?\t)
- |> Enum.to_list()
- end
-
- defp apply_defaults(params) do
- Map.merge(
- %{
- "game_type" => MatchRatingLib.rating_type_list() |> hd(),
- "value_type" => "Leaderboard rating"
- },
- Map.get(params, "report", %{})
- )
- end
-end
diff --git a/lib/teiserver/account/schemas/accolade.ex b/lib/teiserver/account/schemas/accolade.ex
index 2b47a2c5e..ee96170c6 100644
--- a/lib/teiserver/account/schemas/accolade.ex
+++ b/lib/teiserver/account/schemas/accolade.ex
@@ -1,5 +1,8 @@
defmodule Teiserver.Account.Accolade do
- @moduledoc false
+ @moduledoc """
+ Accolade struct
+ """
+
use TeiserverWeb, :schema
typed_schema "teiserver_account_accolades" do
diff --git a/lib/teiserver/application.ex b/lib/teiserver/application.ex
index 4c41e3ec6..622fdf172 100644
--- a/lib/teiserver/application.ex
+++ b/lib/teiserver/application.ex
@@ -69,7 +69,6 @@ defmodule Teiserver.Application do
# Global/singleton registries
{Horde.Registry, [keys: :unique, members: :auto, name: Teiserver.ServerRegistry]},
{Horde.Registry, [keys: :unique, members: :auto, name: Teiserver.ThrottleRegistry]},
- {Horde.Registry, [keys: :unique, members: :auto, name: Teiserver.AccoladesRegistry]},
{Horde.Registry, [keys: :unique, members: :auto, name: Teiserver.ConsulRegistry]},
{Horde.Registry, [keys: :unique, members: :auto, name: Teiserver.BalancerRegistry]},
{Horde.Registry, [keys: :unique, members: :auto, name: Teiserver.LobbyRegistry]},
@@ -150,9 +149,6 @@ defmodule Teiserver.Application do
{DynamicSupervisor,
strategy: :one_for_one, name: Teiserver.Coordinator.BalancerDynamicSupervisor},
- # Accolades
- {DynamicSupervisor, strategy: :one_for_one, name: Teiserver.Account.AccoladeSupervisor},
-
# Achievements
{Teiserver.Game.AchievementServer, name: Teiserver.Game.AchievementServer},
diff --git a/lib/teiserver/battle.ex b/lib/teiserver/battle.ex
index cdd8eb89a..793b1fcc6 100644
--- a/lib/teiserver/battle.ex
+++ b/lib/teiserver/battle.ex
@@ -310,26 +310,6 @@ defmodule Teiserver.Battle do
Match.changeset(match, %{})
end
- # Not to be confused with protocol related adding, this
- # tells the battle lobby to proceed as if the user was just accepted into
- # the battle. It should never be called directly from a protocol
- # related command, only via things like matchmaking our tourneys
- # It is currently not actually used so might be ripe for removal
- # @spec add_player_to_battle(T.userid(), T.lobby_id()) :: :ok | {:error, String.t()}
- # def add_player_to_battle(userid, lobby_id) do
- # case Teiserver.Client.get_client_by_id(userid) do
- # nil ->
- # {:error, "no client"}
- # _ ->
- # case lobby_exists?(lobby_id) do
- # false ->
- # {:error, "no battle"}
- # true ->
- # Teiserver.Lobby.accept_join_request(userid, lobby_id)
- # end
- # end
- # end
-
@spec start_match(nil | T.lobby_id()) :: :ok
def start_match(nil), do: :ok
diff --git a/lib/teiserver/battle/tasks/battle_daily_cleanup_task.ex b/lib/teiserver/battle/tasks/battle_daily_cleanup_task.ex
index 8a6e11880..fd00f2692 100644
--- a/lib/teiserver/battle/tasks/battle_daily_cleanup_task.ex
+++ b/lib/teiserver/battle/tasks/battle_daily_cleanup_task.ex
@@ -141,13 +141,6 @@ defmodule Teiserver.Battle.Tasks.CleanupTask do
[ids]
)
- # Update report groups
- SQL.query!(
- Repo,
- "UPDATE moderation_report_groups SET match_id = NULL WHERE match_id = ANY($1)",
- [ids]
- )
-
# Match specific things we want to delete
SQL.query!(
Repo,
diff --git a/lib/teiserver/bridge/commands/post_command.ex b/lib/teiserver/bridge/commands/post_command.ex
new file mode 100644
index 000000000..289cab031
--- /dev/null
+++ b/lib/teiserver/bridge/commands/post_command.ex
@@ -0,0 +1,124 @@
+defmodule Teiserver.Bridge.Commands.PostCommand do
+ @moduledoc """
+ Calls the bot to post report or action in current channel
+ """
+ alias Teiserver.Account
+ alias Teiserver.Bridge.DiscordBridgeBot
+ alias Teiserver.Communication
+ alias Teiserver.Config
+ alias Teiserver.Moderation
+ alias Teiserver.Moderation.ActionLib
+ require Logger
+
+ @behaviour Teiserver.Bridge.BridgeCommandBehaviour
+
+ @impl Teiserver.Bridge.BridgeCommandBehaviour
+ @spec name() :: String.t()
+ def name, do: "post"
+
+ @impl Teiserver.Bridge.BridgeCommandBehaviour
+ @spec cmd_definition() :: map()
+ def cmd_definition do
+ %{
+ name: "post",
+ description: "Post something into the current channel",
+ options: [
+ %{
+ # type = sub_command
+ type: 1,
+ name: "report",
+ description: "Post a report",
+ required: true,
+ options: [
+ %{
+ name: "id",
+ description: "ID of the report",
+ type: 4,
+ required: true
+ }
+ ]
+ },
+ %{
+ type: 1,
+ name: "action",
+ description: "Post an Action",
+ required: true,
+ options: [
+ %{
+ name: "id",
+ description: "ID of the action",
+ type: 4,
+ required: true
+ }
+ ]
+ },
+ %{
+ type: 1,
+ name: "profile",
+ description: "Post the link of a moderation profile",
+ required: true,
+ options: [
+ %{
+ name: "name",
+ description: "Name of the Account",
+ type: 3,
+ required: true
+ }
+ ]
+ }
+ ],
+ nsfw: false
+ }
+ end
+
+ @impl Teiserver.Bridge.BridgeCommandBehaviour
+ @spec execute(interaction :: Nostrum.Struct.Interaction.t(), options_map :: map()) :: map()
+ def execute(interaction, _options_map) do
+ subcommand = Enum.at(interaction.data.options, 0)
+ args = Enum.at(subcommand.options, 0)
+
+ content =
+ case subcommand.name do
+ "action" ->
+ case Moderation.get_action(args.value) do
+ nil ->
+ "No action with ID \"#{args.value}\" found"
+
+ action ->
+ channel_id =
+ Config.get_site_config_cache("teiserver.Discord channel #moderation-actions")
+
+ ActionLib.generate_discord_message_text(action) <>
+ "\n**Original:** https://discord.com/channels/#{Communication.get_guild_id()}/#{channel_id}/#{action.discord_message_id}"
+ end
+
+ "report" ->
+ case Moderation.get_report(args.value, preload: [:reporter, :target]) do
+ nil ->
+ "No report with ID \"#{args.value}\" found"
+
+ report ->
+ DiscordBridgeBot.get_report_message(report)
+ |> List.delete_at(-1)
+ |> List.insert_at(
+ -1,
+ "**Original:** https://discord.com/channels/#{Communication.get_guild_id()}/#{DiscordBridgeBot.get_channel_for_report_type(report.type)}/#{report.discord_message_id}"
+ )
+ |> Enum.join("\n")
+ end
+
+ "profile" ->
+ name = args.value
+
+ case Account.get_user_by_name(name) do
+ nil ->
+ "User \"#{name}\" not found"
+
+ user ->
+ "https://#{Application.get_env(:teiserver, TeiserverWeb.Endpoint)[:url][:host]}/moderation/report/user/#{user.id}"
+ end
+ end
+
+ Communication.new_interaction_response(content)
+ end
+end
diff --git a/lib/teiserver/bridge/discord_bridge_bot.ex b/lib/teiserver/bridge/discord_bridge_bot.ex
index 84d6a31c2..420735e53 100644
--- a/lib/teiserver/bridge/discord_bridge_bot.ex
+++ b/lib/teiserver/bridge/discord_bridge_bot.ex
@@ -93,7 +93,6 @@ defmodule Teiserver.Bridge.DiscordBridgeBot do
# Stuff we might want to use
def handle_event({:MESSAGE_CREATE, _message, _ws}) do
- # Has an attachment
:ignore
end
@@ -123,6 +122,10 @@ defmodule Teiserver.Bridge.DiscordBridgeBot do
:ignore
end
+ def handle_event({:CHANNEL_CREATE, _channel, _ws}) do
+ :ignore
+ end
+
def handle_event({:CHANNEL_UPDATE, _channel, _ws}) do
:ignore
end
@@ -158,6 +161,7 @@ defmodule Teiserver.Bridge.DiscordBridgeBot do
BridgeServer.cast_bridge(:READY)
add_command(:textcb)
add_command(:findreport)
+ add_command(:post)
:ignore
end
@@ -205,6 +209,60 @@ defmodule Teiserver.Bridge.DiscordBridgeBot do
ApplicationCommand.create_guild_command(Communication.get_guild_id(), command)
end
+ # Teiserver.Bridge.DiscordBridgeBot.add_command(:post)
+ @spec add_command(atom) :: any
+ def add_command(:post) do
+ command = %{
+ name: "post",
+ description: "Post something into the current channel",
+ options: [
+ %{
+ # type = sub_command
+ type: 1,
+ name: "report",
+ description: "Post a report",
+ options: [
+ %{
+ name: "id",
+ description: "ID of the report",
+ type: 4,
+ required: true
+ }
+ ]
+ },
+ %{
+ type: 1,
+ name: "action",
+ description: "Post an Action",
+ options: [
+ %{
+ name: "id",
+ description: "ID of the action",
+ type: 4,
+ required: true
+ }
+ ]
+ },
+ %{
+ type: 1,
+ name: "profile",
+ description: "Post the link of a moderation profile",
+ options: [
+ %{
+ name: "name",
+ description: "Name of the Account",
+ type: 3,
+ required: true
+ }
+ ]
+ }
+ ],
+ nsfw: false
+ }
+
+ ApplicationCommand.create_guild_command(Communication.get_guild_id(), command)
+ end
+
# Teiserver.Bridge.DiscordBridgeBot.add_command(:textcb)
@spec add_command(atom) :: any
def add_command(:textcb) do
@@ -300,29 +358,57 @@ defmodule Teiserver.Bridge.DiscordBridgeBot do
end
end
+ def get_report_message(report) do
+ host = Application.get_env(:teiserver, TeiserverWeb.Endpoint)[:url][:host]
+ url = "https://#{host}/moderation/report?target_id=#{report.target_id}"
+
+ match_icon =
+ if is_nil(report.match_id) do
+ ""
+ else
+ ":crossed_swords:"
+ end
+
+ [
+ "# [Moderation report #{report.type}/#{report.sub_type}](#{url})#{match_icon}",
+ "**Target:** [#{report.target.name}](https://#{host}/moderation/report/user/#{report.target.id})",
+ "**Reporter:** [#{report.reporter.name}](https://#{host}/moderation/report/user/#{report.reporter.id})",
+ "**Reason:** #{format_link(report.extra_text)}"
+ ] ++
+ cond do
+ not is_nil(report.result_id) ->
+ ["**Status:** Actioned :hammer:"]
+
+ report.closed == true ->
+ ["**Status:** Closed :file_folder:"]
+
+ true ->
+ ["**Status:** Open"]
+ end
+ end
+
+ def get_channel_for_report_type(type) do
+ case type do
+ "actions" ->
+ Config.get_site_config_cache("teiserver.Discord channel #overwatch-reports")
+
+ "chat" ->
+ Config.get_site_config_cache("teiserver.Discord channel #moderation-reports")
+
+ _other ->
+ Logger.error("Unknown report type #{type}")
+ raise "Unknown report type #{type}"
+ end
+ end
+
# Teiserver.Moderation.get_report!(123) |> Teiserver.Bridge.DiscordBridgeBot.new_report()
@spec new_report(Moderation.Report.t()) :: any
def new_report(report) do
- channel =
- if report.type == "actions" do
- Config.get_site_config_cache("teiserver.Discord channel #overwatch-reports")
- else
- Config.get_site_config_cache("teiserver.Discord channel #moderation-reports")
- end
+ channel = get_channel_for_report_type(report.type)
if channel do
report = Moderation.get_report!(report.id, preload: [:reporter, :target])
- host = Application.get_env(:teiserver, TeiserverWeb.Endpoint)[:url][:host]
- url = "https://#{host}/moderation/report?target_id=#{report.target_id}"
-
- match_icon =
- if is_nil(report.match_id) do
- ""
- else
- ":crossed_swords:"
- end
-
outstanding_count =
Moderation.list_outstanding_reports_against_user(report.target_id)
|> Enum.count()
@@ -339,14 +425,7 @@ defmodule Teiserver.Bridge.DiscordBridgeBot do
""
end
- msg =
- [
- "# [Moderation report #{report.type}/#{report.sub_type}](#{url})#{match_icon}",
- "**Target:** [#{report.target.name}](https://#{host}/moderation/report/user/#{report.target.id})",
- "**Reporter:** [#{report.reporter.name}](https://#{host}/moderation/report/user/#{report.reporter.id})",
- "**Reason:** #{format_link(report.extra_text)}",
- "**Status:** Open"
- ]
+ msg = get_report_message(report)
reports =
if is_nil(report.match_id) do
diff --git a/lib/teiserver/coordinator/consul_commands.ex b/lib/teiserver/coordinator/consul_commands.ex
index 98083b430..7f47d1fa0 100644
--- a/lib/teiserver/coordinator/consul_commands.ex
+++ b/lib/teiserver/coordinator/consul_commands.ex
@@ -9,7 +9,6 @@ defmodule Teiserver.Coordinator.ConsulCommands do
alias Teiserver.CacheUser
alias Teiserver.Chat.WordLib
alias Teiserver.Client
- alias Teiserver.Config
alias Teiserver.Coordinator
alias Teiserver.Coordinator.ConsulServer
alias Teiserver.Coordinator.RikerssMemes
@@ -86,11 +85,6 @@ defmodule Teiserver.Coordinator.ConsulCommands do
"Host bosses are: #{boss_names}"
end
- tourney_mode =
- if state.tournament_lobby do
- "Tournament mode is enabled"
- end
-
# Party info
parties =
Battle.list_lobby_players(state.lobby_id)
@@ -131,7 +125,6 @@ defmodule Teiserver.Coordinator.ConsulCommands do
"Team size and count are: #{state.host_teamsize} and #{state.host_teamcount}",
"Balance algorithm is: #{state.balance_algorithm}",
boss_string,
- tourney_mode,
"Maximum allowed number of players is #{max_player_count} (Host = #{state.host_teamsize * state.host_teamcount}, Coordinator = #{state.player_limit})",
play_level_bounds,
play_rank_bounds
@@ -238,49 +231,6 @@ defmodule Teiserver.Coordinator.ConsulCommands do
state
end
- def handle_command(%{command: "tournament", senderid: senderid, remaining: rem} = cmd, state) do
- if Config.get_site_config_cache("teiserver.Allow tournament command") do
- if Auth.has_any_role?(senderid, [
- "Moderator",
- "Caster",
- "Tournament player",
- "TourneyPlayer"
- ]) do
- if rem |> String.trim() |> String.downcase() == "off" do
- Battle.update_lobby_values(state.lobby_id, %{tournament: false})
- state = %{state | tournament_lobby: false}
- ConsulServer.say_command(cmd, state)
- else
- Battle.update_lobby_values(state.lobby_id, %{tournament: true})
- # ChatLib.say(senderid, "!preset tourney", state.lobby_id)
- send(self(), :recheck_membership)
- state = %{state | tournament_lobby: true}
- ConsulServer.say_command(cmd, state)
- end
- else
- ChatLib.sayprivateex(
- state.coordinator_id,
- senderid,
- "Only casters, tournament players and moderators can set tournament mode.",
- state.lobby_id
- )
-
- state
- end
- else
- Battle.update_lobby_values(state.lobby_id, %{tournament: false})
-
- ChatLib.sayprivateex(
- state.coordinator_id,
- senderid,
- "Tournament mode has been removed from this lobby.",
- state.lobby_id
- )
-
- %{state | tournament_lobby: false}
- end
- end
-
def handle_command(%{command: "afks", senderid: senderid} = cmd, state) do
min_diff_ms = 20_000
max_diff_s = 300
diff --git a/lib/teiserver/coordinator/consul_server.ex b/lib/teiserver/coordinator/consul_server.ex
index 0247f0033..5b808c38b 100644
--- a/lib/teiserver/coordinator/consul_server.ex
+++ b/lib/teiserver/coordinator/consul_server.ex
@@ -28,7 +28,7 @@ defmodule Teiserver.Coordinator.ConsulServer do
require Logger
import Teiserver.Helper.NumberHelper, only: [int_parse: 1]
- @always_allow ~w(status s y n follow joinq leaveq splitlobby afks roll password? tournament)
+ @always_allow ~w(status s y n follow joinq leaveq splitlobby afks roll password?)
@boss_commands ~w(balancealgorithm gatekeeper welcome-message meme reset-approval rename minchevlevel maxchevlevel resetchevlevels resetratinglevels minratinglevel maxratinglevel setratinglevels)
@host_commands ~w(specunready makeready settag speclock forceplay lobbyban lobbybanmult unban forcespec lock unlock makebalance set-config-teaser)
@admin_commands ~w(shuffle)
@@ -76,7 +76,7 @@ defmodule Teiserver.Coordinator.ConsulServer do
def handle_call(:get_chobby_extra_data, _from, state) do
keys =
- ~w(lobby_policy_id tournament_lobby gatekeeper minimum_rating_to_play maximum_rating_to_play minimum_rank_to_play maximum_rank_to_play minimum_uncertainty_to_play maximum_uncertainty_to_play minimum_skill_to_play maximum_skill_to_play welcome_message player_limit)a
+ ~w(lobby_policy_id gatekeeper minimum_rating_to_play maximum_rating_to_play minimum_rank_to_play maximum_rank_to_play minimum_uncertainty_to_play maximum_uncertainty_to_play minimum_skill_to_play maximum_skill_to_play welcome_message player_limit)a
result =
state
@@ -989,10 +989,6 @@ defmodule Teiserver.Coordinator.ConsulServer do
client.shadowbanned ->
{false, "Err"}
- state.tournament_lobby == true and
- not Auth.has_any_role?(userid, ["Caster", "TourneyPlayer", "Tournament player"]) ->
- {false, "Tournament game"}
-
block_status == :blocking ->
Telemetry.log_simple_lobby_event(userid, match_id, "join_refused.blocking")
{false, "You are blocking too many players in this lobby"}
@@ -1379,7 +1375,6 @@ defmodule Teiserver.Coordinator.ConsulServer do
lobby_id: lobby_id,
host_id: founder_id,
lobby_policy_id: nil,
- tournament_lobby: false,
gatekeeper: "default",
minimum_rating_to_play: 0,
maximum_rating_to_play: 1000,
diff --git a/lib/teiserver/game/servers/lobby_policy_bot_server.ex b/lib/teiserver/game/servers/lobby_policy_bot_server.ex
index 7ee644a43..a18f00238 100644
--- a/lib/teiserver/game/servers/lobby_policy_bot_server.ex
+++ b/lib/teiserver/game/servers/lobby_policy_bot_server.ex
@@ -164,7 +164,6 @@ defmodule Teiserver.Game.LobbyPolicyBotServer do
String.contains?(l.name, "ENGINE TEST") == false and
l.passworded == false and
l.locked == false and
- l.tournament == false and
l.in_progress == false and
not String.contains?(l.name, "ENGINE TEST")
end)
diff --git a/lib/teiserver/helpers/string_helper.ex b/lib/teiserver/helpers/string_helper.ex
index 1948b5045..d00652cdb 100644
--- a/lib/teiserver/helpers/string_helper.ex
+++ b/lib/teiserver/helpers/string_helper.ex
@@ -151,4 +151,14 @@ defmodule Teiserver.Helper.StringHelper do
|> String.split("\n")
|> Enum.map(&String.trim/1)
end
+
+ @doc """
+ Gets the domain from an email address. For example, "user@example.com"
+ would return "example.com".
+ """
+ @spec get_email_domain(String.t()) :: String.t()
+ def get_email_domain(email) do
+ [_first | rest] = String.split(email, "@")
+ Enum.join(rest, "")
+ end
end
diff --git a/lib/teiserver/libs/teiserver_configs.ex b/lib/teiserver/libs/teiserver_configs.ex
index 5b5118782..7852585b4 100644
--- a/lib/teiserver/libs/teiserver_configs.ex
+++ b/lib/teiserver/libs/teiserver_configs.ex
@@ -75,15 +75,6 @@ defmodule Teiserver.TeiserverConfigs do
default: true
})
- add_site_config_type(%{
- key: "teiserver.Inform of new accolades",
- section: "Accolades",
- type: "boolean",
- permissions: ["Server"],
- description: "When set to true, players will be informed when they get a new accolade",
- default: false
- })
-
add_site_config_type(%{
key: "teiserver.Accolade gift limit",
section: "Accolades",
@@ -338,16 +329,6 @@ defmodule Teiserver.TeiserverConfigs do
default: 10
})
- add_site_config_type(%{
- key: "teiserver.Allow tournament command",
- section: "Lobbies",
- type: "boolean",
- permissions: ["Admin"],
- description:
- "When set to true, the $tournament command will be able to be used. When disabled it can still be used but only to turn off tournament mode.",
- default: false
- })
-
add_site_config_type(%{
key: "teiserver.Default player limit",
section: "Lobbies",
diff --git a/lib/teiserver/lobby.ex b/lib/teiserver/lobby.ex
index 7dabb592b..8a79851df 100644
--- a/lib/teiserver/lobby.ex
+++ b/lib/teiserver/lobby.ex
@@ -108,7 +108,6 @@ defmodule Teiserver.Lobby do
lobby_policy_id: nil,
# Meta data
- tournament: false,
silence: false,
in_progress: false,
started_at: nil
diff --git a/lib/teiserver/lobby/schemas/lobby_struct.ex b/lib/teiserver/lobby/schemas/lobby_struct.ex
index 5e3cea327..b4c6d36ba 100644
--- a/lib/teiserver/lobby/schemas/lobby_struct.ex
+++ b/lib/teiserver/lobby/schemas/lobby_struct.ex
@@ -49,7 +49,6 @@ defmodule Teiserver.Lobby.LobbyStruct do
# External references
lobby_policy_id: nil,
queue_id: nil,
- tournament_id: nil,
# Consul server stuff
gatekeeper: "default",
diff --git a/lib/teiserver/lobby/servers/lobby_index_throttle.ex b/lib/teiserver/lobby/servers/lobby_index_throttle.ex
index 00078b1ac..b63f82369 100644
--- a/lib/teiserver/lobby/servers/lobby_index_throttle.ex
+++ b/lib/teiserver/lobby/servers/lobby_index_throttle.ex
@@ -17,9 +17,6 @@ defmodule Teiserver.Battle.LobbyIndexThrottle do
:public ->
state.public_lobby_list
- :tournament ->
- state.tournament_lobby_list
-
_unknown ->
Logger.error("No get_cache handler for #{cache}")
[]
@@ -48,7 +45,7 @@ defmodule Teiserver.Battle.LobbyIndexThrottle do
lobby =
Map.take(
lobby,
- ~w(id name map_name passworded locked public tournament in_progress member_count player_count)a
+ ~w(id name map_name passworded locked public in_progress member_count player_count)a
)
Map.merge(lobby, %{
@@ -63,20 +60,12 @@ defmodule Teiserver.Battle.LobbyIndexThrottle do
complete_list
|> Enum.reject(fn lobby ->
lobby.passworded or
- lobby.locked or
- lobby.tournament
- end)
-
- tournament_list =
- complete_list
- |> Enum.filter(fn lobby ->
- lobby.tournament
+ lobby.locked
end)
%{
complete_lobby_list: complete_list,
- public_lobby_list: public_list,
- tournament_lobby_list: tournament_list
+ public_lobby_list: public_list
}
end
@@ -110,7 +99,6 @@ defmodule Teiserver.Battle.LobbyIndexThrottle do
%{
complete_lobby_list: [],
public_lobby_list: [],
- tournament_lobby_list: [],
last_update: System.system_time(:second)
}}
end
diff --git a/lib/teiserver/moderation.ex b/lib/teiserver/moderation.ex
index e1a2a3733..4baf73cc2 100644
--- a/lib/teiserver/moderation.ex
+++ b/lib/teiserver/moderation.ex
@@ -18,7 +18,6 @@ defmodule Teiserver.Moderation do
alias Teiserver.Moderation.ProposalVoteLib
alias Teiserver.Moderation.RefreshUserRestrictionsTask
alias Teiserver.Moderation.Report
- alias Teiserver.Moderation.ReportGroupLib
alias Teiserver.Moderation.ReportLib
alias Teiserver.Moderation.Response
alias Teiserver.Moderation.ResponseLib
@@ -254,66 +253,6 @@ defmodule Teiserver.Moderation do
Report.changeset(report, %{})
end
- def create_report_group_and_report(report_params) do
- report_group = get_or_make_report_group(report_params.target_id, report_params.match_id)
-
- report_params =
- Map.merge(report_params, %{
- report_group_id: report_group.id
- })
-
- case create_report(report_params) do
- {:ok, report} ->
- {:ok, report_group} =
- update_report_group(report_group, %{
- report_count: report_group.report_count + 1
- })
-
- {:ok, report_group, report}
-
- result ->
- result
- end
- end
-
- @spec list_report_groups() :: [ComplexServerEventType.t()]
- defdelegate list_report_groups(), to: ReportGroupLib
-
- @spec list_report_groups(list) :: [ComplexServerEventType.t()]
- defdelegate list_report_groups(args), to: ReportGroupLib
-
- @spec count_report_groups(list) :: integer()
- defdelegate count_report_groups(args), to: ReportGroupLib
-
- @spec get_report_group!(non_neg_integer) :: ComplexServerEventType.t()
- defdelegate get_report_group!(id), to: ReportGroupLib
-
- @spec get_report_group!(non_neg_integer, list) :: ComplexServerEventType.t()
- defdelegate get_report_group!(id, args), to: ReportGroupLib
-
- @spec create_report_group() :: {:ok, ComplexServerEventType.t()} | {:error, Ecto.Changeset}
- defdelegate create_report_group(), to: ReportGroupLib
-
- @spec create_report_group(map) :: {:ok, ComplexServerEventType.t()} | {:error, Ecto.Changeset}
- defdelegate create_report_group(attrs), to: ReportGroupLib
-
- @spec update_report_group(ComplexServerEventType.t(), map) ::
- {:ok, ComplexServerEventType.t()} | {:error, Ecto.Changeset}
- defdelegate update_report_group(report_group, attrs), to: ReportGroupLib
-
- @spec delete_report_group(ComplexServerEventType) ::
- {:ok, ComplexServerEventType} | {:error, Ecto.Changeset}
- defdelegate delete_report_group(report_group), to: ReportGroupLib
-
- @spec change_report_group(ComplexServerEventType) :: Ecto.Changeset
- defdelegate change_report_group(report_group), to: ReportGroupLib
-
- @spec change_report_group(ComplexServerEventType, map) :: Ecto.Changeset
- defdelegate change_report_group(report_group, attrs), to: ReportGroupLib
-
- @spec get_or_make_report_group(T.userid(), T.match_id() | nil) :: ReportGroup.t()
- defdelegate get_or_make_report_group(target_id, match_id), to: ReportGroupLib
-
@spec response_query(List.t()) :: Ecto.Query.t()
def response_query(args) do
response_query(nil, args)
@@ -591,8 +530,8 @@ defmodule Teiserver.Moderation do
nil
"""
- @spec get_action(Integer.t() | List.t()) :: Action.t()
- @spec get_action(Integer.t(), List.t()) :: Action.t()
+ @spec get_action(Integer.t() | List.t()) :: Action.t() | nil
+ @spec get_action(Integer.t(), List.t()) :: Action.t() | nil
def get_action(id) when not is_list(id) do
action_query(id, [])
|> Repo.one()
diff --git a/lib/teiserver/moderation/libs/action_lib.ex b/lib/teiserver/moderation/libs/action_lib.ex
index 28c2424b1..4fbf267e2 100644
--- a/lib/teiserver/moderation/libs/action_lib.ex
+++ b/lib/teiserver/moderation/libs/action_lib.ex
@@ -179,12 +179,6 @@ defmodule Teiserver.Moderation.ActionLib do
def preload(query, preloads) do
query = if :target in preloads, do: _preload_target(query), else: query
- query = if :report_groups in preloads, do: _preload_report_groups(query), else: query
-
- query =
- if :report_group_reports_and_reporters in preloads,
- do: _preload_report_group_reports_and_reporters(query),
- else: query
query
end
@@ -196,22 +190,6 @@ defmodule Teiserver.Moderation.ActionLib do
preload: [target: targets]
end
- @spec _preload_report_groups(Ecto.Query.t()) :: Ecto.Query.t()
- def _preload_report_groups(query) do
- from actions in query,
- left_join: report_groups in assoc(actions, :report_groups),
- preload: [report_groups: report_groups]
- end
-
- @spec _preload_report_group_reports_and_reporters(Ecto.Query.t()) :: Ecto.Query.t()
- def _preload_report_group_reports_and_reporters(query) do
- from actions in query,
- left_join: report_groups in assoc(actions, :report_group),
- left_join: reports in assoc(report_groups, :reports),
- left_join: reporters in assoc(reports, :reporter),
- preload: [report_group: {report_groups, reports: {reports, reporter: reporters}}]
- end
-
def generate_discord_message_text(nil), do: nil
def generate_discord_message_text(action) do
diff --git a/lib/teiserver/moderation/libs/report_group_lib.ex b/lib/teiserver/moderation/libs/report_group_lib.ex
deleted file mode 100644
index 1bc93b5ce..000000000
--- a/lib/teiserver/moderation/libs/report_group_lib.ex
+++ /dev/null
@@ -1,190 +0,0 @@
-defmodule Teiserver.Moderation.ReportGroupLib do
- @moduledoc false
-
- alias Teiserver.Moderation
- alias Teiserver.Moderation.ReportGroup
- alias Teiserver.Moderation.ReportGroupQueries
- use TeiserverWeb, :library_newform
-
- @spec colour :: atom
- def colour, do: :warning
-
- @spec icon() :: String.t()
- def icon, do: "fa-house-flag"
-
- @spec make_favourite(ReportGroup.t()) :: map()
- def make_favourite(report_group) do
- %{
- type_colour: Moderation.colour(),
- type_icon: Moderation.icon(),
- item_id: report_group.id,
- item_type: "moderation_report_group",
- item_colour: colour(),
- item_icon: icon(),
- item_label: "#{report_group.target.name}",
- url: "/moderation/overwatch/report_group/#{report_group.id}"
- }
- end
-
- @doc """
- Returns the list of report_groups.
-
- ## Examples
-
- iex> list_report_groups()
- [%ReportGroup{}, ...]
-
- """
- @spec list_report_groups(list) :: list
- def list_report_groups(args \\ []) do
- args
- |> ReportGroupQueries.query_report_groups()
- |> Repo.all()
- end
-
- @spec count_report_groups(list) :: integer()
- def count_report_groups(args \\ []) do
- args
- |> ReportGroupQueries.query_report_groups()
- |> Repo.aggregate(:count, :id)
- end
-
- @doc """
- Gets a single report_group.
-
- Raises `Ecto.NoResultsError` if the ReportGroup does not exist.
-
- ## Examples
-
- iex> get_report_group!(123)
- %ReportGroup{}
-
- iex> get_report_group!(456)
- ** (Ecto.NoResultsError)
-
- """
- def get_report_group!(id), do: Repo.get!(ReportGroup, id)
-
- def get_report_group!(id, args) do
- args = args ++ [id: id]
-
- args
- |> ReportGroupQueries.query_report_groups()
- |> Repo.one!()
- end
-
- @spec get_report_group(non_neg_integer(), T.match_id()) :: ReportGroup.t() | nil
- def get_report_group(id, args) when is_list(args) do
- args = args ++ [id: id]
-
- args
- |> ReportGroupQueries.query_report_groups()
- |> Repo.one()
- end
-
- def get_report_group(target_id, match_id) do
- ReportGroupQueries.query_report_groups(
- where: [
- target_id: target_id,
- match_id: match_id
- ]
- )
- |> Repo.one()
- end
-
- @doc """
- Creates a report_group.
-
- ## Examples
-
- iex> create_report_group(%{field: value})
- {:ok, %ReportGroup{}}
-
- iex> create_report_group(%{field: bad_value})
- {:error, %Ecto.Changeset{}}
-
- """
- def create_report_group(attrs \\ %{}) do
- %ReportGroup{}
- |> ReportGroup.changeset(attrs)
- |> Repo.insert()
- end
-
- @doc """
- Updates a report_group.
-
- ## Examples
- iex> update_report_group(report_group, %{field: new_value})
- {:ok, %ReportGroup{}}
-
- iex> update_report_group(report_group, %{field: bad_value})
- {:error, %Ecto.Changeset{}}
-
- """
- def update_report_group(%ReportGroup{} = report_group, attrs) do
- report_group
- |> ReportGroup.changeset(attrs)
- |> Repo.update()
- end
-
- @doc """
- Deletes a report_group.
-
- ## Examples
-
- iex> delete_report_group(report_group)
- {:ok, %ReportGroup{}}
-
- iex> delete_report_group(report_group)
- {:error, %Ecto.Changeset{}}
-
- """
- def delete_report_group(%ReportGroup{} = report_group) do
- Repo.delete(report_group)
- end
-
- @doc """
- Returns an `%Ecto.Changeset{}` for tracking report_group changes.
-
- ## Examples
-
- iex> change_report_group(report_group)
- %Ecto.Changeset{data: %ReportGroup{}}
-
- """
- def change_report_group(%ReportGroup{} = report_group, attrs \\ %{}) do
- ReportGroup.changeset(report_group, attrs)
- end
-
- @spec get_or_make_report_group(T.userid(), T.match_id()) :: ReportGroup.t()
- def get_or_make_report_group(target_id, match_id) when is_integer(match_id) do
- case get_report_group(target_id, match_id) do
- nil ->
- {:ok, rg} = create_report_group(%{target_id: target_id, match_id: match_id})
- rg
-
- r ->
- r
- end
- end
-
- def get_or_make_report_group(target_id, nil) do
- report_group =
- get_report_group(nil,
- where: [
- target_id: target_id,
- match_id: false,
- closed: false
- ]
- )
-
- case report_group do
- nil ->
- {:ok, rg} = create_report_group(%{target_id: target_id})
- rg
-
- _existing ->
- report_group
- end
- end
-end
diff --git a/lib/teiserver/moderation/queries/report_group_queries.ex b/lib/teiserver/moderation/queries/report_group_queries.ex
deleted file mode 100644
index 8344c7ddb..000000000
--- a/lib/teiserver/moderation/queries/report_group_queries.ex
+++ /dev/null
@@ -1,150 +0,0 @@
-defmodule Teiserver.Moderation.ReportGroupQueries do
- @moduledoc false
-
- alias Teiserver.Moderation.ReportGroup
- use TeiserverWeb, :queries
-
- # Queries
- @spec query_report_groups(list) :: Ecto.Query.t()
- def query_report_groups(args) do
- query = from(report_groups in ReportGroup)
-
- query
- |> do_where(id: args[:id])
- |> do_where(args[:where])
- |> do_preload(args[:preload])
- |> do_order_by(args[:order_by])
- |> query_select(args[:select])
- |> limit_query(args[:limit])
- |> offset_query(args[:offset])
- end
-
- @spec do_where(Ecto.Query.t(), list | map | nil) :: Ecto.Query.t()
- defp do_where(query, nil), do: query
-
- defp do_where(query, params) do
- params
- |> Enum.reduce(query, fn {key, value}, query_acc ->
- _where(query_acc, key, value)
- end)
- end
-
- @spec _where(Ecto.Query.t(), atom(), any()) :: Ecto.Query.t()
- defp _where(query, _key, ""), do: query
- defp _where(query, _key, nil), do: query
-
- defp _where(query, :id, id) do
- from report_groups in query,
- where: report_groups.id == ^id
- end
-
- defp _where(query, :id_in, id_list) do
- from report_groups in query,
- where: report_groups.id in ^id_list
- end
-
- defp _where(query, :target_id, target_id) do
- from report_groups in query,
- where: report_groups.target_id == ^target_id
- end
-
- defp _where(query, :match_id, false) do
- from report_groups in query,
- where: is_nil(report_groups.match_id)
- end
-
- defp _where(query, :match_id, match_id) do
- from report_groups in query,
- where: report_groups.match_id == ^match_id
- end
-
- defp _where(query, :closed, closed) do
- from report_groups in query,
- where: report_groups.closed == ^closed
- end
-
- defp _where(query, :actioned, true) do
- from report_groups in query,
- where: report_groups.action_count > 0
- end
-
- defp _where(query, :actioned, false) do
- from report_groups in query,
- where: report_groups.action_count == 0
- end
-
- defp _where(query, :actioned, _value), do: query
-
- defp _where(query, :inserted_after, datetime) do
- from report_groups in query,
- where: report_groups.inserted_at >= ^datetime
- end
-
- defp _where(query, :has_reports_of_kind, kind) do
- from report_groups in query,
- join: reports in assoc(report_groups, :reports),
- where: fragment("? ~* ?", reports.type, ^kind)
- end
-
- @spec do_order_by(Ecto.Query.t(), list | nil) :: Ecto.Query.t()
- defp do_order_by(query, nil), do: query
-
- defp do_order_by(query, params) when is_list(params) do
- params
- |> Enum.reduce(query, fn key, query_acc ->
- _order_by(query_acc, key)
- end)
- end
-
- defp do_order_by(query, params), do: do_order_by(query, [params])
-
- defp _order_by(query, nil), do: query
-
- defp _order_by(query, "Newest first") do
- from report_groups in query,
- order_by: [desc: report_groups.updated_at]
- end
-
- defp _order_by(query, "Oldest first") do
- from report_groups in query,
- order_by: [asc: report_groups.updated_at]
- end
-
- @spec do_preload(Ecto.Query.t(), list() | nil) :: Ecto.Query.t()
- defp do_preload(query, nil), do: query
-
- defp do_preload(query, preloads) do
- preloads
- |> Enum.reduce(query, fn key, query_acc ->
- _preload(query_acc, key)
- end)
- end
-
- defp _preload(query, :target) do
- from report_groups in query,
- join: targets in assoc(report_groups, :target),
- preload: [target: targets]
- end
-
- defp _preload(query, :actions) do
- from report_groups in query,
- left_join: actions in assoc(report_groups, :actions),
- preload: [actions: actions]
- end
-
- defp _preload(query, :reports) do
- from report_groups in query,
- left_join: reports in assoc(report_groups, :reports),
- preload: [reports: reports]
-
- # TODO add reporters here
- end
-
- # defp _preload(query, :users) do
- # from report_groups in query,
- # join: tos in assoc(report_groups, :to),
- # preload: [to: tos],
- # join: froms in assoc(report_groups, :from),
- # preload: [from: froms]
- # end
-end
diff --git a/lib/teiserver/moderation/schemas/action.ex b/lib/teiserver/moderation/schemas/action.ex
index 08ed0d590..c179451dc 100644
--- a/lib/teiserver/moderation/schemas/action.ex
+++ b/lib/teiserver/moderation/schemas/action.ex
@@ -19,9 +19,6 @@ defmodule Teiserver.Moderation.Action do
field :discord_message_id, :integer
- # No longer set nowadays
- belongs_to :report_group, Teiserver.Moderation.ReportGroup
-
timestamps()
end
@@ -35,7 +32,7 @@ defmodule Teiserver.Moderation.Action do
struct
|> cast(
params,
- ~w(target_id report_group_id reason restrictions score_modifier expires notes hidden discord_message_id appeal_status)a
+ ~w(target_id reason restrictions score_modifier expires notes hidden discord_message_id appeal_status)a
)
|> validate_required(~w(target_id reason restrictions expires score_modifier)a)
|> adjust_restrictions()
diff --git a/lib/teiserver/moderation/schemas/report.ex b/lib/teiserver/moderation/schemas/report.ex
index fdd7370f7..ce6a6b18a 100644
--- a/lib/teiserver/moderation/schemas/report.ex
+++ b/lib/teiserver/moderation/schemas/report.ex
@@ -15,7 +15,6 @@ defmodule Teiserver.Moderation.Report do
belongs_to :match, Teiserver.Battle.Match
field :relationship, :string
belongs_to :result, Teiserver.Moderation.Action
- belongs_to :report_group, Teiserver.Moderation.ReportGroup
has_many :responses, Teiserver.Moderation.Response
@@ -31,7 +30,7 @@ defmodule Teiserver.Moderation.Report do
struct
|> cast(
params,
- ~w(reporter_id target_id type sub_type extra_text match_id discord_message_id relationship result_id closed report_group_id)a
+ ~w(reporter_id target_id type sub_type extra_text match_id discord_message_id relationship result_id closed)a
)
|> validate_required(~w(reporter_id target_id type sub_type closed)a)
end
diff --git a/lib/teiserver/moderation/schemas/report_group.ex b/lib/teiserver/moderation/schemas/report_group.ex
deleted file mode 100644
index 5e9e48e8a..000000000
--- a/lib/teiserver/moderation/schemas/report_group.ex
+++ /dev/null
@@ -1,39 +0,0 @@
-defmodule Teiserver.Moderation.ReportGroup do
- @moduledoc false
- use TeiserverWeb, :schema
-
- typed_schema "moderation_report_groups" do
- belongs_to :target, Teiserver.Account.User
- belongs_to :match, Teiserver.Battle.Match
-
- field :closed, :boolean, default: false
- field :report_count, :integer, default: 0
- field :vote_count, :integer, default: 0
- field :action_count, :integer, default: 0
-
- has_many :actions, Teiserver.Moderation.Action
- has_many :reports, Teiserver.Moderation.Report
- has_many :report_group_votes, Teiserver.Moderation.ReportGroupVote
- has_many :report_group_messages, Teiserver.Moderation.ReportGroupMessage
-
- timestamps()
- end
-
- @spec changeset(map(), map()) :: Ecto.Changeset.t()
- def changeset(struct, params \\ %{}) do
- struct
- |> cast(
- params,
- ~w(target_id match_id report_count vote_count action_count closed)a
- )
- |> validate_required(~w(target_id)a)
- end
-
- @spec authorize(atom(), Plug.Conn.t(), map()) :: bool()
- def authorize(:index, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(:search, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(:show, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(:user, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(:respond, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(_action, conn, _params), do: allow?(conn, "Moderator")
-end
diff --git a/lib/teiserver/moderation/schemas/report_group_message.ex b/lib/teiserver/moderation/schemas/report_group_message.ex
deleted file mode 100644
index be0c03647..000000000
--- a/lib/teiserver/moderation/schemas/report_group_message.ex
+++ /dev/null
@@ -1,35 +0,0 @@
-defmodule Teiserver.Moderation.ReportGroupMessage do
- @moduledoc false
- use TeiserverWeb, :schema
-
- typed_schema "moderation_report_group_messages" do
- belongs_to :report_group, Teiserver.Moderation.ReportGroup
- belongs_to :user, Teiserver.Account.User
-
- field :content, :string
-
- timestamps()
- end
-
- @spec changeset(map(), map()) :: Ecto.Changeset.t()
- def changeset(struct, params \\ %{}) do
- params =
- params
- |> trim_strings(~w(content)a)
-
- struct
- |> cast(
- params,
- ~w(report_group_id user_id content)a
- )
- |> validate_required(~w(report_group_id user_id content)a)
- end
-
- @spec authorize(atom(), Plug.Conn.t(), map()) :: bool()
- def authorize(:index, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(:search, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(:show, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(:user, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(:respond, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(_action, conn, _params), do: allow?(conn, "Moderator")
-end
diff --git a/lib/teiserver/moderation/schemas/report_group_vote.ex b/lib/teiserver/moderation/schemas/report_group_vote.ex
deleted file mode 100644
index c16d8c540..000000000
--- a/lib/teiserver/moderation/schemas/report_group_vote.ex
+++ /dev/null
@@ -1,36 +0,0 @@
-defmodule Teiserver.Moderation.ReportGroupVote do
- @moduledoc false
- use TeiserverWeb, :schema
-
- typed_schema "moderation_report_group_votes" do
- belongs_to :report_group, Teiserver.Moderation.ReportGroup
- belongs_to :user, Teiserver.Account.User
-
- field :action, :string
- field :accuracy, :string
-
- timestamps()
- end
-
- @spec changeset(map(), map()) :: Ecto.Changeset.t()
- def changeset(struct, params \\ %{}) do
- params =
- params
- |> trim_strings(~w(action accuracy)a)
-
- struct
- |> cast(
- params,
- ~w(report_group_id user_id action accuracy)a
- )
- |> validate_required(~w(report_group_id user_id action accuracy)a)
- end
-
- @spec authorize(atom(), Plug.Conn.t(), map()) :: bool()
- def authorize(:index, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(:search, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(:show, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(:user, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(:respond, conn, _params), do: allow?(conn, "Overwatch")
- def authorize(_action, conn, _params), do: allow?(conn, "Moderator")
-end
diff --git a/lib/teiserver/servers/telemetry_server.ex b/lib/teiserver/servers/telemetry_server.ex
index bb3014ca5..00fb9e9ec 100644
--- a/lib/teiserver/servers/telemetry_server.ex
+++ b/lib/teiserver/servers/telemetry_server.ex
@@ -235,7 +235,6 @@ defmodule Teiserver.Telemetry.TelemetryServer do
process_counts = %{
system_servers: Horde.Registry.count(Teiserver.ServerRegistry),
throttle_servers: Horde.Registry.count(Teiserver.ThrottleRegistry),
- accolade_servers: Horde.Registry.count(Teiserver.AccoladesRegistry),
consul_servers: Horde.Registry.count(Teiserver.ConsulRegistry),
balancer_servers: Horde.Registry.count(Teiserver.BalancerRegistry),
lobby_servers: Horde.Registry.count(Teiserver.LobbyRegistry),
diff --git a/lib/teiserver/startup.ex b/lib/teiserver/startup.ex
index 9fef1fa51..1a830b6ba 100644
--- a/lib/teiserver/startup.ex
+++ b/lib/teiserver/startup.ex
@@ -2,7 +2,6 @@ defmodule Teiserver.Startup do
@moduledoc false
alias Phoenix.PubSub
- alias Teiserver.Account.AccoladeLib
alias Teiserver.Battle
alias Teiserver.Bridge.CommandLib
alias Teiserver.Communication
@@ -41,13 +40,6 @@ defmodule Teiserver.Startup do
end)
end
- if Application.get_env(:teiserver, Teiserver)[:enable_accolade_mode] do
- spawn(fn ->
- :timer.sleep(200)
- AccoladeLib.start_accolade_server()
- end)
- end
-
Teiserver.cache_put(:application_metadata_cache, "teiserver_partial_startup_completed", true)
Teiserver.cache_put(:application_metadata_cache, "teiserver_full_startup_completed", true)
diff --git a/lib/teiserver_web/controllers/moderation/action_controller.ex b/lib/teiserver_web/controllers/moderation/action_controller.ex
index 548e10cfb..9e3c71b11 100644
--- a/lib/teiserver_web/controllers/moderation/action_controller.ex
+++ b/lib/teiserver_web/controllers/moderation/action_controller.ex
@@ -412,12 +412,6 @@ defmodule TeiserverWeb.Moderation.ActionController do
def delete(conn, %{"id" => id}) do
action = Moderation.get_action!(id)
- # Update any reports which were assigned to this
- # action.report_groups
- # |> Enum.each(fn report ->
- # Moderation.update_report(report, %{result_id: nil})
- # end)
-
Moderation.delete_action(action)
if action.discord_message_id do
diff --git a/lib/teiserver_web/controllers/report/report_controller.ex b/lib/teiserver_web/controllers/report/report_controller.ex
index f9009aff0..a64113fcd 100644
--- a/lib/teiserver_web/controllers/report/report_controller.ex
+++ b/lib/teiserver_web/controllers/report/report_controller.ex
@@ -77,9 +77,6 @@ defmodule TeiserverWeb.Report.ReportController do
"open_skill" ->
Teiserver.Account.OpenSkillReport
- "tournament" ->
- Teiserver.Account.TournamentReport
-
"microblog" ->
Teiserver.Communication.MicroblogReport
diff --git a/lib/teiserver_web/live/admin_dashboard/index.ex b/lib/teiserver_web/live/admin_dashboard/index.ex
index a7b42f3bd..f389f288f 100644
--- a/lib/teiserver_web/live/admin_dashboard/index.ex
+++ b/lib/teiserver_web/live/admin_dashboard/index.ex
@@ -2,7 +2,6 @@ defmodule TeiserverWeb.AdminDashLive.Index do
alias Phoenix.LiveView.Socket
alias Phoenix.PubSub
alias Teiserver
- alias Teiserver.Account.AccoladeLib
alias Teiserver.Admin.AdminLib
alias Teiserver.Battle
alias Teiserver.Battle.MatchMonitorServer
@@ -162,7 +161,6 @@ defmodule TeiserverWeb.AdminDashLive.Index do
server_pids = [
{"Lobby ID server", lobby_id_server_pid},
{"Coordinator", Coordinator.get_coordinator_pid()},
- {"Accolades", AccoladeLib.get_accolade_bot_pid()},
{"Match Monitor", MatchMonitorServer.get_match_monitor_pid()},
{"Automod", AutomodServer.get_automod_pid()},
{"Discord Bridge Bot", BridgeServer.get_bridge_pid()}
diff --git a/lib/teiserver_web/live/battles/battle_components.ex b/lib/teiserver_web/live/battles/battle_components.ex
index ec4bfe243..74f80621e 100644
--- a/lib/teiserver_web/live/battles/battle_components.ex
+++ b/lib/teiserver_web/live/battles/battle_components.ex
@@ -48,15 +48,6 @@ defmodule TeiserverWeb.Battle.BattleComponents do
>
Leaderboard
-
- <.sub_menu_button
- bsname={@view_colour}
- icon="fa-trophy"
- active={@active == "tournaments"}
- url={~p"/tournament/lobbies"}
- >
- Tournaments
-
"""
end
diff --git a/lib/teiserver_web/live/battles/lobbies/chat.ex b/lib/teiserver_web/live/battles/lobbies/chat.ex
index 88e1556ca..1d83b7c88 100644
--- a/lib/teiserver_web/live/battles/lobbies/chat.ex
+++ b/lib/teiserver_web/live/battles/lobbies/chat.ex
@@ -1,7 +1,6 @@
defmodule TeiserverWeb.Battle.LobbyLive.Chat do
alias Phoenix.PubSub
alias Teiserver.Account
- alias Teiserver.Account.Auth
alias Teiserver.Battle
alias Teiserver.CacheUser
alias Teiserver.Chat
@@ -53,15 +52,6 @@ defmodule TeiserverWeb.Battle.LobbyLive.Chat do
lobby == nil ->
index_redirect(socket)
- lobby.tournament and
- not Auth.has_any_role?(current_user.id, [
- "Moderator",
- "Caster",
- "TourneyPlayer",
- "Tournament player"
- ]) ->
- index_redirect(socket)
-
(lobby.locked or lobby.passworded) and not allow?(socket, "Moderator") ->
index_redirect(socket)
diff --git a/lib/teiserver_web/live/battles/lobbies/index.ex b/lib/teiserver_web/live/battles/lobbies/index.ex
index 6513467bf..56061d395 100644
--- a/lib/teiserver_web/live/battles/lobbies/index.ex
+++ b/lib/teiserver_web/live/battles/lobbies/index.ex
@@ -168,15 +168,11 @@ defmodule TeiserverWeb.Battle.LobbyLive.Index do
defp filter_lobbies(lobbies, %{assigns: %{moderator: moderator}} = _socket) do
if moderator do
lobbies
- |> Enum.reject(fn lobby ->
- lobby.tournament
- end)
else
lobbies
|> Enum.reject(fn lobby ->
lobby.locked or
- lobby.passworded or
- lobby.tournament
+ lobby.passworded
end)
end
end
diff --git a/lib/teiserver_web/live/battles/lobbies/show.ex b/lib/teiserver_web/live/battles/lobbies/show.ex
index ca608663b..84dd5db30 100644
--- a/lib/teiserver_web/live/battles/lobbies/show.ex
+++ b/lib/teiserver_web/live/battles/lobbies/show.ex
@@ -89,9 +89,6 @@ defmodule TeiserverWeb.Battle.LobbyLive.Show do
lobby == nil ->
index_redirect(socket)
- lobby.tournament ->
- index_redirect(socket)
-
(lobby.locked or lobby.passworded) and not allow?(socket, "Moderator") ->
index_redirect(socket)
diff --git a/lib/teiserver_web/live/general/home/index.html.heex b/lib/teiserver_web/live/general/home/index.html.heex
index f618edb97..0d3fa6211 100644
--- a/lib/teiserver_web/live/general/home/index.html.heex
+++ b/lib/teiserver_web/live/general/home/index.html.heex
@@ -19,15 +19,6 @@
Appeals
- <.menu_card
- :if={allow?(@current_user, "Overwatch")}
- icon={Teiserver.Moderation.overwatch_icon()}
- icon_class="fa-solid"
- url={~p"/moderation/overwatch"}
- >
- Overwatch
-
-
<.menu_card
:if={allow?(@current_user, "Contributor")}
icon={StylingHelper.icon(:summary)}
diff --git a/lib/teiserver_web/live/moderation/moderation_components.ex b/lib/teiserver_web/live/moderation/moderation_components.ex
index d74af5687..1dd31e862 100644
--- a/lib/teiserver_web/live/moderation/moderation_components.ex
+++ b/lib/teiserver_web/live/moderation/moderation_components.ex
@@ -14,15 +14,6 @@ defmodule TeiserverWeb.Moderation.ModerationComponents do
def sub_menu(assigns) do
~H"""