5 use Illuminate\Database\Eloquent\Factories\HasFactory;
6 use Illuminate\Database\Eloquent\Model;
8 class Channel extends Model
12 public function getCurrentEpisode() {
13 return $this->episodes()
14 ->where('start', '<', now()->subMinutes(10))
15 ->orderBy('start', 'DESC')
19 public function getGuessingLeaderboard() {
20 return $this->winners()->selectRaw('(select t2.uname from guessing_winners t2 where t2.uid = guessing_winners.uid order by created_at desc limit 1) as name, sum(score) as score')->groupBy('uid')->orderBy('score', 'desc')->limit(10)->get();
23 public function hasActiveGuessing() {
24 return !is_null($this->guessing_start);
27 public function isAcceptingGuesses() {
28 return !is_null($this->guessing_start) && is_null($this->guessing_end);
31 public function startGuessing($type) {
32 $this->guessing_type = $type;
33 $this->guessing_start = now();
37 public function stopGuessing() {
38 $this->guessing_end = now();
42 public function getGuessingSetting($name, $default = null) {
43 if (empty($this->guessing_settings) ||
44 empty($this->guessing_type) ||
45 !array_key_exists($this->guessing_type, $this->guessing_settings) ||
46 !array_key_exists($name, $this->guessing_settings[$this->guessing_type])
50 return $this->guessing_settings[$this->guessing_type][$name];
53 public function solveGuessing($solution) {
54 $start = $this->guessing_start;
55 $end = is_null($this->guessing_end) ? now() : $this->guessing_end;
56 $guesses = $this->guesses()->whereBetween('created_at', [$start, $end])->orderBy('created_at', 'ASC')->get();
58 foreach ($guesses as $guess) {
59 $unique_guesses[$guess->uid] = $guess;
62 foreach ($unique_guesses as $guess) {
63 if ($guess->guess == $solution) {
64 $candidates[] = $guess;
67 if (empty($candidates) && is_numeric($solution)) {
69 foreach ($unique_guesses as $guess) {
70 $distance = abs(intval($guess->guess) - intval($solution));
71 if (is_null($min_distance) || $distance == $min_distance) {
72 $candidates[] = $guess;
73 } else if ($distance < $min_distance) {
74 $candidates = [$guess];
75 $min_distance = $distance;
81 foreach ($candidates as $candidate) {
82 $score = $this->scoreGuessing($solution, $candidate->guess, $first);
83 $winner = new GuessingWinner();
84 $winner->channel()->associate($this);
85 $winner->pod = $start;
86 $winner->uid = $candidate->uid;
87 $winner->uname = $candidate->uname;
88 $winner->guess = $candidate->guess;
89 $winner->solution = $solution;
90 $winner->score = $score;
98 public function clearGuessing() {
99 $this->guessing_start = null;
100 $this->guessing_end = null;
104 public function registerGuess($uid, $uname, $guess) {
105 $model = new GuessingGuess();
106 $model->channel()->associate($this);
108 $model->uname = $uname;
109 $model->guess = $guess;
113 public function scoreGuessing($solution, $guess, $first) {
114 if ($guess == $solution) {
116 return $this->getGuessingSetting('points_exact_first', 1);
118 return $this->getGuessingSetting('points_exact_other', 1);
120 $distance = abs(intval($guess) - intval($solution));
121 if ($distance <= $this->getGuessingSetting('points_close_max', 3)) {
123 return $this->getGuessingSetting('points_close_first', 1);
125 return $this->getGuessingSetting('points_close_other', 1);
130 public function isValidGuess($solution) {
131 if ($this->guessing_type == 'gtbk') {
132 $int_solution = intval($solution);
133 return $int_solution > 0 && $int_solution < 23;
138 public function crews() {
139 return $this->hasMany(ChannelCrew::class);
142 public function episodes() {
143 return $this->belongsToMany(Episode::class)
144 ->using(Restream::class)
145 ->withPivot('accept_comms', 'accept_tracker');
148 public function guesses() {
149 return $this->hasMany(GuessingGuess::class);
152 public function organization() {
153 return $this->belongsTo(Organization::class);
156 public function winners() {
157 return $this->hasMany(GuessingWinner::class);
162 'chat_commands' => 'array',
163 'chat_settings' => 'array',
164 'guessing_settings' => 'array',
165 'guessing_start' => 'datetime',
166 'guessing_end' => 'datetime',
167 'languages' => 'array',
171 protected $hidden = [