]> git.localhorst.tv Git - alttp.git/blob - app/Http/Controllers/ChannelController.php
026b9aa8ce9fe18c7d0978be820fc1e911c12018
[alttp.git] / app / Http / Controllers / ChannelController.php
1 <?php
2
3 namespace App\Http\Controllers;
4
5 use App\Models\Channel;
6 use App\Models\TwitchBotCommand;
7 use Illuminate\Database\Eloquent\Builder;
8 use Illuminate\Http\Request;
9 use Illuminate\Support\Collection;
10 use Illuminate\Support\Facades\Gate;
11
12 class ChannelController extends Controller {
13
14         public function search(Request $request) {
15                 $validatedData = $request->validate([
16                         'id' => 'array',
17                         'id.*' => 'integer|numeric',
18                         'joinable' => 'boolean|nullable',
19                         'manageable' => 'boolean|nullable',
20                         'phrase' => 'string|nullable',
21                 ]);
22
23                 $channels = Channel::query();
24                 if (!empty($validatedData['id'])) {
25                         $channels = $channels->whereIn('id', $validatedData['id']);
26                 }
27                 if (isset($validatedData['joinable']) && $validatedData['joinable']) {
28                         $channels = $channels->where('twitch_chat', '!=', '');
29                 }
30                 if (isset($validatedData['manageable']) && $validatedData['manageable']) {
31                         $user = $request->user();
32                         if (!$user) {
33                                 return [];
34                         }
35                         $channels = $channels->whereHas('crews', function (Builder $query) use ($user) {
36                                 $query->where('user_id', '=', $user->id);
37                         });
38                 }
39                 if (!empty($validatedData['phrase'])) {
40                         $channels = $channels->where('title', 'LIKE', '%'.$validatedData['phrase'].'%')
41                                 ->orWhere('short_name', 'LIKE', '%'.$validatedData['phrase'].'%');
42                 }
43                 $channels = $channels->limit(5);
44                 return $this->sendChannels($channels->get());
45         }
46
47         public function single(Request $request, Channel $channel) {
48                 $this->authorize('view', $channel);
49                 return $this->sendChannel($channel);
50         }
51
52         public function chat(Request $request, Channel $channel) {
53                 if (!$channel->twitch_chat) {
54                         throw new \Exception('channel has no twitch chat set');
55                 }
56                 $validatedData = $request->validate([
57                         'bot_nick' => 'string',
58                         'category' => 'string',
59                         'text' => 'string',
60                 ]);
61                 $this->authorize('editRestream', $channel);
62                 $nick = empty($validatedData['bot_nick']) ? 'localhorsttv' : $validatedData['bot_nick'];
63                 if (empty($validatedData['category'])) {
64                         TwitchBotCommand::chat($channel->twitch_chat, $validatedData['text'], $request->user(), $nick);
65                 } else {
66                         TwitchBotCommand::randomChat($channel, $validatedData['category'], $request->user(), $nick);
67                 }
68                 return $this->sendChannel($channel);
69         }
70
71         public function chatBotLog(Request $request, Channel $channel) {
72                 $this->authorize('editRestream', $channel);
73                 $log = $channel->chat_bot_logs()
74                         ->with(['origin', 'user'])
75                         ->orderBy('created_at', 'DESC')
76                         ->limit(150)
77                         ->get();
78                 return $log->values()->toJson();
79         }
80
81         public function chatSettings(Request $request, Channel $channel) {
82                 if (!$channel->twitch_chat) {
83                         throw new \Exception('channel has no twitch chat set');
84                 }
85                 $validatedData = $request->validate([
86                         'language' => 'string|in:de,en,es,fr',
87                         'min_age' => 'integer|min:1',
88                         'respond' => 'string|in:50,no,yes',
89                         'source' => 'string|in:any,cat,catchan,chan',
90                         'wait_msgs_min' => 'integer|min:1',
91                         'wait_msgs_max' => 'integer|min:1',
92                         'wait_time_min' => 'integer',
93                         'wait_time_max' => 'integer',
94                 ]);
95                 $this->authorize('editRestream', $channel);
96                 $channel->chat_settings = $validatedData;
97                 $channel->save();
98                 return $this->sendChannel($channel);
99         }
100
101         public function join(Request $request, Channel $channel) {
102                 if (!$channel->twitch_chat) {
103                         throw new \Exception('channel has no twitch chat set');
104                 }
105                 $validatedData = $request->validate([
106                         'bot_nick' => 'string',
107                 ]);
108                 $this->authorize('editRestream', $channel);
109                 $nick = empty($validatedData['bot_nick']) ? 'localhorsttv' : $validatedData['bot_nick'];
110                 if ($nick == 'localhorsttv') {
111                         $channel->join = true;
112                 } else if ($nick == 'horstiebot') {
113                         $channel->chat = true;
114                 }
115                 $channel->save();
116                 TwitchBotCommand::join($channel->twitch_chat, $request->user(), $nick);
117                 return $this->sendChannel($channel);
118         }
119
120         public function part(Request $request, Channel $channel) {
121                 if (!$channel->twitch_chat) {
122                         throw new \Exception('channel has no twitch chat set');
123                 }
124                 $validatedData = $request->validate([
125                         'bot_nick' => 'string',
126                 ]);
127                 $this->authorize('editRestream', $channel);
128                 $nick = empty($validatedData['bot_nick']) ? 'localhorsttv' : $validatedData['bot_nick'];
129                 if ($nick == 'localhorsttv') {
130                         $channel->join = false;
131                 } else if ($nick == 'horstiebot') {
132                         $channel->chat = false;
133                 }
134                 $channel->save();
135                 TwitchBotCommand::part($channel->twitch_chat, $request->user(), $nick);
136                 return $this->sendChannel($channel);
137         }
138
139         public function deleteCommand(Channel $channel, $command) {
140                 $this->authorize('editRestream', $channel);
141                 if (isset($channel->chat_commands[$command])) {
142                         $cmds = $channel->chat_commands;
143                         unset($cmds[$command]);
144                         $channel->chat_commands = $cmds;
145                         $channel->save();
146                 }
147                 return $this->sendChannel($channel);
148         }
149
150         public function saveCommand(Request $request, Channel $channel, $command) {
151                 $this->authorize('editRestream', $channel);
152
153                 $validatedData = $request->validate([
154                         'command' => 'string',
155                         'restrict' => 'string',
156                         'type' => 'string',
157                 ]);
158
159                 $cmds = $channel->chat_commands;
160                 $cmds[$command] = $validatedData;
161                 $channel->chat_commands = $cmds;
162                 $channel->save();
163
164                 return $this->sendChannel($channel);
165         }
166
167         public function controlGuessingGame(Request $request, Channel $channel, $name) {
168                 $this->authorize('editRestream', $channel);
169
170                 $validatedData = $request->validate([
171                         'action' => 'required|in:cancel,solve,start,stop',
172                         'solution' => '',
173                 ]);
174
175                 switch ($validatedData['action']) {
176                         case 'cancel':
177                                 $channel->clearGuessing();
178                                 $msg = $channel->getGuessingSetting('cancel_message');
179                                 if (!empty($msg)) {
180                                         TwitchBotCommand::chat($channel->twitch_chat, $msg);
181                                 }
182                                 break;
183                         case 'solve':
184                                 if ($channel->hasActiveGuessing() && $channel->isValidGuess($validatedData['solution'])) {
185                                         $winners = $channel->solveGuessing($validatedData['solution']);
186                                         $msg = $channel->listGuessingWinners($winners);
187                                         if (!empty($msg)) {
188                                                 TwitchBotCommand::chat($channel->twitch_chat, $msg);
189                                         }
190                                         $channel->clearGuessing();
191                                 }
192                                 break;
193                         case 'start':
194                                 if (!$channel->hasActiveGuessing()) {
195                                         $channel->startGuessing($name);
196                                         $msg = $channel->getGuessingSetting('start_message');
197                                         if (!empty($msg)) {
198                                                 TwitchBotCommand::chat($channel->twitch_chat, $msg);
199                                         }
200                                 }
201                                 break;
202                         case 'stop':
203                                 if ($channel->hasActiveGuessing()) {
204                                         $channel->stopGuessing();
205                                         $msg = $channel->getGuessingSetting('stop_message');
206                                         if (!empty($msg)) {
207                                                 TwitchBotCommand::chat($channel->twitch_chat, $msg);
208                                         }
209                                 }
210                                 break;
211                 }
212
213                 return $this->sendChannel($channel);
214         }
215
216         public function getGuessingGame(Channel $channel, $name) {
217                 $this->authorize('editRestream', $channel);
218
219                 $cutoff = $channel->guessing_start;
220                 if (is_null($cutoff)) {
221                         $last = $channel->winners()->latest()->first();
222                         $cutoff = $last->pod;
223                 }
224                 $guesses = $channel->guesses()->where('created_at', '>=', $cutoff)->orderBy('created_at')->get();
225                 $winners = $channel->winners()->where('created_at', '>=', $cutoff)->orderBy('created_at')->get();
226                 return [
227                         'guesses' => $guesses->toArray(),
228                         'winners' => $winners->toArray(),
229                 ];
230         }
231
232         public function getGuessingGameLeaderboard(Channel $channel, $type) {
233                 return [
234                         'all' => $channel->getGuessingLeaderboard(),
235                 ];
236         }
237
238         public function getGuessingGameMonitor($key) {
239                 $channel = Channel::where('access_key', '=', $key)->firstOrFail();
240
241                 $cutoff = $channel->guessing_start;
242                 if (is_null($cutoff)) {
243                         $last = $channel->winners()->latest()->first();
244                         $cutoff = $last->pod;
245                 }
246                 $guesses = $channel->guesses()->where('created_at', '>=', $cutoff)->orderBy('created_at')->get();
247                 $winners = $channel->winners()->where('created_at', '>=', $cutoff)->orderBy('created_at')->get();
248                 return [
249                         'channel' => $channel->toArray(),
250                         'guesses' => $guesses->toArray(),
251                         'winners' => $winners->toArray(),
252                 ];
253         }
254
255         public function saveGuessingGame(Request $request, Channel $channel, $name) {
256                 $this->authorize('editRestream', $channel);
257
258                 $validatedData = $request->validate([
259                         'active_message' => 'string',
260                         'cancel_message' => 'string',
261                         'close_winners_message' => 'string',
262                         'invalid_solution_message' => 'string',
263                         'leaderboard_type' => 'string',
264                         'no_winners_message' => 'string',
265                         'not_active_message' => 'string',
266                         'points_exact_first' => 'numeric|min:1|max:5',
267                         'points_exact_other' => 'numeric|min:0|max:5',
268                         'points_close_first' => 'numeric|min:0|max:5',
269                         'points_close_max' => 'integer|min:0',
270                         'points_close_other' => 'numeric|min:0|max:5',
271                         'start_message' => 'string',
272                         'stop_message' => 'string',
273                         'winners_message' => 'string',
274                 ]);
275
276                 $settings = $channel->guessing_settings;
277                 $settings[$name] = $validatedData;
278                 $channel->guessing_settings = $settings;
279                 $channel->save();
280
281                 return $this->sendChannel($channel);
282         }
283
284         protected function sendChannel(Channel $channel) {
285                 if (Gate::allows('editRestream', $channel)) {
286                         $this->unhideChannel($channel);
287                 }
288                 return $channel->toJson();
289         }
290
291         protected function sendChannels(Collection $channels) {
292                 foreach ($channels as $channel) {
293                         if (Gate::allows('editRestream', $channel)) {
294                                 $this->unhideChannel($channel);
295                         }
296                 }
297                 return $channels->toJson();
298         }
299
300         private function unhideChannel(Channel $channel) {
301                 $channel->makeVisible([
302                         'access_key',
303                         'chat',
304                         'chat_commands',
305                         'chat_settings',
306                         'guessing_settings',
307                         'join',
308                         'twitch_chat',
309                 ]);
310         }
311
312 }