+<?php
+
+namespace App\TwitchBot;
+
+use App\Models\Channel;
+use App\Models\ChatLog;
+
+class TwitchChatBot extends TwitchBot {
+
+ public function __construct() {
+ parent::__construct('horstiebot');
+ $this->channels = Channel::where('twitch_chat', '!=', '')->where('chat', '=', true)->get();
+ foreach ($this->channels as $channel) {
+ $this->notes[$channel->id] = [
+ 'last_read' => 0,
+ 'last_write' => time(),
+ 'read_since_last_write' => 0,
+ 'wait_msgs' => $this->randomWaitMsgs($channel),
+ 'wait_time' => $this->randomWaitTime($channel),
+ ];
+ }
+ $this->startTimer();
+ }
+
+ public function joinChannels() {
+ $this->getLogger()->info('joining channels');
+ $names = [];
+ foreach ($this->channels as $channel) {
+ $names[] = $channel->twitch_chat;
+ }
+ $chunks = array_chunk($names, 10);
+ foreach ($chunks as $chunk) {
+ $this->sendIRCMessage(IRCMessage::join($chunk));
+ }
+ }
+
+ public function logMessage(IRCMessage $msg) {
+ $channel = $this->getMessageChannel($msg);
+ if ($channel && !$channel->join) {
+ $msg->log();
+ }
+ }
+
+ public function handlePrivMsg(IRCMessage $msg) {
+ if ($msg->nick == 'horstiebot') return;
+ $channel = $this->getMessageChannel($msg);
+ if (!$channel) return;
+ $this->tagChannelRead($channel);
+ }
+
+
+ private function startTimer() {
+ $this->getLoop()->addPeriodicTimer(1, function () {
+ if (!$this->isReady()) return;
+ foreach ($this->channels as $channel) {
+ $this->decideSend($channel);
+ }
+ });
+ }
+
+ private function decideSend(Channel $channel) {
+ $notes = $this->notes[$channel->id];
+ if ($notes['read_since_last_write'] < $notes['wait_msgs']) {
+ return;
+ }
+ if (time() - $notes['last_write'] < $notes['wait_time']) {
+ return;
+ }
+ if ($notes['read_since_last_write'] == $notes['wait_msgs'] && time() - $notes['last_read'] < 3) {
+ // don't immediately respond if we crossed the msg threshold last
+ return;
+ }
+ $text = $this->randomMsg($channel);
+ if (!$text) return;
+ $this->tagChannelWrite($channel);
+ $this->sendIRCMessage(IRCMessage::privmsg($channel->twitch_chat, $text));
+ }
+
+ private function randomMsg(Channel $channel) {
+ $line = ChatLog::where('type', '=', 'chat')->where('banned', '=', false)->inRandomOrder()->first();
+ return $line->text_content;
+ }
+
+ private function randomWaitMsgs(Channel $channel) {
+ return random_int(1, 10);
+ }
+
+ private function randomWaitTime(Channel $channel) {
+ return random_int(1, 1800);
+ }
+
+ private function tagChannelRead(Channel $channel) {
+ $this->notes[$channel->id]['last_read'] = time();
+ ++$this->notes[$channel->id]['read_since_last_write'];
+ }
+
+ private function tagChannelWrite(Channel $channel) {
+ $this->notes[$channel->id]['last_write'] = time();
+ $this->notes[$channel->id]['read_since_last_write'] = 0;
+ $this->notes[$channel->id]['wait_msgs'] = $this->randomWaitMsgs($channel);
+ $this->notes[$channel->id]['wait_time'] = $this->randomWaitTime($channel);
+ }
+
+ private $channels;
+ private $notes = [];
+
+}