]>
Commit | Line | Data |
---|---|---|
1 | <?php | |
2 | require_once UPATH."/inc/connection.php"; | |
3 | ||
4 | /** | |
5 | * Does a complete checkup of the network. | |
6 | */ | |
7 | class CheckUp | |
8 | { | |
9 | const SCORE_PERFECT = 0; | |
10 | const SCORE_NOT_BAD = 1; | |
11 | const SCORE_COULD_BE_BETTER = 10; | |
12 | const SCORE_NEEDS_ATTENTION = 25; | |
13 | const SCORE_VERY_BAD = 50; | |
14 | ||
15 | public $num_of_problems = [ | |
16 | "chanmodes" => 0, | |
17 | "usermodes" => 0, | |
18 | "modules" => 0, | |
19 | "servers" => 0, | |
20 | "other" => 0, | |
21 | ]; | |
22 | public $problems = [ | |
23 | "chanmodes" => [], | |
24 | "usermodes" => [], | |
25 | "modules" => [], | |
26 | "servers" => [], | |
27 | "other" => [], | |
28 | ]; | |
29 | ||
30 | public $serverlist = []; | |
31 | ||
32 | /** | |
33 | * Construct0r | |
34 | */ | |
35 | function __construct() | |
36 | { | |
37 | global $rpc; | |
38 | ||
39 | $this->serverlist = $rpc->server()->getAll(); | |
40 | $this->chanmode_check(); | |
41 | $this->usermode_check(); | |
42 | $this->module_check(); | |
43 | $this->server_check(); | |
44 | ||
45 | } | |
46 | ||
47 | public function total() | |
48 | { | |
49 | $count = 0; | |
50 | foreach ($this->num_of_problems as $problem) | |
51 | $count += $problem; | |
52 | return $count; | |
53 | } | |
54 | ||
55 | public function equivalate() | |
56 | { | |
57 | $total = $this->total(); | |
58 | if ($total == self::SCORE_PERFECT) | |
59 | return "Perfect"; | |
60 | elseif ($total < self::SCORE_COULD_BE_BETTER) | |
61 | return "Not Bad"; | |
62 | elseif ($total < self::SCORE_NEEDS_ATTENTION) | |
63 | return "Could Be Better"; | |
64 | elseif ($total < self::SCORE_VERY_BAD) | |
65 | return "Needs Attention"; | |
66 | else return "Very Poor"; | |
67 | } | |
68 | public function badgestyle() | |
69 | { | |
70 | $total = $this->total(); | |
71 | if ($total == self::SCORE_PERFECT) | |
72 | return "success"; | |
73 | elseif ($total < self::SCORE_COULD_BE_BETTER) | |
74 | return "info"; | |
75 | elseif ($total < self::SCORE_NEEDS_ATTENTION) | |
76 | return "warning"; | |
77 | elseif ($total < self::SCORE_VERY_BAD) | |
78 | return "danger"; | |
79 | else return "dark"; | |
80 | ||
81 | } | |
82 | ||
83 | /** | |
84 | * Checks channel modes of servers against other servers | |
85 | * @return void | |
86 | */ | |
87 | function chanmode_check() : void | |
88 | { | |
89 | foreach($this->serverlist as $s) // cycle through each server | |
90 | { | |
91 | /* hmm if it's not unreal, skip it too */ | |
92 | if (!isset($s->server->features->software) || !strstr($s->server->features->software,"UnrealIRCd")) | |
93 | continue; | |
94 | /* make a single string from the array of groups */ | |
95 | $ourchmodes = ""; | |
96 | foreach ($s->server->features->chanmodes as $set) | |
97 | for ($i=0; isset($set[$i]); $i++) | |
98 | strcat($ourchmodes,$set[$i]); | |
99 | ||
100 | /* take a look at every other server... yep, we do this for every server */ | |
101 | foreach ($this->serverlist as $serv) | |
102 | { | |
103 | /* except for ourselves lol */ | |
104 | if ($serv->id == $s->id) | |
105 | continue; | |
106 | ||
107 | /* hmm if it's not unreal, skip it too */ | |
108 | if (!isset($serv->server->features->software) || !strstr($serv->server->features->software,"UnrealIRCd")) | |
109 | continue; | |
110 | ||
111 | /* make a single string from the array of groups but for them this time */ | |
112 | $theirchmodes = ""; | |
113 | foreach ($serv->server->features->chanmodes as $set) | |
114 | for ($i=0; isset($set[$i]); $i++) | |
115 | strcat($theirchmodes,$set[$i]); | |
116 | ||
117 | /* check ours against theirs */ | |
118 | for ($i=0; isset($ourchmodes[$i]) && $m = $ourchmodes[$i]; $i++) | |
119 | { | |
120 | /* if we have a mode that they don't have */ | |
121 | if (!strstr($theirchmodes, $m)) | |
122 | { | |
123 | ++$this->num_of_problems['chanmodes']; | |
124 | $this->problems['chanmodes'][] = "Channel mode <code>$m</code> is present on <code>$s->name</code> but missing on <code>$serv->name</code>"; | |
125 | } | |
126 | } | |
127 | } | |
128 | } | |
129 | } | |
130 | ||
131 | /** | |
132 | * Checks user modes of servers against other servers | |
133 | * @return void | |
134 | */ | |
135 | function usermode_check() : void | |
136 | { | |
137 | foreach($this->serverlist as $s) | |
138 | { | |
139 | /* hmm if it's not unreal, skip it too */ | |
140 | if (!isset($s->server->features->software) || !strstr($s->server->features->software,"UnrealIRCd")) | |
141 | continue; | |
142 | /* make a single string from the array of groups */ | |
143 | $ourumodes = $s->server->features->usermodes; | |
144 | ||
145 | /* take a look at every other server... yep, we do this for every server */ | |
146 | foreach ($this->serverlist as $serv) | |
147 | { | |
148 | /* except for ourselves lol */ | |
149 | if ($serv->id == $s->id) | |
150 | continue; | |
151 | ||
152 | /* hmm if it's not unreal, skip it too */ | |
153 | if (!isset($serv->server->features->software) || !strstr($serv->server->features->software,"UnrealIRCd")) | |
154 | continue; | |
155 | ||
156 | $theirumodes = $serv->server->features->usermodes; | |
157 | ||
158 | /* check ours against theirs */ | |
159 | for ($i=0; isset($ourumodes[$i]) && $m = $ourumodes[$i]; $i++) | |
160 | { | |
161 | /* if we have a mode that they don't have */ | |
162 | if (!strstr($theirumodes, $m)) | |
163 | { | |
164 | ++$this->num_of_problems['usermodes']; | |
165 | $this->problems['usermodes'][] = "User mode <code>$m</code> is present on <code>$s->name</code> but missing on <code>$serv->name</code>"; | |
166 | } | |
167 | } | |
168 | } | |
169 | } | |
170 | } | |
171 | ||
172 | /** | |
173 | * Checks modules of servers against other servers | |
174 | * @return void | |
175 | */ | |
176 | function module_check() : void | |
177 | { | |
178 | global $rpc; | |
179 | foreach ($this->serverlist as $s) | |
180 | { | |
181 | /* hmm if it's not unreal, skip it too */ | |
182 | if (!isset($s->server->features->software) || !strstr($s->server->features->software,"UnrealIRCd")) | |
183 | continue; | |
184 | $ourmods = sort_mods(json_decode(json_encode(@$rpc->server()->module_list($s->id)->list), true)); | |
185 | ||
186 | // doesn't support that yet | |
187 | if (empty($ourmods)) | |
188 | continue; | |
189 | ||
190 | foreach ($this->serverlist as $serv) | |
191 | { | |
192 | /* except for ourselves lol */ | |
193 | if ($serv->id == $s->id) | |
194 | continue; | |
195 | ||
196 | /* hmm if it's not unreal, skip it too */ | |
197 | if (!isset($serv->server->features->software) || !strstr($serv->server->features->software,"UnrealIRCd")) | |
198 | continue; | |
199 | ||
200 | $theirmods = sort_mods(json_decode(json_encode(@$rpc->server()->module_list($serv->id)->list), true)); | |
201 | ||
202 | // doesn't support that yet | |
203 | if (empty($theirmods)) | |
204 | continue; | |
205 | // we only check if theirs doesn't match ours | |
206 | foreach ($theirmods as $name => $version) | |
207 | { | |
208 | if (!isset($ourmods[$name])) // we don't have that module | |
209 | { | |
210 | ++$this->num_of_problems['modules']; | |
211 | $this->problems['modules'][] = "Module <code>$name</code> exists on <code>$serv->name</code> but not <code>$s->name</code>"; | |
212 | } | |
213 | else if ((int)$version > (int)$ourmods[$name]) | |
214 | { | |
215 | ++$this->num_of_problems['modules']; | |
216 | $this->problems['modules'][] = "Module <code>$name</code> on <code>$serv->name</code> is newer than on <code>$s->name</code>"; | |
217 | } | |
218 | } | |
219 | } | |
220 | } | |
221 | } | |
222 | ||
223 | function server_check() : void | |
224 | { | |
225 | global $rpc; | |
226 | foreach ($this->serverlist as $s) | |
227 | { | |
228 | /* hmm if it's not unreal, skip it too */ | |
229 | if (!isset($s->server->features->software) || !strstr($s->server->features->software,"UnrealIRCd")) | |
230 | continue; | |
231 | // protocol checking | |
232 | $ours = (int)$s->server->features->protocol; | |
233 | foreach ($this->serverlist as $serv) | |
234 | { | |
235 | if (!isset($serv->server->features->software) || !strstr($serv->server->features->software,"UnrealIRCd")) | |
236 | continue; | |
237 | ||
238 | $theirs = (int)$serv->server->features->protocol; | |
239 | ||
240 | if ($ours < $theirs) | |
241 | { | |
242 | ++$this->num_of_problems['servers']; | |
243 | $this->problems['servers'][] = "Protocol mismatch: <code>$serv->name</code> using protocol <code>$theirs</code> but <code>$s->name</code> using protocol <code>$ours</code>. <a href=\"https://www.unrealircd.org/docs/Upgrading\">Click for upgrade documentation.</a>"; | |
244 | } | |
245 | } | |
246 | ||
247 | // EOL checking | |
248 | $tok = explode('-', $s->server->features->software); | |
249 | if ((int)$tok[1] < 6) | |
250 | { | |
251 | ++$this->num_of_problems['servers']; | |
252 | $this->problems['servers'][] = "EOL: <code>$s->name</code> (".$s->server->features->software.") is running old unsupported software which is no longer receiving security updates. <a href=\"https://www.unrealircd.org/docs/Upgrading\">Click here for upgrade documentation.</a>"; | |
253 | } | |
254 | } | |
255 | } | |
256 | /* Print a widget easy! */ | |
257 | function __toString() | |
258 | { | |
259 | return ' | |
260 | <a style="width:fit-content" id="health_banner" class="card alert text-dark alert-'.(!$this->total() ? "success" : "danger").'" role="alert" href="'.get_config("base_url").'tools/checkup.php"> | |
261 | <i class="fa-solid fa-heart-pulse fa-2x" style="position:absolute;top:10px;left:10px"></i> | |
262 | <h4 class="alert-heading mt-0 mb-0" style="padding-left:40px;">Network Health </h4><span style="position:relative;top:5px;" class="ml-3 badge badge-'.$this->badgestyle().'">'.$this->equivalate().'</span> | |
263 | <p class="ml-4 mt-2 mb-0">Found <b>'.$this->total().'</b> problems in total.</p> | |
264 | </a>'; | |
265 | } | |
266 | ||
267 | public function toTable(Array $array) | |
268 | { | |
269 | echo "<table class=\"table table-striped\">\n"; | |
270 | foreach ($array as $key => $value) | |
271 | { | |
272 | echo "\t<tr><td>$value</td></tr>\n"; | |
273 | } | |
274 | echo "</table>\n"; | |
275 | } | |
276 | } | |
277 | ||
278 | function sort_mods($mods) | |
279 | { | |
280 | $list = []; | |
281 | if (!$mods) | |
282 | return $list; | |
283 | foreach($mods as $mod) | |
284 | $list[$mod["name"]] = $mod["version"]; | |
285 | ||
286 | return $list; | |
287 | } | |
288 | ||
289 | function checkup_widget() | |
290 | { | |
291 | $ch = new CheckUp(); | |
292 | echo $ch; | |
293 | } |