index.php (264827B)
1 <?php 2 3 // Turn off error reporting and display 4 error_reporting(0); 5 ini_set('display_errors', 0); 6 ini_set('display_startup_errors', 0); 7 ini_set('log_errors', 1); 8 ini_set('html_errors', 0); 9 10 /* 11 * status codes 12 * 0 - Kicked/Banned 13 * 1 - Guest 14 * 2 - Applicant 15 * 3 - Member 16 * 4 - System message 17 * 5 - Moderator 18 * 6 - Super-Moderator 19 * 7 - Admin 20 * 8 - Super-Admin 21 * 9 - Private messages 22 */ 23 24 // Dasho (https://dasho.dev) 25 26 send_headers(); 27 // initialize and load variables/configuration 28 $I = []; // Translations 29 $L = []; // Languages 30 $U = []; // This user data 31 $db; // Database connection 32 $memcached; // Memcached connection 33 $language; // user selected language 34 load_config(); 35 // set session variable to cookie if cookies are enabled 36 if (!isset($_REQUEST['session']) && isset($_COOKIE[COOKIENAME])) { 37 38 //Modification that prevents users from doing unwanted things (for example unintentionally deleting their account), if someone else posts a malicious link. 39 // MODIFICATION added logout to list of unwanted things 40 // MODIFICATION fixed: allow setup actions when they're legitimate POST requests or have 'do' parameter (admin operations) 41 if (isset($_REQUEST['action']) && ($_REQUEST['action'] === 'profile' || $_REQUEST['action'] === 'post' || $_REQUEST['action'] === 'admin' || $_REQUEST['action'] === 'logout')) { 42 $_REQUEST['action'] = 'login'; 43 } elseif (isset($_REQUEST['action']) && $_REQUEST['action'] === 'setup' && !isset($_REQUEST['do']) && $_SERVER['REQUEST_METHOD'] !== 'POST') { 44 $_REQUEST['action'] = 'login'; 45 } 46 $_REQUEST['session'] = $_COOKIE[COOKIENAME]; 47 } 48 $_REQUEST['session'] = preg_replace('/[^0-9a-zA-Z]/', '', $_REQUEST['session'] ?? ''); 49 load_lang(); 50 check_db(); 51 cron(); 52 route(); 53 54 // main program: decide what to do based on queries 55 function route() 56 { 57 global $U; 58 if (!isset($_REQUEST['action'])) { 59 send_login(); 60 } elseif ($_REQUEST['action'] === 'view') { 61 check_session(); 62 //Modification chat rooms 63 if (isset($_REQUEST['room'])) { 64 change_room(); 65 check_session(); 66 } 67 // show_rooms('true'); 68 send_messages(); 69 } elseif ($_REQUEST['action'] === 'redirect' && !empty($_REQUEST['url'])) { 70 send_redirect($_REQUEST['url']); 71 } elseif ($_REQUEST['action'] === 'rooms') { 72 check_session(); 73 rooms(); 74 } elseif ($_REQUEST['action'] === 'wait') { 75 parse_sessions(); 76 send_waiting_room(); 77 } elseif ($_REQUEST['action'] === 'post') { 78 check_session(); 79 if (isset($_REQUEST['kick']) && isset($_REQUEST['sendto']) && $_REQUEST['sendto'] !== ('s 48' || 's 56' || 's 65')) { 80 //Modification to allow members to kick guests, if memdel (DEL-Buttons) enabled 81 if ($U['status'] >= 5 || ($U['status'] >= 3 && get_count_mods() == 0 && get_setting('memkick')) || ($U['status'] >= 3 && (int)get_setting('memdel') === 2)) { 82 if (isset($_REQUEST['what']) && $_REQUEST['what'] === 'purge') { 83 kick_chatter([$_REQUEST['sendto']], $_REQUEST['message'], true); 84 } else { 85 kick_chatter([$_REQUEST['sendto']], $_REQUEST['message'], false); 86 } 87 } 88 } elseif (isset($_REQUEST['message']) && isset($_REQUEST['sendto'])) { 89 send_post(validate_input()); 90 } 91 send_post(); 92 } elseif ($_REQUEST['action'] === 'login') { 93 check_login(); 94 send_frameset(); 95 } elseif ($_REQUEST['action'] === 'controls') { 96 check_session(); 97 send_controls(); 98 } elseif ($_REQUEST['action'] === 'greeting') { 99 check_session(); 100 send_greeting(); 101 } elseif ($_REQUEST['action'] === 'delete') { 102 check_session(); 103 if ($_REQUEST['what'] === 'all') { 104 if (isset($_REQUEST['confirm'])) { 105 del_all_messages($U['nickname'], $U['status'] == 1 ? $U['entry'] : 0); 106 } else { 107 send_del_confirm(); 108 } 109 } elseif ($_REQUEST['what'] === 'last') { 110 del_last_message(); 111 } 112 send_post(); 113 } elseif ($_REQUEST['action'] === 'profile') { 114 check_session(); 115 $arg = ''; 116 if (!isset($_REQUEST['do'])) { 117 } elseif ($_REQUEST['do'] === 'save') { 118 $arg = save_profile(); 119 } elseif ($_REQUEST['do'] === 'delete') { 120 if (isset($_REQUEST['confirm'])) { 121 delete_account(); 122 } else { 123 send_delete_account(); 124 } 125 } 126 send_profile($arg); 127 } elseif ($_REQUEST['action'] === 'logout') { 128 kill_session(); 129 send_logout(); 130 } elseif ($_REQUEST['action'] === 'colours') { 131 check_session(); 132 send_colours(); 133 } elseif ($_REQUEST['action'] === 'notes') { 134 check_session(); 135 $sparenotesaccess = (int) get_setting('sparenotesaccess'); 136 if (isset($_REQUEST['do']) && $_REQUEST['do'] === 'admin' && $U['status'] > 6) { 137 send_notes(0); 138 } elseif (isset($_REQUEST['do']) && $_REQUEST['do'] === 'staff' && $U['status'] >= 5) { 139 send_notes(1); 140 // Modification Spare Notes 141 } elseif (isset($_REQUEST['do']) && $_REQUEST['do'] === 'spare' && $U['status'] >= $sparenotesaccess) { 142 send_notes(3); 143 } 144 if ($U['status'] < 3 || !get_setting('personalnotes')) { 145 send_access_denied(); 146 } 147 send_notes(2); 148 } elseif ($_REQUEST['action'] === 'help') { 149 check_session(); 150 send_help(); 151 } elseif ($_REQUEST['action'] === 'inbox') { 152 check_session(); 153 if (isset($_REQUEST['do'])) { 154 clean_inbox_selected(); 155 } 156 send_inbox(); 157 } elseif ($_REQUEST['action'] === 'download') { 158 send_download(); 159 } elseif ($_REQUEST['action'] === 'admin') { 160 check_session(); 161 send_admin(route_admin()); 162 //MODIFICATION DEL-BUTTONS 3 Lines added to enable delete buttons in front of each message. 163 } elseif ($_REQUEST['action'] === 'admin_clean_message') { 164 check_session(); 165 166 //These lines allows members to use the DEL-buttons according to the memdel setting (0 = not allowed , 2 = allowed, 1 = allowed if not mod is present and if DEL-Buttons are activated for members.) 167 $memdel = (int)get_setting('memdel'); 168 if (($U['status'] >= 5) || ($U['status'] >= 3 && $memdel === 2) || ($U['status'] >= 3 && get_count_mods() == 0 && $memdel === 1)) { 169 clean_selected($U['status'], $U['nickname']); 170 } 171 send_messages(); 172 173 //MODIFICATION gallery 174 } elseif ($_REQUEST['action'] === 'gallery') { 175 check_session(); //to get $U['status'] 176 if (!isset($_REQUEST['do'])) { 177 send_gallery(); 178 } else { 179 send_gallery($_REQUEST['do']); 180 } 181 //MODIFICATION links page 182 } elseif ($_REQUEST['action'] === 'links') { 183 check_session(); //to allow links page only for logged in users. 184 send_links_page(); 185 186 //Forum Button was moved to the post box (function send_post) 187 /* 188 }elseif($_REQUEST['action']==='forum'){ 189 check_session(); //to allow link to form only for logged in users. 190 send_to_forum(); 191 */ 192 } elseif ($_REQUEST['action'] === 'setup') { 193 route_setup(); 194 } else { 195 send_login(); 196 } 197 } 198 199 function route_admin() 200 { 201 global $U, $db; 202 203 if ($U['status'] < 5) { 204 send_access_denied(); 205 } 206 //Modification chat rooms 207 $roomcreateaccess = (int) get_setting('roomcreateaccess'); 208 if (!isset($_REQUEST['do'])) { 209 } elseif ($_REQUEST['do'] === 'clean') { 210 if ($_REQUEST['what'] === 'choose') { 211 send_choose_messages(); 212 } elseif ($_REQUEST['what'] === 'selected') { 213 clean_selected($U['status'], $U['nickname']); 214 } elseif ($_REQUEST['what'] === 'chat') { 215 clean_chat(); 216 } elseif ($_REQUEST['what'] === 'room') { 217 clean_room(); 218 } elseif ($_REQUEST['what'] === 'nick') { 219 $stmt = $db->prepare('SELECT null FROM ' . PREFIX . 'members WHERE nickname=? AND status>=?;'); 220 $stmt->execute([$_REQUEST['nickname'], $U['status']]); 221 if (!$stmt->fetch(PDO::FETCH_ASSOC)) { 222 del_all_messages($_REQUEST['nickname'], 0); 223 } 224 } 225 } elseif ($_REQUEST['do'] === 'kick') { 226 if (isset($_REQUEST['name'])) { 227 if (isset($_REQUEST['what']) && $_REQUEST['what'] === 'purge') { 228 kick_chatter($_REQUEST['name'], $_REQUEST['kickmessage'], true); 229 } else { 230 kick_chatter($_REQUEST['name'], $_REQUEST['kickmessage'], false); 231 } 232 } 233 } elseif ($_REQUEST['do'] === 'logout') { 234 if (isset($_REQUEST['name'])) { 235 logout_chatter($_REQUEST['name']); 236 } 237 } elseif ($_REQUEST['do'] === 'sessions') { 238 if (isset($_REQUEST['kick']) && isset($_REQUEST['nick'])) { 239 kick_chatter([$_REQUEST['nick']], '', false); 240 } elseif (isset($_REQUEST['logout']) && isset($_REQUEST['nick'])) { 241 logout_chatter([$_REQUEST['nick']], '', false); 242 } 243 send_sessions(); 244 // MODIFICATION only admins can register to member 245 } elseif ($_REQUEST['do'] === 'register' && $U['status'] > 6) { 246 return register_guest(3, $_REQUEST['name']); 247 } elseif ($_REQUEST['do'] === 'superguest') { 248 return register_guest(2, $_REQUEST['name']); 249 // MODIFICATION only admins can change status 250 } elseif ($_REQUEST['do'] === 'status' && $U['status'] > 6) { 251 return change_status($_REQUEST['name'], $_REQUEST['set']); 252 // MODIFICATION only admins can register new members 253 } elseif ($_REQUEST['do'] === 'regnew' && $U['status'] > 6) { 254 return register_new($_REQUEST['name'], $_REQUEST['pass']); 255 } elseif ($_REQUEST['do'] === 'approve') { 256 approve_session(); 257 send_approve_waiting(); 258 } elseif ($_REQUEST['do'] === 'guestaccess') { 259 if (isset($_REQUEST['guestaccess']) && preg_match('/^[0123]$/', $_REQUEST['guestaccess'])) { 260 update_setting('guestaccess', $_REQUEST['guestaccess']); 261 } 262 //MODIFICATION 2019-08-28 line changed. only smods (status = 6) with name Jonie , admins and above can view or change filters. 263 } elseif (($_REQUEST['do'] === 'filter' && $U['status'] >= 7) || ($_REQUEST['do'] === 'filter' && $U['status'] >= 6 && $U['nickname'] === 'Jonie')) { 264 send_filter(manage_filter()); 265 //MODIFICATION 2019-08-28 line changed. only smods (status = 6) with name Jonie , admins and above can view or change linkfilters. 266 } elseif (($_REQUEST['do'] === 'linkfilter' && $U['status'] >= 7) || ($_REQUEST['do'] === 'linkfilter' && $U['status'] >= 6 && $U['nickname'] === 'Jonie')) { 267 send_linkfilter(manage_linkfilter()); 268 } elseif ($_REQUEST['do'] === 'lastlogin' && $U['status'] >= 7) { 269 send_lastlogin(); 270 } elseif ($_REQUEST['do'] === 'topic') { 271 //Modification "topic with html-code" (2 Lines) 272 if (isset($_REQUEST['topic']) && $U['status'] >= 7) { 273 update_setting('topic', $_REQUEST['topic']); 274 } 275 // MODIFICATION only admins can reset passwords 276 } elseif ($_REQUEST['do'] === 'passreset' && $U['status'] > 6) { 277 return passreset($_REQUEST['name'], $_REQUEST['pass']); 278 //Modification chat rooms 279 } elseif ($_REQUEST['do'] === 'rooms' && $U['status'] >= $roomcreateaccess) { 280 send_rooms(manage_rooms()); 281 } 282 } 283 284 function route_setup() 285 { 286 global $U; 287 if (!valid_admin()) { 288 send_alogin(); 289 } 290 //MODIFICATION incognito setting only for super admin 291 $C['bool_settings'] = ['suguests', 'imgembed', 'timestamps', 'trackip', 'memkick', 'forceredirect', 'sendmail', 'modfallback', 'disablepm', 'eninbox', 'enablegreeting', 'sortupdown', 'hidechatters', 'personalnotes', 'filtermodkick']; 292 $C['colour_settings'] = ['colbg', 'coltxt']; 293 $C['msg_settings'] = ['msgenter', 'msgexit', 'msgmemreg', 'msgsureg', 'msgkick', 'msgmultikick', 'msgallkick', 'msgclean', 'msgsendall', 'msgsendmem', 'msgsendmod', 'msgsendadm', 'msgsendprv', 'msgattache']; 294 $C['number_settings'] = ['memberexpire', 'guestexpire', 'kickpenalty', 'entrywait', 'captchatime', 'messageexpire', 'messagelimit', 'maxmessage', 'maxname', 'minpass', 'defaultrefresh', 'numnotes', 'maxuploadsize', 'enfileupload']; 295 $C['textarea_settings'] = ['rulestxt', 'css', 'disabletext']; 296 $C['text_settings'] = ['dateformat', 'captchachars', 'redirect', 'chatname', 'mailsender', 'mailreceiver', 'nickregex', 'passregex', 'externalcss']; 297 298 //MODIFICATION for links page. setting links and linksenabled added. 299 //MODIFICATION for DEL-Buttons: setting memdel added. 300 //MODIFICATION for galleryaccess: setting galleryaccess added. 301 //MODIFICATION for forumbtnaccess: setting forumbtnaccess added. 302 //MODIFICATION for forumbtnlink: setting forumbtnlink added. 303 //MODIFICATION for frontpagetext: setting frontpagetext added. 304 //MODIFICATION for adminjoinleavemsg: setting adminjoinleavemsg 305 //MODIFICATION for clickablne nicknames: setting clickablenicknamesglobal 306 //MODIFICATION for spare notes: setting sparenotesname, setting sparenotesaccess 307 //MODIFICATION for chat rooms: setting roomcreateaccess, setting roomexpire, setting channelvisinroom 308 $C['settings'] = array_merge(['guestaccess', 'englobalpass', 'globalpass', 'captcha', 'dismemcaptcha', 'topic', 'guestreg', 'defaulttz', 'links', 'linksenabled', 'memdel', 'galleryaccess', 'forumbtnaccess', 'forumbtnlink', 'frontpagetext', 'adminjoinleavemsg', 'clickablenicknamesglobal', 'sparenotesname', 'sparenotesaccess', 'roomcreateaccess', 'roomexpire', 'channelvisinroom'], $C['bool_settings'], $C['colour_settings'], $C['msg_settings'], $C['number_settings'], $C['textarea_settings'], $C['text_settings']); // All settings in the database 309 310 311 //Modification Super Admin settings 312 //MODIFICATION for modsdeladminmsg: Super Admin setting modsdeladminmsg added 313 $C_SAdmin = $C; 314 $C_SAdmin['settings'] = array_merge($C['settings'], ['modsdeladminmsg', 'incognito']); 315 316 317 //Modificatoin Super Admin settings 318 if (!isset($_REQUEST['do'])) { 319 } elseif ($_REQUEST['do'] === 'save' && $U['status'] == 8) { 320 save_setup($C_SAdmin); 321 } elseif ($_REQUEST['do'] === 'save') { 322 save_setup($C); 323 } elseif ($_REQUEST['do'] === 'backup' && $U['status'] == 8) { 324 send_backup($C); 325 } elseif ($_REQUEST['do'] === 'restore' && $U['status'] == 8) { 326 restore_backup($C); 327 send_backup($C); 328 } elseif ($_REQUEST['do'] === 'destroy' && $U['status'] == 8) { 329 if (isset($_REQUEST['confirm'])) { 330 destroy_chat($C); 331 } else { 332 send_destroy_chat(); 333 } 334 } 335 send_setup($C); 336 } 337 338 // html output subs 339 function print_stylesheet($init = false) 340 { 341 global $U; 342 //default css 343 echo '<style type="text/css">'; 344 echo 'body{background-color:#000000;color:#FFFFFF;font-size:14px;text-align:center;} body .rooms {background-color: transparent !important;}'; 345 echo 'a:visited{color:#B33CB4;} a:active{color:#FF0033;} a:link{color:#0000FF;} #messages{word-wrap:break-word;} '; 346 echo 'input,select,textarea{color:#FFFFFF;background-color:#000000;} .messages a img{width:15%} .messages a:hover img{width:35%} '; 347 echo '.error{color:#FF0033;text-align:left;} .delbutton{background-color:#660000;} .backbutton{background-color:#004400;} #exitbutton{background-color:#AA0000;} '; 348 echo '.setup table table,.admin table table,.profile table table{width:100%;text-align:left} '; 349 echo '.alogin table,.init table,.destroy_chat table,.delete_account table,.sessions table,.filter table,.linkfilter table,.notes table,.approve_waiting table,.del_confirm table,.profile table,.admin table,.backup table,.setup table{margin-left:auto;margin-right:auto;} '; 350 echo '.setup table table table,.admin table table table,.profile table table table{border-spacing:0px;margin-left:auto;margin-right:unset;width:unset;} '; 351 echo '.setup table table td,.backup #restoresubmit,.backup #backupsubmit,.admin table table td,.profile table table td,.login td+td,.alogin td+td{text-align:right;} '; 352 echo '.init td,.backup #restorecheck td,.admin #clean td,.admin #regnew td,.session td,.messages,.inbox,.approve_waiting td,.choose_messages,.greeting,.help,.login td,.alogin td{text-align:left;} '; 353 echo '.messages #chatters{max-height:100px;overflow-y:auto;} .messages #chatters a{text-decoration-line:none;} .messages #chatters table{border-spacing:0px;} '; 354 echo '.messages #chatters th,.messages #chatters td,.post #firstline{vertical-align:top;} '; 355 echo '.approve_waiting #action td:only-child,.help #backcredit,.login td:only-child,.alogin td:only-child,.init td:only-child{text-align:center;} .sessions td,.sessions th,.approve_waiting td,.approve_waiting th{padding: 5px;} '; 356 echo '.sessions td td{padding: 1px;} .messages #bottom_link{position:fixed;top:0.5em;right:0.5em;} .messages #top_link{position:fixed;bottom:0.5em;right:0.5em;} '; 357 echo '.post table,.controls table,.login table{border-spacing:0px;margin-left:auto;margin-right:auto;} .login table{border:2px solid;} .controls{overflow-y:none;} '; 358 echo '#manualrefresh{display:block;position:fixed;text-align:center;left:25%;width:50%;top:-200%;animation:timeout_messages '; 359 if (isset($U['refresh'])) { 360 echo $U['refresh'] + 20; 361 } else { 362 echo '160'; 363 } 364 echo 's forwards;z-index:2;background-color:#500000;border:2px solid #ff0000;} '; 365 echo '@keyframes timeout_messages{0%{top:-200%;} 99%{top:-200%;} 100%{top:0%;}} '; 366 echo '.notes textarea{height:80vh;width:80%;}iframe{width:100%;height:100%;margin:0;padding:0;border:none}'; 367 echo '@import url("style.css");'; 368 echo '</style>'; 369 if ($init) { 370 return; 371 } 372 $css = get_setting('css'); 373 $coltxt = get_setting('coltxt'); 374 if (!empty($U['bgcolour'])) { 375 $colbg = $U['bgcolour']; 376 } else { 377 $colbg = get_setting('colbg'); 378 } 379 echo "<link rel=\"shortcut icon\" href=\"https://cdn.sokka.dev/global/images/favicon.svg\">"; 380 //overwrite with custom css 381 echo "<style type=\"text/css\">body{background-color:#$colbg;color:#$coltxt;} $css</style>"; 382 echo "<link rel=\"preload\" href=\"style.css\" as=\"style\"><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">"; 383 } 384 385 function print_end() 386 { 387 echo '</body></html>'; 388 exit; 389 } 390 391 function credit() 392 { 393 return '<small><br><br><a target="_blank" style="color:var(--accent); text-decoration: underline dotted var(--accent)" href="https://4-0-4.io">Project 404</a></small>'; 394 } 395 396 function meta_html() 397 { 398 return '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta http-equiv="Pragma" content="no-cache"><meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate, max-age=0"><meta http-equiv="expires" content="0"><meta name="referrer" content="no-referrer">'; 399 } 400 401 function form($action, $do = '') 402 { 403 global $language; 404 $form = "<form action=\"\" enctype=\"multipart/form-data\" method=\"post\">" . hidden('lang', $language) . hidden('nc', substr(time(), -6)) . hidden('action', $action); 405 if (!empty($_REQUEST['session'])) { 406 $form .= hidden('session', $_REQUEST['session']); 407 } 408 if ($do !== '') { 409 $form .= hidden('do', $do); 410 } 411 return $form; 412 } 413 414 function form_target($target, $action, $do = '') 415 { 416 global $language; 417 $form = "<form action=\"\" enctype=\"multipart/form-data\" method=\"post\" target=\"$target\">" . hidden('lang', $language) . hidden('nc', substr(time(), -6)) . hidden('action', $action); 418 if (!empty($_REQUEST['session'])) { 419 $form .= hidden('session', $_REQUEST['session']); 420 } 421 if ($do !== '') { 422 $form .= hidden('do', $do); 423 } 424 return $form; 425 } 426 427 function hidden($arg1 = '', $arg2 = '') 428 { 429 return "<input type=\"hidden\" name=\"$arg1\" value=\"$arg2\">"; 430 } 431 432 function submit($arg1 = '', $arg2 = '') 433 { 434 return "<input type=\"submit\" value=\"$arg1\" $arg2>"; 435 } 436 437 function thr() 438 { 439 echo '<tr><td><hr></td></tr>'; 440 } 441 442 function print_start($class = '', $ref = 0, $url = '') 443 { 444 global $I; 445 if (!empty($url)) { 446 $url = str_replace('&', '&', $url); // Don't escape "&" in URLs here, it breaks some (older) browsers and js refresh! 447 header("Refresh: $ref; URL=$url"); 448 } 449 echo '<!DOCTYPE html><html><head>' . meta_html(); 450 if (!empty($url)) { 451 echo "<meta http-equiv=\"Refresh\" content=\"$ref; URL=$url\">"; 452 $ref += 5; //only use js if browser refresh stopped working 453 $ref *= 1000; //js uses milliseconds 454 455 // MODIFICATION removed window refresh js 456 /* echo "<script type=\"text/javascript\">setTimeout(function(){window.location.replace(\"$url\");}, $ref);</script>";*/ 457 } 458 if ($class === 'init') { 459 echo "<title>$I[init]</title>"; 460 print_stylesheet(true); 461 } else { 462 echo '<title>' . get_setting('chatname') . '</title>'; 463 print_stylesheet(); 464 } 465 if ($class !== 'init' && ($externalcss = get_setting('externalcss')) != '') { 466 //external css - in body to make it non-renderblocking 467 } 468 echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">"; 469 echo '<meta http-equiv="onion-location" content="http://cboxkuuxrtulkkxhod2pxo3la25tztcp4cdjmc75wc5airqqliq2srad.onion" />'; 470 echo "</head><body class=\"$class\">"; 471 } 472 473 function send_redirect($url) 474 { 475 global $I; 476 $url = trim(htmlspecialchars_decode(rawurldecode($url))); 477 preg_match('~^(.*)://~u', $url, $match); 478 $url = preg_replace('~^(.*)://~u', '', $url); 479 $escaped = htmlspecialchars($url); 480 if (isset($match[1]) && ($match[1] === 'http' || $match[1] === 'https')) { 481 print_start('redirect', 0, $match[0] . $escaped); 482 echo "<p>$I[redirectto] <a href=\"$match[0]$escaped\">$match[0]$escaped</a>.</p>"; 483 } else { 484 print_start('redirect'); 485 if (!isset($match[0])) { 486 $match[0] = ''; 487 } 488 if (preg_match('~^(javascript|blob|data):~', $url)) { 489 echo "<p>$I[dangerousnonhttp] $match[0]$escaped</p>"; 490 } else { 491 echo "<p>$I[nonhttp] <a href=\"$match[0]$escaped\">$match[0]$escaped</a>.</p>"; 492 } 493 echo "<p>$I[httpredir] <a href=\"http://$escaped\">http://$escaped</a>.</p>"; 494 } 495 print_end(); 496 } 497 498 function send_access_denied() 499 { 500 global $I, $U; 501 header('HTTP/1.1 403 Forbidden'); 502 print_start('access_denied'); 503 echo "<h1>$I[accessdenied]</h1>" . sprintf($I['loggedinas'], style_this(htmlspecialchars($U['nickname']), $U['style'])) . '<br>'; 504 echo form('logout'); 505 if (!isset($_REQUEST['session'])) { 506 echo hidden('session', $U['session']); 507 } 508 echo submit($I['logout'], 'id="exitbutton"') . "</form>"; 509 print_end(); 510 } 511 512 function send_captcha() 513 { 514 global $I, $db, $memcached; 515 $difficulty = (int) get_setting('captcha'); 516 if ($difficulty === 0 || !extension_loaded('gd')) { 517 return; 518 } 519 $captchachars = get_setting('captchachars'); 520 $length = strlen($captchachars) - 1; 521 $code = ''; 522 for ($i = 0; $i < 5; ++$i) { 523 $code .= $captchachars[mt_rand(0, $length)]; 524 } 525 $randid = mt_rand(); 526 $time = time(); 527 if (MEMCACHED) { 528 $memcached->set(DBNAME . '-' . PREFIX . "captcha-$randid", $code, get_setting('captchatime')); 529 } else { 530 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'captcha (id, time, code) VALUES (?, ?, ?);'); 531 $stmt->execute([$randid, $time, $code]); 532 } 533 echo "<tr id=\"captcha\"><td><span class=\"centerWrap sprite-decaptcha-logo-night\"></span> "; 534 if ($difficulty === 1) { 535 $im = imagecreatetruecolor(55, 24); 536 $bg = imagecolorallocatealpha($im, 0, 0, 0, 127); 537 $fg = imagecolorallocate($im, 255, 255, 255); 538 imagefill($im, 0, 0, $bg); 539 imagestring($im, 5, 5, 5, $code, $fg); 540 imagesavealpha($im, true); 541 echo '<img class="captchalogincbox" width="55" height="24" src="data:image/gif;base64,'; 542 } elseif ($difficulty === 2) { 543 $im = imagecreatetruecolor(55, 24); 544 $bg = imagecolorallocatealpha($im, 0, 0, 0, 0); 545 $fg = imagecolorallocate($im, 255, 255, 255); 546 imagefill($im, 0, 0, $bg); 547 imagestring($im, 5, 5, 5, $code, $fg); 548 $line = imagecolorallocate($im, 255, 255, 255); 549 for ($i = 0; $i < 2; ++$i) { 550 imageline($im, 0, mt_rand(0, 24), 55, mt_rand(0, 24), $line); 551 } 552 $dots = imagecolorallocate($im, 255, 255, 255); 553 for ($i = 0; $i < 100; ++$i) { 554 imagesetpixel($im, mt_rand(0, 55), mt_rand(0, 24), $dots); 555 } 556 echo '<img class="captchalogincbox" width="55" height="24" src="data:image/gif;base64,'; 557 } else { 558 $im = imagecreatetruecolor(150, 200); 559 $bg = imagecolorallocatealpha($im, 0, 0, 0, 0); 560 $fg = imagecolorallocate($im, 255, 255, 255); 561 imagefill($im, 0, 0, $bg); 562 $chars = []; 563 for ($i = 0; $i < 10; ++$i) { 564 $found = false; 565 while (!$found) { 566 $x = mt_rand(10, 140); 567 $y = mt_rand(10, 180); 568 $found = true; 569 foreach ($chars as $char) { 570 if ($char['x'] >= $x && ($char['x'] - $x) < 25) { 571 $found = false; 572 } elseif ($char['x'] < $x && ($x - $char['x']) < 25) { 573 $found = false; 574 } 575 if (!$found) { 576 if ($char['y'] >= $y && ($char['y'] - $y) < 25) { 577 break; 578 } elseif ($char['y'] < $y && ($y - $char['y']) < 25) { 579 break; 580 } else { 581 $found = true; 582 } 583 } 584 } 585 } 586 $chars[] = ['x', 'y']; 587 $chars[$i]['x'] = $x; 588 $chars[$i]['y'] = $y; 589 if ($i < 5) { 590 imagechar($im, 5, $chars[$i]['x'], $chars[$i]['y'], $captchachars[mt_rand(0, $length)], $fg); 591 } else { 592 imagechar($im, 5, $chars[$i]['x'], $chars[$i]['y'], $code[$i - 5], $fg); 593 } 594 } 595 $follow = imagecolorallocate($im, 200, 0, 0); 596 imagearc($im, $chars[5]['x'] + 4, $chars[5]['y'] + 8, 16, 16, 0, 360, $follow); 597 for ($i = 5; $i < 9; ++$i) { 598 imageline($im, $chars[$i]['x'] + 4, $chars[$i]['y'] + 8, $chars[$i + 1]['x'] + 4, $chars[$i + 1]['y'] + 8, $follow); 599 } 600 $line = imagecolorallocate($im, 255, 255, 255); 601 for ($i = 0; $i < 5; ++$i) { 602 imageline($im, 0, mt_rand(0, 200), 150, mt_rand(0, 200), $line); 603 } 604 $dots = imagecolorallocate($im, 255, 255, 255); 605 for ($i = 0; $i < 1000; ++$i) { 606 imagesetpixel($im, mt_rand(0, 150), mt_rand(0, 200), $dots); 607 } 608 echo '<img class="captchalogincbox" width="150" height="200" src="data:image/gif;base64,'; 609 } 610 ob_start(); 611 imagegif($im); 612 imagedestroy($im); 613 echo base64_encode(ob_get_clean()) . '">'; 614 echo '</td><td>' . hidden('challenge', $randid) . '<input type="text" name="captcha" size="15" autocomplete="off"></td></tr>'; 615 } 616 617 function send_setup($C) 618 { 619 global $I, $U; 620 print_start('setup'); 621 echo "<h2>$I[setup]</h2>" . form('setup', 'save'); 622 if (!isset($_REQUEST['session'])) { 623 echo hidden('session', $U['session']); 624 } 625 echo '<table id="guestaccess">'; 626 thr(); 627 $ga = (int) get_setting('guestaccess'); 628 echo "<tr><td><table><tr><th>$I[guestacc]</th><td>"; 629 echo '<select name="guestaccess">'; 630 echo '<option value="1"'; 631 if ($ga === 1) { 632 echo ' selected'; 633 } 634 echo ">$I[guestallow]</option>"; 635 echo '<option value="2"'; 636 if ($ga === 2) { 637 echo ' selected'; 638 } 639 echo ">$I[guestwait]</option>"; 640 echo '<option value="3"'; 641 if ($ga === 3) { 642 echo ' selected'; 643 } 644 echo ">$I[adminallow]</option>"; 645 echo '<option value="0"'; 646 if ($ga === 0) { 647 echo ' selected'; 648 } 649 echo ">$I[guestdisallow]</option>"; 650 echo '<option value="4"'; 651 if ($ga === 4) { 652 echo ' selected'; 653 } 654 echo ">$I[disablechat]</option>"; 655 echo '</select></td></tr></table></td></tr>'; 656 thr(); 657 $englobal = (int) get_setting('englobalpass'); 658 echo "<tr><td><table id=\"globalpass\"><tr><th>$I[globalloginpass]</th><td>"; 659 echo '<table>'; 660 echo '<tr><td><select name="englobalpass">'; 661 echo '<option value="0"'; 662 if ($englobal === 0) { 663 echo ' selected'; 664 } 665 echo ">$I[disabled]</option>"; 666 echo '<option value="1"'; 667 if ($englobal === 1) { 668 echo ' selected'; 669 } 670 echo ">$I[enabled]</option>"; 671 echo '<option value="2"'; 672 if ($englobal === 2) { 673 echo ' selected'; 674 } 675 echo ">$I[onlyguests]</option>"; 676 echo '</select></td><td> </td>'; 677 echo '<td><input type="text" name="globalpass" value="' . htmlspecialchars(get_setting('globalpass')) . '"></td></tr>'; 678 echo '</table></td></tr></table></td></tr>'; 679 thr(); 680 $ga = (int) get_setting('guestreg'); 681 echo "<tr><td><table id=\"guestreg\"><tr><th>$I[guestreg]</th><td>"; 682 echo '<select name="guestreg">'; 683 echo '<option value="0"'; 684 if ($ga === 0) { 685 echo ' selected'; 686 } 687 echo ">$I[disabled]</option>"; 688 echo '<option value="1"'; 689 if ($ga === 1) { 690 echo ' selected'; 691 } 692 echo ">$I[assuguest]</option>"; 693 echo '<option value="2"'; 694 if ($ga === 2) { 695 echo ' selected'; 696 } 697 echo ">$I[asmember]</option>"; 698 echo '</select></td></tr></table></td></tr>'; 699 thr(); 700 echo "<tr><td><table id=\"sysmessages\"><tr><th>$I[sysmessages]</th><td>"; 701 echo '<table>'; 702 foreach ($C['msg_settings'] as $setting) { 703 echo "<tr><td> $I[$setting]</td><td> <input type=\"text\" name=\"$setting\" value=\"" . get_setting($setting) . '"></td></tr>'; 704 } 705 echo '</table></td></tr></table></td></tr>'; 706 foreach ($C['text_settings'] as $setting) { 707 thr(); 708 echo "<tr><td><table id=\"$setting\"><tr><th>" . $I[$setting] . '</th><td>'; 709 echo "<input type=\"text\" name=\"$setting\" value=\"" . htmlspecialchars(get_setting($setting)) . '">'; 710 echo '</td></tr></table></td></tr>'; 711 } 712 foreach ($C['colour_settings'] as $setting) { 713 thr(); 714 echo "<tr><td><table id=\"$setting\"><tr><th>" . $I[$setting] . '</th><td>'; 715 echo "<input type=\"color\" name=\"$setting\" value=\"#" . htmlspecialchars(get_setting($setting)) . '">'; 716 echo '</td></tr></table></td></tr>'; 717 } 718 thr(); 719 echo "<tr><td><table id=\"captcha\"><tr><th>$I[captcha]</th><td>"; 720 echo '<table>'; 721 if (!extension_loaded('gd')) { 722 echo "<tr><td>$I[gdextrequired]</td></tr>"; 723 } else { 724 echo '<tr><td><select name="dismemcaptcha">'; 725 $dismemcaptcha = (bool) get_setting('dismemcaptcha'); 726 echo '<option value="0"'; 727 if (!$dismemcaptcha) { 728 echo ' selected'; 729 } 730 echo ">$I[enabled]</option>"; 731 echo '<option value="1"'; 732 if ($dismemcaptcha) { 733 echo ' selected'; 734 } 735 echo ">$I[onlyguests]</option>"; 736 echo '</select></td><td><select name="captcha">'; 737 $captcha = (int) get_setting('captcha'); 738 echo '<option value="0"'; 739 if ($captcha === 0) { 740 echo ' selected'; 741 } 742 echo ">$I[disabled]</option>"; 743 echo '<option value="1"'; 744 if ($captcha === 1) { 745 echo ' selected'; 746 } 747 echo ">$I[simple]</option>"; 748 echo '<option value="2"'; 749 if ($captcha === 2) { 750 echo ' selected'; 751 } 752 echo ">$I[moderate]</option>"; 753 echo '<option value="3"'; 754 if ($captcha === 3) { 755 echo ' selected'; 756 } 757 echo ">$I[extreme]</option>"; 758 echo '</select></td></tr>'; 759 } 760 echo '</table></td></tr></table></td></tr>'; 761 thr(); 762 echo "<tr><td><table id=\"defaulttz\"><tr><th>$I[defaulttz]</th><td>"; 763 echo "<select name=\"defaulttz\">"; 764 $tzs = timezone_identifiers_list(); 765 $defaulttz = get_setting('defaulttz'); 766 foreach ($tzs as $tz) { 767 echo "<option value=\"$tz\""; 768 if ($defaulttz == $tz) { 769 echo ' selected'; 770 } 771 echo ">$tz</option>"; 772 } 773 echo '</select>'; 774 echo '</td></tr></table></td></tr>'; 775 foreach ($C['textarea_settings'] as $setting) { 776 thr(); 777 echo "<tr><td><table id=\"$setting\"><tr><th>" . $I[$setting] . '</th><td>'; 778 echo "<textarea name=\"$setting\" rows=\"4\" cols=\"60\">" . htmlspecialchars(get_setting($setting)) . '</textarea>'; 779 echo '</td></tr></table></td></tr>'; 780 } 781 //MODIFICATION textarea to edit links page 782 thr(); 783 echo "<tr><td><table id=\"links\"><tr><th>Links Page (html)</th><td>"; 784 echo "<textarea name=\"links\" rows=\"4\" cols=\"60\">" . htmlspecialchars(get_setting('links')) . '</textarea>'; 785 echo '</td></tr></table></td></tr>'; 786 //End of Modification 787 788 //MODIFICATION frontpagetext: textarea to edit front page 789 thr(); 790 echo "<tr><td><table id=\"frontpagetext\"><tr><th>Text on front page (html)</th><td>"; 791 echo "<textarea name=\"frontpagetext\" rows=\"4\" cols=\"60\">" . htmlspecialchars(get_setting('frontpagetext')) . '</textarea>'; 792 echo '</td></tr></table></td></tr>'; 793 //End of Modification 794 795 foreach ($C['number_settings'] as $setting) { 796 thr(); 797 echo "<tr><td><table id=\"$setting\"><tr><th>" . $I[$setting] . '</th><td>'; 798 echo "<input type=\"number\" name=\"$setting\" value=\"" . htmlspecialchars(get_setting($setting)) . '">'; 799 echo '</td></tr></table></td></tr>'; 800 } 801 foreach ($C['bool_settings'] as $setting) { 802 thr(); 803 echo "<tr><td><table id=\"$setting\"><tr><th>" . $I[$setting] . '</th><td>'; 804 echo "<select name=\"$setting\">"; 805 $value = (bool) get_setting($setting); 806 echo '<option value="0"'; 807 if (!$value) { 808 echo ' selected'; 809 } 810 echo ">$I[disabled]</option>"; 811 echo '<option value="1"'; 812 if ($value) { 813 echo ' selected'; 814 } 815 echo ">$I[enabled]</option>"; 816 echo '</select></td></tr>'; 817 echo '</table></td></tr>'; 818 } 819 //thr(); 820 821 //MODIFICATION to enable links page 822 thr(); 823 echo "<tr><td><table id=\"linksenabled\"><tr><th>Links Page</th><td>"; 824 echo "<select name=\"linksenabled\">"; 825 $value = (bool) get_setting('linksenabled'); 826 echo '<option value="0"'; 827 if (!$value) { 828 echo ' selected'; 829 } 830 echo ">$I[disabled]</option>"; 831 echo '<option value="1"'; 832 if ($value) { 833 echo ' selected'; 834 } 835 echo ">$I[enabled]</option>"; 836 echo '</select></td></tr>'; 837 echo '</table></td></tr>'; 838 thr(); 839 //End of Modification 840 841 //MODIFICATION to enable DEL-Buttons for members (2 = always, 1 = if no mod is present.) 842 //thr(); 843 echo "<tr><td><table id=\"memdel\"><tr><th>Members can delete messages (DEL) and can kick</th><td>"; 844 echo "<select name=\"memdel\">"; 845 $value = (int) get_setting('memdel'); 846 echo '<option value="0"'; 847 if ($value == 0) { 848 echo ' selected'; 849 } 850 echo ">$I[disabled]</option>"; 851 852 echo '<option value="1"'; 853 if ($value == 1) { 854 echo ' selected'; 855 } 856 echo ">DEL-Buttons enabled, if no mod is present</option>"; 857 858 /* 859 echo '</select></td></tr>'; 860 echo '</table></td></tr>'; 861 */ 862 863 echo '<option value="2"'; 864 if ($value == 2) { 865 echo ' selected'; 866 } 867 echo ">$I[enabled]</option>"; 868 echo '</select></td></tr>'; 869 echo '</table></td></tr>'; 870 871 thr(); 872 //End of Modification 873 874 //Modification gallery access 875 echo "<tr><td><table id=\"galleryaccess\"><tr><th>Gallery access</th><td>"; 876 echo "<select name=\"galleryaccess\">"; 877 $value = (int) get_setting('galleryaccess'); 878 879 $options = array(1, 2, 3, 5, 6, 7, 10); 880 881 foreach ($options as $option) { 882 echo "<option value=\"$option\""; 883 884 if ($value == $option) { 885 echo ' selected'; 886 } 887 888 if ($option == 1) echo ">All</option>"; 889 elseif ($option == 2) echo ">Registered guests</option>"; 890 elseif ($option == 3) echo ">Members</option>"; 891 elseif ($option == 5) echo ">Moderators</option>"; 892 elseif ($option == 6) echo ">Super Moderators</option>"; 893 elseif ($option == 7) echo ">Admins</option>"; 894 elseif ($option == 10) echo ">Disabled</option>"; 895 } 896 897 echo '</select></td></tr>'; 898 echo '</table></td></tr>'; 899 thr(); 900 //End of modification 901 902 //Modification forum button visibility 903 echo "<tr><td><table id=\"forumbtnaccess\"><tr><th>Forum Button visibility</th><td>"; 904 echo "<select name=\"forumbtnaccess\">"; 905 $value = (int) get_setting('forumbtnaccess'); 906 907 $options = array(1, 2, 3, 5, 6, 7, 10); 908 909 foreach ($options as $option) { 910 echo "<option value=\"$option\""; 911 912 if ($value == $option) { 913 echo ' selected'; 914 } 915 916 if ($option == 1) echo ">All</option>"; 917 elseif ($option == 2) echo ">Registered guests</option>"; 918 elseif ($option == 3) echo ">Members</option>"; 919 elseif ($option == 5) echo ">Moderators</option>"; 920 elseif ($option == 6) echo ">Super Moderators</option>"; 921 elseif ($option == 7) echo ">Admins</option>"; 922 elseif ($option == 10) echo ">Disabled</option>"; 923 } 924 925 echo '</select></td></tr>'; 926 echo '</table></td></tr>'; 927 thr(); 928 //End of modification 929 930 //Modification forum button link 931 932 echo "<tr><td><table id=\"forumbtnlink\"><tr><th>Forum Button link</th><td>"; 933 echo "<input type=\"text\" name=\"forumbtnlink\" value=\"" . htmlspecialchars(get_setting('forumbtnlink')) . '">'; 934 echo '</td></tr></table></td></tr>'; 935 thr(); 936 //End of modification 937 938 //MODIFICATION adminjoinleavemsg to not create a system message if an admins arrives or leaves the chat 939 echo "<tr><td><table id=\"adminjoinleavemsg\"><tr><th>Show system message if an admin joined or left the chat</th><td>"; 940 echo "<select name=\"adminjoinleavemsg\">"; 941 $value = (bool) get_setting('adminjoinleavemsg'); 942 echo '<option value="0"'; 943 if (!$value) { 944 echo ' selected'; 945 } 946 echo ">$I[disabled]</option>"; 947 echo '<option value="1"'; 948 if ($value) { 949 echo ' selected'; 950 } 951 echo ">$I[enabled]</option>"; 952 echo '</select></td></tr>'; 953 echo '</table></td></tr>'; 954 thr(); 955 //End of Modification 956 957 //MODIFICATION clickablenicknamesglobal to enable/disable clickablenicknames, e. g. in case of errors 958 echo "<tr><td><table id=\"clickablenicknamesglobal\"><tr><th>Clickable nicknames</th><td>"; 959 echo "<select name=\"clickablenicknamesglobal\">"; 960 $value = (bool) get_setting('clickablenicknamesglobal'); 961 echo '<option value="0"'; 962 if (!$value) { 963 echo ' selected'; 964 } 965 echo ">$I[disabled]</option>"; 966 echo '<option value="1"'; 967 if ($value) { 968 echo ' selected'; 969 } 970 echo ">$I[enabled]</option>"; 971 echo '</select></td></tr>'; 972 echo '</table></td></tr>'; 973 thr(); 974 //End of Modification 975 976 // Modification Spare Notes. 977 // Spare Notes name 978 echo '<tr><td><table id="sparenotesname"><tr><th>Spare Notes Name</th><td>'; 979 echo '<input type="text" name="sparenotesname" value="' . htmlspecialchars(get_setting('sparenotesname')) . '">'; 980 echo '</td></tr></table></td></tr>'; 981 thr(); 982 // Spare Notes Access 983 echo "<tr><td><table id=\"sparenotesaccess\"><tr><th>Spare Notes Access</th><td>"; 984 echo "<select name=\"sparenotesaccess\">"; 985 $value = (int) get_setting('sparenotesaccess'); 986 987 $options = array(3, 5, 6, 7, 10); 988 989 foreach ($options as $option) { 990 echo "<option value=\"$option\""; 991 992 if ($value == $option) { 993 echo ' selected'; 994 } 995 996 if ($option == 3) echo ">Members</option>"; 997 elseif ($option == 5) echo ">Moderators</option>"; 998 elseif ($option == 6) echo ">Super Moderators</option>"; 999 elseif ($option == 7) echo ">Admins</option>"; 1000 elseif ($option == 10) echo ">Disabled</option>"; 1001 } 1002 // End of Modification 1003 echo '</select></td></tr>'; 1004 echo '</table></td></tr>'; 1005 thr(); 1006 1007 // Modificatin create chat rooms 1008 echo "<tr><td><table id=\"roomcreateaccess\"><tr><th>Rooms can be created by:</th><td>"; 1009 echo "<select name=\"roomcreateaccess\">"; 1010 $value = (int) get_setting('roomcreateaccess'); 1011 1012 $options = array(5, 6, 7); 1013 1014 foreach ($options as $option) { 1015 echo "<option value=\"$option\""; 1016 1017 if ($value == $option) { 1018 echo ' selected'; 1019 } 1020 1021 if ($option == 5) echo ">Moderators</option>"; 1022 elseif ($option == 6) echo ">Super Moderators</option>"; 1023 elseif ($option == 7) echo ">Admins</option>"; 1024 } 1025 echo '</select></td></tr>'; 1026 echo '</table></td></tr>'; 1027 thr(); 1028 echo "<tr><td><table id=\"roomexpire\"><tr><th>Room Timeout (minutes)</th><td>"; 1029 echo "<input type=\"number\" name=\"roomexpire\" value=\"" . get_setting('roomexpire') . '">'; 1030 echo '</td></tr></table></td></tr>'; 1031 thr(); 1032 1033 echo "<tr><td><table id=\"channelvisinroom\"><tr><th>Channels visible in all rooms</th><td>"; 1034 echo "<select name=\"channelvisinroom\">"; 1035 $value = (int) get_setting('channelvisinroom'); 1036 $options = array(2, 3, 5, 6, 7, 9); 1037 1038 foreach ($options as $option) { 1039 echo "<option value=\"$option\""; 1040 1041 if ($value == $option) { 1042 echo ' selected'; 1043 } 1044 1045 if ($option == 2) echo ">All Channels</option>"; 1046 elseif ($option == 3) echo ">Member Channels</option>"; 1047 elseif ($option == 5) echo ">Staff Channels</option>"; 1048 elseif ($option == 6) echo ">SMod Channels</option>"; 1049 elseif ($option == 7) echo ">Admin Channel</option>"; 1050 elseif ($option == 9) echo ">No channels</option>"; 1051 } 1052 echo '</select></td></tr>'; 1053 echo '</table></td></tr>'; 1054 thr(); 1055 // End of Modification 1056 1057 1058 1059 1060 1061 /***************************************** 1062 *SETTINGS ONLY FOR SUPER ADMIN ARE BELOW 1063 ******************************************/ 1064 if ($U['status'] == 8) { 1065 1066 echo '<tr><td><table>'; 1067 echo "<font color='red'>↓ Setting(s) below can only be viewed and edited by Super Admin ↓</font>"; 1068 echo '</td></tr></table>'; 1069 1070 thr(); 1071 //MODIFICATION modsdeladminmsg to allow mods deleting admin messages 1072 echo "<tr><td><table id=\"modsdeladminmsg\"><tr><th>Staff members can delete messages of higher ranked staff members</th><td>"; 1073 echo "<select name=\"modsdeladminmsg\">"; 1074 $value = (bool) get_setting('modsdeladminmsg'); 1075 echo '<option value="0"'; 1076 if (!$value) { 1077 echo ' selected'; 1078 } 1079 echo ">$I[disabled]</option>"; 1080 echo '<option value="1"'; 1081 if ($value) { 1082 echo ' selected'; 1083 } 1084 echo ">$I[enabled]</option>"; 1085 echo '</select></td></tr>'; 1086 echo '</table></td></tr>'; 1087 thr(); 1088 //End of Modification 1089 1090 //MODIFICATION incognitomode setting only for super admin. 1091 echo "<tr><td><table id=\"incognito\"><tr><th>" . $I['incognito'] . "</th><td>"; 1092 echo "<select name=\"incognito\">"; 1093 $value = (bool) get_setting('incognito'); 1094 echo '<option value="0"'; 1095 if (!$value) { 1096 echo ' selected'; 1097 } 1098 echo ">$I[disabled]</option>"; 1099 echo '<option value="1"'; 1100 if ($value) { 1101 echo ' selected'; 1102 } 1103 echo ">$I[enabled]</option>"; 1104 echo '</select></td></tr>'; 1105 echo '</table></td></tr>'; 1106 thr(); 1107 //End of Modification 1108 1109 echo '<tr><td><table>'; 1110 echo "<font color='red'> ↑ Setting(s) above can only be viewed and edited by Super Admin ↑</font>"; 1111 echo '</td></tr></table>'; 1112 thr(); 1113 } //End if 1114 1115 /***************************************** 1116 *SETTINGS ONLY FOR SUPER ADMIN ARE ABOVE 1117 ******************************************/ 1118 1119 echo '<tr><td>' . submit($I['apply']) . '</td></tr></table></form><br>'; 1120 if ($U['status'] == 8) { 1121 echo '<table id="actions"><tr><td>'; 1122 echo form('setup', 'backup'); 1123 if (!isset($_REQUEST['session'])) { 1124 echo hidden('session', $U['session']); 1125 } 1126 echo submit($I['backuprestore']) . '</form></td><td>'; 1127 echo form('setup', 'destroy'); 1128 if (!isset($_REQUEST['session'])) { 1129 echo hidden('session', $U['session']); 1130 } 1131 echo submit($I['destroy'], 'class="delbutton"') . '</form></td></tr></table><br>'; 1132 } 1133 echo form_target('_parent', 'logout'); 1134 if (!isset($_REQUEST['session'])) { 1135 echo hidden('session', $U['session']); 1136 } 1137 echo submit($I['logout'], 'id="exitbutton"') . '</form>' . credit(); 1138 print_end(); 1139 } 1140 1141 function restore_backup($C) 1142 { 1143 global $db, $memcached; 1144 if (!extension_loaded('json')) { 1145 return; 1146 } 1147 $code = json_decode($_REQUEST['restore'], true); 1148 if (isset($_REQUEST['settings'])) { 1149 foreach ($C['settings'] as $setting) { 1150 if (isset($code['settings'][$setting])) { 1151 update_setting($setting, $code['settings'][$setting]); 1152 } 1153 } 1154 } 1155 if (isset($_REQUEST['filter']) && (isset($code['filters']) || isset($code['linkfilters']))) { 1156 $db->exec('DELETE FROM ' . PREFIX . 'filter;'); 1157 $db->exec('DELETE FROM ' . PREFIX . 'linkfilter;'); 1158 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'filter (filtermatch, filterreplace, allowinpm, regex, kick, cs) VALUES (?, ?, ?, ?, ?, ?);'); 1159 foreach ($code['filters'] as $filter) { 1160 if (!isset($filter['cs'])) { 1161 $filter['cs'] = 0; 1162 } 1163 $stmt->execute([$filter['match'], $filter['replace'], $filter['allowinpm'], $filter['regex'], $filter['kick'], $filter['cs']]); 1164 } 1165 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'linkfilter (filtermatch, filterreplace, regex) VALUES (?, ?, ?);'); 1166 foreach ($code['linkfilters'] as $filter) { 1167 $stmt->execute([$filter['match'], $filter['replace'], $filter['regex']]); 1168 } 1169 if (MEMCACHED) { 1170 $memcached->delete(DBNAME . '-' . PREFIX . 'filter'); 1171 $memcached->delete(DBNAME . '-' . PREFIX . 'linkfilter'); 1172 } 1173 } 1174 if (isset($_REQUEST['members']) && isset($code['members'])) { 1175 $db->exec('DELETE FROM ' . PREFIX . 'inbox;'); 1176 $db->exec('DELETE FROM ' . PREFIX . 'members;'); 1177 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'members (nickname, passhash, status, refresh, bgcolour, regedby, lastlogin, timestamps, embed, incognito, style, nocache, tz, eninbox, sortupdown, hidechatters, nocache_old) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);'); 1178 foreach ($code['members'] as $member) { 1179 $new_settings = ['nocache', 'tz', 'eninbox', 'sortupdown', 'hidechatters', 'nocache_old']; 1180 foreach ($new_settings as $setting) { 1181 if (!isset($member[$setting])) { 1182 $member[$setting] = 0; 1183 } 1184 } 1185 $stmt->execute([$member['nickname'], $member['passhash'], $member['status'], $member['refresh'], $member['bgcolour'], $member['regedby'], $member['lastlogin'], $member['timestamps'], $member['embed'], $member['incognito'], $member['style'], $member['nocache'], $member['tz'], $member['eninbox'], $member['sortupdown'], $member['hidechatters'], $member['nocache_old']]); 1186 } 1187 } 1188 if (isset($_REQUEST['notes']) && isset($code['notes'])) { 1189 $db->exec('DELETE FROM ' . PREFIX . 'notes;'); 1190 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'notes (type, lastedited, editedby, text) VALUES (?, ?, ?, ?);'); 1191 foreach ($code['notes'] as $note) { 1192 if ($note['type'] === 'admin') { 1193 $note['type'] = 0; 1194 } elseif ($note['type'] === 'staff') { 1195 $note['type'] = 1; 1196 } 1197 if (MSGENCRYPTED) { 1198 $note['text'] = base64_encode(sodium_crypto_aead_aes256gcm_encrypt($note['text'], '', AES_IV, ENCRYPTKEY)); 1199 } 1200 $stmt->execute([$note['type'], $note['lastedited'], $note['editedby'], $note['text']]); 1201 } 1202 } 1203 } 1204 1205 function send_backup($C) 1206 { 1207 global $I, $db; 1208 $code = []; 1209 if ($_REQUEST['do'] === 'backup') { 1210 if (isset($_REQUEST['settings'])) { 1211 foreach ($C['settings'] as $setting) { 1212 $code['settings'][$setting] = get_setting($setting); 1213 } 1214 } 1215 if (isset($_REQUEST['filter'])) { 1216 $result = $db->query('SELECT * FROM ' . PREFIX . 'filter;'); 1217 while ($filter = $result->fetch(PDO::FETCH_ASSOC)) { 1218 $code['filters'][] = ['match' => $filter['filtermatch'], 'replace' => $filter['filterreplace'], 'allowinpm' => $filter['allowinpm'], 'regex' => $filter['regex'], 'kick' => $filter['kick'], 'cs' => $filter['cs']]; 1219 } 1220 $result = $db->query('SELECT * FROM ' . PREFIX . 'linkfilter;'); 1221 while ($filter = $result->fetch(PDO::FETCH_ASSOC)) { 1222 $code['linkfilters'][] = ['match' => $filter['filtermatch'], 'replace' => $filter['filterreplace'], 'regex' => $filter['regex']]; 1223 } 1224 } 1225 if (isset($_REQUEST['members'])) { 1226 $result = $db->query('SELECT * FROM ' . PREFIX . 'members;'); 1227 while ($member = $result->fetch(PDO::FETCH_ASSOC)) { 1228 $code['members'][] = $member; 1229 } 1230 } 1231 if (isset($_REQUEST['notes'])) { 1232 $result = $db->query('SELECT * FROM ' . PREFIX . "notes;"); 1233 while ($note = $result->fetch(PDO::FETCH_ASSOC)) { 1234 if (MSGENCRYPTED) { 1235 $note['text'] = sodium_crypto_aead_aes256gcm_decrypt(base64_decode($note['text']), null, AES_IV, ENCRYPTKEY); 1236 } 1237 $code['notes'][] = $note; 1238 } 1239 } 1240 } 1241 if (isset($_REQUEST['settings'])) { 1242 $chksettings = ' checked'; 1243 } else { 1244 $chksettings = ''; 1245 } 1246 if (isset($_REQUEST['filter'])) { 1247 $chkfilters = ' checked'; 1248 } else { 1249 $chkfilters = ''; 1250 } 1251 if (isset($_REQUEST['members'])) { 1252 $chkmembers = ' checked'; 1253 } else { 1254 $chkmembers = ''; 1255 } 1256 if (isset($_REQUEST['notes'])) { 1257 $chknotes = ' checked'; 1258 } else { 1259 $chknotes = ''; 1260 } 1261 print_start('backup'); 1262 echo "<h2>$I[backuprestore]</h2><table>"; 1263 thr(); 1264 if (!extension_loaded('json')) { 1265 echo "<tr><td>$I[jsonextrequired]</td></tr>"; 1266 } else { 1267 echo '<tr><td>' . form('setup', 'backup'); 1268 echo '<table id="backup"><tr><td id="backupcheck">'; 1269 echo "<label><input type=\"checkbox\" name=\"settings\" id=\"backupsettings\" value=\"1\"$chksettings>$I[settings]</label>"; 1270 echo "<label><input type=\"checkbox\" name=\"filter\" id=\"backupfilter\" value=\"1\"$chkfilters>$I[filter]</label>"; 1271 echo "<label><input type=\"checkbox\" name=\"members\" id=\"backupmembers\" value=\"1\"$chkmembers>$I[members]</label>"; 1272 echo "<label><input type=\"checkbox\" name=\"notes\" id=\"backupnotes\" value=\"1\"$chknotes>$I[notes]</label>"; 1273 echo '</td><td id="backupsubmit">' . submit($I['backup']) . '</td></tr></table></form></td></tr>'; 1274 thr(); 1275 echo '<tr><td>' . form('setup', 'restore'); 1276 echo '<table id="restore">'; 1277 echo "<tr><td colspan=\"2\"><textarea name=\"restore\" rows=\"4\" cols=\"60\">" . htmlspecialchars(json_encode($code)) . '</textarea></td></tr>'; 1278 echo "<tr><td id=\"restorecheck\"><label><input type=\"checkbox\" name=\"settings\" id=\"restoresettings\" value=\"1\"$chksettings>$I[settings]</label>"; 1279 echo "<label><input type=\"checkbox\" name=\"filter\" id=\"restorefilter\" value=\"1\"$chkfilters>$I[filter]</label>"; 1280 echo "<label><input type=\"checkbox\" name=\"members\" id=\"restoremembers\" value=\"1\"$chkmembers>$I[members]</label>"; 1281 echo "<label><input type=\"checkbox\" name=\"notes\" id=\"restorenotes\" value=\"1\"$chknotes>$I[notes]</label>"; 1282 echo '</td><td id="restoresubmit">' . submit($I['restore']) . '</td></tr></table>'; 1283 echo '</form></td></tr>'; 1284 } 1285 thr(); 1286 echo '<tr><td>' . form('setup') . submit($I['initgosetup'], 'class="backbutton"') . "</form></tr></td>"; 1287 echo '</table>'; 1288 print_end(); 1289 } 1290 1291 function send_destroy_chat() 1292 { 1293 global $I; 1294 print_start('destroy_chat'); 1295 echo "<table><tr><td colspan=\"2\">$I[confirm]</td></tr><tr><td>"; 1296 echo form_target('_parent', 'setup', 'destroy') . hidden('confirm', 'yes') . submit($I['yes'], 'class="delbutton"') . '</form></td><td>'; 1297 echo form('setup') . submit($I['no'], 'class="backbutton"') . '</form></td><tr></table>'; 1298 print_end(); 1299 } 1300 1301 function send_delete_account() 1302 { 1303 global $I; 1304 print_start('delete_account'); 1305 echo "<table><tr><td colspan=\"2\">$I[confirm]</td></tr><tr><td>"; 1306 echo form('profile', 'delete') . hidden('confirm', 'yes') . submit($I['yes'], 'class="delbutton"') . '</form></td><td>'; 1307 echo form('profile') . submit($I['no'], 'class="backbutton"') . '</form></td><tr></table>'; 1308 print_end(); 1309 } 1310 1311 function send_init() 1312 { 1313 global $I, $L; 1314 print_start('init'); 1315 echo "<h2>$I[init]</h2>"; 1316 echo form('init') . "<table><tr><td><h3>$I[sulogin]</h3><table>"; 1317 echo "<tr><td>$I[sunick]</td><td><input type=\"text\" name=\"sunick\" size=\"15\"></td></tr>"; 1318 echo "<tr><td>$I[supass]</td><td><input type=\"password\" name=\"supass\" size=\"15\"></td></tr>"; 1319 echo "<tr><td>$I[suconfirm]</td><td><input type=\"password\" name=\"supassc\" size=\"15\"></td></tr>"; 1320 echo '</table></td></tr><tr><td><br>' . submit($I['initbtn']) . '</td></tr></table></form>'; 1321 echo "<p id=\"changelang\">$I[changelang]"; 1322 foreach ($L as $lang => $name) { 1323 echo " <a href=\"?action=setup&lang=$lang\">$name</a>"; 1324 } 1325 echo '</p>' . credit(); 1326 print_end(); 1327 } 1328 1329 function send_update($msg) 1330 { 1331 global $I; 1332 print_start('update'); 1333 echo "<h2>$I[dbupdate]</h2><br>" . form('setup') . submit($I['initgosetup']) . "</form>$msg<br>" . credit(); 1334 print_end(); 1335 } 1336 1337 function send_alogin() 1338 { 1339 global $I, $L; 1340 print_start('alogin'); 1341 echo form('setup') . '<table>'; 1342 echo "<tr><td>$I[nick]</td><td><input type=\"text\" name=\"nick\" size=\"15\" autofocus></td></tr>"; 1343 echo "<tr><td>$I[pass]</td><td><input type=\"password\" name=\"pass\" size=\"15\"></td></tr>"; 1344 send_captcha(); 1345 echo '<tr><td colspan="2">' . submit($I['login']) . '</td></tr></table></form>'; 1346 echo "<p id=\"changelang\">$I[changelang]"; 1347 foreach ($L as $lang => $name) { 1348 echo " <a href=\"?action=setup&lang=$lang\">$name</a>"; 1349 } 1350 echo '</p>' . credit(); 1351 print_end(); 1352 } 1353 1354 function send_admin($arg = '') 1355 { 1356 global $I, $U, $db; 1357 $ga = (int) get_setting('guestaccess'); 1358 print_start('admin'); 1359 $chlist = "<select name=\"name[]\" size=\"5\" multiple><option value=\"\">$I[choose]</option>"; 1360 $chlist .= "<option value=\"s &\">$I[allguests]</option>"; 1361 $users = []; 1362 $stmt = $db->query('SELECT nickname, style, status FROM ' . PREFIX . 'sessions WHERE entry!=0 AND status>0 ORDER BY LOWER(nickname);'); 1363 while ($user = $stmt->fetch(PDO::FETCH_NUM)) { 1364 $users[] = [htmlspecialchars($user[0]), $user[1], $user[2]]; 1365 } 1366 foreach ($users as $user) { 1367 if ($user[2] < $U['status']) { 1368 $chlist .= "<option value=\"$user[0]\" style=\"$user[1]\">$user[0]</option>"; 1369 } 1370 } 1371 $chlist .= '</select>'; 1372 echo "<h2>$I[admfunc]</h2><i>$arg</i><table>"; 1373 if ($U['status'] >= 7) { 1374 thr(); 1375 echo '<tr><td>' . form_target('view', 'setup') . submit($I['initgosetup']) . '</form></td></tr>'; 1376 } 1377 thr(); 1378 echo "<tr><td><table id=\"clean\"><tr><th>$I[cleanmsgs]</th><td>"; 1379 echo form('admin', 'clean'); 1380 echo '<table><tr><td><label><input type="radio" name="what" id="room" value="chat">'; 1381 echo $I['chat'] . "</label></td><td> </td><td><label><input type=\"radio\" name=\"what\" id=\"choose\" value=\"room\" checked>"; 1382 echo $I['room'] . "</label></td><td> </td><td></tr><tr><td colspan=\"3\"><label><input type=\"radio\" name=\"what\" id=\"choose\" value=\"choose\" checked>"; 1383 echo $I['selection'] . "</label></td><td> </td></tr><tr><td colspan=\"3\"><label><input type=\"radio\" name=\"what\" id=\"nick\" value=\"nick\">"; 1384 echo $I['cleannick'] . "</label> <select name=\"nickname\" size=\"1\"><option value=\"\">$I[choose]</option>"; 1385 $stmt = $db->prepare('SELECT poster FROM ' . PREFIX . "messages WHERE delstatus<? AND poster!='' GROUP BY poster;"); 1386 $stmt->execute([$U['status']]); 1387 while ($nick = $stmt->fetch(PDO::FETCH_NUM)) { 1388 echo '<option value="' . htmlspecialchars($nick[0]) . '">' . htmlspecialchars($nick[0]) . '</option>'; 1389 } 1390 echo '</select></td><td>'; 1391 echo submit($I['clean'], 'class="delbutton"') . '</td></tr></table></form></td></tr></table></td></tr>'; 1392 thr(); 1393 echo '<tr><td><table id="kick"><tr><th>' . sprintf($I['kickchat'], get_setting('kickpenalty')) . '</th></tr><tr><td>'; 1394 echo form('admin', 'kick'); 1395 echo "<table><tr><td>$I[kickreason]</td><td><input type=\"text\" name=\"kickmessage\" size=\"30\"></td><td> </td></tr>"; 1396 echo "<tr><td><label><input type=\"checkbox\" name=\"what\" value=\"purge\" id=\"purge\">$I[kickpurge]</label></td><td>$chlist</td><td>"; 1397 echo submit($I['kick']) . '</td></tr></table></form></td></tr></table></td></tr>'; 1398 thr(); 1399 echo "<tr><td><table id=\"logout\"><tr><th>$I[logoutinact]</th><td>"; 1400 echo form('admin', 'logout'); 1401 echo "<table><tr><td>$chlist</td><td>"; 1402 echo submit($I['logout']) . '</td></tr></table></form></td></tr></table></td></tr>'; 1403 1404 //MODIFICATION 2019-09-06 last-login table (show when members logged in the last time. 1405 $view_lastlogin = 'lastlogin'; 1406 if ($U['status'] >= 7) { 1407 thr(); 1408 echo "<tr><td><table id=\"$view_lastlogin\"><tr><th>" . "Last logins" . '</th><td>'; 1409 echo form('admin', $view_lastlogin); 1410 echo submit($I['view']) . '</form></td></tr></table></td></tr>'; 1411 } 1412 //MODIFICATION 2019-08-28 one line replaced with 6 lines of code 1413 //filter button and linkfilter button will only be shown to smod 'Jonie' (status = 6), admins and higher. 1414 if (($U['status'] >= 7) || ($U['status'] >= 6 && $U['nickname'] == 'Jonie')) { 1415 $views = ['sessions', 'filter', 'linkfilter']; 1416 } else { 1417 $views = ['sessions']; 1418 } 1419 1420 foreach ($views as $view) { 1421 thr(); 1422 echo "<tr><td><table id=\"$view\"><tr><th>" . $I[$view] . '</th><td>'; 1423 echo form('admin', $view); 1424 echo submit($I['view']) . '</form></td></tr></table></td></tr>'; 1425 } 1426 thr(); 1427 //Modification chat rooms. 1428 $roomcreateaccess = (int) get_setting('roomcreateaccess'); 1429 if ($U['status'] >= $roomcreateaccess) { 1430 echo "<tr><td><table id=\"chatrooms\"><tr><th>" . 'Chat Rooms</th><td>'; 1431 echo form('admin', 'rooms'); 1432 echo submit($I['view']) . '</form></td></tr></table></td></tr>'; 1433 thr(); 1434 } 1435 1436 //Modification "html topic" (Topic can only be set by admins) 1437 if ($U['status'] >= 7) { 1438 1439 echo "<tr><td><table id=\"topic\"><tr><th>$I[topic]</th><td>"; 1440 echo form('admin', 'topic'); 1441 echo '<table><tr><td><input type="text" name="topic" size="20" value="' . htmlspecialchars(get_setting('topic')) . '"></td><td>'; 1442 echo submit($I['change']) . '</td></tr></table></form></td></tr></table></td></tr>'; 1443 thr(); 1444 } 1445 1446 echo "<tr><td><table id=\"guestaccess\"><tr><th>$I[guestacc]</th><td>"; 1447 echo form('admin', 'guestaccess'); 1448 echo '<table>'; 1449 echo '<tr><td><select name="guestaccess">'; 1450 echo '<option value="1"'; 1451 if ($ga === 1) { 1452 echo ' selected'; 1453 } 1454 echo ">$I[guestallow]</option>"; 1455 echo '<option value="2"'; 1456 if ($ga === 2) { 1457 echo ' selected'; 1458 } 1459 echo ">$I[guestwait]</option>"; 1460 echo '<option value="3"'; 1461 if ($ga === 3) { 1462 echo ' selected'; 1463 } 1464 echo ">$I[adminallow]</option>"; 1465 echo '<option value="0"'; 1466 if ($ga === 0) { 1467 echo ' selected'; 1468 } 1469 echo ">$I[guestdisallow]</option>"; 1470 if ($ga === 4) { 1471 echo '<option value="4" selected'; 1472 echo ">$I[disablechat]</option>"; 1473 } 1474 echo '</select></td><td>' . submit($I['change']) . '</td></tr></table></form></td></tr></table></td></tr>'; 1475 thr(); 1476 if (get_setting('suguests')) { 1477 echo "<tr><td><table id=\"suguests\"><tr><th>$I[addsuguest]</th><td>"; 1478 echo form('admin', 'superguest'); 1479 echo "<table><tr><td><select name=\"name\" size=\"1\"><option value=\"\">$I[choose]</option>"; 1480 foreach ($users as $user) { 1481 if ($user[2] == 1) { 1482 echo "<option value=\"$user[0]\" style=\"$user[1]\">$user[0]</option>"; 1483 } 1484 } 1485 echo '</select></td><td>' . submit($I['register']) . '</td></tr></table></form></td></tr></table></td></tr>'; 1486 thr(); 1487 } 1488 if ($U['status'] >= 7) { 1489 echo "<tr><td><table id=\"status\"><tr><th>$I[admmembers]</th><td>"; 1490 echo form('admin', 'status'); 1491 echo "<table><td><select name=\"name\" size=\"1\"><option value=\"\">$I[choose]</option>"; 1492 $members = []; 1493 $result = $db->query('SELECT nickname, style, status FROM ' . PREFIX . 'members ORDER BY LOWER(nickname);'); 1494 while ($temp = $result->fetch(PDO::FETCH_NUM)) { 1495 $members[] = [htmlspecialchars($temp[0]), $temp[1], $temp[2]]; 1496 } 1497 foreach ($members as $member) { 1498 echo "<option value=\"$member[0]\" style=\"$member[1]\">$member[0]"; 1499 if ($member[2] == 0) { 1500 echo ' (!)'; 1501 } elseif ($member[2] == 2) { 1502 echo ' (G)'; 1503 } elseif ($member[2] == 3) { 1504 } elseif ($member[2] == 5) { 1505 echo ' (M)'; 1506 } elseif ($member[2] == 6) { 1507 echo ' (SM)'; 1508 } elseif ($member[2] == 7) { 1509 echo ' (A)'; 1510 } else { 1511 echo ' (SA)'; 1512 } 1513 echo '</option>'; 1514 } 1515 echo "</select><select name=\"set\" size=\"1\"><option value=\"\">$I[choose]</option><option value=\"-\">$I[memdel]</option><option value=\"0\">$I[memdeny]</option>"; 1516 if (get_setting('suguests')) { 1517 echo "<option value=\"2\">$I[memsuguest]</option>"; 1518 } 1519 echo "<option value=\"3\">$I[memreg]</option>"; 1520 echo "<option value=\"5\">$I[memmod]</option>"; 1521 echo "<option value=\"6\">$I[memsumod]</option>"; 1522 if ($U['status'] >= 8) { 1523 echo "<option value=\"7\">$I[memadm]</option>"; 1524 } 1525 echo '</select></td><td>' . submit($I['change']) . '</td></tr></table></form></td></tr></table></td></tr>'; 1526 thr(); 1527 echo "<tr><td><table id=\"passreset\"><tr><th>$I[passreset]</th><td>"; 1528 echo form('admin', 'passreset'); 1529 echo "<table><td><select name=\"name\" size=\"1\"><option value=\"\">$I[choose]</option>"; 1530 foreach ($members as $member) { 1531 echo "<option value=\"$member[0]\" style=\"$member[1]\">$member[0]</option>"; 1532 } 1533 echo '</select></td><td><input type="password" name="pass"></td><td>' . submit($I['change']) . '</td></tr></table></form></td></tr></table></td></tr>'; 1534 thr(); 1535 echo "<tr><td><table id=\"register\"><tr><th>$I[regguest]</th><td>"; 1536 echo form('admin', 'register'); 1537 echo "<table><tr><td><select name=\"name\" size=\"1\"><option value=\"\">$I[choose]</option>"; 1538 foreach ($users as $user) { 1539 if ($user[2] == 1) { 1540 echo "<option value=\"$user[0]\" style=\"$user[1]\">$user[0]</option>"; 1541 } 1542 } 1543 echo '</select></td><td>' . submit($I['register']) . '</td></tr></table></form></td></tr></table></td></tr>'; 1544 thr(); 1545 ////Modification Register new Applicant 1546 echo "<tr><td><table id=\"regnew\"><tr><th>" . (get_setting('suguests') ? "Register new Applicant" : $I['regmem']) . "</th></tr><tr><td>"; 1547 echo form('admin', 'regnew'); 1548 echo "<table><tr><td>$I[nick]</td><td> </td><td><input type=\"text\" name=\"name\" size=\"20\"></td><td> </td></tr>"; 1549 echo "<tr><td>$I[pass]</td><td> </td><td><input type=\"password\" name=\"pass\" size=\"20\"></td><td>"; 1550 echo submit($I['register']) . '</td></tr></table></form></td></tr></table></td></tr>'; 1551 thr(); 1552 } 1553 echo "</table><br>"; 1554 echo form('admin') . submit($I['reload']) . '</form>'; 1555 print_end(); 1556 } 1557 1558 function send_sessions() 1559 { 1560 global $I, $U, $db; 1561 $stmt = $db->prepare('SELECT nickname, style, lastpost, status, useragent, ip FROM ' . PREFIX . 'sessions WHERE entry!=0 AND (incognito=0 OR status<? OR nickname=?) ORDER BY status DESC, lastpost DESC;'); 1562 $stmt->execute([$U['status'], $U['nickname']]); 1563 if (!$lines = $stmt->fetchAll(PDO::FETCH_ASSOC)) { 1564 $lines = []; 1565 } 1566 print_start('sessions'); 1567 echo "<h1>$I[sessact]</h1><table>"; 1568 echo "<tr><th>$I[sessnick]</th><th>$I[sesstimeout]</th><th>$I[sessua]</th>"; 1569 $trackip = (bool) get_setting('trackip'); 1570 $memexpire = (int) get_setting('memberexpire'); 1571 $guestexpire = (int) get_setting('guestexpire'); 1572 if ($trackip) echo "<th>$I[sesip]</th>"; 1573 echo "<th>$I[actions]</th></tr>"; 1574 foreach ($lines as $temp) { 1575 if ($temp['status'] == 0) { 1576 $s = ' (K)'; 1577 } elseif ($temp['status'] <= 2) { 1578 $s = ' (G)'; 1579 } elseif ($temp['status'] == 3) { 1580 $s = ''; 1581 } elseif ($temp['status'] == 5) { 1582 $s = ' (M)'; 1583 } elseif ($temp['status'] == 6) { 1584 $s = ' (SM)'; 1585 } elseif ($temp['status'] == 7) { 1586 $s = ' (A)'; 1587 } else { 1588 $s = ' (SA)'; 1589 } 1590 echo '<tr><td class="nickname">' . style_this(htmlspecialchars($temp['nickname']) . $s, $temp['style']) . '</td><td class="timeout">'; 1591 if ($temp['status'] > 2) { 1592 echo get_timeout($temp['lastpost'], $memexpire); 1593 } else { 1594 echo get_timeout($temp['lastpost'], $guestexpire); 1595 } 1596 echo '</td>'; 1597 if ($U['status'] > $temp['status'] || $U['nickname'] === $temp['nickname']) { 1598 echo "<td class=\"ua\">$temp[useragent]</td>"; 1599 if ($trackip) { 1600 echo "<td class=\"ip\">$temp[ip]</td>"; 1601 } 1602 echo '<td class="action">'; 1603 if ($temp['nickname'] !== $U['nickname']) { 1604 echo '<table><tr>'; 1605 if ($temp['status'] != 0) { 1606 echo '<td>'; 1607 echo form('admin', 'sessions'); 1608 echo hidden('kick', '1') . hidden('nick', htmlspecialchars($temp['nickname'])) . submit($I['kick']) . '</form>'; 1609 echo '</td>'; 1610 } 1611 echo '<td>'; 1612 echo form('admin', 'sessions'); 1613 echo hidden('logout', '1') . hidden('nick', htmlspecialchars($temp['nickname'])) . submit($temp['status'] == 0 ? $I['unban'] : $I['logout']) . '</form>'; 1614 echo '</td></tr></table>'; 1615 } else { 1616 echo '-'; 1617 } 1618 echo '</td></tr>'; 1619 } else { 1620 echo '<td class="ua">-</td>'; 1621 if ($trackip) { 1622 echo '<td class="ip">-</td>'; 1623 } 1624 echo '<td class="action">-</td></tr>'; 1625 } 1626 } 1627 echo "</table><br>"; 1628 echo form('admin', 'sessions') . submit($I['reload']) . '</form>'; 1629 print_end(); 1630 } 1631 1632 //MODIFICATION 2019-09-06 Featrue: last login table. function send_lastlogin() added. 1633 function send_lastlogin() 1634 { 1635 global $I, $U, $db; 1636 1637 if ($U['status'] >= 7) { 1638 $stmt = $db->prepare('SELECT nickname, status, lastlogin, style FROM ' . PREFIX . 'members ORDER BY status DESC, lastlogin DESC'); 1639 $stmt->execute(); 1640 1641 if (!$lines = $stmt->fetchAll(PDO::FETCH_ASSOC)) { 1642 $lines = []; 1643 } 1644 print_start('lastlogin'); 1645 echo "<h1>Last logins</h1><table id=table_lastlogins>"; 1646 1647 echo "<tr><th>Nickname</th><th>Last login</th>"; 1648 1649 foreach ($lines as $temp) { 1650 1651 if ($temp['status'] == 0) { 1652 $s = ' (K)'; 1653 } elseif ($temp['status'] <= 2) { 1654 $s = ' (G)'; 1655 } elseif ($temp['status'] == 3) { 1656 $s = ''; 1657 } elseif ($temp['status'] == 5) { 1658 $s = ' (M)'; 1659 } elseif ($temp['status'] == 6) { 1660 $s = ' (SM)'; 1661 } elseif ($temp['status'] == 7) { 1662 $s = ' (A)'; 1663 } else { 1664 $s = ' (SA)'; 1665 } 1666 1667 echo '<tr><td class="nickname">' . style_this(htmlspecialchars($temp['nickname']) . $s, $temp['style'] . '</td>'); 1668 if ($temp['lastlogin'] === '0') { 1669 echo '<td class="lastlogin">unknown</td>'; 1670 } else { 1671 echo '<td class="lastlogin">' . date('l jS \of F Y h:i:s A', $temp['lastlogin']) . '</td>'; 1672 } 1673 } 1674 echo "</table><br>"; 1675 echo form('admin', 'lastlogin') . submit($I['reload']) . '</form>'; 1676 print_end(); 1677 } 1678 } 1679 1680 function send_gallery($site = 1) 1681 { 1682 global $I, $U, $db; 1683 1684 //gallery version v0.9.3 1685 1686 $link = ''; 1687 $links = []; 1688 $reallinks = []; 1689 $tempmessage = ''; 1690 $gallery_reload_button = 0; 1691 1692 //Use the following patterns, if "force redirection" is enabled in the chat setup. 1693 //pattern to find the hyperlinks. you can add the allowed file extensions here. 1694 $pattern = 'url=http.*\.(jpg|jpeg|png|gif|bmp)'; 1695 1696 //pattern to find just the url (within the hyperlinks). Finds http and https links. 1697 $pattern2 = 'https?\%3A\%2F\%2F.*\.(jpg|jpeg|png|gif|bmp)'; 1698 1699 1700 $GalleryAdminStatus = '5'; 1701 1702 print_start('gallery'); 1703 echo "<h1>The 404 Gallery</h1>"; 1704 1705 if ($U['status'] < (int)get_setting('galleryaccess')) { 1706 1707 echo "You are not allowed to view the gallery"; 1708 } 1709 1710 1711 if (!get_setting('forceredirect')) { 1712 1713 echo "Please enable \"force redirect\" in the chat setup. The gallery won't work otherwise."; 1714 } elseif ($U['status'] >= (int)get_setting('galleryaccess')) { 1715 1716 1717 // Modification chat rooms so that images in channels not visible to the chatter are not shown 1718 $stmt = $db->prepare('SELECT id, text FROM ' . PREFIX . 'messages WHERE poststatus<=? AND (roomid= ANY (SELECT id FROM ' . PREFIX . 'rooms WHERE access<=?) OR roomid IS NULL OR poststatus>1) ORDER BY id DESC;'); 1719 $stmt->execute([$U['status'], $U['status']]); 1720 1721 1722 //START OF LINKS DETECTION Here we start to detect the links in the messages 1723 /*************************/ 1724 1725 $matches = []; 1726 $number_of_matches = 0; 1727 1728 while ($message = $stmt->fetch(PDO::FETCH_ASSOC)) { 1729 1730 prepare_message_print($message, true); //decrypt message if encrypted. 1731 1732 $tempmessage = $message['text']; 1733 1734 1735 1736 //Debug 1737 //echo "Debug. ".htmlspecialchars($message['text'])."<br><br>"; 1738 1739 //Description: Finds all picture-hyperlinks wihtin one message 1740 preg_match('/' . $pattern . '/i', $tempmessage, $matches); 1741 if (!empty($matches['0'])) { 1742 1743 $tempmatch = $matches['0'];; 1744 1745 //Description: Finds all urls within one message 1746 preg_match('/' . $pattern2 . '/i', $tempmatch, $matches); 1747 if (!empty($matches['0'])) { 1748 $link = $matches['0']; 1749 } 1750 1751 1752 $token = strtok($link, " "); 1753 1754 while ($token !== false) { 1755 1756 $links[] = $token; 1757 $token = strtok(" "); 1758 } 1759 1760 $number_of_matches++; 1761 } 1762 } 1763 1764 $arrlength = count($links); 1765 for ($x = 0; $x < $arrlength; $x++) { 1766 preg_match('/' . $pattern2 . '/i', $links[$x], $matches); 1767 if (!empty($matches['0'])) { 1768 $reallinks[] = $matches['0']; 1769 } 1770 } 1771 1772 1773 //END OF LINKS DETECTION. Now we can build the gallery with the detected links. 1774 1775 1776 1777 //START OF PRINTING GALLERY 1778 /**************************/ 1779 $posts_per_site = 12; //default value is 12. Change this value to set the number of pictures per gallery site. 1780 $start = ($site - 1) * $posts_per_site; 1781 1782 1783 //Hyperlinks and embedded images 1784 //count number of links 1785 $number_of_links = count($reallinks); 1786 1787 1788 //PAGINATION CONTROLS TO NAVIGATRE THROUGH GALLERY 1789 //Calculate the number of sites 1790 $number_of_sites = ceil($number_of_links / floatval($posts_per_site)); 1791 1792 //Print links to the different sites 1793 //--------------------------------------------- 1794 echo "<p></p><div id='pagination_controls'>"; 1795 echo "<table id='pagination_controls_table'><tr>"; 1796 if (($site > 1) && ($site <= $number_of_sites)) { 1797 echo '<td>' . form('gallery', $site - 1) . submit('Previous') . '</form>  </td>'; 1798 } 1799 1800 for ($a = 1; $a <= $number_of_sites; $a++) { 1801 1802 //If user is on _this_ site, do not print a link 1803 if ($site == $a) { 1804 echo '<td>' . form('gallery', $a) . submit($a, "id='current_site_button'") . '</form>  </td>'; 1805 $gallery_reload_button = $a; 1806 } else { 1807 //user is not on _this_ site, so print a link. 1808 echo '<td>' . form('gallery', $a) . submit(' ' . $a . ' ') . '</form>  </td>'; 1809 } 1810 } 1811 1812 if (($site >= 1) && ($site < $number_of_sites)) { 1813 echo '<td>' . form('gallery', $site + 1) . submit('Next') . '</form>  </td>'; 1814 } 1815 echo '</tr></table>'; 1816 echo "</div>"; 1817 //END OF PAGNINATION CONTROLS 1818 1819 echo "<div id='live_gallery_div'><table id='live_gallery_table' width='1000' cellpadding='10'><tbody><tr>"; 1820 if (($start + $posts_per_site) < $number_of_links) { 1821 1822 $arrlength2 = $start + $posts_per_site; 1823 } else { 1824 $arrlength2 = $number_of_links; 1825 } 1826 $column_number = 0; 1827 1828 1829 for ($x = $start; $x < $arrlength2; $x++) { 1830 1831 $y = $x + 1; 1832 1833 echo "<td align='center'><a href='#imgdiv" . $y . "'><img id='img" . $y . "' class='img' src='" . urldecode($reallinks[$x]) . "' height='100'></a><br>"; 1834 1835 //echo "<br>"; 1836 $column_number++; 1837 if ($column_number === 6) { //default value is 6. change this value to show more pictures in one row 1838 echo "</tr><tr>"; 1839 $column_number = 0; 1840 } 1841 } 1842 1843 echo "</tbody></table></div>"; 1844 1845 //gallery reload button 1846 //debug 1847 //echo "gallery reload button value: ".$gallery_reload_button; 1848 1849 echo "<table id='gallery_navigation_table'><tr><td>"; 1850 if ($gallery_reload_button >= 1) { 1851 echo "<br>" . form('gallery', $gallery_reload_button) . submit($I['reload']) . '</form>'; 1852 } else { 1853 echo "<br>" . form('gallery') . submit($I['reload']) . '</form>'; 1854 } 1855 1856 echo "</td><td>"; 1857 echo form_target('view', 'view') . submit('Back to chat') . '</form>'; 1858 echo "</td></tr></table>"; 1859 1860 1861 1862 1863 echo "<br>"; 1864 //the variables use here are define avove pagination controls in the code. see above. 1865 //Print a div for each image. Each of them must be hided through css. A div that becomes target must be displayed (with css). 1866 for ($x = $start; $x < $arrlength2; $x++) { 1867 1868 $y = $x + 1; 1869 echo "<a href='#live_gallery_table'><div id='imgdiv" . $y . "' class='imgdiv'><img class='galleryimg' src='" . urldecode($reallinks[$x]) . "'></a><br>" . apply_linkfilter(create_hotlinks(urldecode($reallinks[$x]))) . "</div>"; 1870 } 1871 //END OF PRINTING GALLERY 1872 1873 } 1874 print_end(); 1875 } 1876 1877 //MODIFICATION links page 1878 function send_links_page() 1879 { 1880 1881 global $I; 1882 1883 if (get_setting('linksenabled') === '1') { 1884 $links = get_setting('links'); 1885 1886 print_start('links'); 1887 $links = get_setting('links'); 1888 if (!empty($links)) { 1889 echo "<div id=\"links\"><h2>The Underground Links</h2><br>$links<br>" . form_target('view', 'view') . submit('Back to chat') . "</form></div>"; 1890 } 1891 } else { 1892 return; 1893 } 1894 } 1895 1896 // Modification change chat rooms 1897 function change_room() 1898 { 1899 global $U, $db; 1900 if ($_REQUEST['room'] === '*') { 1901 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET roomid=NULL WHERE id=?;'); 1902 $stmt->execute([$U['id']]); 1903 } else { 1904 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET roomid=(SELECT id FROM ' . PREFIX . 'rooms WHERE id=? AND access<=?) WHERE id=?;'); 1905 $stmt->execute([$_REQUEST['room'], $U['status'], $U['id']]); 1906 } 1907 // Set session flag to indicate room change for post box reload 1908 $_SESSION['room_changed'] = true; 1909 } 1910 1911 // Modification select chat rooms 1912 function print_rooms() 1913 { 1914 global $db, $U; 1915 echo '<div id="roomblock">'; 1916 echo '<div class="room-header">'; 1917 echo '<span class="room-label">💬 Switch Room</span>'; 1918 echo '</div>'; 1919 echo '<div class="room-selector">'; 1920 echo form_target('view', 'view'); 1921 echo "<select name=\"room\" id=\"room\">"; 1922 echo '<option value="*">[Main Chat]</option>'; 1923 $stmt = $db->prepare('SELECT id, name FROM ' . PREFIX . 'rooms WHERE access<=? ORDER BY id ASC;'); 1924 $stmt->execute([$U['status']]); 1925 if (!$rooms = $stmt->fetchAll(PDO::FETCH_ASSOC)) { 1926 $rooms = []; 1927 } 1928 foreach ($rooms as $room) { 1929 $stmt = $db->prepare('SELECT id FROM ' . PREFIX . 'sessions WHERE roomid=?;'); 1930 $stmt->execute([$room['id']]); 1931 $num = count($stmt->fetchAll()); 1932 echo "<option value=\"$room[id]\""; 1933 if ($U['roomid'] === $room['id']) { 1934 echo ' selected'; 1935 } 1936 echo ">$room[name] ($num)</option>"; 1937 } 1938 echo '</select>'; 1939 echo submit('Switch'); 1940 echo '</form>'; 1941 echo '</div>'; 1942 echo '</div>'; 1943 } 1944 1945 // Modification rooms in admin page 1946 function send_rooms($arg = '') 1947 { 1948 global $I, $U, $db; 1949 print_start('linkfilter'); 1950 echo "<h2>Chat Rooms</h2><i>$arg</i><table>"; 1951 thr(); 1952 echo '<tr><th><table style="width:100%;"><tr>'; 1953 echo "<td style=\"width:8em;\">Room ID:</td>"; 1954 echo "<td style=\"width:12em;\">Name</td>"; 1955 echo "<td style=\"width:12em;\">Access</td>"; 1956 if ($U['status'] > 6) { 1957 echo "<td style=\"width:10em;\">Permanent</td>"; 1958 } 1959 echo "<td style=\"width:5em;\">$I[apply]</td>"; 1960 echo "<td style=\"width:8em;\">Expires in</td>"; 1961 echo '</tr></table></th></tr>'; 1962 $stmt = $db->prepare('SELECT * FROM ' . PREFIX . 'rooms WHERE access<=? ORDER BY id ASC;'); 1963 $stmt->execute([$U['status']]); 1964 if (!$rooms = $stmt->fetchAll(PDO::FETCH_ASSOC)) { 1965 $rooms = []; 1966 } 1967 foreach ($rooms as $room) { 1968 if ($room['permanent'] && $U['status'] <= 6) { 1969 continue; 1970 } 1971 if ($room['permanent']) { 1972 $checkedpm = ' checked'; 1973 } else { 1974 $checkedpm = ''; 1975 } 1976 echo '<tr><td>'; 1977 echo form('admin', 'rooms') . hidden('id', $room['id']); 1978 echo "<table style=\"width:100%;\"><tr><th style=\"width:8em;\">Room $room[id]:</th>"; 1979 echo "<td style=\"width:12em;\"><input type=\"text\" name=\"name\" value=\"$room[name]\" size=\"20\" style=\"$U[style]\"></td>"; 1980 echo '<td style="width:12em;">'; 1981 echo "<select name=\"access\">"; 1982 1983 $options = array(1, 2, 3, 5, 6, 7, 8, 10); 1984 1985 foreach ($options as $option) { 1986 if ($U['status'] < $option) { 1987 break; 1988 } 1989 echo "<option value=\"$option\""; 1990 1991 if ($room['access'] == $option) { 1992 echo ' selected'; 1993 } 1994 1995 if ($option == 1) echo ">All</option>"; 1996 elseif ($option == 2) echo ">Registered guests</option>"; 1997 elseif ($option == 3) echo ">Members</option>"; 1998 elseif ($option == 5) echo ">Moderators</option>"; 1999 elseif ($option == 6) echo ">Super Moderators</option>"; 2000 elseif ($option == 7) echo ">Admins</option>"; 2001 elseif ($option == 8) echo ">Super Admins</option>"; 2002 elseif ($option == 10) echo ">Disabled</option>"; 2003 } 2004 2005 echo '</select></td>'; 2006 if ($U['status'] > 6) { 2007 echo "<td style=\"width:10em;\"><label><input type=\"checkbox\" name=\"permanent\" value=\"1\"$checkedpm>Permanent</label></td>"; 2008 } 2009 echo '<td class="roomsubmit" style="width:5em;">' . submit($I['change']) . '</td>'; 2010 $stmt = $db->prepare('SELECT null FROM ' . PREFIX . 'sessions WHERE roomid=?;'); 2011 $stmt->execute([$room['id']]); 2012 if ($stmt->fetch(PDO::FETCH_NUM) || $room['permanent']) { 2013 echo "<th style=\"width:8em;\">--:--</th>"; 2014 } else { 2015 $expire = (int) get_setting('roomexpire'); 2016 echo "<th style=\"width:8em;\">" . get_timeout($room['time'], $expire) . '</th>'; 2017 } 2018 echo "</tr></table></form></td></tr>"; 2019 } 2020 echo '<tr><td>'; 2021 echo form('admin', 'rooms') . hidden('id', '+'); 2022 echo "<table style=\"width:100%;\"><tr><th style=\"width:8em;\">New Room</th>"; 2023 echo "<td style=\"width:12em;\"><input type=\"text\" name=\"name\" value=\"\" size=\"20\" style=\"$U[style]\"></td>"; 2024 echo '<td style="width:12em;">'; 2025 echo "<select name=\"access\">"; 2026 2027 $options = array(1, 2, 3, 5, 6, 7, 8, 10); 2028 2029 foreach ($options as $option) { 2030 if ($U['status'] < $option) { 2031 break; 2032 } 2033 echo "<option value=\"$option\""; 2034 2035 if ($option == 1) echo ">All</option>"; 2036 elseif ($option == 2) echo ">Registered guests</option>"; 2037 elseif ($option == 3) echo ">Members</option>"; 2038 elseif ($option == 5) echo ">Moderators</option>"; 2039 elseif ($option == 6) echo ">Super Moderators</option>"; 2040 elseif ($option == 7) echo ">Admins</option>"; 2041 elseif ($option == 8) echo ">Super Admins</option>"; 2042 elseif ($option == 10) echo ">Disabled</option>"; 2043 } 2044 2045 echo '</select></td>'; 2046 if ($U['status'] > 6) { 2047 echo "<td style=\"width:10em;\"><label><input type=\"checkbox\" name=\"permanent\" value=\"1\">Permanent</label></td>"; 2048 } 2049 echo '<td class="roomsubmit" style="width:5em;">' . submit($I['add']) . '</td>'; 2050 echo "<th style=\"width:8em;\"></th>"; 2051 echo "</tr></table></form></td></tr></table><br>"; 2052 echo form('admin', 'rooms') . submit($I['reload']) . '</form>'; 2053 print_end(); 2054 } 2055 2056 //Forum Link was moved to the post box (function send_post) 2057 /* 2058 function send_to_forum(){ 2059 2060 echo "Add redirect to forum here"; 2061 2062 } 2063 */ 2064 2065 // Modification chat rooms. 2066 function manage_rooms() 2067 { 2068 global $U, $db; 2069 if (!isset($_REQUEST['id']) || !isset($_REQUEST['access']) || !isset($_REQUEST['name']) || $U['status'] < $_REQUEST['access']) { 2070 return; 2071 } 2072 if (!preg_match('/^[A-Za-z0-9\-]{0,50}$/', $_REQUEST['name'])) { 2073 return "Invalid Name."; 2074 } 2075 if (isset($_REQUEST['permanent']) && $_REQUEST['permanent'] && $U['status'] > 6) { 2076 $permanent = 1; 2077 } else { 2078 $permanent = 0; 2079 } 2080 if ($_REQUEST['id'] === '+' && $_REQUEST['name'] !== '') { 2081 $stmt = $db->prepare('SELECT null FROM ' . PREFIX . 'rooms WHERE name=?'); 2082 $stmt->execute([$_REQUEST['name']]); 2083 if ($stmt->fetch(PDO::FETCH_NUM)) { 2084 return; 2085 } 2086 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'rooms (name, access, time, permanent) VALUES (?, ?, ?, ?);'); 2087 $stmt->execute([$_REQUEST['name'], $_REQUEST['access'], time(), $permanent]); 2088 } elseif ($_REQUEST['name'] !== '') { 2089 $stmt = $db->prepare('SELECT null FROM ' . PREFIX . 'rooms WHERE name=? AND id!=?;'); 2090 $stmt->execute([$_REQUEST['name'], $_REQUEST['id']]); 2091 if ($stmt->fetch(PDO::FETCH_NUM)) { 2092 return; 2093 } 2094 if ($U['status'] < 7) { 2095 $stmt = $db->prepare('SELECT null FROM ' . PREFIX . 'rooms WHERE id=? AND permanent=1;'); 2096 $stmt->execute([$_REQUEST['id']]); 2097 if ($stmt->fetch(PDO::FETCH_NUM)) { 2098 return; 2099 } 2100 } 2101 $stmt = $db->prepare('UPDATE ' . PREFIX . 'rooms SET name=?, access=?, permanent=? WHERE id=? AND access<=?;'); 2102 $stmt->execute([$_REQUEST['name'], $_REQUEST['access'], $permanent, $_REQUEST['id'], $U['status']]); 2103 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET roomid=NULL WHERE roomid=? AND status<?;'); 2104 $stmt->execute([$_REQUEST['id'], $_REQUEST['access']]); 2105 } else { 2106 remove_room(false, $_REQUEST['id'], $U['status']); 2107 } 2108 } 2109 2110 function remove_room($all = false, $id = '', $status = 10) 2111 { 2112 global $db; 2113 if ($all) { 2114 //placeholder 2115 } else { 2116 $stmt = $db->prepare('SELECT id FROM ' . PREFIX . "rooms WHERE id=? AND access<=?;"); 2117 $stmt->execute([$id, $status]); 2118 if ($room = $stmt->fetch(PDO::FETCH_ASSOC)) { 2119 $name = $stmt->fetch(PDO::FETCH_NUM); 2120 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'rooms WHERE id=?;'); 2121 $stmt->execute([$room['id']]); 2122 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'messages WHERE roomid=?;'); 2123 $stmt->execute([$room['id']]); 2124 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET roomid=NULL WHERE roomid=?;'); 2125 $stmt->execute([$room['id']]); 2126 } 2127 } 2128 } 2129 2130 2131 function check_filter_match(&$reg) 2132 { 2133 global $I; 2134 $_REQUEST['match'] = htmlspecialchars($_REQUEST['match']); 2135 if (isset($_REQUEST['regex']) && $_REQUEST['regex'] == 1) { 2136 if (!valid_regex($_REQUEST['match'])) { 2137 return "$I[incorregex]<br>$I[prevmatch]: $_REQUEST[match]"; 2138 } 2139 $reg = 1; 2140 } else { 2141 $_REQUEST['match'] = preg_replace('/([^\w\d])/u', "\\\\$1", $_REQUEST['match']); 2142 $reg = 0; 2143 } 2144 if (mb_strlen($_REQUEST['match']) > 255) { 2145 return "$I[matchtoolong]<br>$I[prevmatch]: $_REQUEST[match]"; 2146 } 2147 return false; 2148 } 2149 2150 function manage_filter() 2151 { 2152 global $db, $memcached; 2153 if (isset($_REQUEST['id'])) { 2154 $reg = 0; 2155 if ($tmp = check_filter_match($reg)) { 2156 return $tmp; 2157 } 2158 if (isset($_REQUEST['allowinpm']) && $_REQUEST['allowinpm'] == 1) { 2159 $pm = 1; 2160 } else { 2161 $pm = 0; 2162 } 2163 if (isset($_REQUEST['kick']) && $_REQUEST['kick'] == 1) { 2164 $kick = 1; 2165 } else { 2166 $kick = 0; 2167 } 2168 if (isset($_REQUEST['cs']) && $_REQUEST['cs'] == 1) { 2169 $cs = 1; 2170 } else { 2171 $cs = 0; 2172 } 2173 if (preg_match('/^[0-9]+$/', $_REQUEST['id'])) { 2174 if (empty($_REQUEST['match'])) { 2175 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'filter WHERE id=?;'); 2176 $stmt->execute([$_REQUEST['id']]); 2177 } else { 2178 $stmt = $db->prepare('UPDATE ' . PREFIX . 'filter SET filtermatch=?, filterreplace=?, allowinpm=?, regex=?, kick=?, cs=? WHERE id=?;'); 2179 $stmt->execute([$_REQUEST['match'], $_REQUEST['replace'], $pm, $reg, $kick, $cs, $_REQUEST['id']]); 2180 } 2181 } elseif ($_REQUEST['id'] === '+') { 2182 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'filter (filtermatch, filterreplace, allowinpm, regex, kick, cs) VALUES (?, ?, ?, ?, ?, ?);'); 2183 $stmt->execute([$_REQUEST['match'], $_REQUEST['replace'], $pm, $reg, $kick, $cs]); 2184 } 2185 if (MEMCACHED) { 2186 $memcached->delete(DBNAME . '-' . PREFIX . 'filter'); 2187 } 2188 } 2189 } 2190 2191 function manage_linkfilter() 2192 { 2193 global $db, $memcached; 2194 if (isset($_REQUEST['id'])) { 2195 $reg = 0; 2196 if ($tmp = check_filter_match($reg)) { 2197 return $tmp; 2198 } 2199 if (preg_match('/^[0-9]+$/', $_REQUEST['id'])) { 2200 if (empty($_REQUEST['match'])) { 2201 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'linkfilter WHERE id=?;'); 2202 $stmt->execute([$_REQUEST['id']]); 2203 } else { 2204 $stmt = $db->prepare('UPDATE ' . PREFIX . 'linkfilter SET filtermatch=?, filterreplace=?, regex=? WHERE id=?;'); 2205 $stmt->execute([$_REQUEST['match'], $_REQUEST['replace'], $reg, $_REQUEST['id']]); 2206 } 2207 } elseif ($_REQUEST['id'] === '+') { 2208 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'linkfilter (filtermatch, filterreplace, regex) VALUES (?, ?, ?);'); 2209 $stmt->execute([$_REQUEST['match'], $_REQUEST['replace'], $reg]); 2210 } 2211 if (MEMCACHED) { 2212 $memcached->delete(DBNAME . '-' . PREFIX . 'linkfilter'); 2213 } 2214 } 2215 } 2216 2217 function get_filters() 2218 { 2219 global $db, $memcached; 2220 if (MEMCACHED) { 2221 $filters = $memcached->get(DBNAME . '-' . PREFIX . 'filter'); 2222 } 2223 if (!MEMCACHED || $memcached->getResultCode() !== Memcached::RES_SUCCESS) { 2224 $filters = []; 2225 $result = $db->query('SELECT id, filtermatch, filterreplace, allowinpm, regex, kick, cs FROM ' . PREFIX . 'filter;'); 2226 while ($filter = $result->fetch(PDO::FETCH_ASSOC)) { 2227 $filters[] = ['id' => $filter['id'], 'match' => $filter['filtermatch'], 'replace' => $filter['filterreplace'], 'allowinpm' => $filter['allowinpm'], 'regex' => $filter['regex'], 'kick' => $filter['kick'], 'cs' => $filter['cs']]; 2228 } 2229 if (MEMCACHED) { 2230 $memcached->set(DBNAME . '-' . PREFIX . 'filter', $filters); 2231 } 2232 } 2233 return $filters; 2234 } 2235 2236 function get_linkfilters() 2237 { 2238 global $db, $memcached; 2239 if (MEMCACHED) { 2240 $filters = $memcached->get(DBNAME . '-' . PREFIX . 'linkfilter'); 2241 } 2242 if (!MEMCACHED || $memcached->getResultCode() !== Memcached::RES_SUCCESS) { 2243 $filters = []; 2244 $result = $db->query('SELECT id, filtermatch, filterreplace, regex FROM ' . PREFIX . 'linkfilter;'); 2245 while ($filter = $result->fetch(PDO::FETCH_ASSOC)) { 2246 $filters[] = ['id' => $filter['id'], 'match' => $filter['filtermatch'], 'replace' => $filter['filterreplace'], 'regex' => $filter['regex']]; 2247 } 2248 if (MEMCACHED) { 2249 $memcached->set(DBNAME . '-' . PREFIX . 'linkfilter', $filters); 2250 } 2251 } 2252 return $filters; 2253 } 2254 2255 function send_filter($arg = '') 2256 { 2257 global $I, $U; 2258 print_start('filter'); 2259 echo "<h2>$I[filter]</h2><i>$arg</i><table>"; 2260 thr(); 2261 echo '<tr><th><table style="width:100%;"><tr>'; 2262 echo "<td style=\"width:8em;\">$I[fid]</td>"; 2263 echo "<td style=\"width:12em;\">$I[match]</td>"; 2264 echo "<td style=\"width:12em;\">$I[replace]</td>"; 2265 echo "<td style=\"width:9em;\">$I[allowpm]</td>"; 2266 echo "<td style=\"width:5em;\">$I[regex]</td>"; 2267 echo "<td style=\"width:5em;\">$I[kick]</td>"; 2268 echo "<td style=\"width:5em;\">$I[cs]</td>"; 2269 echo "<td style=\"width:5em;\">$I[apply]</td>"; 2270 echo '</tr></table></th></tr>'; 2271 $filters = get_filters(); 2272 foreach ($filters as $filter) { 2273 if ($filter['allowinpm'] == 1) { 2274 $check = ' checked'; 2275 } else { 2276 $check = ''; 2277 } 2278 if ($filter['regex'] == 1) { 2279 $checked = ' checked'; 2280 } else { 2281 $checked = ''; 2282 $filter['match'] = preg_replace('/(\\\\(.))/u', "$2", $filter['match']); 2283 } 2284 if ($filter['kick'] == 1) { 2285 $checkedk = ' checked'; 2286 } else { 2287 $checkedk = ''; 2288 } 2289 if ($filter['cs'] == 1) { 2290 $checkedcs = ' checked'; 2291 } else { 2292 $checkedcs = ''; 2293 } 2294 echo '<tr><td>'; 2295 echo form('admin', 'filter') . hidden('id', $filter['id']); 2296 echo "<table style=\"width:100%;\"><tr><th style=\"width:8em;\">$I[filter] $filter[id]:</th>"; 2297 echo "<td style=\"width:12em;\"><input type=\"text\" name=\"match\" value=\"$filter[match]\" size=\"20\" style=\"$U[style]\"></td>"; 2298 echo '<td style="width:12em;"><input type="text" name="replace" value="' . htmlspecialchars($filter['replace']) . "\" size=\"20\" style=\"$U[style]\"></td>"; 2299 echo "<td style=\"width:9em;\"><label><input type=\"checkbox\" name=\"allowinpm\" value=\"1\"$check>$I[allowpm]</label></td>"; 2300 echo "<td style=\"width:5em;\"><label><input type=\"checkbox\" name=\"regex\" value=\"1\"$checked>$I[regex]</label></td>"; 2301 echo "<td style=\"width:5em;\"><label><input type=\"checkbox\" name=\"kick\" value=\"1\"$checkedk>$I[kick]</label></td>"; 2302 echo "<td style=\"width:5em;\"><label><input type=\"checkbox\" name=\"cs\" value=\"1\"$checkedcs>$I[cs]</label></td>"; 2303 echo '<td class="filtersubmit" style="width:5em;">' . submit($I['change']) . '</td></tr></table></form></td></tr>'; 2304 } 2305 echo '<tr><td>'; 2306 echo form('admin', 'filter') . hidden('id', '+'); 2307 echo "<table style=\"width:100%;\"><tr><th style=\"width:8em\">$I[newfilter]</th>"; 2308 echo "<td style=\"width:12em;\"><input type=\"text\" name=\"match\" value=\"\" size=\"20\" style=\"$U[style]\"></td>"; 2309 echo "<td style=\"width:12em;\"><input type=\"text\" name=\"replace\" value=\"\" size=\"20\" style=\"$U[style]\"></td>"; 2310 echo "<td style=\"width:9em;\"><label><input type=\"checkbox\" name=\"allowinpm\" id=\"allowinpm\" value=\"1\">$I[allowpm]</label></td>"; 2311 echo "<td style=\"width:5em;\"><label><input type=\"checkbox\" name=\"regex\" id=\"regex\" value=\"1\">$I[regex]</label></td>"; 2312 echo "<td style=\"width:5em;\"><label><input type=\"checkbox\" name=\"kick\" id=\"kick\" value=\"1\">$I[kick]</label></td>"; 2313 echo "<td style=\"width:5em;\"><label><input type=\"checkbox\" name=\"cs\" id=\"cs\" value=\"1\">$I[cs]</label></td>"; 2314 echo '<td class="filtersubmit" style="width:5em;">' . submit($I['add']) . '</td></tr></table></form></td></tr>'; 2315 echo "</table><br>"; 2316 echo form('admin', 'filter') . submit($I['reload']) . '</form>'; 2317 print_end(); 2318 } 2319 2320 function send_linkfilter($arg = '') 2321 { 2322 global $I, $U; 2323 print_start('linkfilter'); 2324 echo "<h2>$I[linkfilter]</h2><i>$arg</i><table>"; 2325 thr(); 2326 echo '<tr><th><table style="width:100%;"><tr>'; 2327 echo "<td style=\"width:8em;\">$I[fid]</td>"; 2328 echo "<td style=\"width:12em;\">$I[match]</td>"; 2329 echo "<td style=\"width:12em;\">$I[replace]</td>"; 2330 echo "<td style=\"width:5em;\">$I[regex]</td>"; 2331 echo "<td style=\"width:5em;\">$I[apply]</td>"; 2332 echo '</tr></table></th></tr>'; 2333 $filters = get_linkfilters(); 2334 foreach ($filters as $filter) { 2335 if ($filter['regex'] == 1) { 2336 $checked = ' checked'; 2337 } else { 2338 $checked = ''; 2339 $filter['match'] = preg_replace('/(\\\\(.))/u', "$2", $filter['match']); 2340 } 2341 echo '<tr><td>'; 2342 echo form('admin', 'linkfilter') . hidden('id', $filter['id']); 2343 echo "<table style=\"width:100%;\"><tr><th style=\"width:8em;\">$I[filter] $filter[id]:</th>"; 2344 echo "<td style=\"width:12em;\"><input type=\"text\" name=\"match\" value=\"$filter[match]\" size=\"20\" style=\"$U[style]\"></td>"; 2345 echo '<td style="width:12em;"><input type="text" name="replace" value="' . htmlspecialchars($filter['replace']) . "\" size=\"20\" style=\"$U[style]\"></td>"; 2346 echo "<td style=\"width:5em;\"><label><input type=\"checkbox\" name=\"regex\" value=\"1\"$checked>$I[regex]</label></td>"; 2347 echo '<td class="filtersubmit" style="width:5em;">' . submit($I['change']) . '</td></tr></table></form></td></tr>'; 2348 } 2349 echo '<tr><td>'; 2350 echo form('admin', 'linkfilter') . hidden('id', '+'); 2351 echo "<table style=\"width:100%;\"><tr><th style=\"width:8em;\">$I[newfilter]</th>"; 2352 echo "<td style=\"width:12em;\"><input type=\"text\" name=\"match\" value=\"\" size=\"20\" style=\"$U[style]\"></td>"; 2353 echo "<td style=\"width:12em;\"><input type=\"text\" name=\"replace\" value=\"\" size=\"20\" style=\"$U[style]\"></td>"; 2354 echo "<td style=\"width:5em;\"><label><input type=\"checkbox\" name=\"regex\" value=\"1\">$I[regex]</label></td>"; 2355 echo '<td class="filtersubmit" style="width:5em;">' . submit($I['add']) . '</td></tr></table></form></td></tr>'; 2356 echo "</table><br>"; 2357 echo form('admin', 'linkfilter') . submit($I['reload']) . '</form>'; 2358 print_end(); 2359 } 2360 2361 function send_frameset() 2362 { 2363 global $I, $U, $db, $language; 2364 echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"><html><head>' . meta_html(); 2365 echo '<title>' . get_setting('chatname') . '</title>'; 2366 print_stylesheet(); 2367 echo '</head><body>'; 2368 if (isset($_REQUEST['sort'])) { 2369 if ($_REQUEST['sort'] == 1) { 2370 $U['sortupdown'] = 1; 2371 $tmp = $U['nocache']; 2372 $U['nocache'] = $U['nocache_old']; 2373 $U['nocache_old'] = $tmp; 2374 } else { 2375 $U['sortupdown'] = 0; 2376 $tmp = $U['nocache']; 2377 $U['nocache'] = $U['nocache_old']; 2378 $U['nocache_old'] = $tmp; 2379 } 2380 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET sortupdown=?, nocache=?, nocache_old=? WHERE nickname=?;'); 2381 $stmt->execute([$U['sortupdown'], $U['nocache'], $U['nocache_old'], $U['nickname']]); 2382 if ($U['status'] > 1) { 2383 $stmt = $db->prepare('UPDATE ' . PREFIX . 'members SET sortupdown=?, nocache=?, nocache_old=? WHERE nickname=?;'); 2384 $stmt->execute([$U['sortupdown'], $U['nocache'], $U['nocache_old'], $U['nickname']]); 2385 } 2386 } 2387 if (($U['status'] >= 5 || ($U['status'] > 2 && get_count_mods() == 0)) && get_setting('enfileupload') > 0 && get_setting('enfileupload') <= $U['status']) { 2388 $postheight = '120px'; 2389 } else { 2390 $postheight = '100px'; 2391 } 2392 $bottom = ''; 2393 if (get_setting('enablegreeting')) { 2394 $action_mid = 'greeting'; 2395 } else { 2396 if ($U['sortupdown']) { 2397 $bottom = '#bottom'; 2398 } 2399 $action_mid = 'view'; 2400 } 2401 if ((!isset($_REQUEST['sort']) && !$U['sortupdown']) || (isset($_REQUEST['sort']) && $_REQUEST['sort'] == 0)) { 2402 $action_top = 'post'; 2403 $action_bot = 'controls'; 2404 $sort_bot = '&sort=1'; 2405 $frameset_mid_style = "position:fixed;top:$postheight;bottom:45px;left:0;right:0;margin:0;padding:0;overflow:hidden;"; 2406 $frameset_top_style = "position:fixed;top:0;left:0;right:0;height:$postheight;margin:0;padding:0;overflow:hidden;border-bottom: 1px solid;"; 2407 $frameset_bot_style = "position:fixed;bottom:0;left:0;right:0;height:45px;margin:0;padding:0;overflow:hidden;border-top:1px solid;"; 2408 $noscroll_bot = "scrolling=\"yes\" style=\"overflow-y:hidden !important;\""; 2409 $noscroll_top = ""; 2410 } else { 2411 $action_top = 'controls'; 2412 $action_bot = 'post'; 2413 $sort_bot = ''; 2414 $frameset_mid_style = "position:fixed;top:45px;bottom:$postheight;left:0;right:0;margin:0;padding:0;overflow:hidden;"; 2415 $frameset_top_style = "position:fixed;top:0;left:0;right:0;height:45px;margin:0;padding:0;overflow:hidden;border-bottom:1px solid;"; 2416 $frameset_bot_style = "position:fixed;bottom:0;left:0;right:0;height:$postheight;margin:0;padding:0;overflow:hidden;border-top:1px solid;"; 2417 $noscroll_top = "scrolling=\"yes\" style=\"overflow-y:hidden !important;\""; 2418 $noscroll_bot = ""; 2419 } 2420 echo "<div id=\"frameset-mid\" style=\"$frameset_mid_style\"><iframe name=\"view\" src=\"?action=$action_mid&session=$U[session]&lang=$language$bottom\">" . noframe_html() . "</iframe></div>"; 2421 echo "<div id=\"frameset-top\" style=\"$frameset_top_style\"><iframe $noscroll_top name=\"$action_top\" src=\"?action=$action_top&session=$U[session]&lang=$language\">" . noframe_html() . "</iframe></div>"; 2422 echo "<div id=\"frameset-bot\" style=\"$frameset_bot_style\"><iframe $noscroll_bot name=\"$action_bot\" src=\"?action=$action_bot&session=$U[session]&lang=$language$sort_bot\">" . noframe_html() . "</iframe></div>"; 2423 echo '</body></html>'; 2424 exit; 2425 } 2426 2427 function rooms() 2428 { 2429 print_start('rooms'); 2430 // if(show_rooms()){ 2431 print_rooms(); 2432 //} 2433 print_end(); 2434 } 2435 2436 function show_rooms($true = "false") 2437 { 2438 $handle = curl_init(); 2439 curl_setopt_array($handle, array( 2440 CURLOPT_URL => $url, 2441 CURLOPT_RETURNTRANSFER => 0, 2442 CURLOPT_POST => true, 2443 CURLOPT_POSTFIELDS => $postData, 2444 )); 2445 curl_exec($handle); 2446 if ($true) { 2447 return true; 2448 } else { 2449 return false; 2450 } 2451 } 2452 function noframe_html(): string 2453 { 2454 global $I; 2455 return "$I[noframes]" . form_target('_parent', '') . submit($I['backtologin'], 'class="backbutton"') . '</form>'; 2456 } 2457 2458 function send_messages() 2459 { 2460 global $I, $U, $language; 2461 if ($U['nocache']) { 2462 $nocache = '&nc=' . substr(time(), -6); 2463 } else { 2464 $nocache = ''; 2465 } 2466 if ($U['sortupdown']) { 2467 $sort = '#bottom'; 2468 } else { 2469 $sort = ''; 2470 } 2471 $modroom = ""; 2472 if (isset($_REQUEST['modroom']) && $_REQUEST['modroom']) { 2473 $modroom = '&modroom=1'; 2474 } 2475 print_start('messages', $U['refresh'], "?action=view&session=$U[session]&lang=$language$nocache$sort$modroom" . uniqid('?r=')); 2476 echo '<a id="top"></a>'; 2477 echo "<a id=\"bottom_link\" href=\"#bottom\">$I[bottom]</a>"; 2478 //MODIFICATION We don't like the manual refresh box. 2479 //echo "<div id=\"manualrefresh\"><br>$I[manualrefresh]<br>".form('view').submit($I['reload']).'</form><br></div>'; 2480 //Modification for mod room for rooms 2481 /*if(isset($_REQUEST['modroom']) && $_REQUEST['modroom']=1 && $U['status']>=5){ 2482 echo '<div id="modroomreload">'; 2483 echo form('view').hidden('modroom','1').submit($I['reload']).'</form>'; 2484 echo '</div>'; 2485 print_messages(0,1); 2486 2487 }else{*/ 2488 if (!$U['sortupdown']) { 2489 echo '<div id="topic">'; 2490 echo get_setting('topic'); 2491 echo '</div>'; 2492 print_chatters(); 2493 print_notifications(); 2494 print_messages(); 2495 } else { 2496 print_messages(); 2497 print_notifications(); 2498 print_chatters(); 2499 echo '<div id="topic">'; 2500 echo get_setting('topic'); 2501 echo '</div>'; 2502 } 2503 //} 2504 echo "<a id=\"bottom\"></a><a id=\"top_link\" href=\"#top\">$I[top]</a>"; 2505 print_end(); 2506 } 2507 2508 function send_inbox() 2509 { 2510 global $I, $U, $db; 2511 print_start('inbox'); 2512 echo form('inbox', 'clean') . submit($I['delselmes'], 'class="delbutton"') . '<br><br>'; 2513 $dateformat = get_setting('dateformat'); 2514 if (!$U['embed'] && get_setting('imgembed')) { 2515 $removeEmbed = true; 2516 } else { 2517 $removeEmbed = false; 2518 } 2519 if ($U['timestamps'] && !empty($dateformat)) { 2520 $timestamps = true; 2521 } else { 2522 $timestamps = false; 2523 } 2524 if ($U['sortupdown']) { 2525 $direction = 'ASC'; 2526 } else { 2527 $direction = 'DESC'; 2528 } 2529 $stmt = $db->prepare('SELECT id, postdate, text FROM ' . PREFIX . "inbox WHERE recipient=? ORDER BY id $direction;"); 2530 $stmt->execute([$U['nickname']]); 2531 while ($message = $stmt->fetch(PDO::FETCH_ASSOC)) { 2532 prepare_message_print($message, $removeEmbed); 2533 echo "<div class=\"msg\"><label><input type=\"checkbox\" name=\"mid[]\" value=\"$message[id]\">"; 2534 if ($timestamps) { 2535 echo ' <small>' . date($dateformat, $message['postdate']) . ' - </small>'; 2536 } 2537 echo " $message[text]</label></div>"; 2538 } 2539 echo '</form><br>' . form('view') . submit($I['backtochat'], 'class="backbutton"') . '</form>'; 2540 print_end(); 2541 } 2542 2543 // Modification type 3 is spare notes 2544 2545 function send_notes($type) 2546 { 2547 global $I, $U, $db; 2548 print_start('notes'); 2549 $personalnotes = (bool) get_setting('personalnotes'); 2550 $sparenotesaccess = (int) get_setting('sparenotesaccess'); 2551 // Modification Spare notes 2552 if (($U['status'] >= 5 && ($personalnotes || $U['status'] > 6)) || ($personalnotes && $U['status'] >= $sparenotesaccess)) { 2553 echo '<table><tr>'; 2554 if ($U['status'] > 6) { 2555 echo '<td>' . form_target('view', 'notes', 'admin') . submit($I['admnotes']) . '</form></td>'; 2556 } 2557 if ($U['status'] >= 5) { 2558 echo '<td>' . form_target('view', 'notes', 'staff') . submit($I['staffnotes']) . '</form></td>'; 2559 } 2560 if ($personalnotes) { 2561 echo '<td>' . form_target('view', 'notes') . submit($I['personalnotes']) . '</form></td>'; 2562 } 2563 if ($U['status'] >= $sparenotesaccess) { 2564 echo '<td>' . form_target('view', 'notes', 'spare') . submit(get_setting('sparenotesname')) . '</form></td>'; 2565 } 2566 echo '</tr></table>'; 2567 } 2568 if ($type === 1) { 2569 echo "<h2>$I[staffnotes]</h2><p>"; 2570 $hiddendo = hidden('do', 'staff'); 2571 } elseif ($type === 0) { 2572 echo "<h2>$I[adminnotes]</h2><p>"; 2573 $hiddendo = hidden('do', 'admin'); 2574 // Modification spare notes 2575 } elseif ($type === 3) { 2576 echo '<h2>' . get_setting('sparenotesname') . '</h2><p>'; 2577 $hiddendo = hidden('do', 'spare'); 2578 } else { 2579 echo "<h2>$I[personalnotes]</h2><p>"; 2580 $hiddendo = ''; 2581 } 2582 if (isset($_REQUEST['text'])) { 2583 if (MSGENCRYPTED) { 2584 $_REQUEST['text'] = base64_encode(sodium_crypto_aead_aes256gcm_encrypt($_REQUEST['text'], '', AES_IV, ENCRYPTKEY)); 2585 } 2586 $time = time(); 2587 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'notes (type, lastedited, editedby, text) VALUES (?, ?, ?, ?);'); 2588 $stmt->execute([$type, $time, $U['nickname'], $_REQUEST['text']]); 2589 echo "<b>$I[notessaved]</b> "; 2590 } 2591 $dateformat = get_setting('dateformat'); 2592 if ($type !== 2) { 2593 $stmt = $db->prepare('SELECT COUNT(*) FROM ' . PREFIX . 'notes WHERE type=?;'); 2594 $stmt->execute([$type]); 2595 } else { 2596 $stmt = $db->prepare('SELECT COUNT(*) FROM ' . PREFIX . 'notes WHERE type=? AND editedby=?;'); 2597 $stmt->execute([$type, $U['nickname']]); 2598 } 2599 $num = $stmt->fetch(PDO::FETCH_NUM); 2600 if (!empty($_REQUEST['revision'])) { 2601 $revision = intval($_REQUEST['revision']); 2602 } else { 2603 $revision = 0; 2604 } 2605 if ($type !== 2) { 2606 $stmt = $db->prepare('SELECT * FROM ' . PREFIX . "notes WHERE type=? ORDER BY id DESC LIMIT 1 OFFSET $revision;"); 2607 $stmt->execute([$type]); 2608 } else { 2609 $stmt = $db->prepare('SELECT * FROM ' . PREFIX . "notes WHERE type=? AND editedby=? ORDER BY id DESC LIMIT 1 OFFSET $revision;"); 2610 $stmt->execute([$type, $U['nickname']]); 2611 } 2612 if ($note = $stmt->fetch(PDO::FETCH_ASSOC)) { 2613 printf($I['lastedited'], htmlspecialchars($note['editedby']), date($dateformat, $note['lastedited'])); 2614 } else { 2615 $note['text'] = ''; 2616 } 2617 if (MSGENCRYPTED) { 2618 $note['text'] = sodium_crypto_aead_aes256gcm_decrypt(base64_decode($note['text']), null, AES_IV, ENCRYPTKEY); 2619 } 2620 echo "</p>" . form('notes'); 2621 echo "$hiddendo<textarea name=\"text\">" . htmlspecialchars($note['text']) . '</textarea><br>'; 2622 echo submit($I['savenotes']) . '</form><br>'; 2623 if ($num[0] > 1) { 2624 echo "<br><table><tr><td>$I[revisions]</td>"; 2625 if ($revision < $num[0] - 1) { 2626 echo '<td>' . form('notes') . hidden('revision', $revision + 1); 2627 echo $hiddendo . submit($I['older']) . '</form></td>'; 2628 } 2629 if ($revision > 0) { 2630 echo '<td>' . form('notes') . hidden('revision', $revision - 1); 2631 echo $hiddendo . submit($I['newer']) . '</form></td>'; 2632 } 2633 echo '</tr></table>'; 2634 } 2635 print_end(); 2636 } 2637 2638 function send_approve_waiting() 2639 { 2640 global $I, $db; 2641 print_start('approve_waiting'); 2642 echo "<h2>$I[waitingroom]</h2>"; 2643 $result = $db->query('SELECT * FROM ' . PREFIX . 'sessions WHERE entry=0 AND status=1 ORDER BY id LIMIT 100;'); 2644 if ($tmp = $result->fetchAll(PDO::FETCH_ASSOC)) { 2645 echo form('admin', 'approve'); 2646 echo '<table>'; 2647 echo "<tr><th>$I[sessnick]</th><th>$I[sessua]</th></tr>"; 2648 foreach ($tmp as $temp) { 2649 echo '<tr>' . hidden('alls[]', htmlspecialchars($temp['nickname'])); 2650 echo '<td><label><input type="checkbox" name="csid[]" value="' . htmlspecialchars($temp['nickname']) . '">'; 2651 echo style_this(htmlspecialchars($temp['nickname']), $temp['style']) . '</label></td>'; 2652 echo "<td>$temp[useragent]</td></tr>"; 2653 } 2654 echo "</table><br><table id=\"action\"><tr><td><label><input type=\"radio\" name=\"what\" value=\"allowchecked\" id=\"allowchecked\" checked>$I[allowchecked]</label></td>"; 2655 echo "<td><label><input type=\"radio\" name=\"what\" value=\"allowall\" id=\"allowall\">$I[allowall]</label></td>"; 2656 echo "<td><label><input type=\"radio\" name=\"what\" value=\"denychecked\" id=\"denychecked\">$I[denychecked]</label></td>"; 2657 echo "<td><label><input type=\"radio\" name=\"what\" value=\"denyall\" id=\"denyall\">$I[denyall]</label></td></tr><tr><td colspan=\"8\">$I[denymessage] <input type=\"text\" name=\"kickmessage\" size=\"45\"></td>"; 2658 echo '</tr><tr><td colspan="8">' . submit($I['butallowdeny']) . '</td></tr></table></form>'; 2659 } else { 2660 echo "$I[waitempty]<br>"; 2661 } 2662 echo '<br>' . form('admin', 'approve'); 2663 echo submit($I['reload']) . '</form>'; 2664 echo '<br>' . form('view') . submit($I['backtochat'], 'class="backbutton"') . '</form>'; 2665 print_end(); 2666 } 2667 2668 function send_waiting_room() 2669 { 2670 global $I, $U, $db, $language; 2671 $ga = (int) get_setting('guestaccess'); 2672 if ($ga === 3 && (get_count_mods() > 0 || !get_setting('modfallback'))) { 2673 $wait = false; 2674 } else { 2675 $wait = true; 2676 } 2677 check_expired(); 2678 check_kicked(); 2679 $timeleft = get_setting('entrywait') - (time() - $U['lastpost']); 2680 if ($wait && ($timeleft <= 0 || $ga === 1)) { 2681 $U['entry'] = $U['lastpost']; 2682 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET entry=lastpost WHERE session=?;'); 2683 $stmt->execute([$U['session']]); 2684 send_frameset(); 2685 } elseif (!$wait && $U['entry'] != 0) { 2686 send_frameset(); 2687 } else { 2688 $refresh = (int) get_setting('defaultrefresh'); 2689 print_start('waitingroom', $refresh, "?action=wait&session=$U[session]&lang=$language&nc=" . substr(time(), -6)); 2690 echo "<h2>$I[waitingroom]</h2><p>"; 2691 if ($wait) { 2692 printf($I['waittext'], style_this(htmlspecialchars($U['nickname']), $U['style']), $timeleft); 2693 } else { 2694 printf($I['admwaittext'], style_this(htmlspecialchars($U['nickname']), $U['style'])); 2695 } 2696 echo '</p><br><p>'; 2697 printf($I['waitreload'], $refresh); 2698 echo '</p><br><br>'; 2699 echo '<hr>' . form('wait'); 2700 if (!isset($_REQUEST['session'])) { 2701 echo hidden('session', $U['session']); 2702 } 2703 echo submit($I['reload']) . '</form><br>'; 2704 echo form('logout'); 2705 if (!isset($_REQUEST['session'])) { 2706 echo hidden('session', $U['session']); 2707 } 2708 echo submit($I['exit'], 'id="exitbutton"') . '</form>'; 2709 $rulestxt = get_setting('rulestxt'); 2710 if (!empty($rulestxt)) { 2711 echo "<div id=\"rules\"><h2>$I[rules]</h2><b>$rulestxt</b></div>"; 2712 } 2713 print_end(); 2714 } 2715 } 2716 2717 function send_choose_messages() 2718 { 2719 global $I, $U; 2720 print_start('choose_messages'); 2721 echo form('admin', 'clean'); 2722 echo hidden('what', 'selected') . submit($I['delselmes'], 'class="delbutton"') . '<br><br>'; 2723 print_messages($U['status']); 2724 echo '<br>' . submit($I['delselmes'], 'class="delbutton"') . "</form>"; 2725 print_end(); 2726 } 2727 2728 function send_del_confirm() 2729 { 2730 global $I; 2731 print_start('del_confirm'); 2732 echo "<table><tr><td colspan=\"2\">$I[confirm]</td></tr><tr><td>" . form('delete'); 2733 if (isset($_REQUEST['multi'])) { 2734 echo hidden('multi', 'on'); 2735 } 2736 if (isset($_REQUEST['sendto'])) { 2737 echo hidden('sendto', $_REQUEST['sendto']); 2738 } 2739 echo hidden('confirm', 'yes') . hidden('what', $_REQUEST['what']) . submit($I['yes'], 'class="delbutton"') . '</form></td><td>' . form('post'); 2740 if (isset($_REQUEST['multi'])) { 2741 echo hidden('multi', 'on'); 2742 } 2743 if (isset($_REQUEST['sendto'])) { 2744 echo hidden('sendto', $_REQUEST['sendto']); 2745 } 2746 echo submit($I['no'], 'class="backbutton"') . '</form></td><tr></table>'; 2747 print_end(); 2748 } 2749 2750 2751 2752 function send_post($rejected = '') 2753 { 2754 global $I, $U, $db; 2755 print_start('post'); 2756 2757 if (!isset($_REQUEST['sendto'])) { 2758 $_REQUEST['sendto'] = ''; 2759 } 2760 echo '<table><tr><td>' . form('post'); 2761 echo hidden('postid', substr(time(), -6)); 2762 if (isset($_REQUEST['multi'])) { 2763 echo hidden('multi', 'on'); 2764 } 2765 echo '<table><tr><td><table><tr id="firstline"><td>' . style_this(htmlspecialchars($U['nickname']), $U['style']) . '</td><td>:</td>'; 2766 if (isset($_REQUEST['multi'])) { 2767 echo "<td><textarea name=\"message\" rows=\"3\" cols=\"40\" style=\"$U[style]\" autofocus>$rejected</textarea></td>"; 2768 } else { 2769 //some lines changed for clickable nicknames that select username in the text box 2770 if (($rejected === '') && (!empty($_REQUEST['nickname']))) { 2771 echo "<td><input type=\"text\" name=\"message\" value=\"" . $_REQUEST['nickname'] . "\" size=\"40\" style=\"$U[style]\" autofocus></td>"; 2772 } else { 2773 echo "<td><input type=\"text\" name=\"message\" value=\"$rejected\" size=\"40\" style=\"$U[style]\" autofocus></td>"; 2774 } 2775 } 2776 echo '<td>' . submit($I['talkto']) . '</td><td><select name="sendto" size="1">'; 2777 echo '<option '; 2778 if ($_REQUEST['sendto'] === 's 17') { 2779 echo 'selected '; 2780 } 2781 2782 echo "value=\"s 17\">- All Chatters -</option>"; 2783 2784 //Modification added an option to send to all rooms. 2785 if ($U['status'] >= 5) { 2786 echo '<option '; 2787 if ($_REQUEST['sendto'] === 'r @') { 2788 echo 'selected '; 2789 } 2790 echo "value=\"r @\">- All Rooms -</option>"; 2791 } 2792 2793 //MODIFICATION 7 lines added for the RG channel (option to write to registered guests) 2794 if ($U['status'] >= 2) { 2795 echo '<option '; 2796 if ($_REQUEST['sendto'] === 's 24') { 2797 echo 'selected '; 2798 } 2799 echo "value=\"s 24\">- Junior Members -</option>"; 2800 } 2801 2802 if ($U['status'] >= 3) { 2803 echo '<option '; 2804 if ($_REQUEST['sendto'] === 's 31') { 2805 echo 'selected '; 2806 } 2807 echo "value=\"s 31\">- Senior Members -</option>"; 2808 } 2809 if ($U['status'] >= 5) { 2810 echo '<option '; 2811 if ($_REQUEST['sendto'] === 's 48') { 2812 echo 'selected '; 2813 } 2814 echo "value=\"s 48\">- Staff -</option>"; 2815 } 2816 //MODICATION description of item in dropdown menu changed to SMods only 2817 if ($U['status'] >= 6) { 2818 echo '<option '; 2819 if ($_REQUEST['sendto'] === 's 56') { 2820 echo 'selected '; 2821 } 2822 echo "value=\"s 56\">- Admins -</option>"; 2823 } 2824 2825 //MODIFICATION 7 lines added for the new admin channel (option to admins only) 2826 if ($U['status'] >= 7) { 2827 echo '<option '; 2828 if ($_REQUEST['sendto'] === 's 65') { 2829 echo 'selected '; 2830 } 2831 echo "value=\"s 65\">- Gods -</option>"; 2832 } 2833 $disablepm = (bool) get_setting('disablepm'); 2834 if (!$disablepm) { 2835 $users = []; 2836 $stmt = $db->prepare('SELECT * FROM (SELECT nickname, style, 0 AS offline FROM ' . PREFIX . 'sessions WHERE entry!=0 AND status>0 AND incognito=0 UNION SELECT nickname, style, 1 AS offline FROM ' . PREFIX . 'members WHERE eninbox!=0 AND eninbox<=? AND nickname NOT IN (SELECT nickname FROM ' . PREFIX . 'sessions WHERE incognito=0)) AS t WHERE nickname NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=? UNION SELECT ignby FROM ' . PREFIX . 'ignored WHERE ign=?) ORDER BY LOWER(nickname);'); 2837 $stmt->execute([$U['status'], $U['nickname'], $U['nickname']]); 2838 while ($tmp = $stmt->fetch(PDO::FETCH_ASSOC)) { 2839 if ($tmp['offline']) { 2840 $users[] = ["$tmp[nickname] $I[offline]", $tmp['style'], $tmp['nickname']]; 2841 } else { 2842 $users[] = [$tmp['nickname'], $tmp['style'], $tmp['nickname']]; 2843 } 2844 } 2845 foreach ($users as $user) { 2846 if ($U['nickname'] !== $user[2]) { 2847 echo '<option '; 2848 if ($_REQUEST['sendto'] == $user[2]) { 2849 echo 'selected '; 2850 } 2851 echo 'value="' . htmlspecialchars($user[2]) . "\" style=\"$user[1]\">" . htmlspecialchars($user[0]) . '</option>'; 2852 } 2853 } 2854 } 2855 echo '</select></td>'; 2856 if (get_setting('enfileupload') > 0 && get_setting('enfileupload') <= $U['status']) { 2857 if (!$disablepm && ($U['status'] >= 5 || ($U['status'] >= 3 && get_count_mods() == 0 && get_setting('memkick')))) { 2858 echo '</tr></table><table><tr id="secondline">'; 2859 } 2860 printf("<td><input type=\"file\" name=\"file\"><small>$I[maxsize]</small></td>", get_setting('maxuploadsize')); 2861 } 2862 2863 //Modification to enable kick function, if memdel hast value 2 2864 if (!$disablepm && ($U['status'] >= 5 || ($U['status'] >= 3 && get_count_mods() == 0 && get_setting('memkick')) || ($U['status'] >= 3 && (int)get_setting('memdel') === 2))) { 2865 echo "<td><label><input type=\"checkbox\" name=\"kick\" id=\"kick\" value=\"kick\">$I[kick]</label></td>"; 2866 echo "<td><label><input type=\"checkbox\" name=\"what\" id=\"what\" value=\"purge\" checked>$I[alsopurge]</label></td>"; 2867 } 2868 echo '</tr></table></td></tr></table></form></td></tr><tr><td><table><tr id="thirdline"><td>' . form('delete'); 2869 if (isset($_REQUEST['multi'])) { 2870 echo hidden('multi', 'on'); 2871 } 2872 echo hidden('sendto', $_REQUEST['sendto']) . hidden('what', 'last'); 2873 echo submit($I['dellast'], 'class="delbutton"') . '</form></td><td>' . form('delete'); 2874 if (isset($_REQUEST['multi'])) { 2875 echo hidden('multi', 'on'); 2876 } 2877 echo hidden('sendto', $_REQUEST['sendto']) . hidden('what', 'all'); 2878 echo submit($I['delall'], 'class="delbutton"') . '</form></td><td style="width:10px;"></td><td>' . form('post'); 2879 if (isset($_REQUEST['multi'])) { 2880 echo submit($I['switchsingle']); 2881 } else { 2882 echo hidden('multi', 'on') . submit($I['switchmulti']); 2883 } 2884 echo hidden('sendto', $_REQUEST['sendto']) . '</form></td>'; 2885 echo '</tr></table></td></tr></table>'; 2886 2887 //External Links section start 2888 //div left for links section 2889 echo "<div align='left'>"; 2890 //one line added (emoji-link with id for css) 2891 echo "<a id='emoji_link' target='view' rel='noopener noreferrer' href='emojis.html'>Emojis</a>"; 2892 echo " "; 2893 2894 2895 //modification forum button 2896 if ($U['status'] >= (int)get_setting('forumbtnaccess')) { 2897 echo "<a id='forum_link' target='_blank' href='" . get_setting('forumbtnlink') . "'>Forum</a>"; 2898 } 2899 echo "<div style=\"position: absolute; bottom: 10%; right: 4%; width: 220px; height: auto; overflow-y: hidden\">"; 2900 print_rooms(); 2901 echo "</div>"; 2902 //echo "</div>"; 2903 //External Links section end 2904 2905 print_end(); 2906 } 2907 2908 function send_greeting() 2909 { 2910 global $I, $U, $language; 2911 print_start('greeting', $U['refresh'], "?action=view&session=$U[session]&lang=$language"); 2912 printf("<h1>$I[greetingmsg]</h1>", style_this(htmlspecialchars($U['nickname']), $U['style'])); 2913 printf("<hr><small>$I[entryhelp]</small>", $U['refresh']); 2914 $rulestxt = get_setting('rulestxt'); 2915 if (!empty($rulestxt)) { 2916 echo "<hr><div id=\"rules\"><h2>$I[rules]</h2>$rulestxt</div>"; 2917 } 2918 print_end(); 2919 } 2920 2921 function send_help() 2922 { 2923 global $I, $U; 2924 print_start('help'); 2925 $rulestxt = get_setting('rulestxt'); 2926 if (!empty($rulestxt)) { 2927 echo "<div id=\"rules\"><h2>$I[rules]</h2>$rulestxt<br></div><hr>"; 2928 } 2929 echo "<h2>$I[help]</h2>$I[helpguest]"; 2930 if (get_setting('imgembed')) { 2931 echo "<br>$I[helpembed]"; 2932 } 2933 if ($U['status'] >= 3) { 2934 echo "<br><br>$I[helpmem]<br><br>"; 2935 if ($U['status'] >= 5) { 2936 echo "<br>$I[helpmod]<br><br>"; 2937 if ($U['status'] >= 7) { 2938 echo "<br>$I[helpadm]<br><br>"; 2939 } 2940 } 2941 } 2942 // MODIFICATION removed script version. 2943 echo '<br><hr><div id="backcredit">' . form('view') . submit($I['backtochat'], 'class="backbutton"') . '</form>'/*.credit()*/ . '</div>'; 2944 print_end(); 2945 } 2946 2947 function send_profile($arg = '') 2948 { 2949 global $I, $L, $U, $db, $language; 2950 print_start('profile'); 2951 echo form('profile', 'save') . "<h2>$I[profile]</h2><i>$arg</i><table>"; 2952 thr(); 2953 $ignored = []; 2954 $stmt = $db->prepare('SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=? ORDER BY LOWER(ign);'); 2955 $stmt->execute([$U['nickname']]); 2956 while ($tmp = $stmt->fetch(PDO::FETCH_ASSOC)) { 2957 $ignored[] = htmlspecialchars($tmp['ign']); 2958 } 2959 if (count($ignored) > 0) { 2960 echo "<tr><td><table id=\"unignore\"><tr><th>$I[unignore]</th><td>"; 2961 echo "<select name=\"unignore\" size=\"1\"><option value=\"\">$I[choose]</option>"; 2962 foreach ($ignored as $ign) { 2963 echo "<option value=\"$ign\">$ign</option>"; 2964 } 2965 echo '</select></td></tr></table></td></tr>'; 2966 thr(); 2967 } 2968 echo "<tr><td><table id=\"ignore\"><tr><th>$I[ignore]</th><td>"; 2969 echo "<select name=\"ignore\" size=\"1\"><option value=\"\">$I[choose]</option>"; 2970 $stmt = $db->prepare('SELECT poster, style FROM ' . PREFIX . 'messages INNER JOIN (SELECT nickname, style FROM ' . PREFIX . 'sessions UNION SELECT nickname, style FROM ' . PREFIX . 'members) AS t ON (' . PREFIX . 'messages.poster=t.nickname) WHERE poster!=? AND poster NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=?) GROUP BY poster ORDER BY LOWER(poster);'); 2971 $stmt->execute([$U['nickname'], $U['nickname']]); 2972 while ($nick = $stmt->fetch(PDO::FETCH_NUM)) { 2973 echo '<option value="' . htmlspecialchars($nick[0]) . "\" style=\"$nick[1]\">" . htmlspecialchars($nick[0]) . '</option>'; 2974 } 2975 echo '</select></td></tr></table></td></tr>'; 2976 thr(); 2977 echo "<tr><td><table id=\"refresh\"><tr><th>$I[refreshrate]</th><td>"; 2978 echo "<input type=\"number\" name=\"refresh\" size=\"3\" maxlength=\"3\" min=\"5\" max=\"150\" value=\"$U[refresh]\"></td></tr></table></td></tr>"; 2979 thr(); 2980 preg_match('/#([0-9a-f]{6})/i', $U['style'], $matches); 2981 echo "<tr><td><table id=\"colour\"><tr><th>$I[fontcolour] (<a href=\"?action=colours&session=$U[session]&lang=$language\" target=\"view\">$I[viewexample]</a>)</th><td>"; 2982 echo "<input type=\"color\" value=\"#$matches[1]\" name=\"colour\"></td></tr></table></td></tr>"; 2983 thr(); 2984 echo "<tr><td><table id=\"bgcolour\"><tr><th>$I[bgcolour] (<a href=\"?action=colours&session=$U[session]&lang=$language\" target=\"view\">$I[viewexample]</a>)</th><td>"; 2985 echo "<input type=\"color\" value=\"#$U[bgcolour]\" name=\"bgcolour\"></td></tr></table></td></tr>"; 2986 thr(); 2987 if ($U['status'] >= 3) { 2988 echo "<tr><td><table id=\"font\"><tr><th>$I[fontface]</th><td><table>"; 2989 echo "<tr><td> </td><td><select name=\"font\" size=\"1\"><option value=\"\">* $I[roomdefault] *</option>"; 2990 $F = load_fonts(); 2991 foreach ($F as $name => $font) { 2992 echo "<option style=\"$font\" "; 2993 if (strpos($U['style'], $font) !== false) { 2994 echo 'selected '; 2995 } 2996 echo "value=\"$name\">$name</option>"; 2997 } 2998 echo '</select></td><td> </td><td><label><input type="checkbox" name="bold" id="bold" value="on"'; 2999 if (strpos($U['style'], 'font-weight:bold;') !== false) { 3000 echo ' checked'; 3001 } 3002 echo "><b>$I[bold]</b></label></td><td> </td><td><label><input type=\"checkbox\" name=\"italic\" id=\"italic\" value=\"on\""; 3003 if (strpos($U['style'], 'font-style:italic;') !== false) { 3004 echo ' checked'; 3005 } 3006 echo "><i>$I[italic]</i></label></td><td> </td><td><label><input type=\"checkbox\" name=\"small\" id=\"small\" value=\"on\""; 3007 if (strpos($U['style'], 'font-size:smaller;') !== false) { 3008 echo ' checked'; 3009 } 3010 echo "><small>$I[small]</small></label></td></tr></table></td></tr></table></td></tr>"; 3011 thr(); 3012 } 3013 echo '<tr><td>' . style_this(htmlspecialchars($U['nickname']) . " : $I[fontexample]", $U['style']) . '</td></tr>'; 3014 thr(); 3015 $bool_settings = ['timestamps', 'nocache', 'sortupdown', 'hidechatters']; 3016 if (get_setting('imgembed')) { 3017 $bool_settings[] = 'embed'; 3018 } 3019 if ($U['status'] >= 5 && get_setting('incognito')) { 3020 $bool_settings[] = 'incognito'; 3021 } 3022 foreach ($bool_settings as $setting) { 3023 echo "<tr><td><table id=\"$setting\"><tr><th>" . $I[$setting] . '</th><td>'; 3024 echo "<label><input type=\"checkbox\" name=\"$setting\" value=\"on\""; 3025 if ($U[$setting]) { 3026 echo ' checked'; 3027 } 3028 echo "><b>$I[enabled]</b></label></td></tr></table></td></tr>"; 3029 thr(); 3030 } 3031 if ($U['status'] >= 2 && get_setting('eninbox')) { 3032 echo "<tr><td><table id=\"eninbox\"><tr><th>$I[eninbox]</th><td>"; 3033 echo "<select name=\"eninbox\" id=\"eninbox\">"; 3034 echo '<option value="0"'; 3035 if ($U['eninbox'] == 0) { 3036 echo ' selected'; 3037 } 3038 echo ">$I[disabled]</option>"; 3039 echo '<option value="1"'; 3040 if ($U['eninbox'] == 1) { 3041 echo ' selected'; 3042 } 3043 echo ">$I[eninall]</option>"; 3044 echo '<option value="3"'; 3045 if ($U['eninbox'] == 3) { 3046 echo ' selected'; 3047 } 3048 echo ">$I[eninmem]</option>"; 3049 echo '<option value="5"'; 3050 if ($U['eninbox'] == 5) { 3051 echo ' selected'; 3052 } 3053 echo ">$I[eninstaff]</option>"; 3054 echo '</select></td></tr></table></td></tr>'; 3055 thr(); 3056 } 3057 echo "<tr><td><table id=\"tz\"><tr><th>$I[tz]</th><td>"; 3058 echo "<select name=\"tz\">"; 3059 $tzs = timezone_identifiers_list(); 3060 foreach ($tzs as $tz) { 3061 echo "<option value=\"$tz\""; 3062 if ($U['tz'] == $tz) { 3063 echo ' selected'; 3064 } 3065 echo ">$tz</option>"; 3066 } 3067 echo '</select></td></tr></table></td></tr>'; 3068 3069 //MODIFICATION nicklinks setting (setting for clickable nicknames in the message frame 3070 //REMOVE LATER (Remove 18 LINES (Modification no longer needed) 3071 /* 3072 thr(); 3073 echo "<tr><td><table id=\"clickablenicknames\"><tr><th>Clickable nicknames</th><td>"; 3074 echo "<select name=\"clickablenicknames\">"; 3075 3076 3077 $options = array(0, 1, 2); 3078 foreach($options as $option){ 3079 echo "<option value=\"$option\""; 3080 3081 if($U['clickablenicknames']==$option){ 3082 echo ' selected'; 3083 } 3084 3085 if ($option == 0) echo ">Disabled</option>"; 3086 elseif($option == 1) echo ">Select nickname from dropdown menu</option>"; 3087 elseif($option == 2) echo ">Copy nickname to post box</option>"; 3088 } 3089 echo '</select></td></tr></table></td></tr>'; 3090 */ 3091 3092 thr(); 3093 if ($U['status'] >= 2) { 3094 echo "<tr><td><table id=\"changepass\"><tr><th>$I[changepass]</th></tr>"; 3095 echo '<tr><td><table>'; 3096 echo "<tr><td> </td><td>$I[oldpass]</td><td><input type=\"password\" name=\"oldpass\" size=\"20\"></td></tr>"; 3097 echo "<tr><td> </td><td>$I[newpass]</td><td><input type=\"password\" name=\"newpass\" size=\"20\"></td></tr>"; 3098 echo "<tr><td> </td><td>$I[confirmpass]</td><td><input type=\"password\" name=\"confirmpass\" size=\"20\"></td></tr>"; 3099 echo '</table></td></tr></table></td></tr>'; 3100 thr(); 3101 echo "<tr><td><table id=\"changenick\"><tr><th>$I[changenick]</th><td><table>"; 3102 echo "<tr><td> </td><td>$I[newnickname]</td><td><input type=\"text\" name=\"newnickname\" size=\"20\">"; 3103 echo '</table></td></tr></table></td></tr>'; 3104 thr(); 3105 } 3106 echo '<tr><td>' . submit($I['savechanges']) . '</td></tr></table></form>'; 3107 if ($U['status'] > 1 && $U['status'] < 8) { 3108 echo '<br>' . form('profile', 'delete') . submit($I['deleteacc'], 'class="delbutton"') . '</form>'; 3109 } 3110 echo "<br><p id=\"changelang\">$I[changelang]"; 3111 foreach ($L as $lang => $name) { 3112 echo " <a href=\"?lang=$lang&session=$U[session]&action=controls\" target=\"controls\">$name</a>"; 3113 } 3114 echo '</p><br>' . form('view') . submit($I['backtochat'], 'class="backbutton"') . '</form>'; 3115 print_end(); 3116 } 3117 3118 function send_controls() 3119 { 3120 global $I, $U; 3121 print_start('controls'); 3122 $personalnotes = (bool) get_setting('personalnotes'); 3123 echo '<table><tr>'; 3124 echo '<td>' . form_target('post', 'post') . submit($I['reloadpb']) . '</form></td>'; 3125 echo '<td>' . form_target('view', 'view') . submit($I['reloadmsgs']) . '</form></td>'; 3126 echo '<td>' . form_target('view', 'profile') . submit($I['chgprofile']) . '</form></td>'; 3127 //MODIFICATION Links Page 3128 if (get_setting('linksenabled') === '1') { 3129 echo '<td>' . form_target('view', 'links') . submit('Links') . '</form></td>'; 3130 } 3131 3132 //Forum Button was moved to the postbox (function send_post) 3133 /* 3134 if($U['status']>= (int)get_setting('forumbtnaccess')){ 3135 echo '<td>'.form_target('_blank', 'forum').submit('Forum').'</form></td>'; 3136 } 3137 //ToDo handle forum request in function validate_input (redirect to forum page) 3138 */ 3139 3140 //MODIFICATION for feature gallery 3141 if ($U['status'] >= (int)get_setting('galleryaccess')) { 3142 echo '<td>' . form_target('view', 'gallery') . submit('Gallery') . '</form></td>'; 3143 } 3144 3145 if ($U['status'] >= 5) { 3146 echo '<td>' . form_target('view', 'view') . hidden('modroom', '1') . submit('Mod Rooms') . '</form></td>'; 3147 } 3148 3149 3150 if ($U['status'] >= 5) { 3151 echo '<td>' . form_target('view', 'admin') . submit($I['adminbtn']) . '</form></td>'; 3152 //MODIFICATION for feature gallery. one line changed. 3153 //echo '<td>'.form_target('_blank', 'gallery').submit('Gallery').'</form></td>'; 3154 if (!$personalnotes) { 3155 echo '<td>' . form_target('view', 'notes', 'staff') . submit($I['notes']) . '</form></td>'; 3156 } 3157 } 3158 // Modification spare notes 3159 $sparenotesaccess = (int) get_setting('sparenotesaccess'); 3160 if ($U['status'] >= 3) { 3161 if ($personalnotes) { 3162 echo '<td>' . form_target('view', 'notes') . submit($I['notes']) . '</form></td>'; 3163 } elseif ($U['status'] >= $sparenotesaccess && $U['status'] === 3) { 3164 echo '<td>' . form_target('view', 'notes', 'spare') . submit($I['notes']) . '</form></td>'; 3165 } 3166 echo '<td>' . form_target('_blank', 'login') . submit($I['clone']) . '</form></td>'; 3167 } 3168 if (!isset($_REQUEST['sort'])) { 3169 $sort = 0; 3170 } else { 3171 $sort = $_REQUEST['sort']; 3172 } 3173 echo '<td>' . form_target('_parent', 'login') . hidden('sort', $sort) . submit($I['sortframe']) . '</form></td>'; 3174 echo '<td>' . form_target('view', 'help') . submit($I['randh']) . '</form></td>'; 3175 echo '<td>' . form_target('_parent', 'logout') . submit($I['exit'], 'id="exitbutton"') . '</form></td>'; 3176 echo '</tr></table>'; 3177 print_end(); 3178 } 3179 3180 function send_download() 3181 { 3182 global $I, $db; 3183 if (isset($_REQUEST['id'])) { 3184 $stmt = $db->prepare('SELECT filename, type, data FROM ' . PREFIX . 'files WHERE hash=?;'); 3185 $stmt->execute([$_REQUEST['id']]); 3186 if ($data = $stmt->fetch(PDO::FETCH_ASSOC)) { 3187 header("Content-Type: $data[type]"); 3188 header("Content-Disposition: filename=\"$data[filename]\""); 3189 header('Pragma: no-cache'); 3190 header('Cache-Control: no-cache, no-store, must-revalidate, max-age=0, private'); 3191 header('Expires: 0'); 3192 echo base64_decode($data['data']); 3193 } else { 3194 send_error($I['filenotfound']); 3195 } 3196 } else { 3197 send_error($I['filenotfound']); 3198 } 3199 } 3200 3201 function send_logout() 3202 { 3203 global $I, $U; 3204 print_start('logout'); 3205 echo '<h1>' . sprintf($I['bye'], style_this(htmlspecialchars($U['nickname']), $U['style'])) . '</h1>' . form_target('_parent', '') . submit($I['backtologin'], 'class="backbutton"') . '</form>'; 3206 print_end(); 3207 } 3208 3209 function send_colours() 3210 { 3211 global $I; 3212 print_start('colours'); 3213 echo "<h2>$I[colourtable]</h2><kbd><b>"; 3214 for ($red = 0x00; $red <= 0xFF; $red += 0x33) { 3215 for ($green = 0x00; $green <= 0xFF; $green += 0x33) { 3216 for ($blue = 0x00; $blue <= 0xFF; $blue += 0x33) { 3217 $hcol = sprintf('%02X%02X%02X', $red, $green, $blue); 3218 echo "<span style=\"color:#$hcol\">$hcol</span> "; 3219 } 3220 echo '<br>'; 3221 } 3222 echo '<br>'; 3223 } 3224 echo '</b></kbd>' . form('profile') . submit($I['backtoprofile'], ' class="backbutton"') . '</form>'; 3225 print_end(); 3226 } 3227 3228 function nav() 3229 { 3230 echo ' 3231 <div class="navbartitle"><a href="#" style="text-decoration: none; color: #fff;">404 Chatroom Not Found</a></div> 3232 <nav class="topnav"> 3233 <ul class="topnav"> 3234 <li><a href="#ABOUT" target="_self">About</a></li> 3235 <li><a href="https://github.com/d-a-s-h-o/universe" target="_blank">Source</a></li> 3236 <li><a href="/" target="_blank">Homepage</a></li> 3237 <a class="wgbtn" href="#logincbox">Login</a> 3238 </ul> </nav>'; 3239 } 3240 3241 function send_login() 3242 { 3243 global $I, $L; 3244 $ga = (int) get_setting('guestaccess'); 3245 if ($ga === 4) { 3246 send_chat_disabled(); 3247 } 3248 print_start('login'); 3249 nav(); 3250 $englobal = (int) get_setting('englobalpass'); 3251 //MODIFICATION frontpagetext 3252 //Frontpage text added 3253 /* $frontpagetext=get_setting('frontpagetext'); 3254 if(!empty($frontpagetext)){ 3255 echo "<span id=\"\">$frontpagetext</span>"; 3256 } */ 3257 //MODIFICATION Javascript check. 3258 //ToDo (Maybe later) 3259 3260 //MODIFICATION Topic on Frontpage disabled 3261 //echo '<h1 id="chatname">'.get_setting('chatname').'</h1>'; 3262 echo '<div id="logincbox" class="overlaycbx"><div class="popupcbx"><h2>Login</h2><a class="closecbx" href="#">×</a><div class="contentcbx">'; 3263 echo form_target('_parent', 'login') . '<table>'; 3264 if ($englobal === 1 && isset($_REQUEST['globalpass'])) { 3265 echo hidden('globalpass', $_REQUEST['globalpass']); 3266 } 3267 if ($englobal !== 1 || (isset($_REQUEST['globalpass']) && $_REQUEST['globalpass'] == get_setting('globalpass'))) { 3268 echo "<tr><td>$I[nick]</td><td><input type=\"text\" name=\"nick\" size=\"15\" autofocus></td></tr>"; 3269 echo "<tr><td>$I[pass]</td><td><input type=\"password\" name=\"pass\" size=\"15\"></td></tr>"; 3270 send_captcha(); 3271 if ($ga !== 0) { 3272 if (get_setting('guestreg') != 0) { 3273 echo "<tr><td>$I[regpass]</td><td><input type=\"password\" name=\"regpass\" size=\"15\" placeholder=\"$I[optional]\"></td></tr>"; 3274 } 3275 if ($englobal === 2) { 3276 echo "<tr><td>$I[globalloginpass]</td><td><input type=\"password\" name=\"globalpass\" size=\"15\"></td></tr>"; 3277 } 3278 echo "<tr><td colspan=\"2\">$I[choosecol]<br><select name=\"colour\"><option value=\"\">* $I[randomcol] *</option>"; 3279 print_colours(); 3280 echo '</select></td></tr>'; 3281 } else { 3282 echo "<tr><td colspan=\"2\">$I[noguests]</td></tr>"; 3283 } 3284 echo '<tr><td colspan="2">' . submit($I['enter']) . '</td></tr></table></form>'; 3285 echo '<br>'; 3286 get_nowchatting(); 3287 // echo '<br><div id="topic">'; 3288 //MODIFICATION Topic on Frontpage disabled. 1 lines "removed" 3289 //echo get_setting('topic'); 3290 // echo '</div>'; 3291 $rulestxt = get_setting('rulestxt'); 3292 3293 //MODIFICATION Rules on Frontpage disabled. 3 lines "removed" 3294 /* 3295 if(!empty($rulestxt)){ 3296 echo "<div id=\"rules\"><h2>$I[rules]</h2><b>$rulestxt</b></div>"; 3297 } 3298 */ 3299 } else { 3300 echo "<tr><td>$I[globalloginpass]</td><td><input type=\"password\" name=\"globalpass\" size=\"15\" autofocus></td></tr>"; 3301 if ($ga === 0) { 3302 echo "<tr><td colspan=\"2\">$I[noguests]</td></tr>"; 3303 } 3304 echo '<tr><td colspan="2">' . submit($I['enter']) . '</td></tr></table></form>'; 3305 } 3306 /*echo "<p id=\"changelang\">$I[changelang]"; 3307 foreach($L as $lang=>$name){ 3308 echo " <a href=\"$_SERVER[SCRIPT_NAME]?lang=$lang\">$name</a>"; 3309 }*/ 3310 3311 //MODIFICATION we hide our script version for security reasons and because it was modificated. 1 line replaced. 3312 //echo '</p>'.credit(); 3313 //echo '</p>'; 3314 echo '</table>'; 3315 $link4o4 = 'https://4-0-4.io'; 3316 $class = 'clearnet'; 3317 3318 echo '</div></div></div>'; 3319 echo "<div class=\"odiv\"><div class=\"splash\"><h2><strong>Welcome to the 404 Chatroom</strong></h2><div class=\"splashcard\"><br> 3320 <h3><ins>Shocking News</ins>: New Updates! We're online!</h3><br> 3321 <strong>Welcome to the 404 Chatroom - <em>The most over-compensating chat on tor</em>.</strong> 3322 <br>Are you looking for a fun - stress free, user friendly - totally secret awesome badass cool darkweb chat? That's such a coincidence, because that's what this is. All you have to do is press the <strong>Login</strong> button in the top right hand corner, enter your credentials, and start chatting. If you want to chat anonymously, just enter any nickname press <strong>Enter Chat</strong> straight away and get at it. We hope you have fun! 3323 <br><br> 3324 <div class=\"callout alert\" style=\"background: none; border: 2px; border-style: solid; border-color: #ffff80; border-radius: 0.5em; padding: 1em; color: white; margin-left: 10%; margin-right: 10%;\"> <p style=\"color: white; text-align: center\"><center>The <span style=\"color: #404 Chatroomffff80;\">404 Chatroom</span> Rules</center></p><hr><ol> <li><span style=\"color: #ffff80;\">Nothing gross or illegal.</span></li> <li>Freedom of speech is welcomed, but be nice.</li> <li>Please <span style=\"color: #ffff80;\">be respectful</span> to other chatters</li> <li>Please <span style=\"color: #ffff80;\">use meaningful</span> and <span style=\"color: #ffff80;\">non-offensive nicknames</span>. No pedo nicks.</li> <li>Please <span style=\"color: #ffff80;\">use English</span> in the Main Chat please.</li> <li>Please <span style=\"color: #ffff80;\">no advertising</span> with out staff approval .</li> <li>No drug or gun endorsements, or endorsements of other illegal markets.</li></ol> <hr /></div> 3325 <br><br> 3326 </div><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> 3327 <a href=\"http://4o4o4hn4hsujpnbsso7tqigujuokafxys62thulbk2k3mf46vq22qfqd.onion/\"><div class=\"tip\" style=\"position: fixed; bottom : 0; width: 100%\"><h4 style=\"color:white;\">~ Part of the 404 Project ~</h4></div> 3328 </a> 3329 <div class=\"idiv\" id=\"ABOUT\"><div class=\"idivs1\"> </div> 3330 3331 <div class=\"idivc\"> 3332 3333 <div style=\"text-align:center\"><h3><a name=\"Links\">About The Chat</a></h3></div> 3334 <br><br> 3335 <div class=\"insb\">Spread the word</div> 3336 <br> 3337 If you are passionate about promoting this chat, why not put a link to the site/chat in your regular forum profile signature? Go to your signature edit box and use something like this:<br><br> 3338 <div class=\"scrollbox\"><div class=\"sbc\"><pre><code>[b][size=100][bgcolor=#121525][color=#166FA6][/color][color=#F7F7F7]the 404 Chatroom:[/color][color=#166FA6] [/color][/bgcolor][/size] [size=100][bgcolor=#C13B5B][color=#F7F7F7]The dopest chat of darkweb.[/color][color=#C13B5B][/color][/bgcolor][/size][/b]</code></pre></div></div> <br> 3339 3340 <div class=\"insb\">Ideas and to-do's that need your input</div> 3341 <br> 3342 If you have theme ideas for the chat - or other improvements you'd like to see implemented, just contact a member of staff. Your feedback is highly appreciated.<br><br> 3343 </div><div class=\"idivs2\"> </div><br> 3344 </div></div>"; 3345 print_end(); 3346 } 3347 3348 function send_chat_disabled() 3349 { 3350 print_start('disabled'); 3351 echo get_setting('disabletext'); 3352 print_end(); 3353 } 3354 3355 function send_error($err) 3356 { 3357 global $I; 3358 print_start('error'); 3359 echo "<h2>$I[error]: $err</h2>" . form_target('_parent', '') . submit($I['backtologin'], 'class="backbutton"') . '</form>'; 3360 print_end(); 3361 } 3362 3363 function send_fatal_error($err) 3364 { 3365 global $I; 3366 echo '<!DOCTYPE html><html><head>' . meta_html(); 3367 echo "<title>$I[fatalerror]</title>"; 3368 echo "<style type=\"text/css\">body{background-color:#000000;color:#FF0033;}</style>"; 3369 echo '</head><body>'; 3370 echo "<h2>$I[fatalerror]: $err</h2>"; 3371 print_end(); 3372 } 3373 3374 function print_notifications() 3375 { 3376 global $I, $U, $db; 3377 echo '<span id="notifications">'; 3378 if ($U['status'] >= 2 && $U['eninbox'] != 0) { 3379 $stmt = $db->prepare('SELECT COUNT(*) FROM ' . PREFIX . 'inbox WHERE recipient=?;'); 3380 $stmt->execute([$U['nickname']]); 3381 $tmp = $stmt->fetch(PDO::FETCH_NUM); 3382 if ($tmp[0] > 0) { 3383 echo '<p>' . form('inbox') . submit(sprintf($I['inboxmsgs'], $tmp[0])) . '</form></p>'; 3384 } 3385 } 3386 if ($U['status'] >= 5 && get_setting('guestaccess') == 3) { 3387 $result = $db->query('SELECT COUNT(*) FROM ' . PREFIX . 'sessions WHERE entry=0 AND status=1;'); 3388 $temp = $result->fetch(PDO::FETCH_NUM); 3389 if ($temp[0] > 0) { 3390 echo '<p>'; 3391 echo form('admin', 'approve'); 3392 echo submit(sprintf($I['approveguests'], $temp[0])) . '</form></p>'; 3393 } 3394 } 3395 echo '</span>'; 3396 } 3397 function print_chatters() 3398 { 3399 global $I, $U, $db, $language; 3400 3401 $icon_star_red = "<img border='0' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wgIACgc4JxSRwAAARBJREFUKM99kL1KA1EQhb/Z6+4GJQQbDQi+Q7CPYMBGKxtrVyRsaSkEg4iCBGxMuQQ2kGewzxtYiW+gpSD5u94dq4hsLp5u5jtnhhnwaJ6mu4tOZ93H1nxNJpNjrDXAUxkF+HWi1p75wErAjkZGnGsBDdvtbpa5zNN0X6bTDQBVFTFmT527ARCRnqqORaQgCNA4nsq83d5mNnsGGvyvFyqVI1lWiyS5UufufU4Jw9soy64B5C9YJMmlOvdYMneiLLvzHq3OHZSnq7VN75e+h8MAaAGIMRcShueAAofu7TVYCRTjcRP4kmq1Hg0GWZRlA6nVdoAP99A7XQmoMXGc51tRv//xu78o3uM8r2sYfi5bP+VcXsOKMjGVAAAAAElFTkSuQmCC'/>"; 3402 3403 $icon_star_gold = "<img border='0' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAABKElEQVQoz32QvUoDQRSFz53ZjfEnMTFgkkYQrOyCragYsdFCLAIpRXwASyEIIoog2PgQiUbRTsXON4i1D7AKmhUk2d3MzLWKhOzgKb9vhnvvASwJb2dnOo+LYzbnWGHkbUr9JQFcDjsBa3ibdLhjM7EP7deaBKsymbDUeV7LDnvq3RSXhfoZBzFgiFjIBaH8IwAwcuKcmF5AbAiAdlJdipqFvFT+A5mghH/CItnSTnqD+qB3NXUgVfsU4Nhj42aOnYp/CAA0KFQjsy+0fzHItJuruZXPE+vRxMFqrBXdWbK25LXOBHGvDBIwTnZPu5O7gGTicP0p4Hj96jq3ouuJj+79XL7Pgrv5oq4nPN1IV2MTtEyOyGo0Pbr19v63IkJPVqOCclLfffYLGXVpfXSgIhUAAAAASUVORK5CYII='/>"; 3404 3405 $icon_star_silver = "<img border='0' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA8ElEQVQoz42STSuEURiGr/tgw8pOTfkPk61GIQorG6uz0CRri1moSUmklF8gm/PuZI1m5x/MrPwEH8VGQym3zVHT6yw8y/ujnufqgcKklGaHt/OTJS+URNsb1y+77X8XgE3b2/8qvA26Y8AS0Bz2lqfrvlJKC8BUXkWS5mwfAkg6s30v6TvnP8aBB9s3QDOXRm/pAJ2s9SWta4TMvu2T0t6SjmKMBwCq4dyzfV4Ld2OMx8WjbS8WELeKlB77pyHTQdKOpDZgYOXu0+FPoTdotID3EMJMjPEixng58fXaAJ6er6qt0jus1rWqqpS9tV/tB1UBYQLU/vuEAAAAAElFTkSuQmCC'/>"; 3406 3407 $icon_star_bronze = "<img border='0' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAABEElEQVQoz42QL0hDYRTFf/d7s2jSYhN8w2YZVpmgsoGaDL5ZBBl2hRVhCCoMYWw2g8UijIF9yprYZQOjrymaBiLTsPddgz7Bx4fspnvPuX/OPeCIesGf6l/Pj7o44wIHka6dXTwXhx4A1q3V7aEGet2yp7AEZPrt5fEkL/WCvxBZHQNQRURkTlUPAUSoqnIrggXBM3xILfAnI6stIMP/0fGMrEpcVTf8fVWtOHUbOS41wwMALwbbD7273OzEG5BPNJdLzfDI+bSqLia3W6tZp0svnRPDtzuIyI4xUgQUyN186m9fKk4uK+dZ4H0kZab3Go+vAFe7M63waXDf3UoHQOPP6Vrg55NyTjfT8sOtxNgX5ehXBVg4i6sAAAAASUVORK5CYII='/>"; 3408 3409 $icon_heart_red = "<img border='0' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAABs0lEQVQoz22Ry2sTURSHv3vvPNLMTBLTiiVIFSsuxFCIuBJEKi58LN3730k0BRcVBVEpXSloN1IrrYJSHyQTZ5pn03nc6yJpF+K3/J3v/BbnCIDnNqeWa9WrjuN4xlJbF3Z+7gNsX1pccjPdyI3u7+13P9zP6InXc1SvXDy/UQn8upSSLM97nU7nzmGaumdrtXVHWb7BEPf6W+8/f1+1Fqqle+XAr9u2DYBlWWW3OPfCEYHrFQoFYwwAlVLQOHcmuGVpaEgpOUYbw+nqfNkYw7EMoKREIlZkotlO9HRghABAGIMUApSCWWa0xlFqR/7pDzZ+t8NxNhojkgSpNUJMPZFmiMkEMRqQxPFwPBi+lXdH5steO3zZ7Ubo8RjybNYqwOSQpiSDEV/b4bOVOP2mAKzEtBZ1+jAwVHzHBrcASkKuSQ4GfOzGnxrR0SqABHjgCx1m+vpubxiFYYzp9WFyRBYdsBvFnR+T9OZm2REnF3hcVAA0PevyZqVgftUqJlpaMO/mPb0e2MsAT2bOCS1/+oeWZ197U3IOX5XcYdOz6wBPA4f/sjZbahbV7UdFdQNg7R/5Lza2vZnfg8j9AAAAAElFTkSuQmCC'/>"; 3410 3411 //Color was changed from blue to light blue 3412 $icon_heart_blue = "<img border='0' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAABqUlEQVQoz2WQu2tTYRiHn/c7JyeXJpbopnAU9yJEHFSUEHUoTiIOXQTXtouLf4K46RBHVxcLHQwIIhKdXOwi6iISW/Ba06QnObmc7/teB220+My/Gz8BaNz9WK2W8yejiDkR2Xh4/fAWwNKDrdgGpmas3/2a+Ncvbh7ty8X7nYNHyrl2qWgWAq9YY/r9JFu0nvyhueBxaCgDJBPd6HRtI6wUgsulolmIAIwQoPNRaJ5EkM+HUuAPpaLUqgeCCyFQC7yCEQCcCpVCMC8o/xJ4JXT+hHEqb60xM/EeRkBE9plE5L1JJ7bdS2w6yhTUIyiB/E53XnFeGakwmPjBKNNX5tnKsQ/bY/t0J1MmVlH9O8UrTB2Mpo7toW+1luOOAfjSD64mvazTszBB9uoBmFrPTuLetZbjJQADcOd27MehOTsY2O7uwJJ6yJwynCrd1H9Plfpi85PMDKk3tFfjzyPkXG8MvcTyc+j4NnI6VDnzfCX+cePWcQWY3fConOPaIKNxr3MqDMxL47wbh+Z0ezV+s16JuJJM+Y+1cg6AenPzUr25eR5grRLt0/wCkH7H2hCmE9kAAAAASUVORK5CYII='/>"; 3413 3414 3415 if (!$U['hidechatters']) { 3416 echo '<div id="chatters">'; 3417 if ($U['status'] >= 5) { 3418 $stmt = $db->prepare('SELECT nickname, style, status, roomid FROM ' . PREFIX . 'sessions WHERE entry!=0 AND status>0 AND incognito=0 AND nickname NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=? UNION SELECT ignby FROM ' . PREFIX . 'ignored WHERE ign=?) ORDER BY status DESC, lastpost DESC;'); 3419 } else { 3420 $stmt = $db->prepare('SELECT nickname, style, status, roomid FROM ' . PREFIX . 'sessions WHERE entry!=0 AND status>0 AND incognito=0 AND nickname NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=? UNION SELECT ignby FROM ' . PREFIX . 'ignored WHERE ign=?) ORDER BY lastpost DESC;'); 3421 } 3422 $stmt->execute([$U['nickname'], $U['nickname']]); 3423 $nc = substr(time(), -6); 3424 $G = $RG = $M = $S = []; 3425 while ($user = $stmt->fetch(PDO::FETCH_BOTH)) { 3426 //MODIFICATION chat rooms 3427 $roomclass = 'notinroom'; 3428 if ($U['roomid'] === $user['roomid']) { 3429 $roomclass = 'inroom'; 3430 } 3431 $stmt1 = $db->prepare('SELECT name FROM ' . PREFIX . 'rooms WHERE id=? AND access<=? ;'); 3432 $stmt1->execute([$user['roomid'], $U['status']]); 3433 if ($room = $stmt1->fetch(PDO::FETCH_NUM)) { 3434 $roomname = $room[0]; 3435 } else { 3436 $roomname = " "; 3437 if ($user['roomid'] === null) { 3438 $roomname = "[Main Chat]"; 3439 } 3440 } 3441 $roomprefix = "<span class=\"$roomclass\" title=\"$roomname\">"; 3442 $roompostfix = '</span>'; 3443 3444 $link = "<a style=\"text-decoration: none;\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=" . htmlspecialchars($user[0]) . '" target="post">' . style_this(htmlspecialchars($user[0]), $user[1]) . '</a>'; 3445 3446 //staff can see the different rank icons of the staff people 3447 if ($U['status'] >= 5) { //if logged in user is moderator or higher 3448 3449 if ($user[2] >= 8) { 3450 $link = "<nobr>" . rank_this($user[2]) . $roomprefix . $link . $roompostfix . "</nobr>"; //adds red star icon in front of the nick. 3451 $S[] = $link; 3452 } elseif ($user[2] == 7) { 3453 $link = "<nobr>" . rank_this($user[2]) . $roomprefix . $link . $roompostfix . "</nobr>"; //adds gold star icon in front of the nick. 3454 $S[] = $link; 3455 } elseif ($user[2] == 6) { 3456 $link = "<nobr>" . rank_this($user[2]) . $roomprefix . $link . $roompostfix . "</nobr>"; //adds silver star icon in front of the nick. 3457 $S[] = $link; 3458 } elseif ($user[2] == 5) { 3459 $link = "<nobr>" . rank_this($user[2]) . $roomprefix . $link . $roompostfix . "</nobr>"; //adds bronze star icon in front of the nick. 3460 $S[] = $link; 3461 } elseif ($user[2] == 3) { 3462 $link = "<nobr>" . rank_this($user[2]) . $roomprefix . $link . $roompostfix . "</nobr>"; //adds "heart icon red" in front of the nick. 3463 $M[] = $link; 3464 } elseif ($user[2] == 2) { 3465 $link = "<nobr>" . rank_this($user[2]) . $roomprefix . $link . $roompostfix . "</nobr>"; //adds "heart icon pink" in front of the nick. 3466 $RG[] = $link; 3467 } else { 3468 $G[] = $roomprefix . $link . $roompostfix; 3469 } 3470 3471 //guests and members can't see the different rank icons of the staff 3472 } else { 3473 if ($user[2] >= 5) { 3474 $link = "<nobr>" . rank_this('5') . $roomprefix . $link . $roompostfix . "</nobr>"; //adds star icon in front of the nick. No break tags (deprecated) to prevent line break between icon and nickname. 3475 $M[] = $link; 3476 } elseif ($user[2] == 3) { 3477 $link = "<nobr>" . rank_this('3') . $roomprefix . $link . $roompostfix . "</nobr>"; //adds "heart icon red" in front of the nick. 3478 $M[] = $link; 3479 } elseif ($user[2] == 2) { 3480 $link = "<nobr>" . rank_this('2') . $roomprefix . $link . $roompostfix . "</nobr>"; //adds "heart icon" pink in front of the nick. 3481 $RG[] = $link; 3482 } else { 3483 $G[] = $roomprefix . $link . $roompostfix; 3484 } 3485 } //end if 3486 3487 } //end while 3488 if ($U['status'] >= 5) { 3489 $chanlinks = "<a style=\"color:#fff; text-decoration: none\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=s 48\" target=\"post\">$I[staff]</a>"; 3490 $chanlinkm = "<a style=\"color:#fff; text-decoration: none\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=s 31\" target=\"post\">$I[members2]</a>"; 3491 $chanlinkrg = "<a style=\"color:#fff; text-decoration: none\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=s 24\" target=\"post\">$I[regguests]</a>"; 3492 $chanlinkg = "<a style=\"color:#fff; text-decoration: none\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=s 17\" target=\"post\">$I[guests]</a>"; 3493 } elseif ($U['status'] == 3) { 3494 $chanlinks = "$I[staff]"; 3495 $chanlinkm = "<a style=\"color:#fff; text-decoration: none\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=s 31\" target=\"post\">$I[members2]</a>"; 3496 $chanlinkrg = "<a style=\"color:#fff; text-decoration: none\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=s 24\" target=\"post\">$I[regguests]</a>"; 3497 $chanlinkg = "<a style=\"color:#fff; text-decoration: none\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=s 17\" target=\"post\">$I[guests]</a>"; 3498 } elseif ($U['status'] == 2) { 3499 $chanlinks = "$I[staff]"; 3500 $chanlinkm = "$I[members2]"; 3501 $chanlinkrg = "<a style=\"color:#fff; text-decoration: none\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=s 24\" target=\"post\">$I[regguests]</a>"; 3502 $chanlinkg = "<a style=\"color:#fff; text-decoration: none\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=s 17\" target=\"post\">$I[guests]</a>"; 3503 } else { 3504 $chanlinks = "$I[staff]"; 3505 $chanlinkm = "$I[members2]"; 3506 $chanlinkrg = "$I[regguests]"; 3507 $chanlinkg = "<a style=\"color:#fff; text-decoration: none\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=s 17\" target=\"post\">$I[guests]</a>"; 3508 } 3509 if (!empty($S)) { 3510 echo "<span class='group'>" . $chanlinks . " (" . count($S) . ")</span><div>" . implode('</span><br><span>', $S) . '</div>'; 3511 if (!empty($M) || !empty($R) || !empty($G)) { 3512 echo '<div> </div>'; 3513 } 3514 } 3515 if (!empty($M)) { 3516 echo "<span class='group'>" . $chanlinkm . " (" . count($M) . ")</span><div>" . implode('</span><br><span>', $M) . '</div>'; 3517 if (!empty($R) || !empty($G)) { 3518 echo '<div> </div>'; 3519 } 3520 } 3521 if (!empty($RG)) { 3522 echo "<span class='group'>" . $chanlinkrg . " (" . count($RG) . ")</span><div>" . implode('</span><br><span>', $RG) . '</div>'; 3523 if (!empty($G)) { 3524 echo '<div> </div>'; 3525 } 3526 } 3527 if (!empty($G)) { 3528 echo "<span class='group'>" . $chanlinkg . " (" . count($G) . ")</span><div>" . implode('</span><br><span>', $G) . '</div>'; 3529 } 3530 echo '</div>'; 3531 } //end if 3532 } //end function print_chatters 3533 3534 // session management 3535 3536 function create_session($setup, $nickname, $password) 3537 { 3538 global $I, $U; 3539 $U['nickname'] = preg_replace('/\s/', '', $nickname); 3540 if (check_member($password)) { 3541 if ($setup && $U['status'] >= 7) { 3542 $U['incognito'] = 1; 3543 } 3544 $U['entry'] = $U['lastpost'] = time(); 3545 } else { 3546 add_user_defaults($password); 3547 check_captcha(isset($_REQUEST['challenge']) ? $_REQUEST['challenge'] : '', isset($_REQUEST['captcha']) ? $_REQUEST['captcha'] : ''); 3548 $ga = (int) get_setting('guestaccess'); 3549 if (!valid_nick($U['nickname'])) { 3550 send_error(sprintf($I['invalnick'], get_setting('maxname'), get_setting('nickregex'))); 3551 } 3552 if (!valid_pass($password)) { 3553 send_error(sprintf($I['invalpass'], get_setting('minpass'), get_setting('passregex'))); 3554 } 3555 if ($ga === 0) { 3556 send_error($I['noguests']); 3557 } elseif ($ga === 3) { 3558 $U['entry'] = 0; 3559 } 3560 if (get_setting('englobalpass') != 0 && isset($_REQUEST['globalpass']) && $_REQUEST['globalpass'] != get_setting('globalpass')) { 3561 send_error($I['wrongglobalpass']); 3562 } 3563 } 3564 write_new_session($password); 3565 } 3566 3567 function rank_this($status) 3568 { 3569 3570 /* 3571 1 .rank.g { background-image: url('green-1.png'); } 3572 2 .rank.ra { background-image: url('green-2.png'); } 3573 3 .rank.m { background-image: url('blue-1.png'); } 3574 5 .rank.mod { background-image: url('red-1.png'); } 3575 6 .rank.sm { background-image: url('red-2.png'); } 3576 7 .rank.a { background-image: url('red-3.png'); } 3577 8 .rank.sa { background-image: url('yellow-1.png'); } 3578 */ 3579 3580 $rank = ""; 3581 3582 switch ($status) { 3583 case 1: 3584 $rank = "g"; 3585 break; 3586 case 2: 3587 $rank = "ra"; 3588 break; 3589 case 3: 3590 $rank = "m"; 3591 break; 3592 case 5: 3593 $rank = "mod"; 3594 break; 3595 case 6: 3596 $rank = "sm"; 3597 break; 3598 case 7: 3599 $rank = "a"; 3600 break; 3601 case 8: 3602 $rank = "sa"; 3603 break; 3604 case 9: 3605 $rank = "sa"; 3606 break; 3607 default: 3608 $rank = ""; 3609 } 3610 3611 if (strlen($rank)) { 3612 return sprintf("<span class=\"rank %s\"></span><bdi class=\"spacer\"></bdi>", $rank); 3613 } 3614 return ''; 3615 } 3616 3617 function check_captcha($challenge, $captcha_code) 3618 { 3619 global $I, $db, $memcached; 3620 $captcha = (int) get_setting('captcha'); 3621 if ($captcha !== 0) { 3622 if (empty($challenge)) { 3623 send_error($I['wrongcaptcha']); 3624 } 3625 if (MEMCACHED) { 3626 if (!$code = $memcached->get(DBNAME . '-' . PREFIX . "captcha-$_REQUEST[challenge]")) { 3627 send_error($I['captchaexpire']); 3628 } 3629 $memcached->delete(DBNAME . '-' . PREFIX . "captcha-$_REQUEST[challenge]"); 3630 } else { 3631 $stmt = $db->prepare('SELECT code FROM ' . PREFIX . 'captcha WHERE id=?;'); 3632 $stmt->execute([$challenge]); 3633 $stmt->bindColumn(1, $code); 3634 if (!$stmt->fetch(PDO::FETCH_BOUND)) { 3635 send_error($I['captchaexpire']); 3636 } 3637 $time = time(); 3638 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'captcha WHERE id=? OR time<(?-(SELECT value FROM ' . PREFIX . "settings WHERE setting='captchatime'));"); 3639 $stmt->execute([$challenge, $time]); 3640 } 3641 if ($captcha_code !== $code) { 3642 if ($captcha !== 3 || strrev($captcha_code) !== $code) { 3643 send_error($I['wrongcaptcha']); 3644 } 3645 } 3646 } 3647 } 3648 3649 function is_definitely_ssl() 3650 { 3651 if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') { 3652 return true; 3653 } 3654 if (isset($_SERVER['SERVER_PORT']) && ('443' == $_SERVER['SERVER_PORT'])) { 3655 return true; 3656 } 3657 if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && ('https' == $_SERVER['HTTP_X_FORWARDED_PROTO'])) { 3658 return true; 3659 } 3660 return false; 3661 } 3662 3663 function set_secure_cookie($name, $value) 3664 { 3665 if (version_compare(PHP_VERSION, '7.3.0') >= 0) { 3666 setcookie($name, $value, ['expires' => 0, 'path' => '/', 'domain' => '', 'secure' => is_definitely_ssl(), 'httponly' => true, 'samesite' => 'Strict']); 3667 } else { 3668 setcookie($name, $value, 0, '/', '', is_definitely_ssl(), true); 3669 } 3670 } 3671 3672 function write_new_session($password) 3673 { 3674 global $I, $U, $db; 3675 $stmt = $db->prepare('SELECT * FROM ' . PREFIX . 'sessions WHERE nickname=?;'); 3676 $stmt->execute([$U['nickname']]); 3677 if ($temp = $stmt->fetch(PDO::FETCH_ASSOC)) { 3678 // check whether alrady logged in 3679 if (password_verify($password, $temp['passhash'])) { 3680 $U = $temp; 3681 check_kicked(); 3682 set_secure_cookie(COOKIENAME, $U['session']); 3683 } else { 3684 send_error("$I[userloggedin]<br>$I[wrongpass]"); 3685 } 3686 } else { 3687 // create new session 3688 $stmt = $db->prepare('SELECT null FROM ' . PREFIX . 'sessions WHERE session=?;'); 3689 do { 3690 if (function_exists('random_bytes')) { 3691 $U['session'] = bin2hex(random_bytes(16)); 3692 } else { 3693 $U['session'] = md5(uniqid($U['nickname'], true) . mt_rand()); 3694 } 3695 $stmt->execute([$U['session']]); 3696 } while ($stmt->fetch(PDO::FETCH_NUM)); // check for hash collision 3697 if (isset($_SERVER['HTTP_USER_AGENT'])) { 3698 $useragent = htmlspecialchars($_SERVER['HTTP_USER_AGENT']); 3699 } else { 3700 $useragent = ''; 3701 } 3702 if (get_setting('trackip')) { 3703 $ip = $_SERVER['REMOTE_ADDR']; 3704 } else { 3705 $ip = ''; 3706 } 3707 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'sessions (session, nickname, status, refresh, style, lastpost, passhash, useragent, bgcolour, entry, timestamps, embed, incognito, ip, nocache, tz, eninbox, sortupdown, hidechatters, nocache_old) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);'); 3708 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'sessions (session, nickname, status, refresh, style, lastpost, passhash, useragent, bgcolour, entry, timestamps, embed, incognito, ip, nocache, tz, eninbox, sortupdown, hidechatters, nocache_old) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);'); 3709 $stmt->execute([$U['session'], $U['nickname'], $U['status'], $U['refresh'], $U['style'], $U['lastpost'], $U['passhash'], $useragent, $U['bgcolour'], $U['entry'], $U['timestamps'], $U['embed'], $U['incognito'], $ip, $U['nocache'], $U['tz'], $U['eninbox'], $U['sortupdown'], $U['hidechatters'], $U['nocache_old']]); 3710 set_secure_cookie(COOKIENAME, $U['session']); 3711 3712 //MDIFICATION for clickable nicknames setting. (clickablenicknames value added) 3713 /* REMVOE LATER 3714 $stmt=$db->prepare('INSERT INTO ' . PREFIX . 'sessions (session, nickname, status, refresh, style, lastpost, passhash, useragent, bgcolour, entry, timestamps, embed, incognito, ip, nocache, tz, eninbox, sortupdown, hidechatters, nocache_old, clickablenicknames) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);'); 3715 $stmt->execute([$U['session'], $U['nickname'], $U['status'], $U['refresh'], $U['style'], $U['lastpost'], $U['passhash'], $useragent, $U['bgcolour'], $U['entry'], $U['timestamps'], $U['embed'], $U['incognito'], $ip, $U['nocache'], $U['tz'], $U['eninbox'], $U['sortupdown'], $U['hidechatters'], $U['nocache_old'],$U['clickablenicknames'] ]); 3716 setcookie(COOKIENAME, $U['session']); 3717 */ 3718 3719 //MODIFICATION adminjoinleavemsg setting for join/leave message for admins 3720 if (($U['status'] >= 3 && $U['status'] <= 6 && !$U['incognito']) || ($U['status'] >= 7 && !$U['incognito'] && (bool) get_setting('adminjoinleavemsg'))) { 3721 add_system_message(sprintf(get_setting('msgenter'), style_this_clickable(htmlspecialchars($U['nickname']), $U['style']))); 3722 } 3723 } 3724 } 3725 3726 function approve_session() 3727 { 3728 global $db; 3729 if (isset($_REQUEST['what'])) { 3730 if ($_REQUEST['what'] === 'allowchecked' && isset($_REQUEST['csid'])) { 3731 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET entry=lastpost WHERE nickname=?;'); 3732 foreach ($_REQUEST['csid'] as $nick) { 3733 $stmt->execute([$nick]); 3734 } 3735 } elseif ($_REQUEST['what'] === 'allowall' && isset($_REQUEST['alls'])) { 3736 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET entry=lastpost WHERE nickname=?;'); 3737 foreach ($_REQUEST['alls'] as $nick) { 3738 $stmt->execute([$nick]); 3739 } 3740 } elseif ($_REQUEST['what'] === 'denychecked' && isset($_REQUEST['csid'])) { 3741 $time = 60 * (get_setting('kickpenalty') - get_setting('guestexpire')) + time(); 3742 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET lastpost=?, status=0, kickmessage=? WHERE nickname=? AND status=1;'); 3743 foreach ($_REQUEST['csid'] as $nick) { 3744 $stmt->execute([$time, $_REQUEST['kickmessage'], $nick]); 3745 } 3746 } elseif ($_REQUEST['what'] === 'denyall' && isset($_REQUEST['alls'])) { 3747 $time = 60 * (get_setting('kickpenalty') - get_setting('guestexpire')) + time(); 3748 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET lastpost=?, status=0, kickmessage=? WHERE nickname=? AND status=1;'); 3749 foreach ($_REQUEST['alls'] as $nick) { 3750 $stmt->execute([$time, $_REQUEST['kickmessage'], $nick]); 3751 } 3752 } 3753 } 3754 } 3755 3756 function check_login() 3757 { 3758 global $I, $U, $db; 3759 $ga = (int) get_setting('guestaccess'); 3760 if (isset($_REQUEST['session'])) { 3761 parse_sessions(); 3762 } 3763 if (isset($U['session'])) { 3764 check_kicked(); 3765 } elseif (get_setting('englobalpass') == 1 && (!isset($_REQUEST['globalpass']) || $_REQUEST['globalpass'] != get_setting('globalpass'))) { 3766 send_error($I['wrongglobalpass']); 3767 } elseif (!isset($_REQUEST['nick']) || !isset($_REQUEST['pass'])) { 3768 send_login(); 3769 } else { 3770 if ($ga === 4) { 3771 send_chat_disabled(); 3772 } 3773 if (!empty($_REQUEST['regpass']) && $_REQUEST['regpass'] !== $_REQUEST['pass']) { 3774 send_error($I['noconfirm']); 3775 } 3776 create_session(false, $_REQUEST['nick'], $_REQUEST['pass']); 3777 if (!empty($_REQUEST['regpass'])) { 3778 $guestreg = (int) get_setting('guestreg'); 3779 if ($guestreg === 1) { 3780 register_guest(2, $_REQUEST['nick']); 3781 $U['status'] = 2; 3782 } elseif ($guestreg === 2) { 3783 register_guest(3, $_REQUEST['nick']); 3784 $U['status'] = 3; 3785 } 3786 } 3787 } 3788 if ($U['status'] == 1) { 3789 if ($ga === 2 || $ga === 3) { 3790 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET entry=0 WHERE session=?;'); 3791 $stmt->execute([$U['session']]); 3792 send_waiting_room(); 3793 } 3794 } 3795 } 3796 3797 function kill_session() 3798 { 3799 global $U, $db; 3800 parse_sessions(); 3801 check_expired(); 3802 check_kicked(); 3803 setcookie(COOKIENAME, false); 3804 $_REQUEST['session'] = ''; 3805 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'sessions WHERE session=?;'); 3806 $stmt->execute([$U['session']]); 3807 3808 //Modification adminjoinleavemsg 3809 if (($U['status'] >= 3 && $U['status'] <= 6 && !$U['incognito']) || ($U['status'] >= 7 && !$U['incognito'] && (bool) get_setting('adminjoinleavemsg'))) { 3810 //MODIFICATION for clickablenicknames stlye_this_clickable instead of style_this 3811 add_system_message(sprintf(get_setting('msgexit'), style_this_clickable(htmlspecialchars($U['nickname']), $U['style']))); 3812 } 3813 } 3814 3815 function kick_chatter($names, $mes, $purge) 3816 { 3817 global $U, $db; 3818 $lonick = ''; 3819 $time = 60 * (get_setting('kickpenalty') - get_setting('guestexpire')) + time(); 3820 $check = $db->prepare('SELECT style, entry FROM ' . PREFIX . 'sessions WHERE nickname=? AND status!=0 AND (status<? OR nickname=?);'); 3821 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET lastpost=?, status=0, kickmessage=? WHERE nickname=?;'); 3822 $all = false; 3823 if ($names[0] === 's &') { 3824 $tmp = $db->query('SELECT nickname FROM ' . PREFIX . 'sessions WHERE status=1;'); 3825 $names = []; 3826 while ($name = $tmp->fetch(PDO::FETCH_NUM)) { 3827 $names[] = $name[0]; 3828 } 3829 $all = true; 3830 } 3831 $i = 0; 3832 foreach ($names as $name) { 3833 $check->execute([$name, $U['status'], $U['nickname']]); 3834 if ($temp = $check->fetch(PDO::FETCH_ASSOC)) { 3835 $stmt->execute([$time, $mes, $name]); 3836 if ($purge) { 3837 del_all_messages($name, $temp['entry']); 3838 } 3839 //MODIFICATION style_thins replaced with style_this_clickable 3840 $lonick .= style_this_clickable(htmlspecialchars($name), $temp['style']) . ', '; 3841 ++$i; 3842 } 3843 } 3844 if ($i > 0) { 3845 if ($all) { 3846 add_system_message(get_setting('msgallkick')); 3847 } else { 3848 $lonick = substr($lonick, 0, -2); 3849 if ($i > 1) { 3850 add_system_message(sprintf(get_setting('msgmultikick'), $lonick)); 3851 } else { 3852 add_system_message(sprintf(get_setting('msgkick'), $lonick)); 3853 } 3854 } 3855 return true; 3856 } 3857 return false; 3858 } 3859 3860 function logout_chatter($names) 3861 { 3862 global $U, $db; 3863 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'sessions WHERE nickname=? AND status<?;'); 3864 if ($names[0] === 's &') { 3865 $tmp = $db->query('SELECT nickname FROM ' . PREFIX . 'sessions WHERE status=1;'); 3866 $names = []; 3867 while ($name = $tmp->fetch(PDO::FETCH_NUM)) { 3868 $names[] = $name[0]; 3869 } 3870 } 3871 foreach ($names as $name) { 3872 $stmt->execute([$name, $U['status']]); 3873 } 3874 } 3875 3876 function check_session() 3877 { 3878 global $U; 3879 parse_sessions(); 3880 check_expired(); 3881 check_kicked(); 3882 if ($U['entry'] == 0) { 3883 send_waiting_room(); 3884 } 3885 } 3886 3887 function check_expired() 3888 { 3889 global $I, $U; 3890 if (!isset($U['session'])) { 3891 setcookie(COOKIENAME, false); 3892 $_REQUEST['session'] = ''; 3893 send_error($I['expire']); 3894 } 3895 } 3896 3897 function get_count_mods() 3898 { 3899 global $db; 3900 $c = $db->query('SELECT COUNT(*) FROM ' . PREFIX . 'sessions WHERE status>=5')->fetch(PDO::FETCH_NUM); 3901 return $c[0]; 3902 } 3903 3904 function check_kicked() 3905 { 3906 global $I, $U; 3907 if ($U['status'] == 0) { 3908 setcookie(COOKIENAME, false); 3909 $_REQUEST['session'] = ''; 3910 send_error("$I[kicked]<br>$U[kickmessage]"); 3911 } 3912 } 3913 3914 function get_nowchatting() 3915 { 3916 global $I, $db; 3917 parse_sessions(); 3918 $stmt = $db->query('SELECT COUNT(*) FROM ' . PREFIX . 'sessions WHERE entry!=0 AND status>0 AND incognito=0;'); 3919 $count = $stmt->fetch(PDO::FETCH_NUM); 3920 echo '<div id="chatters">' . sprintf($I['curchat'], $count[0]) . '<br>'; 3921 if (!get_setting('hidechatters')) { 3922 3923 //MODIFICATION hidden ranks on frontpage. Some lines changed and some lines added. 3924 $stmt = $db->query('SELECT nickname, style FROM ' . PREFIX . 'sessions WHERE entry!=0 AND status>=3 AND incognito=0 ORDER BY lastpost DESC;'); 3925 while ($user = $stmt->fetch(PDO::FETCH_NUM)) { 3926 echo style_this(htmlspecialchars($user[0]), $user[1]) . ' '; 3927 } 3928 3929 $stmt = $db->query('SELECT nickname, style FROM ' . PREFIX . 'sessions WHERE entry!=0 AND status>0 AND status<3 AND incognito=0 ORDER BY status DESC, lastpost DESC;'); 3930 while ($user = $stmt->fetch(PDO::FETCH_NUM)) { 3931 echo style_this(htmlspecialchars($user[0]), $user[1]) . ' '; 3932 } 3933 } 3934 3935 echo '</div>'; 3936 } 3937 3938 function parse_sessions() 3939 { 3940 global $U, $db; 3941 // look for our session 3942 if (isset($_REQUEST['session'])) { 3943 $stmt = $db->prepare('SELECT * FROM ' . PREFIX . 'sessions WHERE session=?;'); 3944 $stmt->execute([$_REQUEST['session']]); 3945 if ($tmp = $stmt->fetch(PDO::FETCH_ASSOC)) { 3946 $U = $tmp; 3947 } 3948 } 3949 set_default_tz(); 3950 } 3951 3952 // member handling 3953 3954 function check_member($password) 3955 { 3956 global $I, $U, $db; 3957 $stmt = $db->prepare('SELECT * FROM ' . PREFIX . 'members WHERE nickname=?;'); 3958 $stmt->execute([$U['nickname']]); 3959 if ($temp = $stmt->fetch(PDO::FETCH_ASSOC)) { 3960 if (get_setting('dismemcaptcha') == 0) { 3961 check_captcha(isset($_REQUEST['challenge']) ? $_REQUEST['challenge'] : '', isset($_REQUEST['captcha']) ? $_REQUEST['captcha'] : ''); 3962 } 3963 if ($temp['passhash'] === md5(sha1(md5($U['nickname'] . $password)))) { 3964 // old hashing method, update on the fly 3965 $temp['passhash'] = password_hash($password, PASSWORD_DEFAULT); 3966 $stmt = $db->prepare('UPDATE ' . PREFIX . 'members SET passhash=? WHERE nickname=?;'); 3967 $stmt->execute([$temp['passhash'], $U['nickname']]); 3968 } 3969 if (password_verify($password, $temp['passhash'])) { 3970 $U = $temp; 3971 $stmt = $db->prepare('UPDATE ' . PREFIX . 'members SET lastlogin=? WHERE nickname=?;'); 3972 $stmt->execute([time(), $U['nickname']]); 3973 return true; 3974 } else { 3975 send_error("$I[regednick]<br>$I[wrongpass]"); 3976 } 3977 } 3978 return false; 3979 } 3980 3981 function delete_account() 3982 { 3983 global $U, $db; 3984 if ($U['status'] < 8) { 3985 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET status=1, incognito=0 WHERE nickname=?;'); 3986 $stmt->execute([$U['nickname']]); 3987 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'members WHERE nickname=?;'); 3988 $stmt->execute([$U['nickname']]); 3989 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'inbox WHERE recipient=?;'); 3990 $stmt->execute([$U['nickname']]); 3991 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'notes WHERE type=2 AND editedby=?;'); 3992 $stmt->execute([$U['nickname']]); 3993 $U['status'] = 1; 3994 } 3995 } 3996 3997 function register_guest($status, $nick) 3998 { 3999 global $I, $U, $db; 4000 $stmt = $db->prepare('SELECT style FROM ' . PREFIX . 'members WHERE nickname=?'); 4001 $stmt->execute([$nick]); 4002 if ($tmp = $stmt->fetch(PDO::FETCH_NUM)) { 4003 return sprintf($I['alreadyreged'], style_this(htmlspecialchars($nick), $tmp[0])); 4004 } 4005 $stmt = $db->prepare('SELECT * FROM ' . PREFIX . 'sessions WHERE nickname=? AND status=1;'); 4006 $stmt->execute([$nick]); 4007 if ($reg = $stmt->fetch(PDO::FETCH_ASSOC)) { 4008 $reg['status'] = $status; 4009 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET status=? WHERE session=?;'); 4010 $stmt->execute([$reg['status'], $reg['session']]); 4011 } else { 4012 return sprintf($I['cantreg'], htmlspecialchars($nick)); 4013 } 4014 4015 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'members (nickname, passhash, status, refresh, bgcolour, regedby, timestamps, embed, style, incognito, nocache, tz, eninbox, sortupdown, hidechatters, nocache_old) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);'); 4016 4017 //MODIFICATION for clickable nicknames 4018 /* REMOVE LATER 4019 $stmt=$db->prepare('INSERT INTO ' . PREFIX . 'members (nickname, passhash, status, refresh, bgcolour, regedby, timestamps, embed, style, incognito, nocache, tz, eninbox, sortupdown, hidechatters, clickablenicknames, nocache_old) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);'); 4020 */ 4021 4022 //MODIFICATION for clickable nicknames 4023 /* REMOVE LATER 4024 $stmt->execute([$reg['nickname'], $reg['passhash'], $reg['status'], $reg['refresh'], $reg['bgcolour'], $U['nickname'], $reg['timestamps'], $reg['embed'], $reg['style'], $reg['incognito'], $reg['nocache'], $reg['tz'], $reg['eninbox'], $reg['sortupdown'], $reg['hidechatters'], $reg['clickablenicknames'], $reg['nocache_old']]); 4025 */ 4026 $stmt->execute([$reg['nickname'], $reg['passhash'], $reg['status'], $reg['refresh'], $reg['bgcolour'], $U['nickname'], $reg['timestamps'], $reg['embed'], $reg['style'], $reg['incognito'], $reg['nocache'], $reg['tz'], $reg['eninbox'], $reg['sortupdown'], $reg['hidechatters'], $reg['nocache_old']]); 4027 if ($reg['status'] == 3) { 4028 //MODIFICATION stlye_this_clickable instead of style_this 4029 add_system_message(sprintf(get_setting('msgmemreg'), style_this_clickable(htmlspecialchars($reg['nickname']), $reg['style']))); 4030 } else { 4031 //MODIFICATION stlye_this_clickable instead of style_this 4032 add_system_message(sprintf(get_setting('msgsureg'), style_this_clickable(htmlspecialchars($reg['nickname']), $reg['style']))); 4033 } 4034 return sprintf($I['successreg'], style_this(htmlspecialchars($reg['nickname']), $reg['style'])); 4035 } 4036 4037 function register_new($nick, $pass) 4038 { 4039 global $I, $U, $db; 4040 $nick = preg_replace('/\s/', '', $nick); 4041 if (empty($nick)) { 4042 return ''; 4043 } 4044 $stmt = $db->prepare('SELECT null FROM ' . PREFIX . 'sessions WHERE nickname=?'); 4045 $stmt->execute([$nick]); 4046 if ($stmt->fetch(PDO::FETCH_NUM)) { 4047 return sprintf($I['cantreg'], htmlspecialchars($nick)); 4048 } 4049 if (!valid_nick($nick)) { 4050 return sprintf($I['invalnick'], get_setting('maxname'), get_setting('nickregex')); 4051 } 4052 if (!valid_pass($pass)) { 4053 return sprintf($I['invalpass'], get_setting('minpass'), get_setting('passregex')); 4054 } 4055 $stmt = $db->prepare('SELECT null FROM ' . PREFIX . 'members WHERE nickname=?'); 4056 $stmt->execute([$nick]); 4057 if ($stmt->fetch(PDO::FETCH_NUM)) { 4058 return sprintf($I['alreadyreged'], htmlspecialchars($nick)); 4059 } 4060 4061 $reg = [ 4062 'nickname' => $nick, 4063 'passhash' => password_hash($pass, PASSWORD_DEFAULT), 4064 //Modification Register new Applicant 4065 'status' => (get_setting('suguests') ? 2 : 3), 4066 4067 'refresh' => get_setting('defaultrefresh'), 4068 'bgcolour' => get_setting('colbg'), 4069 'regedby' => $U['nickname'], 4070 'timestamps' => get_setting('timestamps'), 4071 'style' => 'color:#' . get_setting('coltxt') . ';', 4072 'embed' => 1, 4073 'incognito' => 0, 4074 'nocache' => 0, 4075 'nocache_old' => 1, 4076 'tz' => get_setting('defaulttz'), 4077 'eninbox' => 0, 4078 'sortupdown' => get_setting('sortupdown'), 4079 'hidechatters' => get_setting('hidechatters'), 4080 4081 //MODIFICATION clickable nicknames 4082 /* REMOVE LATER 4083 'clickablenicknames' =>0, 4084 */ 4085 ]; 4086 /*REMOVE LATER 4087 $stmt=$db->prepare('INSERT INTO ' . PREFIX . 'members (nickname, passhash, status, refresh, bgcolour, regedby, timestamps, style, embed, incognito, nocache, tz, eninbox, sortupdown, hidechatters, clickablenicknames, nocache_old) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);'); 4088 */ 4089 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'members (nickname, passhash, status, refresh, bgcolour, regedby, timestamps, style, embed, incognito, nocache, tz, eninbox, sortupdown, hidechatters, nocache_old) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);'); 4090 $stmt->execute([$reg['nickname'], $reg['passhash'], $reg['status'], $reg['refresh'], $reg['bgcolour'], $reg['regedby'], $reg['timestamps'], $reg['style'], $reg['embed'], $reg['incognito'], $reg['nocache'], $reg['tz'], $reg['eninbox'], $reg['sortupdown'], $reg['hidechatters'], $reg['nocache_old']]); 4091 return sprintf($I['successreg'], htmlspecialchars($reg['nickname'])); 4092 } 4093 4094 function change_status($nick, $status) 4095 { 4096 global $I, $U, $db; 4097 if (empty($nick)) { 4098 return ''; 4099 } elseif ($U['status'] <= $status || !preg_match('/^[023567\-]$/', $status)) { 4100 return sprintf($I['cantchgstat'], htmlspecialchars($nick)); 4101 } 4102 $stmt = $db->prepare('SELECT incognito, style FROM ' . PREFIX . 'members WHERE nickname=? AND status<?;'); 4103 $stmt->execute([$nick, $U['status']]); 4104 if (!$old = $stmt->fetch(PDO::FETCH_NUM)) { 4105 return sprintf($I['cantchgstat'], htmlspecialchars($nick)); 4106 } 4107 if ($_REQUEST['set'] === '-') { 4108 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'members WHERE nickname=?;'); 4109 $stmt->execute([$nick]); 4110 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET status=1, incognito=0 WHERE nickname=?;'); 4111 $stmt->execute([$nick]); 4112 return sprintf($I['succdel'], style_this(htmlspecialchars($nick), $old[1])); 4113 } else { 4114 if ($status < 5) { 4115 $old[0] = 0; 4116 } 4117 $stmt = $db->prepare('UPDATE ' . PREFIX . 'members SET status=?, incognito=? WHERE nickname=?;'); 4118 $stmt->execute([$status, $old[0], $nick]); 4119 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET status=?, incognito=? WHERE nickname=?;'); 4120 $stmt->execute([$status, $old[0], $nick]); 4121 return sprintf($I['succchg'], style_this(htmlspecialchars($nick), $old[1])); 4122 } 4123 } 4124 4125 function passreset($nick, $pass) 4126 { 4127 global $I, $U, $db; 4128 if (empty($nick)) { 4129 return ''; 4130 } 4131 $stmt = $db->prepare('SELECT null FROM ' . PREFIX . 'members WHERE nickname=? AND status<?;'); 4132 $stmt->execute([$nick, $U['status']]); 4133 if ($stmt->fetch(PDO::FETCH_ASSOC)) { 4134 $passhash = password_hash($pass, PASSWORD_DEFAULT); 4135 $stmt = $db->prepare('UPDATE ' . PREFIX . 'members SET passhash=? WHERE nickname=?;'); 4136 $stmt->execute([$passhash, $nick]); 4137 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET passhash=? WHERE nickname=?;'); 4138 $stmt->execute([$passhash, $nick]); 4139 return sprintf($I['succpassreset'], htmlspecialchars($nick)); 4140 } else { 4141 return sprintf($I['cantresetpass'], htmlspecialchars($nick)); 4142 } 4143 } 4144 4145 function amend_profile() 4146 { 4147 global $U; 4148 if (isset($_REQUEST['refresh'])) { 4149 $U['refresh'] = $_REQUEST['refresh']; 4150 } 4151 if ($U['refresh'] < 5) { 4152 $U['refresh'] = 5; 4153 } elseif ($U['refresh'] > 150) { 4154 $U['refresh'] = 150; 4155 } 4156 if (preg_match('/^#([a-f0-9]{6})$/i', $_REQUEST['colour'], $match)) { 4157 $colour = $match[1]; 4158 } else { 4159 preg_match('/#([0-9a-f]{6})/i', $U['style'], $matches); 4160 $colour = $matches[1]; 4161 } 4162 if (preg_match('/^#([a-f0-9]{6})$/i', $_REQUEST['bgcolour'], $match)) { 4163 $U['bgcolour'] = $match[1]; 4164 } 4165 $U['style'] = "color:#$colour;"; 4166 if ($U['status'] >= 3) { 4167 $F = load_fonts(); 4168 if (isset($F[$_REQUEST['font']])) { 4169 $U['style'] .= $F[$_REQUEST['font']]; 4170 } 4171 if (isset($_REQUEST['small'])) { 4172 $U['style'] .= 'font-size:smaller;'; 4173 } 4174 if (isset($_REQUEST['italic'])) { 4175 $U['style'] .= 'font-style:italic;'; 4176 } 4177 if (isset($_REQUEST['bold'])) { 4178 $U['style'] .= 'font-weight:bold;'; 4179 } 4180 } 4181 if ($U['status'] >= 5 && isset($_REQUEST['incognito']) && get_setting('incognito')) { 4182 $U['incognito'] = 1; 4183 } else { 4184 $U['incognito'] = 0; 4185 } 4186 if (isset($_REQUEST['tz'])) { 4187 $tzs = timezone_identifiers_list(); 4188 if (in_array($_REQUEST['tz'], $tzs)) { 4189 $U['tz'] = $_REQUEST['tz']; 4190 } 4191 } 4192 4193 //MODIFICATION for clicable nicknames setting 4194 /* REMOVE LATER 4195 $clickablelinks_allowedvalues = array(0, 1, 2); 4196 if(isset($_REQUEST['clickablenicknames']) && in_array($_REQUEST['clickablenicknames'], $clickablelinks_allowedvalues)){ 4197 $U['clickablenicknames'] = (int) $_REQUEST['clickablenicknames']; 4198 } 4199 */ 4200 4201 if (isset($_REQUEST['eninbox']) && $_REQUEST['eninbox'] >= 0 && $_REQUEST['eninbox'] <= 5) { 4202 $U['eninbox'] = $_REQUEST['eninbox']; 4203 } 4204 $bool_settings = ['timestamps', 'embed', 'nocache', 'sortupdown', 'hidechatters']; 4205 foreach ($bool_settings as $setting) { 4206 if (isset($_REQUEST[$setting])) { 4207 $U[$setting] = 1; 4208 } else { 4209 $U[$setting] = 0; 4210 } 4211 } 4212 } 4213 4214 function save_profile() 4215 { 4216 global $I, $U, $db; 4217 amend_profile(); 4218 //MODIFICATION for clickable nicknames setting 4219 /* REMOVE LATER 4220 $stmt=$db->prepare('UPDATE ' . PREFIX . 'sessions SET refresh=?, style=?, bgcolour=?, timestamps=?, embed=?, incognito=?, nocache=?, tz=?, eninbox=?, sortupdown=?, hidechatters=?, clickablenicknames=? WHERE session=?;'); 4221 */ 4222 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET refresh=?, style=?, bgcolour=?, timestamps=?, embed=?, incognito=?, nocache=?, tz=?, eninbox=?, sortupdown=?, hidechatters=? WHERE session=?;'); 4223 4224 //MODIFICATION for clickable nicknames (clickablenicknames) 4225 /* REMOVE LATER 4226 $stmt->execute([$U['refresh'], $U['style'], $U['bgcolour'], $U['timestamps'], $U['embed'], $U['incognito'], $U['nocache'], $U['tz'], $U['eninbox'], $U['sortupdown'], $U['hidechatters'], $U['clickablenicknames'], $U['session']]); 4227 */ 4228 $stmt->execute([$U['refresh'], $U['style'], $U['bgcolour'], $U['timestamps'], $U['embed'], $U['incognito'], $U['nocache'], $U['tz'], $U['eninbox'], $U['sortupdown'], $U['hidechatters'], $U['session']]); 4229 4230 if ($U['status'] >= 2) { 4231 /* REMOVE LATER 4232 $stmt=$db->prepare('UPDATE ' . PREFIX . 'members SET refresh=?, bgcolour=?, timestamps=?, embed=?, incognito=?, style=?, nocache=?, tz=?, eninbox=?, sortupdown=?, hidechatters=?, clickablenicknames=? WHERE nickname=?;'); 4233 $stmt->execute([$U['refresh'], $U['bgcolour'], $U['timestamps'], $U['embed'], $U['incognito'], $U['style'], $U['nocache'], $U['tz'], $U['eninbox'], $U['sortupdown'], $U['hidechatters'], $U['clickablenicknames'], $U['nickname']]); 4234 */ 4235 $stmt = $db->prepare('UPDATE ' . PREFIX . 'members SET refresh=?, bgcolour=?, timestamps=?, embed=?, incognito=?, style=?, nocache=?, tz=?, eninbox=?, sortupdown=?, hidechatters=? WHERE nickname=?;'); 4236 $stmt->execute([$U['refresh'], $U['bgcolour'], $U['timestamps'], $U['embed'], $U['incognito'], $U['style'], $U['nocache'], $U['tz'], $U['eninbox'], $U['sortupdown'], $U['hidechatters'], $U['nickname']]); 4237 } 4238 if (!empty($_REQUEST['unignore'])) { 4239 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'ignored WHERE ign=? AND ignby=?;'); 4240 $stmt->execute([$_REQUEST['unignore'], $U['nickname']]); 4241 } 4242 if (!empty($_REQUEST['ignore'])) { 4243 $stmt = $db->prepare('SELECT null FROM ' . PREFIX . 'messages WHERE poster=? AND poster NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=?);'); 4244 $stmt->execute([$_REQUEST['ignore'], $U['nickname']]); 4245 if ($U['nickname'] !== $_REQUEST['ignore'] && $stmt->fetch(PDO::FETCH_NUM)) { 4246 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'ignored (ign, ignby) VALUES (?, ?);'); 4247 $stmt->execute([$_REQUEST['ignore'], $U['nickname']]); 4248 } 4249 } 4250 if ($U['status'] > 1 && !empty($_REQUEST['newpass'])) { 4251 if (!valid_pass($_REQUEST['newpass'])) { 4252 return sprintf($I['invalpass'], get_setting('minpass'), get_setting('passregex')); 4253 } 4254 if (!isset($_REQUEST['oldpass'])) { 4255 $_REQUEST['oldpass'] = ''; 4256 } 4257 if (!isset($_REQUEST['confirmpass'])) { 4258 $_REQUEST['confirmpass'] = ''; 4259 } 4260 if ($_REQUEST['newpass'] !== $_REQUEST['confirmpass']) { 4261 return $I['noconfirm']; 4262 } else { 4263 $U['newhash'] = password_hash($_REQUEST['newpass'], PASSWORD_DEFAULT); 4264 } 4265 if (!password_verify($_REQUEST['oldpass'], $U['passhash'])) { 4266 return $I['wrongpass']; 4267 } 4268 $U['passhash'] = $U['newhash']; 4269 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET passhash=? WHERE session=?;'); 4270 $stmt->execute([$U['passhash'], $U['session']]); 4271 $stmt = $db->prepare('UPDATE ' . PREFIX . 'members SET passhash=? WHERE nickname=?;'); 4272 $stmt->execute([$U['passhash'], $U['nickname']]); 4273 } 4274 if ($U['status'] > 1 && !empty($_REQUEST['newnickname'])) { 4275 $msg = set_new_nickname(); 4276 if ($msg !== '') { 4277 return $msg; 4278 } 4279 } 4280 return $I['succprofile']; 4281 } 4282 4283 function set_new_nickname() 4284 { 4285 global $I, $U, $db; 4286 $_REQUEST['newnickname'] = preg_replace('/\s/', '', $_REQUEST['newnickname']); 4287 if (!valid_nick($_REQUEST['newnickname'])) { 4288 return sprintf($I['invalnick'], get_setting('maxname'), get_setting('nickregex')); 4289 } 4290 $stmt = $db->prepare('SELECT id FROM ' . PREFIX . 'sessions WHERE nickname=? UNION SELECT id FROM ' . PREFIX . 'members WHERE nickname=?;'); 4291 $stmt->execute([$_REQUEST['newnickname'], $_REQUEST['newnickname']]); 4292 if ($stmt->fetch(PDO::FETCH_NUM)) { 4293 return $I['nicknametaken']; 4294 } else { 4295 $stmt = $db->prepare('UPDATE ' . PREFIX . 'members SET nickname=? WHERE nickname=?;'); 4296 $stmt->execute([$_REQUEST['newnickname'], $U['nickname']]); 4297 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET nickname=? WHERE nickname=?;'); 4298 $stmt->execute([$_REQUEST['newnickname'], $U['nickname']]); 4299 $stmt = $db->prepare('UPDATE ' . PREFIX . 'messages SET poster=? WHERE poster=?;'); 4300 $stmt->execute([$_REQUEST['newnickname'], $U['nickname']]); 4301 $stmt = $db->prepare('UPDATE ' . PREFIX . 'messages SET recipient=? WHERE recipient=?;'); 4302 $stmt->execute([$_REQUEST['newnickname'], $U['nickname']]); 4303 $stmt = $db->prepare('UPDATE ' . PREFIX . 'ignored SET ignby=? WHERE ignby=?;'); 4304 $stmt->execute([$_REQUEST['newnickname'], $U['nickname']]); 4305 $stmt = $db->prepare('UPDATE ' . PREFIX . 'ignored SET ign=? WHERE ign=?;'); 4306 $stmt->execute([$_REQUEST['newnickname'], $U['nickname']]); 4307 $stmt = $db->prepare('UPDATE ' . PREFIX . 'inbox SET poster=? WHERE poster=?;'); 4308 $stmt->execute([$_REQUEST['newnickname'], $U['nickname']]); 4309 $stmt = $db->prepare('UPDATE ' . PREFIX . 'notes SET editedby=? WHERE editedby=?;'); 4310 $stmt->execute([$_REQUEST['newnickname'], $U['nickname']]); 4311 $U['nickname'] = $_REQUEST['newnickname']; 4312 } 4313 return ''; 4314 } 4315 4316 //sets default settings for guests 4317 function add_user_defaults($password) 4318 { 4319 global $U; 4320 $U['refresh'] = get_setting('defaultrefresh'); 4321 $U['bgcolour'] = get_setting('colbg'); 4322 if (!isset($_REQUEST['colour']) || !preg_match('/^[a-f0-9]{6}$/i', $_REQUEST['colour']) || abs(greyval($_REQUEST['colour']) - greyval(get_setting('colbg'))) < 75) { 4323 do { 4324 $colour = sprintf('%06X', mt_rand(0, 16581375)); 4325 } while (abs(greyval($colour) - greyval(get_setting('colbg'))) < 75); 4326 } else { 4327 $colour = $_REQUEST['colour']; 4328 } 4329 $U['style'] = "color:#$colour;"; 4330 $U['timestamps'] = get_setting('timestamps'); 4331 $U['embed'] = 1; 4332 $U['incognito'] = 0; 4333 $U['status'] = 1; 4334 $U['nocache'] = get_setting('sortupdown'); 4335 if ($U['nocache']) { 4336 $U['nocache_old'] = 0; 4337 } else { 4338 $U['nocache_old'] = 1; 4339 } 4340 $U['tz'] = get_setting('defaulttz'); 4341 $U['eninbox'] = 1; 4342 $U['sortupdown'] = get_setting('sortupdown'); 4343 $U['hidechatters'] = get_setting('hidechatters'); 4344 $U['passhash'] = password_hash($password, PASSWORD_DEFAULT); 4345 $U['entry'] = $U['lastpost'] = time(); 4346 4347 //MODIFICATION for clickable nicknames 4348 /* REMOVE LATER 4349 $U['clickablenicknames']=0; 4350 */ 4351 } 4352 4353 // message handling 4354 4355 function validate_input() 4356 { 4357 //global $U, $db; 4358 global $U, $db, $language; 4359 4360 $inbox = false; 4361 $maxmessage = get_setting('maxmessage'); 4362 $message = mb_substr($_REQUEST['message'], 0, $maxmessage); 4363 $rejected = mb_substr($_REQUEST['message'], $maxmessage); 4364 if ($U['postid'] === $_REQUEST['postid']) { // ignore double post=reload from browser or proxy 4365 $message = ''; 4366 } elseif ((time() - $U['lastpost']) <= 1) { // time between posts too short, reject! 4367 $rejected = $_REQUEST['message']; 4368 $message = ''; 4369 } 4370 if (!empty($rejected)) { 4371 $rejected = trim($rejected); 4372 $rejected = htmlspecialchars($rejected); 4373 } 4374 $message = htmlspecialchars($message); 4375 $message = preg_replace("/(\r?\n|\r\n?)/u", '<br>', $message); 4376 if (isset($_REQUEST['multi'])) { 4377 $message = preg_replace('/\s*<br>/u', '<br>', $message); 4378 $message = preg_replace('/<br>(<br>)+/u', '<br><br>', $message); 4379 $message = preg_replace('/<br><br>\s*$/u', '<br>', $message); 4380 $message = preg_replace('/^<br>\s*$/u', '', $message); 4381 } else { 4382 $message = str_replace('<br>', ' ', $message); 4383 } 4384 $message = trim($message); 4385 $message = preg_replace('/\s+/u', ' ', $message); 4386 $recipient = ''; 4387 4388 //This ist the the place where the username is added to $displaysend (and later to the message). 4389 4390 /* 4391 'r @' 4392 's 17' 4393 's 24' 4394 's 31' 4395 's 48' 4396 's 56' 4397 's 65' 4398 */ 4399 4400 if ($_REQUEST['sendto'] === 's 17') { 4401 $poststatus = 1; 4402 //MODIFICATION for clickablenicknames stlye_this_clickable instead of style_this 4403 $displaysend = sprintf(get_setting('msgsendall'), style_this_clickable(htmlspecialchars($U['nickname']), $U['style'])); 4404 //MODIFICATION 3 lines added for the RG channel 4405 } elseif ($_REQUEST['sendto'] === 's 24' && $U['status'] >= 2) { 4406 $poststatus = 2; 4407 //MODIFICATION for clickablenicknames stlye_this_clickable instead of style_this 4408 $displaysend = sprintf('[RG] %s - ', style_this_clickable(htmlspecialchars($U['nickname']), $U['style'])); 4409 } elseif ($_REQUEST['sendto'] === 's 31' && $U['status'] >= 3) { 4410 $poststatus = 3; 4411 //MODIFICATION for clickablenicknames stlye_this_clickable instead of style_this 4412 $displaysend = sprintf(get_setting('msgsendmem'), style_this_clickable(htmlspecialchars($U['nickname']), $U['style'])); 4413 } elseif ($_REQUEST['sendto'] === 's 48' && $U['status'] >= 5) { 4414 $poststatus = 5; 4415 //MODIFICATION for clickablenicknames stlye_this_clickable instead of style_this 4416 $displaysend = sprintf(get_setting('msgsendmod'), style_this_clickable(htmlspecialchars($U['nickname']), $U['style'])); 4417 // Modifcation added all rooms channel 4418 } elseif ($_REQUEST['sendto'] === 'r @' && $U['status'] >= 5) { 4419 $poststatus = 1; 4420 $displaysend = sprintf('[All Rooms] %s - ', style_this_clickable(htmlspecialchars($U['nickname']), $U['style'])); 4421 //MODIFICATION 1 line replaced for the new SMod channel ([SMods] in front of the line. 4422 } elseif ($_REQUEST['sendto'] === 's 56' && $U['status'] >= 6) { 4423 $poststatus = 6; 4424 //MODIFICATION for clickablenicknames stlye_this_clickable instead of style_this 4425 $displaysend = sprintf('[SMods] %s - ', style_this_clickable(htmlspecialchars($U['nickname']), $U['style'])); 4426 4427 //MODIFICATION 3 lines added for the new admin channel (admins only, no smods) 4428 } elseif ($_REQUEST['sendto'] === 's 65' && $U['status'] >= 7) { 4429 $poststatus = 7; 4430 //MODIFICATION for clickablenicknames stlye_this_clickable instead of style_this 4431 $displaysend = sprintf(get_setting('msgsendadm'), style_this_clickable(htmlspecialchars($U['nickname']), $U['style'])); 4432 } else { // known nick in room? 4433 if (get_setting('disablepm')) { 4434 //PMs disabled 4435 return; 4436 } 4437 $stmt = $db->prepare('SELECT null FROM ' . PREFIX . 'ignored WHERE (ignby=? AND ign=?) OR (ign=? AND ignby=?);'); 4438 $stmt->execute([$_REQUEST['sendto'], $U['nickname'], $_REQUEST['sendto'], $U['nickname']]); 4439 if ($stmt->fetch(PDO::FETCH_NUM)) { 4440 //ignored 4441 return; 4442 } 4443 $tmp = false; 4444 $stmt = $db->prepare('SELECT s.style, 0 AS inbox FROM ' . PREFIX . 'sessions AS s LEFT JOIN ' . PREFIX . 'members AS m ON (m.nickname=s.nickname) WHERE s.nickname=? AND (s.incognito=0 OR (m.eninbox!=0 AND m.eninbox<=?));'); 4445 $stmt->execute([$_REQUEST['sendto'], $U['status']]); 4446 if (!$tmp = $stmt->fetch(PDO::FETCH_ASSOC)) { 4447 $stmt = $db->prepare('SELECT style, 1 AS inbox FROM ' . PREFIX . 'members WHERE nickname=? AND eninbox!=0 AND eninbox<=?;'); 4448 $stmt->execute([$_REQUEST['sendto'], $U['status']]); 4449 if (!$tmp = $stmt->fetch(PDO::FETCH_ASSOC)) { 4450 //nickname left or disabled offline inbox for us 4451 return; 4452 } 4453 } 4454 $recipient = $_REQUEST['sendto']; 4455 $poststatus = 9; 4456 4457 $displaysend = sprintf(get_setting('msgsendprv'), style_this_clickable(htmlspecialchars($U['nickname']), $U['style']), style_this_clickable(htmlspecialchars($recipient), $tmp['style'])); 4458 $inbox = $tmp['inbox']; 4459 } 4460 if ($poststatus !== 9 && preg_match('~^/me~iu', $message)) { 4461 $displaysend = style_this(htmlspecialchars("$U[nickname] "), $U['style']); 4462 $message = preg_replace("~^/me\s?~iu", '', $message); 4463 } 4464 $message = apply_filter($message, $poststatus, $U['nickname']); 4465 $message = create_hotlinks($message); 4466 $message = apply_linkfilter($message); 4467 if (isset($_FILES['file']) && get_setting('enfileupload') > 0 && get_setting('enfileupload') <= $U['status']) { 4468 if ($_FILES['file']['error'] === UPLOAD_ERR_OK && $_FILES['file']['size'] <= (1024 * get_setting('maxuploadsize'))) { 4469 $hash = sha1_file($_FILES['file']['tmp_name']); 4470 $name = htmlspecialchars($_FILES['file']['name']); 4471 $message = sprintf(get_setting('msgattache'), "<a class=\"attachement\" href=\"?action=download&id=$hash\" target=\"_blank\">$name</a>", $message); 4472 } 4473 } 4474 if (add_message($message, $recipient, $U['nickname'], $U['status'], $poststatus, $displaysend, $U['style'])) { 4475 $U['lastpost'] = time(); 4476 $stmt = $db->prepare('UPDATE ' . PREFIX . 'sessions SET lastpost=?, postid=? WHERE session=?;'); 4477 $stmt->execute([$U['lastpost'], $_REQUEST['postid'], $U['session']]); 4478 $stmt = $db->prepare('SELECT id FROM ' . PREFIX . 'messages WHERE poster=? ORDER BY id DESC LIMIT 1;'); 4479 $stmt->execute([$U['nickname']]); 4480 $id = $stmt->fetch(PDO::FETCH_NUM); 4481 if ($inbox && $id) { 4482 $newmessage = [ 4483 'postdate' => time(), 4484 'poster' => $U['nickname'], 4485 'recipient' => $recipient, 4486 4487 'text' => "<span class=\"usermsg\">$displaysend" . style_this($message, $U['style']) . '</span>' 4488 ]; 4489 if (MSGENCRYPTED) { 4490 $newmessage['text'] = base64_encode(sodium_crypto_aead_aes256gcm_encrypt($newmessage['text'], '', AES_IV, ENCRYPTKEY)); 4491 } 4492 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'inbox (postdate, postid, poster, recipient, text) VALUES(?, ?, ?, ?, ?)'); 4493 $stmt->execute([$newmessage['postdate'], $id[0], $newmessage['poster'], $newmessage['recipient'], $newmessage['text']]); 4494 } 4495 if (isset($hash) && $id) { 4496 if (!empty($_FILES['file']['type']) && preg_match('~^[a-z0-9/\-\.\+]*$~i', $_FILES['file']['type'])) { 4497 $type = $_FILES['file']['type']; 4498 } else { 4499 $type = 'application/octet-stream'; 4500 } 4501 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'files (postid, hash, filename, type, data) VALUES (?, ?, ?, ?, ?);'); 4502 $stmt->execute([$id[0], $hash, str_replace('"', '\"', $_FILES['file']['name']), $type, base64_encode(file_get_contents($_FILES['file']['tmp_name']))]); 4503 unlink($_FILES['file']['tmp_name']); 4504 } 4505 } 4506 return $rejected; 4507 } 4508 4509 function apply_filter($message, $poststatus, $nickname) 4510 { 4511 global $I, $U; 4512 $message = str_replace('<br>', "\n", $message); 4513 $message = apply_mention($message); 4514 $filters = get_filters(); 4515 foreach ($filters as $filter) { 4516 //MODIFICATION line changed (! removed) 4517 if ($poststatus !== 9 || $filter['allowinpm']) { 4518 if ($filter['cs']) { 4519 $message = preg_replace("/$filter[match]/u", $filter['replace'], $message, -1, $count); 4520 } else { 4521 $message = preg_replace("/$filter[match]/iu", $filter['replace'], $message, -1, $count); 4522 } 4523 } 4524 if (isset($count) && $count > 0 && $filter['kick'] && ($U['status'] < 5 || get_setting('filtermodkick'))) { 4525 kick_chatter([$nickname], $filter['replace'], false); 4526 setcookie(COOKIENAME, false); 4527 $_REQUEST['session'] = ''; 4528 send_error("$I[kicked]<br>$filter[replace]"); 4529 } 4530 } 4531 $message = str_replace("\n", '<br>', $message); 4532 return $message; 4533 } 4534 4535 function apply_linkfilter($message) 4536 { 4537 $filters = get_linkfilters(); 4538 foreach ($filters as $filter) { 4539 $message = preg_replace_callback( 4540 "/<a href=\"([^\"]+)\" target=\"_blank\"( rel=\"noreferrer noopener\")?>(.*?(?=<\/a>))<\/a>/iu", 4541 function ($matched) use (&$filter) { 4542 return "<a href=\"$matched[1]\" target=\"_blank\"$matched[2]>" . preg_replace("/$filter[match]/iu", $filter['replace'], $matched[3]) . '</a>'; 4543 }, 4544 $message 4545 ); 4546 } 4547 $redirect = get_setting('redirect'); 4548 if (get_setting('imgembed')) { 4549 $message = preg_replace_callback( 4550 '/\[img\]\s?<a href="([^"]+)" target="_blank"( rel=\"noreferrer noopener\")?>(.*?(?=<\/a>))<\/a>/iu', 4551 function ($matched) { 4552 return str_ireplace('[/img]', '', "<br><a href=\"$matched[1]\" target=\"_blank\"$matched[2]><img src=\"$matched[1]\"></a><br>"); 4553 }, 4554 $message 4555 ); 4556 } 4557 if (empty($redirect)) { 4558 $redirect = "?action=redirect&url="; 4559 } 4560 if (get_setting('forceredirect')) { 4561 $message = preg_replace_callback( 4562 '/<a href="([^"]+)" target="_blank"( rel=\"noreferrer noopener\")?>(.*?(?=<\/a>))<\/a>/u', 4563 function ($matched) use ($redirect) { 4564 return "<a href=\"$redirect" . rawurlencode($matched[1]) . "\" target=\"_blank\"$matched[2]>$matched[3]</a>"; 4565 }, 4566 $message 4567 ); 4568 } elseif (preg_match_all('/<a href="([^"]+)" target="_blank"( rel=\"noreferrer noopener\")?>(.*?(?=<\/a>))<\/a>/u', $message, $matches)) { 4569 foreach ($matches[1] as $match) { 4570 if (!preg_match('~^http(s)?://~u', $match)) { 4571 $message = preg_replace_callback( 4572 '/<a href="(' . preg_quote($match, '/') . ')\" target=\"_blank\"( rel=\"noreferrer noopener\")?>(.*?(?=<\/a>))<\/a>/u', 4573 function ($matched) use ($redirect) { 4574 return "<a href=\"$redirect" . rawurlencode($matched[1]) . "\" target=\"_blank\"$matched[2]>$matched[3]</a>"; 4575 }, 4576 $message 4577 ); 4578 } 4579 } 4580 } 4581 return $message; 4582 } 4583 4584 function create_hotlinks($message) 4585 { 4586 //Make hotlinks for URLs, redirect through dereferrer script to prevent session leakage 4587 // 1. all explicit schemes with whatever xxx://yyyyyyy 4588 $message = preg_replace('~(^|[^\w"])(\w+://[^\s<>]+)~iu', "$1<<$2>>", $message); 4589 // 2. valid URLs without scheme: 4590 $message = preg_replace('~((?:[^\s<>]*:[^\s<>]*@)?[a-z0-9\-]+(?:\.[a-z0-9\-]+)+(?::\d*)?/[^\s<>]*)(?![^<>]*>)~iu', "<<$1>>", $message); // server/path given 4591 $message = preg_replace('~((?:[^\s<>]*:[^\s<>]*@)?[a-z0-9\-]+(?:\.[a-z0-9\-]+)+:\d+)(?![^<>]*>)~iu', "<<$1>>", $message); // server:port given 4592 $message = preg_replace('~([^\s<>]*:[^\s<>]*@[a-z0-9\-]+(?:\.[a-z0-9\-]+)+(?::\d+)?)(?![^<>]*>)~iu', "<<$1>>", $message); // au:th@server given 4593 // 3. likely servers without any hints but not filenames like *.rar zip exe etc. 4594 $message = preg_replace('~((?:[a-z0-9\-]+\.)*(?:[a-z2-7]{55}d|[a-z2-7]{16})\.onion)(?![^<>]*>)~iu', "<<$1>>", $message); // *.onion 4595 $message = preg_replace('~([a-z0-9\-]+(?:\.[a-z0-9\-]+)+(?:\.(?!rar|zip|exe|gz|7z|bat|doc)[a-z]{2,}))(?=[^a-z0-9\-\.]|$)(?![^<>]*>)~iu', "<<$1>>", $message); // xxx.yyy.zzz 4596 // Convert every <<....>> into proper links: 4597 $message = preg_replace_callback( 4598 '/<<([^<>]+)>>/u', 4599 function ($matches) { 4600 if (strpos($matches[1], '://') === false) { 4601 return "<a href=\"http://$matches[1]\" target=\"_blank\" rel=\"noreferrer noopener\">$matches[1]</a>"; 4602 } else { 4603 return "<a href=\"$matches[1]\" target=\"_blank\" rel=\"noreferrer noopener\">$matches[1]</a>"; 4604 } 4605 }, 4606 $message 4607 ); 4608 return $message; 4609 } 4610 4611 function apply_mention($message) 4612 { 4613 return preg_replace_callback('/\@([^\s]+)/iu', function ($matched) { 4614 global $db; 4615 $nick = htmlspecialchars_decode($matched[1]); 4616 $rest = ''; 4617 for ($i = 0; $i <= 3; ++$i) { 4618 //match case-sensitive present nicknames 4619 $stmt = $db->prepare('SELECT style FROM ' . PREFIX . 'sessions WHERE nickname=?;'); 4620 $stmt->execute([$nick]); 4621 if ($tmp = $stmt->fetch(PDO::FETCH_NUM)) { 4622 return style_this(htmlspecialchars("@$nick"), $tmp[0]) . $rest; 4623 } 4624 //match case-insensitive present nicknames 4625 $stmt = $db->prepare('SELECT style FROM ' . PREFIX . 'sessions WHERE LOWER(nickname)=LOWER(?);'); 4626 $stmt->execute([$nick]); 4627 if ($tmp = $stmt->fetch(PDO::FETCH_NUM)) { 4628 return style_this(htmlspecialchars("@$nick"), $tmp[0]) . $rest; 4629 } 4630 //match case-sensitive members 4631 $stmt = $db->prepare('SELECT style FROM ' . PREFIX . 'members WHERE nickname=?;'); 4632 $stmt->execute([$nick]); 4633 if ($tmp = $stmt->fetch(PDO::FETCH_NUM)) { 4634 return style_this(htmlspecialchars("@$nick"), $tmp[0]) . $rest; 4635 } 4636 //match case-insensitive members 4637 $stmt = $db->prepare('SELECT style FROM ' . PREFIX . 'members WHERE LOWER(nickname)=LOWER(?);'); 4638 $stmt->execute([$nick]); 4639 if ($tmp = $stmt->fetch(PDO::FETCH_NUM)) { 4640 return style_this(htmlspecialchars("@$nick"), $tmp[0]) . $rest; 4641 } 4642 if (strlen($nick) === 1) { 4643 break; 4644 } 4645 $rest = mb_substr($nick, -1) . $rest; 4646 $nick = mb_substr($nick, 0, -1); 4647 } 4648 return $matched[0]; 4649 }, $message); 4650 } 4651 4652 function add_message($message, $recipient, $poster, $delstatus, $poststatus, $displaysend, $style) 4653 { 4654 global $db, $U; 4655 if ($message === '') { 4656 return false; 4657 } 4658 //Modifications for chat rooms 4659 $roomid = $U['roomid']; 4660 if (isset($_REQUEST['sendto']) && $_REQUEST['sendto'] === 'r @' && $U['status'] >= 5) { 4661 $allrooms = 1; 4662 $roomid = null; 4663 } else { 4664 $allrooms = 0; 4665 } 4666 $newmessage = [ 4667 'postdate' => time(), 4668 'poststatus' => $poststatus, 4669 'poster' => $poster, 4670 'recipient' => $recipient, 4671 'text' => "<span class=\"usermsg\">$displaysend" . style_this($message, $style) . '</span>', 4672 'delstatus' => $delstatus, 4673 'roomid' => $roomid, 4674 'allrooms' => $allrooms 4675 ]; 4676 //Modifcation chat rooms 4677 if ($newmessage['roomid'] === NULL) { 4678 //prevent posting the same message twice, if no other message was posted in-between. 4679 $stmt = $db->prepare('SELECT id FROM ' . PREFIX . 'messages WHERE poststatus=? AND poster=? AND recipient=? AND text=? AND roomid IS NULL AND id IN (SELECT * FROM (SELECT id FROM ' . PREFIX . 'messages ORDER BY id DESC LIMIT 1) AS t);'); 4680 $stmt->execute([$newmessage['poststatus'], $newmessage['poster'], $newmessage['recipient'], $newmessage['text']]); 4681 } else { 4682 $stmt = $db->prepare('SELECT id FROM ' . PREFIX . 'messages WHERE poststatus=? AND poster=? AND recipient=? AND text=? AND roomid=? AND id IN (SELECT * FROM (SELECT id FROM ' . PREFIX . 'messages ORDER BY id DESC LIMIT 1) AS t);'); 4683 $stmt->execute([$newmessage['poststatus'], $newmessage['poster'], $newmessage['recipient'], $newmessage['text'], $newmessage['roomid']]); 4684 } 4685 if ($stmt->fetch(PDO::FETCH_NUM)) { 4686 return false; 4687 } 4688 write_message($newmessage); 4689 return true; 4690 } 4691 //Modification chat rooms 4692 function add_system_message($mes, $roomid = NULL) 4693 { 4694 if ($mes === '') { 4695 return; 4696 } 4697 $sysmessage = [ 4698 'postdate' => time(), 4699 'poststatus' => 1, 4700 'poster' => '', 4701 'recipient' => '', 4702 'text' => "<span class=\"sysmsg\">$mes</span>", 4703 'delstatus' => 4, 4704 'roomid' => $roomid, 4705 'allrooms' => 0 4706 ]; 4707 write_message($sysmessage); 4708 } 4709 4710 function write_message($message) 4711 { 4712 global $db; 4713 if (MSGENCRYPTED) { 4714 $message['text'] = base64_encode(sodium_crypto_aead_aes256gcm_encrypt($message['text'], '', AES_IV, ENCRYPTKEY)); 4715 } 4716 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'messages (postdate, poststatus, poster, recipient, text, delstatus, roomid, allrooms) VALUES (?, ?, ?, ?, ?, ?, ?, ?);'); 4717 $stmt->execute([$message['postdate'], $message['poststatus'], $message['poster'], $message['recipient'], $message['text'], $message['delstatus'], $message['roomid'], $message['allrooms']]); 4718 if ($message['poststatus'] < 9 && get_setting('sendmail')) { 4719 $subject = 'New Chat message'; 4720 $headers = 'From: ' . get_setting('mailsender') . "\r\nX-Mailer: PHP/" . phpversion() . "\r\nContent-Type: text/html; charset=UTF-8\r\n"; 4721 $body = '<html><body style="background-color:#' . get_setting('colbg') . ';color:#' . get_setting('coltxt') . ";\">$message[text]</body></html>"; 4722 mail(get_setting('mailreceiver'), $subject, $body, $headers); 4723 } 4724 } 4725 4726 //Modified 4727 function clean_chat() 4728 { 4729 global $db; 4730 $db->query('DELETE FROM ' . PREFIX . 'messages;'); 4731 add_system_message(sprintf(get_setting('msgclean'), get_setting('chatname'))); 4732 } 4733 //Modified 4734 function clean_room() 4735 { 4736 global $db, $U; 4737 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'messages where roomid=?;'); 4738 $stmt->execute([$U['roomid']]); 4739 } 4740 4741 function clean_selected($status, $nick) 4742 { 4743 global $db; 4744 if (isset($_REQUEST['mid'])) { 4745 4746 //Modification modsdeladminmsg - moderators can delete admin messages (but he can only delete the messages he is able to read.) 4747 if ((get_setting('modsdeladminmsg') == 1) && ($status >= 5)) { 4748 4749 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'messages WHERE id=? AND (poster=? OR recipient=? OR (poststatus<= ' . $status . ' AND delstatus<9));'); 4750 foreach ($_REQUEST['mid'] as $mid) { 4751 $stmt->execute([$mid, $nick, $nick]); 4752 } 4753 } else { 4754 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'messages WHERE id=? AND (poster=? OR recipient=? OR (poststatus<? AND delstatus<?));'); 4755 foreach ($_REQUEST['mid'] as $mid) { 4756 $stmt->execute([$mid, $nick, $nick, $status, $status]); 4757 } 4758 } 4759 } 4760 } 4761 4762 function clean_inbox_selected() 4763 { 4764 global $U, $db; 4765 if (isset($_REQUEST['mid'])) { 4766 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'inbox WHERE id=? AND recipient=?;'); 4767 foreach ($_REQUEST['mid'] as $mid) { 4768 $stmt->execute([$mid, $U['nickname']]); 4769 } 4770 } 4771 } 4772 4773 function del_all_messages($nick, $entry) 4774 { 4775 global $db; 4776 if ($nick == '') { 4777 return; 4778 } 4779 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'messages WHERE poster=? AND postdate>=?;'); 4780 $stmt->execute([$nick, $entry]); 4781 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'inbox WHERE poster=? AND postdate>=?;'); 4782 $stmt->execute([$nick, $entry]); 4783 } 4784 4785 function del_last_message() 4786 { 4787 4788 global $U, $db; 4789 if ($U['status'] > 1) { 4790 $entry = 0; 4791 } else { 4792 $entry = $U['entry']; 4793 } 4794 $stmt = $db->prepare('SELECT id FROM ' . PREFIX . 'messages WHERE poster=? AND postdate>=? ORDER BY id DESC LIMIT 1;'); 4795 $stmt->execute([$U['nickname'], $entry]); 4796 if ($id = $stmt->fetch(PDO::FETCH_NUM)) { 4797 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'messages WHERE id=?;'); 4798 $stmt->execute($id); 4799 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'inbox WHERE postid=?;'); 4800 $stmt->execute($id); 4801 } 4802 } 4803 4804 function print_messages($delstatus = 0, $modroom = 0) 4805 { 4806 //line changed 4807 global $U, $I, $db, $language; 4808 4809 4810 $dateformat = get_setting('dateformat'); 4811 if (!$U['embed'] && get_setting('imgembed')) { 4812 $removeEmbed = true; 4813 } else { 4814 $removeEmbed = false; 4815 } 4816 if ($U['timestamps'] && !empty($dateformat)) { 4817 $timestamps = true; 4818 } else { 4819 $timestamps = false; 4820 } 4821 if ($U['sortupdown']) { 4822 $direction = 'ASC'; 4823 } else { 4824 $direction = 'DESC'; 4825 } 4826 if ($U['status'] > 1) { 4827 $entry = 0; 4828 } else { 4829 $entry = $U['entry']; 4830 } 4831 if (isset($_REQUEST['modroom']) && $_REQUEST['modroom'] && $U['status'] >= 5) { 4832 $modroom = 1; 4833 } else { 4834 $modroom = 0; 4835 } 4836 4837 //MODIFCATION chat rooms to only show messages of the all rooms 4838 4839 //MODIFICATION DEL-BUTTONS some lines added to enable delete buttons in front of messages for mods and above. 4840 // look at function send_choose_messages for better understanding 4841 $modmode = false; 4842 4843 4844 4845 4846 4847 //modmode (DEL-Buttons) for mods. and for members (according to the memdel setting (always OR if no mod is present and if memkick setting enabled.) 4848 $memdel = (int)get_setting('memdel'); 4849 if (($delstatus === 0 && $U['status'] >= 5) || ($U['status'] >= 3 && $memdel == 2) || ($U['status'] >= 3 && get_count_mods() == 0 && $memdel == 1)) { 4850 $modmode = true; 4851 $delstatus = $U['status']; 4852 //debug 4853 //echo "modmode active"; 4854 } 4855 4856 4857 //Modification for visibility of channels in all roooms 4858 $channelvisinroom = (int) get_setting('channelvisinroom'); 4859 if ($channelvisinroom == 0) { 4860 $channelvisinroom = 2; 4861 } 4862 4863 4864 echo '<div id="messages">'; 4865 4866 if ($modmode === true) { 4867 echo form('admin_clean_message', 'clean'); 4868 echo hidden('what', 'selected'); 4869 echo hidden('modroom', $modroom); // so that deleting a message does not cause exiting modroom 4870 4871 $stmt = $db->prepare('SELECT id, postdate, text, poststatus, delstatus, poster, recipient, roomid, allrooms FROM ' . PREFIX . 'messages WHERE (poststatus<=? OR ' . 4872 '(poststatus=9 AND ( (poster=? AND recipient NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=?) ) OR recipient=?) AND postdate>=?)' . 4873 ') AND poster NOT IN (SELECT ign FROM ' . PREFIX . "ignored WHERE ignby=?) ORDER BY id $direction;"); 4874 $stmt->execute([$U['status'], $U['nickname'], $U['nickname'], $U['nickname'], $entry, $U['nickname']]); 4875 4876 4877 while ($message = $stmt->fetch(PDO::FETCH_ASSOC)) { 4878 4879 //Modification for chat rooms 4880 if ($message['poststatus'] < $channelvisinroom && $message['roomid'] !== $U['roomid'] && !$message['allrooms'] && !$modroom) { 4881 continue; 4882 } 4883 4884 //Modification for modrooms in chat rooms 4885 $roomname = ""; 4886 if ($modroom && !$message['allrooms']) { 4887 $roomname = 'Main Chat'; 4888 if ($message['roomid'] != null) { 4889 $stmt1 = $db->prepare('SELECT name FROM ' . PREFIX . 'rooms WHERE id=? AND access<=?'); 4890 $stmt1->execute([$message['roomid'], $U['status']]); 4891 if (!$name = $stmt1->fetch(PDO::FETCH_NUM)) { 4892 continue; 4893 } 4894 $roomname = $name[0]; 4895 } 4896 $roomname = '[' . $roomname . ']'; 4897 } 4898 4899 prepare_message_print($message, $removeEmbed); 4900 //MODIFICATION modsdeladminmsg (mods can delete admins messages) 4901 if (get_setting('modsdeladminmsg') == 1 && $U['status'] >= 5) { 4902 if (($message['poststatus'] <= $U['status'] && $message['delstatus'] < 9) || ($message['poster'] === $U['nickname'] || ($message['recipient'] === $U['nickname']) && $message['postdate'] >= $entry)) { 4903 echo "<div class=\"msg\"><button title = \"Delete message\" class = \"delbutton_inline_removable\" name=\"mid[]\" type=\"submit\" value=\"$message[id]\">DEL</button>"; 4904 } 4905 } elseif (($message['poststatus'] < $U['status'] && $message['delstatus'] < $U['status']) || ($message['poster'] === $U['nickname'] || ($message['recipient'] === $U['nickname']) && $message['postdate'] >= $entry)) { 4906 echo "<div class=\"msg\"><button title = \"Delete message\" class = \"delbutton_inline_removable\" name=\"mid[]\" type=\"submit\" value=\"$message[id]\">DEL</button>"; 4907 } else { 4908 //next line is for debug output (to check if permissions to delete messages are correct. test passed! (everything okay) 4909 //echo "<div class=\"msg\"><button class = \"delbutton_inline_unremovable\" name=\"mid[]\" type=\"submit\" value=\"$message[id]\">-----</button>"; 4910 echo "<div class=\"msg\">        "; 4911 } 4912 4913 4914 4915 //if((int)$U['clickablenicknames']>0){ //REMOVE LINE LATER 4916 if ((bool) get_setting('clickablenicknamesglobal')) { 4917 4918 $message_new = make_nicknames_clickable($message['text']); 4919 } else { 4920 4921 $message_new = $message['text']; 4922 } 4923 4924 if ($timestamps) { 4925 echo ' <small>' . date($dateformat, $message['postdate']) . ' - </small>'; 4926 } 4927 4928 if ($modroom) { 4929 echo "<span class=\"modroom\">$roomname</span>"; 4930 } 4931 echo " $message_new</div>"; 4932 } 4933 echo "</form>"; 4934 } elseif ($delstatus > 0) { 4935 //Modification modsdeladminmsg 4936 4937 if (get_setting('modsdeladminmsg') == 1) { 4938 $stmt = $db->prepare('SELECT postdate, id, poststatus, roomid, allrooms text FROM ' . PREFIX . 'messages WHERE ' . 4939 "(poststatus<=? AND delstatus<9) OR ((poster=? OR recipient=?) AND postdate>=?) ORDER BY id $direction;"); 4940 $stmt->execute([$U['status'], $U['nickname'], $U['nickname'], $entry]); 4941 while ($message = $stmt->fetch(PDO::FETCH_ASSOC)) { 4942 //Modification for chat rooms 4943 if ($message['poststatus'] < $channelvisinroom && $message['roomid'] !== $U['roomid'] && !$message['allrooms']) { 4944 continue; 4945 } 4946 4947 prepare_message_print($message, $removeEmbed); 4948 echo "<div class=\"msg\"><label><input type=\"checkbox\" name=\"mid[]\" value=\"$message[id]\">"; 4949 if ($timestamps) { 4950 echo ' <small>' . date($dateformat, $message['postdate']) . ' - </small>'; 4951 } 4952 echo " $message[text]</label></div>"; 4953 } 4954 } else { 4955 $stmt = $db->prepare('SELECT postdate, id, text, poststatus, roomid, allrooms FROM ' . PREFIX . 'messages WHERE ' . 4956 "(poststatus<? AND delstatus<?) OR ((poster=? OR recipient=?) AND postdate>=?) ORDER BY id $direction;"); 4957 $stmt->execute([$U['status'], $delstatus, $U['nickname'], $U['nickname'], $entry]); 4958 while ($message = $stmt->fetch(PDO::FETCH_ASSOC)) { 4959 //Modification for chat rooms 4960 if ($message['poststatus'] < $channelvisinroom && $message['roomid'] !== $U['roomid'] && !$message['allrooms']) { 4961 continue; 4962 } 4963 prepare_message_print($message, $removeEmbed); 4964 echo "<div class=\"msg\"><label><input type=\"checkbox\" name=\"mid[]\" value=\"$message[id]\">"; 4965 if ($timestamps) { 4966 echo ' <small>' . date($dateformat, $message['postdate']) . ' - </small>'; 4967 } 4968 echo " $message[text]</label></div>"; 4969 } 4970 } 4971 } else { 4972 $stmt = $db->prepare('SELECT id, postdate, text, roomid, allrooms, poststatus FROM ' . PREFIX . 'messages WHERE (poststatus<=? OR ' . 4973 '(poststatus=9 AND ( (poster=? AND recipient NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=?) ) OR recipient=?) AND postdate>=?)' . 4974 ') AND poster NOT IN (SELECT ign FROM ' . PREFIX . "ignored WHERE ignby=?) ORDER BY id $direction;"); 4975 $stmt->execute([$U['status'], $U['nickname'], $U['nickname'], $U['nickname'], $entry, $U['nickname']]); 4976 while ($message = $stmt->fetch(PDO::FETCH_ASSOC)) { 4977 //Modification for chat rooms 4978 if ($message['poststatus'] < $channelvisinroom && $message['roomid'] !== $U['roomid'] && !$message['allrooms']) { 4979 continue; 4980 } 4981 4982 prepare_message_print($message, $removeEmbed); 4983 echo '<div class="msg">'; 4984 4985 //MODIFICATION to make nicknames clickable //REMOVE LINE LATER 4986 //if((int)$U['clickablenicknames']>0){//REMOVE LINE LATER 4987 //MODIFICATION to make nicknames clickable (global setting 4988 if ((bool) get_setting('clickablenicknamesglobal')) { 4989 $message_new = make_nicknames_clickable($message['text']); 4990 } else { 4991 4992 $message_new = $message['text']; 4993 } 4994 4995 4996 4997 if ($timestamps) { 4998 echo '<small>' . date($dateformat, $message['postdate']) . ' - </small>'; 4999 } 5000 echo "$message_new</div>"; 5001 } 5002 } 5003 echo '</div>'; 5004 } 5005 5006 //MODIFICATION for clickable nicknames 5007 function make_nicknames_clickable($message) 5008 { 5009 5010 global $U, $language; 5011 $nc = substr(time(), -6); 5012 5013 $channel = ""; 5014 $sender = ""; 5015 $recipient = ""; 5016 $pm = false; 5017 5018 $channel_encoded = ""; 5019 5020 //pattern for default system message settings in chat setup. If system messages are changed in the setup, this pattern has to be changed as well. 5021 $pattern_channel_detect = "(\[RG\]\ |\[M\]\ |\[Staff\]\ |\[SMods\]\ |\[Admin\]\ )"; 5022 5023 $pattern_pm_detect = "\[(\<span\ style\=\"[^\"]{1,}\"\><span\ class\=\"clickablenickname\"\>[A-Za-z0-9]{1,}\<\/span\>\<\/span\>)\ to\ ((?1))\]"; 5024 5025 $pattern = "(\<span\ style\=\"[^\"]{1,}\"\>\<span\ class\=\"clickablenickname\"\>([A-Za-z0-9]{1,})\<\/span\>)"; 5026 5027 5028 preg_match('/' . $pattern_pm_detect . '/i', $message, $matches); 5029 if (!empty($matches['0'])) { 5030 $pm = true; 5031 } 5032 5033 preg_match('/' . $pattern_channel_detect . '/i', $message, $matches); 5034 if (!empty($matches['0'])) { 5035 if ($matches['0'] === "[RG] ") { 5036 $channel = "s 24"; 5037 } elseif ($matches['0'] === "[M] ") { 5038 $channel = "s 31"; 5039 } elseif ($matches['0'] === "[Staff] ") { 5040 $channel = "s 48"; 5041 } elseif ($matches['0'] === "[Admins] ") { 5042 $channel = "s 56"; 5043 } elseif ($matches['0'] === "[Gods] ") { 5044 $channel = "s 65"; 5045 } 5046 } else { 5047 $channel = "s 17"; // send to all 5048 } 5049 5050 //channel must be encoded because of special character + and & and space 5051 $channel_encoded = urlencode($channel); 5052 5053 /* REMOVE LATER 5054 //option 1 5055 if($pm || ((int)$U['clickablenicknames']===1)){ 5056 $replacement = "<a class=\"nicklink\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=".htmlspecialchars('$2').'" target="post">'.'$1'.'</a>'; 5057 } 5058 5059 //option 2 5060 if(!$pm && ((int)$U['clickablenicknames']===2)){ 5061 $replacement = "<a class=\"nicklink\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=".$channel_encoded."&nickname=@".htmlspecialchars('$2').' " target="post">'.'$1'.'</a>'; 5062 } 5063 */ 5064 5065 if ($pm) { //IF PM DETECTED 5066 $replacement = "<a class=\"nicklink\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=" . htmlspecialchars('$2') . '" target="post">' . '$1' . '</a>'; 5067 } else { //Message to all or to one of the channels 5068 $replacement = "<a class=\"nicklink\" href=\"?action=post&session=$U[session]&lang=$language&nc=$nc&sendto=" . $channel_encoded . "&nickname=@" . htmlspecialchars('$2') . ' " target="post">' . '$1' . '</a>'; 5069 } 5070 5071 //regex for option 1 and option 2 and PM 5072 $message = preg_replace("/$pattern/", $replacement, $message); 5073 5074 return $message; 5075 } 5076 5077 5078 function prepare_message_print(&$message, $removeEmbed) 5079 { 5080 if (MSGENCRYPTED) { 5081 $message['text'] = sodium_crypto_aead_aes256gcm_decrypt(base64_decode($message['text']), null, AES_IV, ENCRYPTKEY); 5082 } 5083 if ($removeEmbed) { 5084 $message['text'] = preg_replace_callback( 5085 '/<img src="([^"]+)"><\/a>/u', 5086 function ($matched) { 5087 return "$matched[1]</a>"; 5088 }, 5089 $message['text'] 5090 ); 5091 } 5092 } 5093 5094 // this and that 5095 5096 function send_headers() 5097 { 5098 header('Content-Type: text/html; charset=UTF-8'); 5099 header('Pragma: no-cache'); 5100 header('Cache-Control: no-cache, no-store, must-revalidate, max-age=0'); 5101 header('Expires: 0'); 5102 header('Referrer-Policy: no-referrer'); 5103 header("Content-Security-Policy: default-src 'self'; img-src * data:; media-src * data:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"); 5104 header('X-Content-Type-Options: nosniff'); 5105 header('X-Frame-Options: sameorigin'); 5106 header('X-XSS-Protection: 1; mode=block'); 5107 if ($_SERVER['REQUEST_METHOD'] === 'HEAD') { 5108 exit; // headers sent, no further processing needed 5109 } 5110 } 5111 5112 function save_setup($C) 5113 { 5114 global $db; 5115 //sanity checks and escaping 5116 foreach ($C['msg_settings'] as $setting) { 5117 $_REQUEST[$setting] = htmlspecialchars($_REQUEST[$setting]); 5118 } 5119 foreach ($C['number_settings'] as $setting) { 5120 settype($_REQUEST[$setting], 'int'); 5121 } 5122 foreach ($C['colour_settings'] as $setting) { 5123 if (preg_match('/^#([a-f0-9]{6})$/i', $_REQUEST[$setting], $match)) { 5124 $_REQUEST[$setting] = $match[1]; 5125 } else { 5126 unset($_REQUEST[$setting]); 5127 } 5128 } 5129 settype($_REQUEST['guestaccess'], 'int'); 5130 if (!preg_match('/^[01234]$/', $_REQUEST['guestaccess'])) { 5131 unset($_REQUEST['guestaccess']); 5132 } elseif ($_REQUEST['guestaccess'] == 4) { 5133 $db->exec('DELETE FROM ' . PREFIX . 'sessions WHERE status<7;'); 5134 } 5135 settype($_REQUEST['englobalpass'], 'int'); 5136 settype($_REQUEST['captcha'], 'int'); 5137 settype($_REQUEST['dismemcaptcha'], 'int'); 5138 settype($_REQUEST['guestreg'], 'int'); 5139 if (isset($_REQUEST['defaulttz'])) { 5140 $tzs = timezone_identifiers_list(); 5141 if (!in_array($_REQUEST['defaulttz'], $tzs)) { 5142 unset($_REQUEST['defualttz']); 5143 } 5144 } 5145 $_REQUEST['rulestxt'] = preg_replace("/(\r?\n|\r\n?)/u", '<br>', $_REQUEST['rulestxt']); 5146 $_REQUEST['chatname'] = htmlspecialchars($_REQUEST['chatname']); 5147 $_REQUEST['redirect'] = htmlspecialchars($_REQUEST['redirect']); 5148 if ($_REQUEST['memberexpire'] < 5) { 5149 $_REQUEST['memberexpire'] = 5; 5150 } 5151 if ($_REQUEST['captchatime'] < 30) { 5152 $_REQUEST['memberexpire'] = 30; 5153 } 5154 if ($_REQUEST['defaultrefresh'] < 5) { 5155 $_REQUEST['defaultrefresh'] = 5; 5156 } elseif ($_REQUEST['defaultrefresh'] > 150) { 5157 $_REQUEST['defaultrefresh'] = 150; 5158 } 5159 if ($_REQUEST['maxname'] < 1) { 5160 $_REQUEST['maxname'] = 1; 5161 } elseif ($_REQUEST['maxname'] > 50) { 5162 $_REQUEST['maxname'] = 50; 5163 } 5164 if ($_REQUEST['maxmessage'] < 1) { 5165 $_REQUEST['maxmessage'] = 1; 5166 } elseif ($_REQUEST['maxmessage'] > 16000) { 5167 $_REQUEST['maxmessage'] = 16000; 5168 } 5169 if ($_REQUEST['numnotes'] < 1) { 5170 $_REQUEST['numnotes'] = 1; 5171 } 5172 if (!valid_regex($_REQUEST['nickregex'])) { 5173 unset($_REQUEST['nickregex']); 5174 } 5175 if (!valid_regex($_REQUEST['passregex'])) { 5176 unset($_REQUEST['passregex']); 5177 } 5178 // Modification spare notes 5179 if (!preg_match('/^[3567]$/', $_REQUEST['sparenotesaccess'])) { 5180 $_REQUEST['sparenotesaccess'] = '10'; 5181 } 5182 $_REQUEST['sparenotesname'] = htmlspecialchars($_REQUEST['sparenotesname']); 5183 // End modification 5184 // Modification chat rooms 5185 if (!preg_match('/^[567]$/', $_REQUEST['roomcreateaccess'])) { 5186 unset($_REQUEST['roomcreateaccess']); 5187 } 5188 settype($_REQUEST['roomexpire'], 'int'); 5189 if (!preg_match('/^[235679]$/', $_REQUEST['channelvisinroom'])) { 5190 unset($_REQUEST['channelvisinroom']); 5191 } 5192 // End modification 5193 5194 //save values 5195 foreach ($C['settings'] as $setting) { 5196 if (isset($_REQUEST[$setting])) { 5197 update_setting($setting, $_REQUEST[$setting]); 5198 } 5199 } 5200 } 5201 5202 function set_default_tz() 5203 { 5204 global $U; 5205 if (isset($U['tz'])) { 5206 date_default_timezone_set($U['tz']); 5207 } else { 5208 date_default_timezone_set(get_setting('defaulttz')); 5209 } 5210 } 5211 5212 function valid_admin() 5213 { 5214 global $U; 5215 if (isset($_REQUEST['session'])) { 5216 parse_sessions(); 5217 } 5218 if (!isset($U['session']) && isset($_REQUEST['nick']) && isset($_REQUEST['pass'])) { 5219 create_session(true, $_REQUEST['nick'], $_REQUEST['pass']); 5220 } 5221 if (isset($U['status'])) { 5222 if ($U['status'] >= 7) { 5223 return true; 5224 } 5225 send_access_denied(); 5226 } 5227 return false; 5228 } 5229 5230 function valid_nick($nick) 5231 { 5232 $len = mb_strlen($nick); 5233 if ($len < 1 || $len > get_setting('maxname')) { 5234 return false; 5235 } 5236 return preg_match('/' . get_setting('nickregex') . '/u', $nick); 5237 } 5238 5239 function valid_pass($pass) 5240 { 5241 if (mb_strlen($pass) < get_setting('minpass')) { 5242 return false; 5243 } 5244 return preg_match('/' . get_setting('passregex') . '/u', $pass); 5245 } 5246 5247 function valid_regex(&$regex) 5248 { 5249 $regex = preg_replace('~(^|[^\\\\])/~', "$1\/u", $regex); // Escape "/" if not yet escaped 5250 return (@preg_match("/$_REQUEST[match]/u", '') !== false); 5251 } 5252 5253 function get_timeout($lastpost, $expire) 5254 { 5255 $s = ($lastpost + 60 * $expire) - time(); 5256 $m = floor($s / 60); 5257 $s %= 60; 5258 if ($s < 10) { 5259 $s = "0$s"; 5260 } 5261 if ($m > 60) { 5262 $h = floor($m / 60); 5263 $m %= 60; 5264 if ($m < 10) { 5265 $m = "0$m"; 5266 } 5267 return "$h:$m:$s"; 5268 } else { 5269 return "$m:$s"; 5270 } 5271 } 5272 5273 function print_colours() 5274 { 5275 global $I; 5276 // Prints a short list with selected named HTML colours and filters out illegible text colours for the given background. 5277 // It's a simple comparison of weighted grey values. This is not very accurate but gets the job done well enough. 5278 // name=>[colour, greyval(colour)] 5279 $colours = ['Beige' => ['F5F5DC', 242.25], 'Black' => ['000000', 0], 'Blue' => ['0000FF', 28.05], 'BlueViolet' => ['8A2BE2', 91.63], 'Brown' => ['A52A2A', 78.9], 'Cyan' => ['00FFFF', 178.5], 'DarkBlue' => ['00008B', 15.29], 'DarkGreen' => ['006400', 59], 'DarkRed' => ['8B0000', 41.7], 'DarkViolet' => ['9400D3', 67.61], 'DeepSkyBlue' => ['00BFFF', 140.74], 'Gold' => ['FFD700', 203.35], 'Grey' => ['808080', 128], 'Green' => ['008000', 75.52], 'HotPink' => ['FF69B4', 158.25], 'Indigo' => ['4B0082', 36.8], 'LightBlue' => ['ADD8E6', 204.64], 'LightGreen' => ['90EE90', 199.46], 'LimeGreen' => ['32CD32', 141.45], 'Magenta' => ['FF00FF', 104.55], 'Olive' => ['808000', 113.92], 'Orange' => ['FFA500', 173.85], 'OrangeRed' => ['FF4500', 117.21], 'Purple' => ['800080', 52.48], 'Red' => ['FF0000', 76.5], 'RoyalBlue' => ['4169E1', 106.2], 'SeaGreen' => ['2E8B57', 105.38], 'Sienna' => ['A0522D', 101.33], 'Silver' => ['C0C0C0', 192], 'Tan' => ['D2B48C', 184.6], 'Teal' => ['008080', 89.6], 'Violet' => ['EE82EE', 174.28], 'White' => ['FFFFFF', 255], 'Yellow' => ['FFFF00', 226.95], 'YellowGreen' => ['9ACD32', 172.65]]; 5280 $greybg = greyval(get_setting('colbg')); 5281 foreach ($colours as $name => $colour) { 5282 if (abs($greybg - $colour[1]) > 75) { 5283 echo "<option value=\"$colour[0]\" style=\"color:#$colour[0];\">$I[$name]</option>"; 5284 } 5285 } 5286 } 5287 5288 function greyval($colour) 5289 { 5290 return hexdec(substr($colour, 0, 2)) * .3 + hexdec(substr($colour, 2, 2)) * .59 + hexdec(substr($colour, 4, 2)) * .11; 5291 } 5292 5293 function style_this($text, $styleinfo) 5294 { 5295 return "<span style=\"$styleinfo\">$text</span>"; 5296 } 5297 5298 //new function for clickablenicknames 5299 function style_this_clickable($text, $styleinfo) 5300 { 5301 return "<span style=\"$styleinfo\"><span class=\"clickablenickname\">$text</span></span>"; 5302 } 5303 5304 function check_init() 5305 { 5306 global $db; 5307 return @$db->query('SELECT null FROM ' . PREFIX . 'settings LIMIT 1;'); 5308 } 5309 5310 // run every minute doing various database cleanup task 5311 function cron() 5312 { 5313 global $db; 5314 $time = time(); 5315 if (get_setting('nextcron') > $time) { 5316 return; 5317 } 5318 update_setting('nextcron', $time + 10); 5319 // delete old sessions 5320 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'sessions WHERE (status<=2 AND lastpost<(?-60*(SELECT value FROM ' . PREFIX . "settings WHERE setting='guestexpire'))) OR (status>2 AND lastpost<(?-60*(SELECT value FROM " . PREFIX . "settings WHERE setting='memberexpire')));"); 5321 $stmt->execute([$time, $time]); 5322 // delete old messages 5323 $limit = get_setting('messagelimit'); 5324 $stmt = $db->query('SELECT id FROM ' . PREFIX . "messages WHERE poststatus=1 AND roomid IS NULL ORDER BY id DESC LIMIT 1 OFFSET $limit;"); 5325 if ($id = $stmt->fetch(PDO::FETCH_NUM)) { 5326 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'messages WHERE id<=?;'); 5327 $stmt->execute($id); 5328 } 5329 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'messages WHERE id IN (SELECT * FROM (SELECT id FROM ' . PREFIX . 'messages WHERE postdate<(?-60*(SELECT value FROM ' . PREFIX . "settings WHERE setting='messageexpire'))) AS t);"); 5330 $stmt->execute([$time]); 5331 // delete expired ignored people 5332 $result = $db->query('SELECT id FROM ' . PREFIX . 'ignored WHERE ign NOT IN (SELECT nickname FROM ' . PREFIX . 'sessions UNION SELECT nickname FROM ' . PREFIX . 'members UNION SELECT poster FROM ' . PREFIX . 'messages) OR ignby NOT IN (SELECT nickname FROM ' . PREFIX . 'sessions UNION SELECT nickname FROM ' . PREFIX . 'members UNION SELECT poster FROM ' . PREFIX . 'messages);'); 5333 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'ignored WHERE id=?;'); 5334 while ($tmp = $result->fetch(PDO::FETCH_NUM)) { 5335 $stmt->execute($tmp); 5336 } 5337 // delete files that do not belong to any message 5338 $result = $db->query('SELECT id FROM ' . PREFIX . 'files WHERE postid NOT IN (SELECT id FROM ' . PREFIX . 'messages UNION SELECT postid FROM ' . PREFIX . 'inbox);'); 5339 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'files WHERE id=?;'); 5340 while ($tmp = $result->fetch(PDO::FETCH_NUM)) { 5341 $stmt->execute($tmp); 5342 } 5343 // delete old notes 5344 $limit = get_setting('numnotes'); 5345 // Modification for spare notes 5346 $db->exec('DELETE FROM ' . PREFIX . 'notes WHERE type!=2 AND id NOT IN (SELECT * FROM ( (SELECT id FROM ' . PREFIX . "notes WHERE type=0 ORDER BY id DESC LIMIT $limit) UNION (SELECT id FROM " . PREFIX . "notes WHERE type=3 ORDER BY id DESC LIMIT $limit)UNION (SELECT id FROM " . PREFIX . "notes WHERE type=1 ORDER BY id DESC LIMIT $limit) ) AS t);"); 5347 $result = $db->query('SELECT editedby, COUNT(*) AS cnt FROM ' . PREFIX . "notes WHERE type=2 GROUP BY editedby HAVING cnt>$limit;"); 5348 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'notes WHERE type=2 AND editedby=? AND id NOT IN (SELECT * FROM (SELECT id FROM ' . PREFIX . "notes WHERE type=2 AND editedby=? ORDER BY id DESC LIMIT $limit) AS t);"); 5349 while ($tmp = $result->fetch(PDO::FETCH_NUM)) { 5350 $stmt->execute([$tmp[0], $tmp[0]]); 5351 } 5352 // delete old captchas 5353 $stmt = $db->prepare('DELETE FROM ' . PREFIX . 'captcha WHERE time<(?-(SELECT value FROM ' . PREFIX . "settings WHERE setting='captchatime'));"); 5354 $stmt->execute([$time]); 5355 5356 // modification expire rooms 5357 $result = $db->query('SELECT DISTINCT roomid FROM ' . PREFIX . 'sessions where roomid is not null;'); 5358 while ($active = $result->fetch(PDO::FETCH_ASSOC)) { 5359 $stmt = $db->prepare('UPDATE ' . PREFIX . 'rooms SET time=? WHERE id=?'); 5360 $stmt->execute([$time, $active['roomid']]); 5361 } 5362 $expire = (int) get_setting('roomexpire') * 60; 5363 $stmt = $db->prepare('SELECT id FROM ' . PREFIX . 'rooms WHERE time<=? AND permanent=0'); 5364 $stmt->execute([$time - $expire]); 5365 if (!$rooms = $stmt->fetchAll(PDO::FETCH_ASSOC)) { 5366 $rooms = []; 5367 } 5368 foreach ($rooms as $room) { 5369 remove_room(false, $room['id']); 5370 } 5371 5372 // End modifications for rooms 5373 } 5374 5375 function destroy_chat($C) 5376 { 5377 global $I, $db, $memcached; 5378 setcookie(COOKIENAME, false); 5379 $_REQUEST['session'] = ''; 5380 print_start('destory'); 5381 $db->exec('DROP TABLE ' . PREFIX . 'captcha;'); 5382 $db->exec('DROP TABLE ' . PREFIX . 'files;'); 5383 $db->exec('DROP TABLE ' . PREFIX . 'filter;'); 5384 $db->exec('DROP TABLE ' . PREFIX . 'ignored;'); 5385 $db->exec('DROP TABLE ' . PREFIX . 'inbox;'); 5386 $db->exec('DROP TABLE ' . PREFIX . 'linkfilter;'); 5387 $db->exec('DROP TABLE ' . PREFIX . 'members;'); 5388 $db->exec('DROP TABLE ' . PREFIX . 'messages;'); 5389 $db->exec('DROP TABLE ' . PREFIX . 'notes;'); 5390 $db->exec('DROP TABLE ' . PREFIX . 'sessions;'); 5391 $db->exec('DROP TABLE ' . PREFIX . 'settings;'); 5392 if (MEMCACHED) { 5393 $memcached->delete(DBNAME . '-' . PREFIX . 'filter'); 5394 $memcached->delete(DBANEM . '-' . PREFIX . 'linkfilter'); 5395 foreach ($C['settings'] as $setting) { 5396 $memcached->delete(DBNAME . '-' . PREFIX . "settings-$setting"); 5397 } 5398 $memcached->delete(DBNAME . '-' . PREFIX . 'settings-dbversion'); 5399 $memcached->delete(DBNAME . '-' . PREFIX . 'settings-msgencrypted'); 5400 $memcached->delete(DBNAME . '-' . PREFIX . 'settings-nextcron'); 5401 } 5402 echo "<h2>$I[destroyed]</h2><br><br><br>"; 5403 echo form('setup') . submit($I['init']) . '</form>' . credit(); 5404 print_end(); 5405 } 5406 5407 function init_chat() 5408 { 5409 global $I, $db; 5410 $suwrite = ''; 5411 if (check_init()) { 5412 $suwrite = $I['initdbexist']; 5413 $result = $db->query('SELECT null FROM ' . PREFIX . 'members WHERE status=8;'); 5414 if ($result->fetch(PDO::FETCH_NUM)) { 5415 $suwrite = $I['initsuexist']; 5416 } 5417 } elseif (!preg_match('/^[a-z0-9]{1,20}$/i', $_REQUEST['sunick'])) { 5418 $suwrite = sprintf($I['invalnick'], 20, '^[A-Za-z1-9]*$'); 5419 } elseif (mb_strlen($_REQUEST['supass']) < 5) { 5420 $suwrite = sprintf($I['invalpass'], 5, '.*'); 5421 } elseif ($_REQUEST['supass'] !== $_REQUEST['supassc']) { 5422 $suwrite = $I['noconfirm']; 5423 } else { 5424 ignore_user_abort(true); 5425 set_time_limit(0); 5426 if (DBDRIVER === 0) { //MySQL 5427 $memengine = ' ENGINE=MEMORY'; 5428 $diskengine = ' ENGINE=InnoDB'; 5429 $charset = ' DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin'; 5430 $primary = 'integer PRIMARY KEY AUTO_INCREMENT'; 5431 $longtext = 'longtext'; 5432 } elseif (DBDRIVER === 1) { //PostgreSQL 5433 $memengine = ''; 5434 $diskengine = ''; 5435 $charset = ''; 5436 $primary = 'serial PRIMARY KEY'; 5437 $longtext = 'text'; 5438 } else { //SQLite 5439 $memengine = ''; 5440 $diskengine = ''; 5441 $charset = ''; 5442 $primary = 'integer PRIMARY KEY'; 5443 $longtext = 'text'; 5444 } 5445 $db->exec('CREATE TABLE ' . PREFIX . "captcha (id $primary, time integer NOT NULL, code char(5) NOT NULL)$memengine$charset;"); 5446 $db->exec('CREATE TABLE ' . PREFIX . "files (id $primary, postid integer NOT NULL UNIQUE, filename varchar(255) NOT NULL, hash char(40) NOT NULL, type varchar(255) NOT NULL, data $longtext NOT NULL)$diskengine$charset;"); 5447 $db->exec('CREATE INDEX ' . PREFIX . 'files_hash ON ' . PREFIX . 'files(hash);'); 5448 $db->exec('CREATE TABLE ' . PREFIX . "filter (id $primary, filtermatch varchar(255) NOT NULL, filterreplace text NOT NULL, allowinpm smallint NOT NULL, regex smallint NOT NULL, kick smallint NOT NULL, cs smallint NOT NULL)$diskengine$charset;"); 5449 $db->exec('CREATE TABLE ' . PREFIX . "ignored (id $primary, ign varchar(50) NOT NULL, ignby varchar(50) NOT NULL)$diskengine$charset;"); 5450 $db->exec('CREATE INDEX ' . PREFIX . 'ign ON ' . PREFIX . 'ignored(ign);'); 5451 $db->exec('CREATE INDEX ' . PREFIX . 'ignby ON ' . PREFIX . 'ignored(ignby);'); 5452 $db->exec('CREATE TABLE ' . PREFIX . "inbox (id $primary, postdate integer NOT NULL, postid integer NOT NULL UNIQUE, poster varchar(50) NOT NULL, recipient varchar(50) NOT NULL, text text NOT NULL)$diskengine$charset;"); 5453 $db->exec('CREATE INDEX ' . PREFIX . 'inbox_poster ON ' . PREFIX . 'inbox(poster);'); 5454 $db->exec('CREATE INDEX ' . PREFIX . 'inbox_recipient ON ' . PREFIX . 'inbox(recipient);'); 5455 $db->exec('CREATE TABLE ' . PREFIX . "linkfilter (id $primary, filtermatch varchar(255) NOT NULL, filterreplace varchar(255) NOT NULL, regex smallint NOT NULL)$diskengine$charset;"); 5456 5457 //MODIFICATION clickable nicknames 5458 /*REMOVE LATER 5459 $db->exec('CREATE TABLE ' . PREFIX . "members (id $primary, nickname varchar(50) NOT NULL UNIQUE, passhash varchar(255) NOT NULL, status smallint NOT NULL, refresh smallint NOT NULL, bgcolour char(6) NOT NULL, regedby varchar(50) DEFAULT '', lastlogin integer DEFAULT 0, timestamps smallint NOT NULL, embed smallint NOT NULL, incognito smallint NOT NULL, style varchar(255) NOT NULL, nocache smallint NOT NULL, tz varchar(255) NOT NULL, eninbox smallint NOT NULL, sortupdown smallint NOT NULL, hidechatters smallint NOT NULL, nocache_old smallint NOT NULL, clickablenicknames smallint NOT NULL DEFAULT 0)$diskengine$charset;"); 5460 */ 5461 $db->exec('CREATE TABLE ' . PREFIX . "members (id $primary, nickname varchar(50) NOT NULL UNIQUE, passhash varchar(255) NOT NULL, status smallint NOT NULL, refresh smallint NOT NULL, bgcolour char(6) NOT NULL, regedby varchar(50) DEFAULT '', lastlogin integer DEFAULT 0, timestamps smallint NOT NULL, embed smallint NOT NULL, incognito smallint NOT NULL, style varchar(255) NOT NULL, nocache smallint NOT NULL, tz varchar(255) NOT NULL, eninbox smallint NOT NULL, sortupdown smallint NOT NULL, hidechatters smallint NOT NULL, nocache_old smallint NOT NULL)$diskengine$charset;"); 5462 5463 5464 $db->exec('ALTER TABLE ' . PREFIX . 'inbox ADD FOREIGN KEY (recipient) REFERENCES ' . PREFIX . 'members(nickname) ON DELETE CASCADE ON UPDATE CASCADE;'); 5465 $db->exec('CREATE TABLE ' . PREFIX . "messages (id $primary, postdate integer NOT NULL, poststatus smallint NOT NULL, poster varchar(50) NOT NULL, recipient varchar(50) NOT NULL, text text NOT NULL, delstatus smallint NOT NULL)$diskengine$charset;"); 5466 $db->exec('CREATE INDEX ' . PREFIX . 'poster ON ' . PREFIX . 'messages (poster);'); 5467 $db->exec('CREATE INDEX ' . PREFIX . 'recipient ON ' . PREFIX . 'messages(recipient);'); 5468 $db->exec('CREATE INDEX ' . PREFIX . 'postdate ON ' . PREFIX . 'messages(postdate);'); 5469 $db->exec('CREATE INDEX ' . PREFIX . 'poststatus ON ' . PREFIX . 'messages(poststatus);'); 5470 $db->exec('CREATE TABLE ' . PREFIX . "notes (id $primary, type smallint NOT NULL, lastedited integer NOT NULL, editedby varchar(50) NOT NULL, text text NOT NULL)$diskengine$charset;"); 5471 $db->exec('CREATE INDEX ' . PREFIX . 'notes_type ON ' . PREFIX . 'notes(type);'); 5472 $db->exec('CREATE INDEX ' . PREFIX . 'notes_editedby ON ' . PREFIX . 'notes(editedby);'); 5473 5474 //MODIFICATION clickable nicknames 5475 /* REMOVE LATER 5476 $db->exec('CREATE TABLE ' . PREFIX . "sessions (id $primary, session char(32) NOT NULL UNIQUE, nickname varchar(50) NOT NULL UNIQUE, status smallint NOT NULL, refresh smallint NOT NULL, style varchar(255) NOT NULL, lastpost integer NOT NULL, passhash varchar(255) NOT NULL, postid char(6) NOT NULL DEFAULT '000000', useragent varchar(255) NOT NULL, kickmessage varchar(255) DEFAULT '', bgcolour char(6) NOT NULL, entry integer NOT NULL, timestamps smallint NOT NULL, embed smallint NOT NULL, incognito smallint NOT NULL, ip varchar(45) NOT NULL, nocache smallint NOT NULL, tz varchar(255) NOT NULL, eninbox smallint NOT NULL, sortupdown smallint NOT NULL, hidechatters smallint NOT NULL, nocache_old smallint NOT NULL, clickablenicknames smallint NOT NULL DEFAULT 0)$memengine$charset;"); 5477 */ 5478 $db->exec('CREATE TABLE ' . PREFIX . "sessions (id $primary, session char(32) NOT NULL UNIQUE, nickname varchar(50) NOT NULL UNIQUE, status smallint NOT NULL, refresh smallint NOT NULL, style varchar(255) NOT NULL, lastpost integer NOT NULL, passhash varchar(255) NOT NULL, postid char(6) NOT NULL DEFAULT '000000', useragent varchar(255) NOT NULL, kickmessage varchar(255) DEFAULT '', bgcolour char(6) NOT NULL, entry integer NOT NULL, timestamps smallint NOT NULL, embed smallint NOT NULL, incognito smallint NOT NULL, ip varchar(45) NOT NULL, nocache smallint NOT NULL, tz varchar(255) NOT NULL, eninbox smallint NOT NULL, sortupdown smallint NOT NULL, hidechatters smallint NOT NULL, nocache_old smallint NOT NULL)$memengine$charset;"); 5479 5480 $db->exec('CREATE INDEX ' . PREFIX . 'status ON ' . PREFIX . 'sessions(status);'); 5481 $db->exec('CREATE INDEX ' . PREFIX . 'lastpost ON ' . PREFIX . 'sessions(lastpost);'); 5482 $db->exec('CREATE INDEX ' . PREFIX . 'incognito ON ' . PREFIX . 'sessions(incognito);'); 5483 $db->exec('CREATE TABLE ' . PREFIX . "settings (setting varchar(50) NOT NULL PRIMARY KEY, value text NOT NULL)$diskengine$charset;"); 5484 5485 // Modification for chat rooms 5486 $db->exec('CREATE TABLE ' . PREFIX . "rooms (id $primary, name varchar(50) NOT NULL UNIQUE, access smallint NOT NULL, time integer NOT NULL, permanent smallint NOT NULL DEFAULT(0))$diskengine$charset;"); 5487 $db->exec('ALTER TABLE ' . PREFIX . 'sessions ADD COLUMN roomid integer;'); 5488 $db->exec('ALTER TABLE ' . PREFIX . 'messages ADD COLUMN roomid integer;'); 5489 $db->exec('CREATE INDEX ' . PREFIX . 'sroomid ON ' . PREFIX . 'sessions(roomid);'); 5490 $db->exec('CREATE INDEX ' . PREFIX . 'mroomid ON ' . PREFIX . 'messages(roomid);'); 5491 $db->exec('ALTER TABLE ' . PREFIX . 'messages ADD COLUMN allrooms smallint NOT NULL DEFAULT(0);'); 5492 5493 5494 $settings = [ 5495 ['guestaccess', '0'], 5496 ['globalpass', ''], 5497 ['englobalpass', '0'], 5498 ['captcha', '0'], 5499 ['dateformat', 'm-d H:i:s'], 5500 ['rulestxt', ''], 5501 ['msgencrypted', '0'], 5502 ['dbversion', DBVERSION], 5503 ['css', ''], 5504 ['memberexpire', '60'], 5505 ['guestexpire', '15'], 5506 ['kickpenalty', '10'], 5507 ['entrywait', '120'], 5508 ['messageexpire', '14400'], 5509 ['messagelimit', '150'], 5510 ['maxmessage', 2000], 5511 ['captchatime', '600'], 5512 ['colbg', '000000'], 5513 ['coltxt', 'FFFFFF'], 5514 ['maxname', '20'], 5515 ['minpass', '5'], 5516 ['defaultrefresh', '20'], 5517 ['dismemcaptcha', '0'], 5518 ['suguests', '0'], 5519 ['imgembed', '1'], 5520 ['timestamps', '1'], 5521 ['trackip', '0'], 5522 ['captchachars', '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'], 5523 ['memkick', '1'], 5524 ['forceredirect', '0'], 5525 ['redirect', ''], 5526 ['incognito', '1'], 5527 ['chatname', 'My Chat'], 5528 ['topic', ''], 5529 ['msgsendall', $I['sendallmsg']], 5530 ['msgsendmem', $I['sendmemmsg']], 5531 ['msgsendmod', $I['sendmodmsg']], 5532 ['msgsendadm', $I['sendadmmsg']], 5533 ['msgsendprv', $I['sendprvmsg']], 5534 ['msgenter', $I['entermsg']], 5535 ['msgexit', $I['exitmsg']], 5536 ['msgmemreg', $I['memregmsg']], 5537 ['msgsureg', $I['suregmsg']], 5538 ['msgkick', $I['kickmsg']], 5539 ['msgmultikick', $I['multikickmsg']], 5540 ['msgallkick', $I['allkickmsg']], 5541 ['msgclean', $I['cleanmsg']], 5542 ['numnotes', '3'], 5543 ['mailsender', 'www-data <www-data@localhost>'], 5544 ['mailreceiver', 'Webmaster <webmaster@localhost>'], 5545 ['sendmail', '0'], 5546 ['modfallback', '1'], 5547 ['guestreg', '0'], 5548 ['disablepm', '0'], 5549 ['disabletext', "<h1>$I[disabledtext]</h1>"], 5550 ['defaulttz', 'UTC'], 5551 ['eninbox', '0'], 5552 ['passregex', '.*'], 5553 ['nickregex', '^[A-Za-z0-9]*$'], 5554 ['externalcss', ''], 5555 ['enablegreeting', '0'], 5556 ['sortupdown', '0'], 5557 ['hidechatters', '0'], 5558 ['enfileupload', '0'], 5559 ['msgattache', '%2$s [%1$s]'], 5560 ['maxuploadsize', '1024'], 5561 ['nextcron', '0'], 5562 ['personalnotes', '1'], 5563 ['filtermodkick', '0'], 5564 5565 //MODIFICATION Text field for links in settings and option to enable or disable links page. 5566 ['links', ''], 5567 ['linksenabled', '0'], 5568 5569 //MODIFICATION option to enable or disable DEL-Buttons for members, if no mod is present. (DEL Buttons can bes used to delete messages within the message frame) 5570 ['memdel', '0'], 5571 5572 //MODIFICATION option to set galleryaccess for users depending on their rank(status). 5573 ['galleryaccess', '10'], 5574 5575 //MODIFICATION option to set forum button visibility for users depending on their rank(status). 5576 ['forumbtnaccess', '10'], 5577 5578 //MODIFICATION option to set link for the forum button 5579 ['forumbtnlink', 'forum/index.php'], 5580 5581 //MODIFICATION frontpagetext (text for front page) 5582 ['frontpagetext', ''], 5583 5584 //MODIFICATION adminjoinleavemsg (admin join leave messages can be hidden) 5585 ['adminjoinleavemsg', '1'], 5586 5587 //MODIFICATION modsdeladminmsg (mods can delete admin messages) 5588 ['modsdeladminmsg', '0'], 5589 5590 //MODIFICATION clickablenicknamesglobal (nicknames at beginning of messages are clickable) 5591 ['clickablenicknamesglobal', '1'], 5592 5593 //MODIFICATION spare notes. 5594 ['sparenotesname', ''], 5595 ['sparenotesaccess', '10'], 5596 5597 //MODIFICATION rooms 5598 ['roomcreateaccess', '7'], 5599 ['roomexpire', '10'], 5600 ['channelvisinroom', '2'] 5601 ]; 5602 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'settings (setting, value) VALUES (?, ?);'); 5603 foreach ($settings as $pair) { 5604 $stmt->execute($pair); 5605 } 5606 $reg = [ 5607 'nickname' => $_REQUEST['sunick'], 5608 'passhash' => password_hash($_REQUEST['supass'], PASSWORD_DEFAULT), 5609 'status' => 8, 5610 'refresh' => 20, 5611 'bgcolour' => '000000', 5612 'timestamps' => 1, 5613 'style' => 'color:#FFFFFF;', 5614 'embed' => 1, 5615 'incognito' => 0, 5616 'nocache' => 0, 5617 'nocache_old' => 1, 5618 'tz' => 'UTC', 5619 'eninbox' => 0, 5620 'sortupdown' => 0, 5621 'hidechatters' => 0, 5622 ]; 5623 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'members (nickname, passhash, status, refresh, bgcolour, timestamps, style, embed, incognito, nocache, tz, eninbox, sortupdown, hidechatters, nocache_old) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);'); 5624 $stmt->execute([$reg['nickname'], $reg['passhash'], $reg['status'], $reg['refresh'], $reg['bgcolour'], $reg['timestamps'], $reg['style'], $reg['embed'], $reg['incognito'], $reg['nocache'], $reg['tz'], $reg['eninbox'], $reg['sortupdown'], $reg['hidechatters'], $reg['nocache_old']]); 5625 $suwrite = $I['susuccess']; 5626 } 5627 print_start('init'); 5628 echo "<h2>$I[init]</h2><br><h3>$I[sulogin]</h3>$suwrite<br><br><br>"; 5629 echo form('setup') . submit($I['initgosetup']) . '</form>' . credit(); 5630 print_end(); 5631 } 5632 5633 function update_db() 5634 { 5635 global $I, $db, $memcached; 5636 $dbversion = (int) get_setting('dbversion'); 5637 $msgencrypted = (bool) get_setting('msgencrypted'); 5638 if ($dbversion >= DBVERSION && $msgencrypted === MSGENCRYPTED) { 5639 return; 5640 } 5641 ignore_user_abort(true); 5642 set_time_limit(0); 5643 if (DBDRIVER === 0) { //MySQL 5644 $memengine = ' ENGINE=MEMORY'; 5645 $diskengine = ' ENGINE=InnoDB'; 5646 $charset = ' DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin'; 5647 $primary = 'integer PRIMARY KEY AUTO_INCREMENT'; 5648 $longtext = 'longtext'; 5649 } elseif (DBDRIVER === 1) { //PostgreSQL 5650 $memengine = ''; 5651 $diskengine = ''; 5652 $charset = ''; 5653 $primary = 'serial PRIMARY KEY'; 5654 $longtext = 'text'; 5655 } else { //SQLite 5656 $memengine = ''; 5657 $diskengine = ''; 5658 $charset = ''; 5659 $primary = 'integer PRIMARY KEY'; 5660 $longtext = 'text'; 5661 } 5662 $msg = ''; 5663 if ($dbversion < 2) { 5664 $db->exec('CREATE TABLE IF NOT EXISTS ' . PREFIX . "ignored (id integer unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, ignored varchar(50) NOT NULL, `by` varchar(50) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;"); 5665 } 5666 if ($dbversion < 3) { 5667 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('rulestxt', '');"); 5668 } 5669 if ($dbversion < 4) { 5670 $db->exec('ALTER TABLE ' . PREFIX . 'members ADD incognito smallint NOT NULL;'); 5671 } 5672 if ($dbversion < 5) { 5673 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('globalpass', '');"); 5674 } 5675 if ($dbversion < 6) { 5676 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('dateformat', 'm-d H:i:s');"); 5677 } 5678 if ($dbversion < 7) { 5679 $db->exec('ALTER TABLE ' . PREFIX . 'captcha ADD code char(5) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;'); 5680 } 5681 if ($dbversion < 8) { 5682 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('captcha', '0'), ('englobalpass', '0');"); 5683 $ga = (int) get_setting('guestaccess'); 5684 if ($ga === -1) { 5685 update_setting('guestaccess', 0); 5686 update_setting('englobalpass', 1); 5687 } elseif ($ga === 4) { 5688 update_setting('guestaccess', 1); 5689 update_setting('englobalpass', 2); 5690 } 5691 } 5692 if ($dbversion < 9) { 5693 $db->exec('INSERT INTO ' . PREFIX . "settings (setting,value) VALUES ('msgencrypted', '0');"); 5694 $db->exec('ALTER TABLE ' . PREFIX . 'settings MODIFY value varchar(20000) NOT NULL;'); 5695 $db->exec('ALTER TABLE ' . PREFIX . 'messages DROP postid;'); 5696 } 5697 if ($dbversion < 10) { 5698 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('css', ''), ('memberexpire', '60'), ('guestexpire', '15'), ('kickpenalty', '10'), ('entrywait', '120'), ('messageexpire', '14400'), ('messagelimit', '150'), ('maxmessage', 2000), ('captchatime', '600');"); 5699 } 5700 if ($dbversion < 11) { 5701 $db->exec('ALTER TABLE ', PREFIX . 'captcha CHARACTER SET utf8 COLLATE utf8_bin;'); 5702 $db->exec('ALTER TABLE ' . PREFIX . 'filter CHARACTER SET utf8 COLLATE utf8_bin;'); 5703 $db->exec('ALTER TABLE ' . PREFIX . 'ignored CHARACTER SET utf8 COLLATE utf8_bin;'); 5704 $db->exec('ALTER TABLE ' . PREFIX . 'messages CHARACTER SET utf8 COLLATE utf8_bin;'); 5705 $db->exec('ALTER TABLE ' . PREFIX . 'notes CHARACTER SET utf8 COLLATE utf8_bin;'); 5706 $db->exec('ALTER TABLE ' . PREFIX . 'settings CHARACTER SET utf8 COLLATE utf8_bin;'); 5707 $db->exec('CREATE TABLE ' . PREFIX . "linkfilter (id integer unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, `match` varchar(255) NOT NULL, `replace` varchar(255) NOT NULL, regex smallint NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;"); 5708 $db->exec('ALTER TABLE ' . PREFIX . 'members ADD style varchar(255) NOT NULL;'); 5709 $result = $db->query('SELECT * FROM ' . PREFIX . 'members;'); 5710 $stmt = $db->prepare('UPDATE ' . PREFIX . 'members SET style=? WHERE id=?;'); 5711 $F = load_fonts(); 5712 while ($temp = $result->fetch(PDO::FETCH_ASSOC)) { 5713 $style = "color:#$temp[colour];"; 5714 if (isset($F[$temp['fontface']])) { 5715 $style .= $F[$temp['fontface']]; 5716 } 5717 if (strpos($temp['fonttags'], 'i') !== false) { 5718 $style .= 'font-style:italic;'; 5719 } 5720 if (strpos($temp['fonttags'], 'b') !== false) { 5721 $style .= 'font-weight:bold;'; 5722 } 5723 $stmt->execute([$style, $temp['id']]); 5724 } 5725 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('colbg', '000000'), ('coltxt', 'FFFFFF'), ('maxname', '20'), ('minpass', '5'), ('defaultrefresh', '20'), ('dismemcaptcha', '0'), ('suguests', '0'), ('imgembed', '1'), ('timestamps', '1'), ('trackip', '0'), ('captchachars', '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), ('memkick', '1'), ('forceredirect', '0'), ('redirect', ''), ('incognito', '1');"); 5726 } 5727 if ($dbversion < 12) { 5728 $db->exec('ALTER TABLE ' . PREFIX . 'captcha MODIFY code char(5) NOT NULL, DROP INDEX id, ADD PRIMARY KEY (id) USING BTREE;'); 5729 $db->exec('ALTER TABLE ' . PREFIX . 'captcha ENGINE=MEMORY;'); 5730 $db->exec('ALTER TABLE ' . PREFIX . 'filter MODIFY id integer unsigned NOT NULL AUTO_INCREMENT, MODIFY `match` varchar(255) NOT NULL, MODIFY replace varchar(20000) NOT NULL;'); 5731 $db->exec('ALTER TABLE ' . PREFIX . 'ignored MODIFY ignored varchar(50) NOT NULL, MODIFY `by` varchar(50) NOT NULL, ADD INDEX(ignored), ADD INDEX(`by`);'); 5732 $db->exec('ALTER TABLE ' . PREFIX . 'linkfilter MODIFY match varchar(255) NOT NULL, MODIFY replace varchar(255) NOT NULL;'); 5733 $db->exec('ALTER TABLE ' . PREFIX . 'messages MODIFY poster varchar(50) NOT NULL, MODIFY recipient varchar(50) NOT NULL, MODIFY text varchar(20000) NOT NULL, ADD INDEX(poster), ADD INDEX(recipient), ADD INDEX(postdate), ADD INDEX(poststatus);'); 5734 $db->exec('ALTER TABLE ' . PREFIX . 'notes MODIFY type char(5) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, MODIFY editedby varchar(50) NOT NULL, MODIFY text varchar(20000) NOT NULL;'); 5735 $db->exec('ALTER TABLE ' . PREFIX . 'settings MODIFY id integer unsigned NOT NULL, MODIFY setting varchar(50) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, MODIFY value varchar(20000) NOT NULL;'); 5736 $db->exec('ALTER TABLE ' . PREFIX . 'settings DROP PRIMARY KEY, DROP id, ADD PRIMARY KEY(setting);'); 5737 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('chatname', 'My Chat'), ('topic', ''), ('msgsendall', '$I[sendallmsg]'), ('msgsendmem', '$I[sendmemmsg]'), ('msgsendmod', '$I[sendmodmsg]'), ('msgsendadm', '$I[sendadmmsg]'), ('msgsendprv', '$I[sendprvmsg]'), ('numnotes', '3');"); 5738 } 5739 if ($dbversion < 13) { 5740 $db->exec('ALTER TABLE ' . PREFIX . 'filter CHANGE `match` filtermatch varchar(255) NOT NULL, CHANGE `replace` filterreplace varchar(20000) NOT NULL;'); 5741 $db->exec('ALTER TABLE ' . PREFIX . 'ignored CHANGE ignored ign varchar(50) NOT NULL, CHANGE `by` ignby varchar(50) NOT NULL;'); 5742 $db->exec('ALTER TABLE ' . PREFIX . 'linkfilter CHANGE `match` filtermatch varchar(255) NOT NULL, CHANGE `replace` filterreplace varchar(255) NOT NULL;'); 5743 } 5744 if ($dbversion < 14) { 5745 if (MEMCACHED) { 5746 $memcached->delete(DBNAME . '-' . PREFIX . 'members'); 5747 $memcached->delete(DBNAME . '-' . PREFIX . 'ignored'); 5748 } 5749 if (DBDRIVER === 0) { //MySQL - previously had a wrong SQL syntax and the captcha table was not created. 5750 $db->exec('CREATE TABLE IF NOT EXISTS ' . PREFIX . 'captcha (id integer unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, time integer unsigned NOT NULL, code char(5) NOT NULL) ENGINE=MEMORY DEFAULT CHARSET=utf8 COLLATE=utf8_bin;'); 5751 } 5752 } 5753 if ($dbversion < 15) { 5754 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('mailsender', 'www-data <www-data@localhost>'), ('mailreceiver', 'Webmaster <webmaster@localhost>'), ('sendmail', '0'), ('modfallback', '1'), ('guestreg', '0');"); 5755 } 5756 if ($dbversion < 17) { 5757 $db->exec('ALTER TABLE ' . PREFIX . 'members ADD COLUMN nocache smallint NOT NULL DEFAULT 0;'); 5758 } 5759 if ($dbversion < 18) { 5760 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('disablepm', '0');"); 5761 } 5762 if ($dbversion < 19) { 5763 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('disabletext', '<h1>$I[disabledtext]</h1>');"); 5764 } 5765 if ($dbversion < 20) { 5766 $db->exec('ALTER TABLE ' . PREFIX . 'members ADD COLUMN tz smallint NOT NULL DEFAULT 0;'); 5767 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('defaulttz', 'UTC');"); 5768 } 5769 if ($dbversion < 21) { 5770 $db->exec('ALTER TABLE ' . PREFIX . 'members ADD COLUMN eninbox smallint NOT NULL DEFAULT 0;'); 5771 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('eninbox', '0');"); 5772 if (DBDRIVER === 0) { 5773 $db->exec('CREATE TABLE ' . PREFIX . "inbox (id integer unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, postid integer unsigned NOT NULL, postdate integer unsigned NOT NULL, poster varchar(50) NOT NULL, recipient varchar(50) NOT NULL, text varchar(20000) NOT NULL, INDEX(postid), INDEX(poster), INDEX(recipient)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;"); 5774 } else { 5775 $db->exec('CREATE TABLE ' . PREFIX . "inbox (id $primary, postdate integer NOT NULL, postid integer NOT NULL, poster varchar(50) NOT NULL, recipient varchar(50) NOT NULL, text varchar(20000) NOT NULL);"); 5776 $db->exec('CREATE INDEX ' . PREFIX . 'inbox_postid ON ' . PREFIX . 'inbox(postid);'); 5777 $db->exec('CREATE INDEX ' . PREFIX . 'inbox_poster ON ' . PREFIX . 'inbox(poster);'); 5778 $db->exec('CREATE INDEX ' . PREFIX . 'inbox_recipient ON ' . PREFIX . 'inbox(recipient);'); 5779 } 5780 } 5781 if ($dbversion < 23) { 5782 $db->exec('DELETE FROM ' . PREFIX . "settings WHERE setting='enablejs';"); 5783 } 5784 if ($dbversion < 25) { 5785 $db->exec('DELETE FROM ' . PREFIX . "settings WHERE setting='keeplimit';"); 5786 } 5787 if ($dbversion < 26) { 5788 $db->exec('INSERT INTO ' . PREFIX . 'settings (setting, value) VALUES (\'passregex\', \'.*\'), (\'nickregex\', \'^[A-Za-z0-9]*$\');'); 5789 } 5790 if ($dbversion < 27) { 5791 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('externalcss', '');"); 5792 } 5793 if ($dbversion < 28) { 5794 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('enablegreeting', '0');"); 5795 } 5796 if ($dbversion < 29) { 5797 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('sortupdown', '0');"); 5798 $db->exec('ALTER TABLE ' . PREFIX . 'members ADD COLUMN sortupdown smallint NOT NULL DEFAULT 0;'); 5799 } 5800 if ($dbversion < 30) { 5801 $db->exec('ALTER TABLE ' . PREFIX . 'filter ADD COLUMN cs smallint NOT NULL DEFAULT 0;'); 5802 if (MEMCACHED) { 5803 $memcached->delete(DBNAME . '-' . PREFIX . "filter"); 5804 } 5805 } 5806 if ($dbversion < 31) { 5807 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('hidechatters', '0');"); 5808 $db->exec('ALTER TABLE ' . PREFIX . 'members ADD COLUMN hidechatters smallint NOT NULL DEFAULT 0;'); 5809 } 5810 if ($dbversion < 32 && DBDRIVER === 0) { 5811 //recreate db in utf8mb4 5812 try { 5813 $olddb = new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, [PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT => PERSISTENT]); 5814 } catch (PDOException $e) { 5815 send_fatal_error($I['nodb']); 5816 } 5817 $db->exec('DROP TABLE ' . PREFIX . 'captcha;'); 5818 $db->exec('CREATE TABLE ' . PREFIX . "captcha (id integer PRIMARY KEY AUTO_INCREMENT, time integer NOT NULL, code char(5) NOT NULL) ENGINE=MEMORY DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;"); 5819 $result = $olddb->query('SELECT filtermatch, filterreplace, allowinpm, regex, kick, cs FROM ' . PREFIX . 'filter;'); 5820 $data = $result->fetchAll(PDO::FETCH_NUM); 5821 $db->exec('DROP TABLE ' . PREFIX . 'filter;'); 5822 $db->exec('CREATE TABLE ' . PREFIX . "filter (id integer PRIMARY KEY AUTO_INCREMENT, filtermatch varchar(255) NOT NULL, filterreplace text NOT NULL, allowinpm smallint NOT NULL, regex smallint NOT NULL, kick smallint NOT NULL, cs smallint NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;"); 5823 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'filter (filtermatch, filterreplace, allowinpm, regex, kick, cs) VALUES(?, ?, ?, ?, ?, ?);'); 5824 foreach ($data as $tmp) { 5825 $stmt->execute($tmp); 5826 } 5827 $result = $olddb->query('SELECT ign, ignby FROM ' . PREFIX . 'ignored;'); 5828 $data = $result->fetchAll(PDO::FETCH_NUM); 5829 $db->exec('DROP TABLE ' . PREFIX . 'ignored;'); 5830 $db->exec('CREATE TABLE ' . PREFIX . "ignored (id integer PRIMARY KEY AUTO_INCREMENT, ign varchar(50) NOT NULL, ignby varchar(50) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;"); 5831 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'ignored (ign, ignby) VALUES(?, ?);'); 5832 foreach ($data as $tmp) { 5833 $stmt->execute($tmp); 5834 } 5835 $db->exec('CREATE INDEX ' . PREFIX . 'ign ON ' . PREFIX . 'ignored(ign);'); 5836 $db->exec('CREATE INDEX ' . PREFIX . 'ignby ON ' . PREFIX . 'ignored(ignby);'); 5837 $result = $olddb->query('SELECT postdate, postid, poster, recipient, text FROM ' . PREFIX . 'inbox;'); 5838 $data = $result->fetchAll(PDO::FETCH_NUM); 5839 $db->exec('DROP TABLE ' . PREFIX . 'inbox;'); 5840 $db->exec('CREATE TABLE ' . PREFIX . "inbox (id integer PRIMARY KEY AUTO_INCREMENT, postdate integer NOT NULL, postid integer NOT NULL UNIQUE, poster varchar(50) NOT NULL, recipient varchar(50) NOT NULL, text text NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;"); 5841 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'inbox (postdate, postid, poster, recipient, text) VALUES(?, ?, ?, ?, ?);'); 5842 foreach ($data as $tmp) { 5843 $stmt->execute($tmp); 5844 } 5845 $db->exec('CREATE INDEX ' . PREFIX . 'inbox_poster ON ' . PREFIX . 'inbox(poster);'); 5846 $db->exec('CREATE INDEX ' . PREFIX . 'inbox_recipient ON ' . PREFIX . 'inbox(recipient);'); 5847 $result = $olddb->query('SELECT filtermatch, filterreplace, regex FROM ' . PREFIX . 'linkfilter;'); 5848 $data = $result->fetchAll(PDO::FETCH_NUM); 5849 $db->exec('DROP TABLE ' . PREFIX . 'linkfilter;'); 5850 $db->exec('CREATE TABLE ' . PREFIX . "linkfilter (id integer PRIMARY KEY AUTO_INCREMENT, filtermatch varchar(255) NOT NULL, filterreplace varchar(255) NOT NULL, regex smallint NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;"); 5851 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'linkfilter (filtermatch, filterreplace, regex) VALUES(?, ?, ?);'); 5852 foreach ($data as $tmp) { 5853 $stmt->execute($tmp); 5854 } 5855 $result = $olddb->query('SELECT nickname, passhash, status, refresh, bgcolour, regedby, lastlogin, timestamps, embed, incognito, style, nocache, tz, eninbox, sortupdown, hidechatters FROM ' . PREFIX . 'members;'); 5856 $data = $result->fetchAll(PDO::FETCH_NUM); 5857 $db->exec('DROP TABLE ' . PREFIX . 'members;'); 5858 $db->exec('CREATE TABLE ' . PREFIX . "members (id integer PRIMARY KEY AUTO_INCREMENT, nickname varchar(50) NOT NULL UNIQUE, passhash char(32) NOT NULL, status smallint NOT NULL, refresh smallint NOT NULL, bgcolour char(6) NOT NULL, regedby varchar(50) DEFAULT '', lastlogin integer DEFAULT 0, timestamps smallint NOT NULL, embed smallint NOT NULL, incognito smallint NOT NULL, style varchar(255) NOT NULL, nocache smallint NOT NULL, tz smallint NOT NULL, eninbox smallint NOT NULL, sortupdown smallint NOT NULL, hidechatters smallint NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;"); 5859 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'members (nickname, passhash, status, refresh, bgcolour, regedby, lastlogin, timestamps, embed, incognito, style, nocache, tz, eninbox, sortupdown, hidechatters) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);'); 5860 foreach ($data as $tmp) { 5861 $stmt->execute($tmp); 5862 } 5863 $result = $olddb->query('SELECT postdate, poststatus, poster, recipient, text, delstatus FROM ' . PREFIX . 'messages;'); 5864 $data = $result->fetchAll(PDO::FETCH_NUM); 5865 $db->exec('DROP TABLE ' . PREFIX . 'messages;'); 5866 $db->exec('CREATE TABLE ' . PREFIX . "messages (id integer PRIMARY KEY AUTO_INCREMENT, postdate integer NOT NULL, poststatus smallint NOT NULL, poster varchar(50) NOT NULL, recipient varchar(50) NOT NULL, text text NOT NULL, delstatus smallint NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;"); 5867 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'messages (postdate, poststatus, poster, recipient, text, delstatus) VALUES(?, ?, ?, ?, ?, ?);'); 5868 foreach ($data as $tmp) { 5869 $stmt->execute($tmp); 5870 } 5871 $db->exec('CREATE INDEX ' . PREFIX . 'poster ON ' . PREFIX . 'messages (poster);'); 5872 $db->exec('CREATE INDEX ' . PREFIX . 'recipient ON ' . PREFIX . 'messages(recipient);'); 5873 $db->exec('CREATE INDEX ' . PREFIX . 'postdate ON ' . PREFIX . 'messages(postdate);'); 5874 $db->exec('CREATE INDEX ' . PREFIX . 'poststatus ON ' . PREFIX . 'messages(poststatus);'); 5875 $result = $olddb->query('SELECT type, lastedited, editedby, text FROM ' . PREFIX . 'notes;'); 5876 $data = $result->fetchAll(PDO::FETCH_NUM); 5877 $db->exec('DROP TABLE ' . PREFIX . 'notes;'); 5878 $db->exec('CREATE TABLE ' . PREFIX . "notes (id integer PRIMARY KEY AUTO_INCREMENT, type char(5) NOT NULL, lastedited integer NOT NULL, editedby varchar(50) NOT NULL, text text NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;"); 5879 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'notes (type, lastedited, editedby, text) VALUES(?, ?, ?, ?);'); 5880 foreach ($data as $tmp) { 5881 $stmt->execute($tmp); 5882 } 5883 $result = $olddb->query('SELECT setting, value FROM ' . PREFIX . 'settings;'); 5884 $data = $result->fetchAll(PDO::FETCH_NUM); 5885 $db->exec('DROP TABLE ' . PREFIX . 'settings;'); 5886 $db->exec('CREATE TABLE ' . PREFIX . "settings (setting varchar(50) NOT NULL PRIMARY KEY, value text NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;"); 5887 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'settings (setting, value) VALUES(?, ?);'); 5888 foreach ($data as $tmp) { 5889 $stmt->execute($tmp); 5890 } 5891 } 5892 if ($dbversion < 33) { 5893 $db->exec('CREATE TABLE ' . PREFIX . "files (id $primary, postid integer NOT NULL UNIQUE, filename varchar(255) NOT NULL, hash char(40) NOT NULL, type varchar(255) NOT NULL, data $longtext NOT NULL)$diskengine$charset;"); 5894 $db->exec('CREATE INDEX ' . PREFIX . 'files_hash ON ' . PREFIX . 'files(hash);'); 5895 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('enfileupload', '0'), ('msgattache', '%2\$s [%1\$s]'), ('maxuploadsize', '1024');"); 5896 } 5897 if ($dbversion < 34) { 5898 $msg .= "<br>$I[cssupdate]"; 5899 $db->exec('ALTER TABLE ' . PREFIX . 'members ADD COLUMN nocache_old smallint NOT NULL DEFAULT 0;'); 5900 } 5901 if ($dbversion < 37) { 5902 $db->exec('ALTER TABLE ' . PREFIX . 'members MODIFY tz varchar(255) NOT NULL;'); 5903 $db->exec('UPDATE ' . PREFIX . "members SET tz='UTC';"); 5904 $db->exec('UPDATE ' . PREFIX . "settings SET value='UTC' WHERE setting='defaulttz';"); 5905 } 5906 if ($dbversion < 38) { 5907 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('nextcron', '0');"); 5908 $db->exec('DELETE FROM ' . PREFIX . 'inbox WHERE recipient NOT IN (SELECT nickname FROM ' . PREFIX . 'members);'); // delete inbox of members who deleted themselves 5909 } 5910 if ($dbversion < 39) { 5911 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('personalnotes', '1');"); 5912 $result = $db->query('SELECT type, id FROM ' . PREFIX . 'notes;'); 5913 while ($tmp = $result->fetch(PDO::FETCH_NUM)) { 5914 if ($tmp[0] === 'admin') { 5915 $tmp[0] = 0; 5916 } else { 5917 $tmp[0] = 1; 5918 } 5919 $data[] = $tmp; 5920 } 5921 $db->exec('ALTER TABLE ' . PREFIX . 'notes MODIFY type smallint NOT NULL;'); 5922 $stmt = $db->prepare('UPDATE ' . PREFIX . 'notes SET type=? WHERE id=?;'); 5923 foreach ($data as $tmp) { 5924 $stmt->execute($tmp); 5925 } 5926 $db->exec('CREATE INDEX ' . PREFIX . 'notes_type ON ' . PREFIX . 'notes(type);'); 5927 $db->exec('CREATE INDEX ' . PREFIX . 'notes_editedby ON ' . PREFIX . 'notes(editedby);'); 5928 } 5929 if ($dbversion < 41) { 5930 $db->exec('DROP TABLE ' . PREFIX . 'sessions;'); 5931 $db->exec('CREATE TABLE ' . PREFIX . "sessions (id $primary, session char(32) NOT NULL UNIQUE, nickname varchar(50) NOT NULL UNIQUE, status smallint NOT NULL, refresh smallint NOT NULL, style varchar(255) NOT NULL, lastpost integer NOT NULL, passhash varchar(255) NOT NULL, postid char(6) NOT NULL DEFAULT '000000', useragent varchar(255) NOT NULL, kickmessage varchar(255) DEFAULT '', bgcolour char(6) NOT NULL, entry integer NOT NULL, timestamps smallint NOT NULL, embed smallint NOT NULL, incognito smallint NOT NULL, ip varchar(45) NOT NULL, nocache smallint NOT NULL, tz varchar(255) NOT NULL, eninbox smallint NOT NULL, sortupdown smallint NOT NULL, hidechatters smallint NOT NULL, nocache_old smallint NOT NULL)$memengine$charset;"); 5932 $db->exec('CREATE INDEX ' . PREFIX . 'status ON ' . PREFIX . 'sessions(status);'); 5933 $db->exec('CREATE INDEX ' . PREFIX . 'lastpost ON ' . PREFIX . 'sessions(lastpost);'); 5934 $db->exec('CREATE INDEX ' . PREFIX . 'incognito ON ' . PREFIX . 'sessions(incognito);'); 5935 $result = $db->query('SELECT nickname, passhash, status, refresh, bgcolour, regedby, lastlogin, timestamps, embed, incognito, style, nocache, nocache_old, tz, eninbox, sortupdown, hidechatters FROM ' . PREFIX . 'members;'); 5936 $members = $result->fetchAll(PDO::FETCH_NUM); 5937 $result = $db->query('SELECT postdate, postid, poster, recipient, text FROM ' . PREFIX . 'inbox;'); 5938 $inbox = $result->fetchAll(PDO::FETCH_NUM); 5939 $db->exec('DROP TABLE ' . PREFIX . 'inbox;'); 5940 $db->exec('DROP TABLE ' . PREFIX . 'members;'); 5941 $db->exec('CREATE TABLE ' . PREFIX . "members (id $primary, nickname varchar(50) NOT NULL UNIQUE, passhash varchar(255) NOT NULL, status smallint NOT NULL, refresh smallint NOT NULL, bgcolour char(6) NOT NULL, regedby varchar(50) DEFAULT '', lastlogin integer DEFAULT 0, timestamps smallint NOT NULL, embed smallint NOT NULL, incognito smallint NOT NULL, style varchar(255) NOT NULL, nocache smallint NOT NULL, nocache_old smallint NOT NULL, tz varchar(255) NOT NULL, eninbox smallint NOT NULL, sortupdown smallint NOT NULL, hidechatters smallint NOT NULL)$diskengine$charset"); 5942 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'members (nickname, passhash, status, refresh, bgcolour, regedby, lastlogin, timestamps, embed, incognito, style, nocache, nocache_old, tz, eninbox, sortupdown, hidechatters) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);'); 5943 foreach ($members as $tmp) { 5944 $stmt->execute($tmp); 5945 } 5946 $db->exec('CREATE TABLE ' . PREFIX . "inbox (id $primary, postdate integer NOT NULL, postid integer NOT NULL UNIQUE, poster varchar(50) NOT NULL, recipient varchar(50) NOT NULL, text text NOT NULL)$diskengine$charset;"); 5947 $stmt = $db->prepare('INSERT INTO ' . PREFIX . 'inbox (postdate, postid, poster, recipient, text) VALUES(?, ?, ?, ?, ?);'); 5948 foreach ($inbox as $tmp) { 5949 $stmt->execute($tmp); 5950 } 5951 $db->exec('CREATE INDEX ' . PREFIX . 'inbox_poster ON ' . PREFIX . 'inbox(poster);'); 5952 $db->exec('CREATE INDEX ' . PREFIX . 'inbox_recipient ON ' . PREFIX . 'inbox(recipient);'); 5953 $db->exec('ALTER TABLE ' . PREFIX . 'inbox ADD FOREIGN KEY (recipient) REFERENCES ' . PREFIX . 'members(nickname) ON DELETE CASCADE ON UPDATE CASCADE;'); 5954 } 5955 if ($dbversion < 42) { 5956 $db->exec('INSERT IGNORE INTO ' . PREFIX . "settings (setting, value) VALUES ('filtermodkick', '1');"); 5957 } 5958 //MODIFICATION Text field for links in settings and option to enable or disable links page. 5959 if ($dbversion < 1142) { 5960 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('links', '');"); 5961 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('linksenabled', '0');"); 5962 } 5963 //MODIFICATION option to enable or disable DEL-Buttons for members, if no mod is present. (DEL Buttons can bes used to delete messages within the message frame) 5964 if ($dbversion < 1242) { 5965 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('memdel', '0');"); 5966 } 5967 5968 //MODIFICATION clickable nicknames 5969 /* REMOVE LATER 5970 if($dbversion<1243){ 5971 $db->exec('ALTER TABLE ' . PREFIX . 'sessions ADD COLUMN clickablenicknames smallint NOT NULL DEFAULT 0;'); 5972 $db->exec('ALTER TABLE ' . PREFIX . 'members ADD COLUMN clickablenicknames smallint NOT NULL DEFAULT 0;'); 5973 } 5974 */ 5975 5976 //MODIFICATION option to set galleryaccess and forum button visibility for users depending on their rank(status). 5977 if ($dbversion < 1342) { 5978 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('galleryaccess', '10');"); 5979 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('forumbtnaccess', '10');"); 5980 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('forumbtnlink', 'forum/index.php');"); 5981 } 5982 //MODIFICATION fontpgagetext - Text field for text on front page of the chat. 5983 if ($dbversion < 1442) { 5984 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('frontpagetext', '');"); 5985 } 5986 //MODIFICATION modsdeladminmsg - mods can delete admin messages. To be more precise: Staff members can delete messages of higher ranked staff members, bot only those messages that the lower ranked staff member can read (where status <= poststatus). 5987 if ($dbversion < 1542) { 5988 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('modsdeladminmsg', '0');"); 5989 } 5990 //MODIFICATION adminjoinleavemsg to not create a system message if an admins arrives or leaves the chat 5991 if ($dbversion < 1642) { 5992 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('adminjoinleavemsg', '1');"); 5993 } 5994 5995 //MODIFICATION clickablenicknamesglobal (nicknames at beginning of messages are clickable) 5996 if ($dbversion < 1742) { 5997 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('clickablenicknamesglobal', '1');"); 5998 } 5999 // Modification spare notes 6000 if ($dbversion < 2100) { 6001 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('sparenotesaccess', '10');"); 6002 $db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('sparenotesname', '');"); 6003 } 6004 // Modification for rooms 6005 if ($dbversion < 2101) { 6006 $db->exec('INSERT IGNORE INTO ' . PREFIX . "settings (setting, value) VALUES ('roomcreateaccess', '7');"); 6007 $db->exec('CREATE TABLE ' . PREFIX . "rooms (id $primary, name varchar(50) NOT NULL UNIQUE, access smallint NOT NULL, time integer NOT NULL)$diskengine$charset"); 6008 $db->exec('ALTER TABLE ' . PREFIX . 'sessions ADD COLUMN roomid integer;'); 6009 $db->exec('ALTER TABLE ' . PREFIX . 'messages ADD COLUMN roomid integer;'); 6010 $db->exec('CREATE INDEX ' . PREFIX . 'sroomid ON ' . PREFIX . 'sessions(roomid);'); 6011 $db->exec('CREATE INDEX ' . PREFIX . 'mroomid ON ' . PREFIX . 'messages(roomid);'); 6012 $db->exec('INSERT IGNORE INTO ' . PREFIX . "settings (setting, value) VALUES ('roomexpire', '10');"); 6013 } 6014 // Modification for rooms 6015 if ($dbversion < 2102) { 6016 $db->exec('ALTER TABLE ' . PREFIX . 'rooms ADD COLUMN permanent smallint NOT NULL DEFAULT(0);'); 6017 $db->exec('ALTER TABLE ' . PREFIX . 'messages ADD COLUMN allrooms smallint NOT NULL DEFAULT(0);'); 6018 } 6019 // Modification for rooms 6020 if ($dbversion < 2103) { 6021 $db->exec('INSERT IGNORE INTO ' . PREFIX . "settings (setting, value) VALUES ('channelvisinroom', '2');"); 6022 } 6023 update_setting('dbversion', DBVERSION); 6024 if ($msgencrypted !== MSGENCRYPTED) { 6025 if (!extension_loaded('sodium')) { 6026 send_fatal_error($I['sodiumextrequired']); 6027 } 6028 $result = $db->query('SELECT id, text FROM ' . PREFIX . 'messages;'); 6029 $stmt = $db->prepare('UPDATE ' . PREFIX . 'messages SET text=? WHERE id=?;'); 6030 while ($message = $result->fetch(PDO::FETCH_ASSOC)) { 6031 if (MSGENCRYPTED) { 6032 $message['text'] = base64_encode(sodium_crypto_aead_aes256gcm_encrypt($message['text'], '', AES_IV, ENCRYPTKEY)); 6033 } else { 6034 $message['text'] = sodium_crypto_aead_aes256gcm_decrypt(base64_decode($message['text']), null, AES_IV, ENCRYPTKEY); 6035 } 6036 $stmt->execute([$message['text'], $message['id']]); 6037 } 6038 $result = $db->query('SELECT id, text FROM ' . PREFIX . 'notes;'); 6039 $stmt = $db->prepare('UPDATE ' . PREFIX . 'notes SET text=? WHERE id=?;'); 6040 while ($message = $result->fetch(PDO::FETCH_ASSOC)) { 6041 if (MSGENCRYPTED) { 6042 $message['text'] = base64_encode(sodium_crypto_aead_aes256gcm_encrypt($message['text'], '', AES_IV, ENCRYPTKEY)); 6043 } else { 6044 $message['text'] = sodium_crypto_aead_aes256gcm_decrypt(base64_decode($message['text']), null, AES_IV, ENCRYPTKEY); 6045 } 6046 $stmt->execute([$message['text'], $message['id']]); 6047 } 6048 update_setting('msgencrypted', (int) MSGENCRYPTED); 6049 } 6050 send_update($msg); 6051 } 6052 6053 function get_setting($setting) 6054 { 6055 global $db, $memcached; 6056 if (!MEMCACHED || !$value = $memcached->get(DBNAME . '-' . PREFIX . "settings-$setting")) { 6057 $stmt = $db->prepare('SELECT value FROM ' . PREFIX . 'settings WHERE setting=?;'); 6058 $stmt->execute([$setting]); 6059 $stmt->bindColumn(1, $value); 6060 $stmt->fetch(PDO::FETCH_BOUND); 6061 if (MEMCACHED) { 6062 $memcached->set(DBNAME . '-' . PREFIX . "settings-$setting", $value); 6063 } 6064 } 6065 return $value; 6066 } 6067 6068 function update_setting($setting, $value) 6069 { 6070 global $db, $memcached; 6071 $stmt = $db->prepare('UPDATE ' . PREFIX . 'settings SET value=? WHERE setting=?;'); 6072 $stmt->execute([$value, $setting]); 6073 if (MEMCACHED) { 6074 $memcached->set(DBNAME . '-' . PREFIX . "settings-$setting", $value); 6075 } 6076 } 6077 6078 // configuration, defaults and internals 6079 6080 function check_db() 6081 { 6082 global $I, $db, $memcached; 6083 $options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT => PERSISTENT]; 6084 try { 6085 if (DBDRIVER === 0) { 6086 if (!extension_loaded('pdo_mysql')) { 6087 send_fatal_error($I['pdo_mysqlextrequired']); 6088 } 6089 $db = new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME . ';charset=utf8mb4', DBUSER, DBPASS, $options); 6090 } elseif (DBDRIVER === 1) { 6091 if (!extension_loaded('pdo_pgsql')) { 6092 send_fatal_error($I['pdo_pgsqlextrequired']); 6093 } 6094 $db = new PDO('pgsql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, $options); 6095 } else { 6096 if (!extension_loaded('pdo_sqlite')) { 6097 send_fatal_error($I['pdo_sqliteextrequired']); 6098 } 6099 $db = new PDO('sqlite:' . SQLITEDBFILE, NULL, NULL, $options); 6100 } 6101 } catch (PDOException $e) { 6102 try { 6103 //Attempt to create database 6104 if (DBDRIVER === 0) { 6105 $db = new PDO('mysql:host=' . DBHOST, DBUSER, DBPASS, $options); 6106 if (false !== $db->exec('CREATE DATABASE ' . DBNAME)) { 6107 $db = new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME . ';charset=utf8mb4', DBUSER, DBPASS, $options); 6108 } else { 6109 send_fatal_error($I['nodbsetup']); 6110 } 6111 } elseif (DBDRIVER === 1) { 6112 $db = new PDO('pgsql:host=' . DBHOST, DBUSER, DBPASS, $options); 6113 if (false !== $db->exec('CREATE DATABASE ' . DBNAME)) { 6114 $db = new PDO('pgsql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, $options); 6115 } else { 6116 send_fatal_error($I['nodbsetup']); 6117 } 6118 } else { 6119 if (isset($_REQUEST['action']) && $_REQUEST['action'] === 'setup') { 6120 send_fatal_error($I['nodbsetup']); 6121 } else { 6122 send_fatal_error($I['nodb']); 6123 } 6124 } 6125 } catch (PDOException $e) { 6126 if (isset($_REQUEST['action']) && $_REQUEST['action'] === 'setup') { 6127 send_fatal_error($I['nodbsetup']); 6128 } else { 6129 send_fatal_error($I['nodb']); 6130 } 6131 } 6132 } 6133 if (MEMCACHED) { 6134 if (!extension_loaded('memcached')) { 6135 send_fatal_error($I['memcachedextrequired']); 6136 } 6137 $memcached = new Memcached(); 6138 $memcached->addServer(MEMCACHEDHOST, MEMCACHEDPORT); 6139 } 6140 if (!isset($_REQUEST['action']) || $_REQUEST['action'] === 'setup') { 6141 if (!check_init()) { 6142 send_init(); 6143 } 6144 update_db(); 6145 } elseif ($_REQUEST['action'] === 'init') { 6146 init_chat(); 6147 } 6148 } 6149 6150 function load_fonts() 6151 { 6152 return [ 6153 'Arial' => "font-family:'Arial','Helvetica','sans-serif';", 6154 'Book Antiqua' => "font-family:'Book Antiqua','MS Gothic';", 6155 'Comic' => "font-family:'Comic Sans MS','Papyrus';", 6156 'Courier' => "font-family:'Courier New','Courier','monospace';", 6157 'Cursive' => "font-family:'Cursive','Papyrus';", 6158 'Fantasy' => "font-family:'Fantasy','Futura','Papyrus';", 6159 'Garamond' => "font-family:'Garamond','Palatino','serif';", 6160 'Georgia' => "font-family:'Georgia','Times New Roman','Times','serif';", 6161 'Serif' => "font-family:'MS Serif','New York','serif';", 6162 'System' => "font-family:'System','Chicago','sans-serif';", 6163 'Times New Roman' => "font-family:'Times New Roman','Times','serif';", 6164 'Verdana' => "font-family:'Verdana','Geneva','Arial','Helvetica','sans-serif';", 6165 ]; 6166 } 6167 6168 function load_lang() 6169 { 6170 global $I, $L, $language; 6171 $L = [ 6172 'bg' => 'Български', 6173 'cz' => 'čeština', 6174 'de' => 'Deutsch', 6175 'en' => 'English', 6176 'es' => 'Español', 6177 'fr' => 'Français', 6178 'id' => 'Bahasa Indonesia', 6179 'it' => 'Italiano', 6180 'ru' => 'Русский', 6181 'tr' => 'Türkçe', 6182 'uk' => 'Українська', 6183 'zh_CN' => '简体中文', 6184 ]; 6185 if (isset($_REQUEST['lang']) && isset($L[$_REQUEST['lang']])) { 6186 $language = $_REQUEST['lang']; 6187 if (!isset($_COOKIE['language']) || $_COOKIE['language'] !== $language) { 6188 set_secure_cookie('language', $language); 6189 } 6190 } elseif (isset($_COOKIE['language']) && isset($L[$_COOKIE['language']])) { 6191 $language = $_COOKIE['language']; 6192 } else { 6193 $language = LANG; 6194 set_secure_cookie('language', $language); 6195 } 6196 include('lang_en.php'); //always include English 6197 if ($language !== 'en') { 6198 $T = []; 6199 include("lang_$language.php"); //replace with translation if available 6200 foreach ($T as $name => $translation) { 6201 $I[$name] = $translation; 6202 } 6203 } 6204 } 6205 6206 function load_config() 6207 { 6208 mb_internal_encoding('UTF-8'); 6209 define('VERSION', '2.2.2'); // Script version 6210 //See changelog 6211 6212 define('DBVERSION', 10); // Database layout version 6213 //Paste other config below this line: 6214 define('MSGENCRYPTED', false); // Store messages encrypted in the database to prevent other database users from reading them - true/false - visit the setup page after editing! 6215 define('ENCRYPTKEY_PASS', 'MY_SECRET_KEY'); // Recommended length: 32. Encryption key for messages 6216 define('AES_IV_PASS', '012345678912'); // Recommended length: 12. AES Encryption IV 6217 define('DBHOST', 'dbhost'); // Database host 6218 define('DBUSER', 'dbuser'); // Database user 6219 define('DBPASS', 'dbpass'); // Database password 6220 define('DBNAME', 'dbname'); // Database 6221 define('PERSISTENT', true); // Use persistent database conection true/false 6222 define('PREFIX', ''); // Prefix - Set this to a unique value for every chat, if you have more than 1 chats on the same database or domain - use only alpha-numeric values (A-Z, a-z, 0-9, or _) other symbols might break the queries 6223 define('MEMCACHED', false); // Enable/disable memcached caching true/false - needs memcached extension and a memcached server. 6224 if (MEMCACHED) { 6225 define('MEMCACHEDHOST', 'localhost'); // Memcached host 6226 define('MEMCACHEDPORT', '11211'); // Memcached port 6227 } 6228 define('DBDRIVER', 2); // Selects the database driver to use - 0=MySQL, 1=PostgreSQL, 2=sqlite 6229 if (DBDRIVER === 2) { 6230 define('SQLITEDBFILE', $_ENV['SQLITE_DB_PATH'] ?? getenv('SQLITE_DB_PATH') ?? 'super_chat.sqlite'); // Filepath of the sqlite database, if sqlite is used - make sure it is writable for the webserver user 6231 } 6232 define('COOKIENAME', PREFIX . 'chat_session'); // Cookie name storing the session information 6233 define('LANG', 'en'); // Default language 6234 if (MSGENCRYPTED) { 6235 if (version_compare(PHP_VERSION, '7.2.0') < 0) { 6236 die("You need at least PHP >= 7.2.x"); 6237 } 6238 //Do not touch: Compute real keys needed by encryption functions 6239 if (strlen(ENCRYPTKEY_PASS) !== SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES) { 6240 define('ENCRYPTKEY', substr(hash("sha512/256", ENCRYPTKEY_PASS), 0, SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES)); 6241 } else { 6242 define('ENCRYPTKEY', ENCRYPTKEY_PASS); 6243 } 6244 if (strlen(AES_IV_PASS) !== SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES) { 6245 define('AES_IV', substr(hash("sha512/256", AES_IV_PASS), 0, SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES)); 6246 } else { 6247 define('AES_IV', AES_IV_PASS); 6248 } 6249 } 6250 }