Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion lib/teiserver/coordinator/coordinator_commands.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ defmodule Teiserver.Coordinator.CoordinatorCommands do
@splitter "---------------------------"
@always_allow ~w(help whoami whois discord coc mute unmute ignore unignore website party)
# These commands are handled by coordinator commands, but are not on the always allow list
@mod_allow ~w(modparty unparty)
@mod_allow ~w(modparty unparty modme unmodme)
@forward_to_consul ~w(s status players follow joinq leaveq splitlobby y yes n no explain)
@admin_commands ~w(broadcast)

Expand Down Expand Up @@ -524,6 +524,24 @@ defmodule Teiserver.Coordinator.CoordinatorCommands do
state
end

# Changes the client status to show the person is a moderator
defp do_handle(%{command: "modme", senderid: sender_id} = _cmd, state) do
client = Account.get_client_by_id(sender_id)

if client.moderator do
Client.merge_update_client(sender_id, %{show_moderator: true})
end

state
end

# Changes the client status to hide the person is a moderator
defp do_handle(%{command: "unmodme", senderid: sender_id} = _cmd, state) do
Client.merge_update_client(sender_id, %{show_moderator: false})

state
end

defp do_handle(%{command: "website", senderid: senderid} = _cmd, state) do
client = Client.get_client_by_id(senderid)
sender = Account.get_user(senderid)
Expand Down
7 changes: 7 additions & 0 deletions lib/teiserver/data/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ defmodule Teiserver.Client do
away: false,
rank: 1,
moderator: false,

# Used to control showing/hiding the moderator-ness of the client
show_moderator: false,
bot: false,

# Battle stuff
Expand Down Expand Up @@ -97,6 +100,7 @@ defmodule Teiserver.Client do
tcp_pid: self(),
rank: user.rank,
moderator: Auth.moderator?(db_user) or Auth.is_event_organizer?(db_user),
show_moderator: false,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default to not showing it at login

bot: Auth.is_bot?(db_user),
away: false,
in_game: false,
Expand Down Expand Up @@ -198,6 +202,9 @@ defmodule Teiserver.Client do
T.client()
def update(client, reason), do: ClientLib.replace_update_client(client, reason)

@spec merge_update_client(User.id(), map()) :: nil | :ok
defdelegate merge_update_client(user_id, updates), to: ClientLib

@spec get_client_pid(User.id()) :: pid() | nil
defdelegate get_client_pid(userid), to: ClientLib

Expand Down
13 changes: 10 additions & 3 deletions lib/teiserver/protocols/spring/spring.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,24 @@ defmodule Teiserver.Protocols.Spring do
}
end

@spec create_client_status(map()) :: Integer.t()
def create_client_status(client) do
@spec create_client_status(map(), boolean()) :: Integer.t()
def create_client_status(client, true_mod_status \\ false) do
[r1, r2, r3] = BitParse.parse_bits("#{client.rank || 1}", 3)

moderator =
if true_mod_status do
client.moderator
else
Map.get(client, :show_moderator, client.moderator)
end
Comment on lines +26 to +31

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the part controlling what is shown to other clients., If true_mod_status is true we will always show the moderation status of the client. If not we will get the show_moderator value with a fallback to their true status.


[
if(client.in_game, do: 1, else: 0),
if(client.away, do: 1, else: 0),
r3,
r2,
r1,
if(client.moderator, do: 1, else: 0),
if(moderator, do: 1, else: 0),
if(client.bot, do: 1, else: 0)
]
|> Enum.reverse()
Expand Down
6 changes: 5 additions & 1 deletion lib/teiserver/protocols/spring/spring_out.ex
Original file line number Diff line number Diff line change
Expand Up @@ -354,11 +354,15 @@ defmodule Teiserver.Protocols.SpringOut do

defp do_reply(:client_status, nil), do: ""

defp do_reply(:client_status, client) do
defp do_reply(:client_status, client) when is_map(client) do
status = Spring.create_client_status(client)
"CLIENTSTATUS #{client.name} #{status}\n"
end

defp do_reply(:client_status, {name, status}) do
"CLIENTSTATUS #{name} #{status}\n"
end

defp do_reply(:client_battlestatus, nil), do: nil

