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