]> git.localhorst.tv Git - alttp.git/blob - app/TwitchBot/IRCMessage.php
better quota system for contextual messages
[alttp.git] / app / TwitchBot / IRCMessage.php
1 <?php
2
3 namespace App\TwitchBot;
4
5 use App\Models\ChatLog;
6
7 class IRCMessage {
8
9         public $command = null;
10         public $params = [];
11         public $nick = null;
12         public $user = null;
13         public $host = null;
14         public $servername = null;
15         public $tags = [];
16
17         public static function fromString($message) {
18                 $msg = new static();
19
20                 $raw = rtrim($message);
21                 $processed = $raw;
22
23                 if ($processed[0] == '@') {
24                         $tags = explode(' ', $processed, 2);
25                         $processed = $tags[1];
26                         $tags = explode(';', ltrim(trim($tags[0]), '@'));
27                         foreach ($tags as $tag) {
28                                 $parts = explode('=', $tag, 2);
29                                 $msg->tags[$parts[0]] = $parts[1] == '' ? null : $parts[1];
30                         }
31                 }
32
33                 if ($processed[0] == ':') {
34                         $has_user = false;
35                         $has_host = false;
36                         $prefix = explode(' ', $processed, 2);
37                         $processed = $prefix[1];
38                         $prefix = $prefix[0][0] === ':' ? substr($prefix[0], 1) : $prefix[0];
39                         if (strpos($prefix, '!') !== false) {
40                                 $has_user = true;
41                         }
42                         if (strpos($prefix, '@') !== false) {
43                                 $has_host = true;
44                         }
45                         if ($has_user && $has_host) {
46                                 $prefix_part = explode('!', $prefix, 2);
47                                 $msg->nick = $prefix_part[0];
48                                 $prefix_part = explode('@', $prefix_part[1], 2);
49                                 $msg->user = $prefix_part[0];
50                                 $msg->host = $prefix_part[1];
51                         } else if ($has_user) {
52                                 $prefix_part = explode('!', $prefix, 2);
53                                 $msg->nick = $prefix_part[0];
54                                 $msg->user = $prefix_part[1];
55                         } else if ($has_host) {
56                                 $prefix_part = explode('@', $prefix, 2);
57                                 $msg->nick = $prefix_part[0];
58                                 $msg->host = $prefix_part[1];
59                         } else {
60                                 $msg->servername = $prefix;
61                         }
62                 }
63
64                 $command = explode(' ', $processed, 2);
65                 $msg->command = $command[0];
66                 $processed = $command[1] ?? '';
67
68                 while (strlen($processed)) {
69                         if ($processed[0] == ':') {
70                                 $msg->params[] = substr($processed, 1);
71                                 break;
72                         }
73                         $e = explode(' ', $processed, 2);
74                         $msg->params[] = $e[0];
75                         if (isset($e[1])) {
76                                 $processed = $e[1];
77                         } else {
78                                 break;
79                         }
80                 }
81
82                 return $msg;
83         }
84
85         public function encode() {
86                 $str = '';
87                 if (!empty($this->tags)) {
88                         $str .= '@';
89                         $first = true;
90                         foreach ($this->tags as $name => $value) {
91                                 if ($first) {
92                                         $first = false;
93                                 } else {
94                                         $str .= ';';
95                                 }
96                                 $str .= $name.'=';
97                                 if (!empty($value)) {
98                                         $str .= $value;
99                                 }
100                         }
101                         $str .= ' ';
102                 }
103
104                 if (!empty($this->servername)) {
105                         $str .= ':'.$this->servername.' ';
106                 } else if (!empty($this->nick)) {
107                         $str .= ':'.$this->nick;
108                         if (!empty($this->user)) {
109                                 $str .= '!'.$this->user;
110                         }
111                         if (!empty($this->host)) {
112                                 $str .= '@'.$this->host;
113                         }
114                         $str .= ' ';
115                 }
116
117                 $str .= $this->command;
118
119                 if (!empty($this->params)) {
120                         $n = count($this->params) - 1;
121                         for ($i = 0; $i < $n; ++$i) {
122                                 $str .= ' '.$this->params[$i];
123                         }
124                         $str .= ' :'.$this->params[$n];
125                 }
126
127                 return $str;
128         }
129
130         public function log() {
131                 ChatLog::create([
132                         'command' => $this->command,
133                         'nick' => $this->nick,
134                         'params' => $this->params,
135                         'tags' => $this->tags,
136                 ]);
137         }
138
139         public function tokenize() {
140                 return TokenizedMessage::fromIRC($this);
141         }
142
143         public static function join($channels) {
144                 $msg = new IRCMessage();
145                 $msg->command = 'JOIN';
146                 $msg->params[] = implode(',', $channels);
147                 return $msg;
148         }
149
150         public static function part($channels) {
151                 $msg = new IRCMessage();
152                 $msg->command = 'PART';
153                 $msg->params[] = implode(',', $channels);
154                 return $msg;
155         }
156
157         public static function ping($token = 'localhorsttv') {
158                 $msg = new IRCMessage();
159                 $msg->command = 'PING';
160                 $msg->params[] = $token;
161                 return $msg;
162         }
163
164         public static function privmsg($target, $message) {
165                 $msg = new IRCMessage();
166                 $msg->command = 'PRIVMSG';
167                 $msg->params[] = $target;
168                 $msg->params[] = $message;
169                 return $msg;
170         }
171
172         public function getPrivMsgTarget() {
173                 if (!empty($this->params)) {
174                         return $this->params[0];
175                 }
176                 return '';
177         }
178
179         public function getText() {
180                 if (!empty($this->params)) {
181                         return $this->params[count($this->params) - 1];
182                 }
183                 return '';
184         }
185
186         public function isNotice() {
187                 return $this->command == 'NOTICE';
188         }
189
190         public function isPing() {
191                 return $this->command == 'PING';
192         }
193
194         public function isPong() {
195                 return $this->command == 'PONG';
196         }
197
198         public function isPrivMsg() {
199                 return $this->command == 'PRIVMSG';
200         }
201
202         public function isOwner() {
203                 return substr($this->getPrivMsgTarget(), 1) == $this->nick;
204         }
205
206         public function isMod() {
207                 return $this->isOwner() || (isset($this->tags['mod']) && $this->tags['mod'] == '1');
208         }
209
210         public function makePong() {
211                 $msg = new IRCMessage();
212                 $msg->command = 'PONG';
213                 $msg->params = array_values($this->params);
214                 return $msg;
215         }
216
217 }
218
219 ?>