1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
defmodule Chessh.SSH.Client.SelectBot do
alias Chessh.{Utils, Bot, Repo, Game}
alias Chessh.SSH.Client.Selector
import Ecto.Query
require Logger
use Chessh.SSH.Client.SelectPaginatePoller
def refresh_options_ms(), do: 4000
def max_displayed_options(), do: 5
def title(), do: ["-- Select Bot To Play Against --"]
def dynamic_options(), do: true
def get_bots(player_id, current_id \\ nil, direction \\ :desc) do
Selector.paginate_ish_query(
Bot
|> where([b], b.player_id == ^player_id or b.public == true)
|> limit(^max_displayed_options()),
current_id,
direction
)
end
def format_bot_tuple(%Bot{id: id, name: name}), do: {name, id}
def next_page_options(%State{
options: options,
player_session: %PlayerSession{
player_id: player_id
}
}) do
{_label, previous_last_bot_id} = List.last(options)
next_bots = get_bots(player_id, previous_last_bot_id, :desc)
if length(next_bots) > 0,
do:
next_bots
|> Enum.map(&format_bot_tuple/1),
else: options
end
def previous_page_options(%State{
options: options,
player_session: %PlayerSession{player_id: player_id}
}) do
{_label, previous_first_bot_id} = List.first(options)
previous_bots = get_bots(player_id, previous_first_bot_id, :asc)
if length(previous_bots) > 0,
do:
previous_bots
|> Enum.map(&format_bot_tuple/1),
else: options
end
def initial_options(%State{
player_session: %PlayerSession{player_id: player_id}
}) do
get_bots(player_id)
|> Enum.map(&format_bot_tuple/1)
end
def refresh_options(%State{
options: options,
player_session: %PlayerSession{player_id: player_id}
}) do
previous_last_bot_id =
case List.last(options) do
{_name, id} -> id
_ -> 1
end
current_screen_games = get_bots(player_id, previous_last_bot_id - 1, :asc)
if !is_nil(current_screen_games) && length(current_screen_games),
do:
current_screen_games
|> Enum.map(&format_bot_tuple/1),
else: options
end
def make_process_tuple(selected_id, %State{
player_session: player_session,
extra_info: %{color: color}
}) do
[create_game_ms, create_game_rate] =
Application.get_env(:chessh, RateLimits)
|> Keyword.take([:create_game_ms, :create_game_rate])
|> Keyword.values()
case Hammer.check_rate_inc(
:redis,
"player-#{player_session.player_id}-create-game-rate",
create_game_ms,
create_game_rate,
1
) do
{:allow, _count} ->
{:ok, game} =
Game.changeset(
Game.new_game(color, player_session.player_id),
%{
bot_id: selected_id
}
)
|> Repo.insert()
spawn(fn -> Bot.send_update(game |> Repo.preload([:bot])) end)
{Chessh.SSH.Client.Game,
%Chessh.SSH.Client.Game.State{player_session: player_session, color: color, game: game}}
{:deny, _limit} ->
{Chessh.SSH.Client.MainMenu,
%Chessh.SSH.Client.SelectPaginatePoller.State{player_session: player_session}}
end
end
end
|