defp do_reply(:client_battlestatus, client) do
Expand Down
7 changes: 6 additions & 1 deletion lib/teiserver/tcp/spring/spring_tcp_server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule Teiserver.SpringTcpServer do
alias Teiserver.Coordinator
alias Teiserver.Data.Types, as: T
alias Teiserver.Helpers.BurstyRateLimiter
alias Teiserver.Protocols.Spring
alias Teiserver.Protocols.Spring.PartyIn
alias Teiserver.Protocols.SpringIn
alias Teiserver.Protocols.SpringOut
Expand Down Expand Up @@ -772,7 +773,11 @@ defmodule Teiserver.SpringTcpServer do
new_knowns = Map.put(state.known_users, userid, new_user)
%{state | known_users: new_knowns}
else
SpringOut.reply(:client_status, new_client, nil, state)
# For bots we want to show them as a moderator regardless of what
# they are showing to others
true_mod_status = Auth.is_bot?(state.userid)
status = Spring.create_client_status(new_client, true_mod_status)
SpringOut.reply(:client_status, {new_client.name, status}, nil, state)
end
end

Expand Down
62 changes: 62 additions & 0 deletions test/teiserver/coordinator/coordinator_commands_sync_test.exs

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you are testing at the socket level, shouldn't you check you receive the correct status message through a socket instead of reaching for the internals?

None of these test really make sure other clients will see the correct status for the client you are modifying.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule Teiserver.Coordinator.CoordinatorCommandsSyncTest do
alias Teiserver.Account
alias Teiserver.Account.Auth
alias Teiserver.Account.UserLib
alias Teiserver.CacheUser

Expand All @@ -8,6 +9,9 @@ defmodule Teiserver.Coordinator.CoordinatorCommandsSyncTest do
import TeiserverTestLib,
only: [
auth_setup: 1,
auth_setup: 2,
new_user: 1,
_recv_until: 1,
_send_raw: 2,
_recv_raw: 1,
start_spring_server: 1
Expand Down Expand Up @@ -50,5 +54,63 @@ defmodule Teiserver.Coordinator.CoordinatorCommandsSyncTest do

Application.put_env(:teiserver, Teiserver, config)
end

test "modme - not moderator", %{socket: socket, user: user} do
client = Account.get_client_by_id(user.id)
refute client.moderator
refute client.show_moderator

_send_raw(socket, "SAYPRIVATE coordinator $modme\n")
:timer.sleep(100)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the sleeps aren't ideal, there are a few helper function under Teiserver.Support.Polling that you should use instead, it'll help reduce the duration of tests.


client = Account.get_client_by_id(user.id)
refute client.moderator
refute client.show_moderator
end

test "modme/unmodme - as moderator", context do
user_watcher = new_user("user_watcher")
%{socket: user_watcher_socket} = auth_setup(context, user_watcher)
bot_watcher = new_user("bot_watcher")
%{socket: bot_watcher_socket} = auth_setup(context, bot_watcher)
{:ok, _} = Auth.add_roles(bot_watcher.id, ["Bot"])

std_user = new_user("std_watcher")
%{socket: std_socket} = auth_setup(context, std_user)
mod_user = new_user("mod_user")
%{socket: mod_socket} = auth_setup(context, mod_user)
{:ok, _} = Auth.add_roles(mod_user.id, ["Moderator"])

lines1 = _recv_until(user_watcher_socket)
lines2 = _recv_until(bot_watcher_socket)

_recv_until(mod_socket)

IO.puts "MODME"
_send_raw(std_socket, "SAYPRIVATE coordinator $modme\n")
_send_raw(mod_socket, "SAYPRIVATE coordinator $modme\n")

lines3 = _recv_until(user_watcher_socket)
lines4 = _recv_until(bot_watcher_socket)

lines5 = _recv_until(mod_socket)

IO.puts "lines1"
IO.puts lines1
IO.puts ""
IO.puts "lines2"
IO.puts lines2
IO.puts ""
IO.puts "lines3"
IO.puts lines3
IO.puts ""
IO.puts "lines4"
IO.puts lines4
IO.puts ""

IO.puts ""
IO.puts lines5
IO.puts ""
end
end
end
Loading