diff --git a/api/index.php b/api/index.php index a061df0..2b1859b 100644 --- a/api/index.php +++ b/api/index.php @@ -14,7 +14,7 @@ header("Content-Type: application/json; charset=UTF-8"); if (isset($_GET['apikey'])) { $matchkey = 0; foreach($cfg['stats_api_keys'] as $apikey => $desc) { - if ($apikey == $_GET['apikey']) $matchkey = 1; + if (hash_equals($apikey, $_GET['apikey'])) $matchkey = 1; } if ($matchkey == 0) { $json = array( diff --git a/install.php b/install.php index 4dbba78..034c8e1 100644 --- a/install.php +++ b/install.php @@ -1,5 +1,5 @@ exec("DROP DATABASE `$dbname`")) === false) { } + $stmt = $mysqlcon->query('SHOW DATABASES'); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + if ($row['Database'] == $dbname) { + $dbExists = true; + break; + } + } + if ($dbExists) { + if(($mysqlcon->exec("DROP DATABASE `$dbname`")) === false) { } + } if($mysqlcon->exec("CREATE DATABASE `$dbname`") === false) { $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2; @@ -168,7 +177,7 @@ $db[\'dbname\']=\''.$dbname.'\'; $count++; } - if($mysqlcon->exec("INSERT INTO `$dbname`.`job_check` (`job_name`) VALUES ('calc_user_limit'),('calc_user_lastscan'),('calc_user_removed'),('check_update'),('database_export'),('get_version'),('clean_db'),('clean_clients'),('calc_donut_chars'),('calc_server_stats'),('get_avatars'),('last_snapshot_id'),('last_snapshot_time'),('last_update'),('reload_trigger'),('reset_user_time'),('reset_user_delete'),('reset_group_withdraw'),('reset_webspace_cache'),('reset_usage_graph'),('reset_stop_after'),('runtime_check'),('update_channel'),('update_groups')") === false) { + if($mysqlcon->exec("INSERT INTO `$dbname`.`job_check` (`job_name`) VALUES ('calc_user_limit'),('calc_user_lastscan'),('calc_user_removed'),('check_update'),('clean_user_iphash'),('database_export'),('get_version'),('clean_db'),('clean_clients'),('calc_donut_chars'),('calc_server_stats'),('get_avatars'),('last_snapshot_id'),('last_snapshot_time'),('last_update'),('reload_trigger'),('reset_user_time'),('reset_user_delete'),('reset_group_withdraw'),('reset_webspace_cache'),('reset_usage_graph'),('reset_stop_after'),('runtime_check'),('update_channel'),('update_groups')") === false) { $err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'
'; $err_lvl = 2; $count++; } diff --git a/jobs/addon_channelinfo_toplist.php b/jobs/addon_channelinfo_toplist.php index 8221904..bece647 100644 --- a/jobs/addon_channelinfo_toplist.php +++ b/jobs/addon_channelinfo_toplist.php @@ -92,12 +92,12 @@ function addon_channelinfo_toplist(&$addons_config,$ts3,$mysqlcon,$cfg,$dbname,$ $smarty->assign('CLIENT_NEXT_RANKUP_TIME_'.($nr + 1),$userdata[$nr]['nextup']); $smarty->assign('CLIENT_CURRENT_RANK_GROUP_ID_'.($nr + 1),$userdata[$nr]['grpid']); - if(isset($db_cache['groups'][$userdata[$nr]['grpid']]['sgidname'])) { + if(isset($db_cache['groups'][$userdata[$nr]['grpid']]['sgidname']) && $userdata[$nr]['grpid'] != 0) { $smarty->assign('CLIENT_CURRENT_RANK_GROUP_NAME_'.($nr + 1),substr($db_cache['groups'][$userdata[$nr]['grpid']]['sgidname'],1,-1)); } else { $smarty->assign('CLIENT_CURRENT_RANK_GROUP_NAME_'.($nr + 1),'unknown_group'); } - if(isset($db_cache['groups'][$userdata[$nr]['grpid']]['iconid']) && isset($db_cache['groups'][$userdata[$nr]['grpid']]['ext'])) { + if(isset($db_cache['groups'][$userdata[$nr]['grpid']]['iconid']) && isset($db_cache['groups'][$userdata[$nr]['grpid']]['ext']) && $userdata[$nr]['grpid'] != 0) { $smarty->assign('CLIENT_CURRENT_RANK_GROUP_ICON_URL_'.($nr + 1),'tsicons/'.$db_cache['groups'][$userdata[$nr]['grpid']]['iconid'].'.'.$db_cache['groups'][$userdata[$nr]['grpid']]['ext']); } else { $smarty->assign('CLIENT_CURRENT_RANK_GROUP_ICON_URL_'.($nr + 1),'file_not_found'); diff --git a/jobs/bot.php b/jobs/bot.php index 2f7ef14..334be78 100644 --- a/jobs/bot.php +++ b/jobs/bot.php @@ -145,7 +145,7 @@ function run_bot(&$cfg) { enter_logfile($cfg,9," Select virtual server..."); try { - if(version_compare($ts3version['version'],'3.4.0','>=')) { + if(version_compare($ts3version['version'],'3.4.0','>=') || version_compare($ts3version['version'],'3.0.0','<=')) { usleep($cfg['teamspeak_query_command_delay']); $ts3server = $ts3host->serverGetByPort($cfg['teamspeak_voice_port'], $cfg['teamspeak_query_nickname']); } else { diff --git a/jobs/calc_serverstats.php b/jobs/calc_serverstats.php index 8f41787..4ec5796 100644 --- a/jobs/calc_serverstats.php +++ b/jobs/calc_serverstats.php @@ -408,8 +408,6 @@ function calc_serverstats($ts3,$mysqlcon,&$cfg,$dbname,$dbtype,$serverinfo,&$db_ $cfg['temp_db_version'] ); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,false); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,false); curl_setopt($ch, CURLOPT_MAXREDIRS, 10); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); @@ -435,14 +433,20 @@ function calc_serverstats($ts3,$mysqlcon,&$cfg,$dbname,$dbtype,$serverinfo,&$db_ } //Calc Rank + $dbversion = $mysqlcon->getAttribute(PDO::ATTR_SERVER_VERSION); + preg_match("/^[0-9\.-]+/", $dbversion, $version_number); if ($cfg['rankup_time_assess_mode'] == 1) { - $sqlexec .= "SET @a:=0;\nUPDATE `$dbname`.`user` AS `u` INNER JOIN (SELECT @a:=@a+1 `nr`,`uuid` FROM `$dbname`.`user` WHERE `except`<2 ORDER BY (`count` - `idle`) DESC) AS `s` USING (`uuid`) SET `u`.`rank`=`s`.`nr`;\n"; - //MySQL 8 or above - //UPDATE `user` AS `u` INNER JOIN (SELECT RANK() OVER (ORDER BY (`count` - `idle`) DESC) AS `rank`, `uuid` FROM `$dbname`.`user` WHERE `except`<2) AS `s` USING (`uuid`) SET `u`.`rank`=`s`.`rank`; + if(version_compare($version_number[0], '10.6', '>=') || version_compare($version_number[0], '5.5.5-10.6', '>=')) { + $sqlexec .= "UPDATE `$dbname`.`user` AS `u` INNER JOIN (SELECT RANK() OVER (ORDER BY (`count` - `idle`) DESC) AS `rank`, `uuid` FROM `$dbname`.`user` WHERE `except`<2) AS `s` USING (`uuid`) SET `u`.`rank`=`s`.`rank`;\n"; + } else { + $sqlexec .= "SET @a:=0;\nUPDATE `$dbname`.`user` AS `u` INNER JOIN (SELECT @a:=@a+1 `nr`,`uuid` FROM `$dbname`.`user` WHERE `except`<2 ORDER BY (`count` - `idle`) DESC) AS `s` USING (`uuid`) SET `u`.`rank`=`s`.`nr`;\n"; + } } else { - $sqlexec .= "SET @a:=0;\nUPDATE `$dbname`.`user` AS `u` INNER JOIN (SELECT @a:=@a+1 `nr`,`uuid` FROM `$dbname`.`user` WHERE `except`<2 ORDER BY `count` DESC) AS `s` USING (`uuid`) SET `u`.`rank`=`s`.`nr`;\n"; - //MySQL 8 or above - //UPDATE `user` AS `u` INNER JOIN (SELECT RANK() OVER (ORDER BY `count` DESC) AS `rank`, `uuid` FROM `$dbname`.`user` WHERE `except`<2) AS `s` USING (`uuid`) SET `u`.`rank`=`s`.`rank`; + if(version_compare($version_number[0], '10.6', '>=') || version_compare($version_number[0], '5.5.5-10.6', '>=')) { + $sqlexec .= "UPDATE `$dbname`.`user` AS `u` INNER JOIN (SELECT RANK() OVER (ORDER BY `count` DESC) AS `rank`, `uuid` FROM `$dbname`.`user` WHERE `except`<2) AS `s` USING (`uuid`) SET `u`.`rank`=`s`.`rank`;\n"; + } else { + $sqlexec .= "SET @a:=0;\nUPDATE `$dbname`.`user` AS `u` INNER JOIN (SELECT @a:=@a+1 `nr`,`uuid` FROM `$dbname`.`user` WHERE `except`<2 ORDER BY `count` DESC) AS `s` USING (`uuid`) SET `u`.`rank`=`s`.`nr`;\n"; + } } } diff --git a/jobs/calc_user.php b/jobs/calc_user.php index 7ce71e1..b92fb88 100644 --- a/jobs/calc_user.php +++ b/jobs/calc_user.php @@ -90,7 +90,7 @@ function calc_user($ts3,$mysqlcon,$lang,$cfg,$dbname,$allclients,$phpcommand,&$d $name = $mysqlcon->quote((mb_substr(mb_convert_encoding($client['client_nickname'],'UTF-8','auto'),0,30)), ENT_QUOTES); $uid = htmlspecialchars($client['client_unique_identifier'], ENT_QUOTES); $sgroups = array_flip(explode(",", $client['client_servergroups'])); - if(strlen($client['client_country']) > 2 || $client['client_country'] == '') $client['client_country'] = 'XX'; + if($client['client_country'] !== NULL && strlen($client['client_country']) > 2 || $client['client_country'] === NULL) $client['client_country'] = 'XX'; $client['client_platform'] = mb_substr($client['client_platform'],0,32); $client['client_version'] = mb_substr($client['client_version'],0,64); @@ -108,17 +108,18 @@ function calc_user($ts3,$mysqlcon,$lang,$cfg,$dbname,$allclients,$phpcommand,&$d if(isset($db_cache['all_user'][$uid]['except']) && ($db_cache['all_user'][$uid]['except'] == 3 || $db_cache['all_user'][$uid]['except'] == 2) && $cfg['rankup_excepted_mode'] == 2) { $db_cache['all_user'][$uid]['count'] = 0; $db_cache['all_user'][$uid]['idle'] = 0; - enter_logfile($cfg,5,sprintf($lang['resettime'], $name, $uid, $client['client_database_id'])); - $sqlexec .= "DELETE FROM `$dbname`.`user_snapshot` WHERE `uuid`='$uid';\n"; + enter_logfile($cfg,5,sprintf($lang['resettime'], $client['client_nickname'], $uid, $client['client_database_id'])); + $sqlexec .= "DELETE FROM `$dbname`.`user_snapshot` WHERE `cldbid`='{$client['client_database_id']}';\n"; } $except = 0; } if(isset($db_cache['all_user'][$uid])) { $idle = $db_cache['all_user'][$uid]['idle'] + $clientidle; if ($db_cache['all_user'][$uid]['cldbid'] != $client['client_database_id'] && $cfg['rankup_client_database_id_change_switch'] == 1) { - enter_logfile($cfg,5,sprintf($lang['changedbid'], $name, $uid, $client['client_database_id'], $db_cache['all_user'][$uid]['cldbid'])); + enter_logfile($cfg,5,sprintf($lang['changedbid'], $client['client_nickname'], $uid, $client['client_database_id'], $db_cache['all_user'][$uid]['cldbid'])); $count = 1; $idle = 0; + $boosttime = 0; } else { $hitboost = 0; $boosttime = $db_cache['all_user'][$uid]['boosttime']; @@ -129,14 +130,15 @@ function calc_user($ts3,$mysqlcon,$lang,$cfg,$dbname,$allclients,$phpcommand,&$d if($db_cache['all_user'][$uid]['boosttime']==0) { $boosttime = $nowtime; } else { - if ($nowtime > $db_cache['all_user'][$uid]['boosttime'] + $boost['time']) { + if ($nowtime > $db_cache['all_user'][$uid]['boosttime'] + $boost['time'] && (!isset($db_cache['all_user'][$uid]['grouperror']) || $db_cache['all_user'][$uid]['grouperror'] < ($nowtime - 300))) { usleep($cfg['teamspeak_query_command_delay']); try { $ts3->serverGroupClientDel($boost['group'], $client['client_database_id']); $boosttime = 0; - enter_logfile($cfg,5,sprintf($lang['sgrprm'], $db_cache['groups'][$boost['group']]['sgidname'], $boost['group'], $name, $uid, $client['client_database_id']).' [Boost-Group]'); + enter_logfile($cfg,5,sprintf($lang['sgrprm'], $db_cache['groups'][$boost['group']]['sgidname'], $boost['group'], $client['client_nickname'], $uid, $client['client_database_id']).' [Boost-Group]'); } catch (Exception $e) { - enter_logfile($cfg,2,"TS3 error: ".$e->getCode().': '.$e->getMessage()." ; ".sprintf($lang['sgrprerr'], $name, $uid, $client['client_database_id'], $db_cache['groups'][$db_cache['all_user'][$uid]['grpid']]['sgidname'], $db_cache['all_user'][$uid]['grpid'])); + enter_logfile($cfg,2,"TS3 error: ".$e->getCode().': '.$e->getMessage()." ; ".sprintf($lang['sgrprerr'], $client['client_nickname'], $uid, $client['client_database_id'], $db_cache['groups'][$db_cache['all_user'][$uid]['grpid']]['sgidname'], $db_cache['all_user'][$uid]['grpid'])); + $db_cache['all_user'][$uid]['grouperror'] = $nowtime; } } } @@ -189,31 +191,35 @@ function calc_user($ts3,$mysqlcon,$lang,$cfg,$dbname,$allclients,$phpcommand,&$d $donotremove = 1; break; } } - if($donotremove == 0) { + if($donotremove == 0 && (!isset($db_cache['all_user'][$uid]['grouperror']) || $db_cache['all_user'][$uid]['grouperror'] < ($nowtime - 300))) { usleep($cfg['teamspeak_query_command_delay']); try { $ts3->serverGroupClientDel($db_cache['all_user'][$uid]['grpid'], $client['client_database_id']); - enter_logfile($cfg,5,sprintf($lang['sgrprm'], $db_cache['groups'][$db_cache['all_user'][$uid]['grpid']]['sgidname'], $db_cache['all_user'][$uid]['grpid'], $name, $uid, $client['client_database_id'])); + enter_logfile($cfg,5,sprintf($lang['sgrprm'], $db_cache['groups'][$db_cache['all_user'][$uid]['grpid']]['sgidname'], $db_cache['all_user'][$uid]['grpid'], $client['client_nickname'], $uid, $client['client_database_id'])); if(isset($client_groups_rankup[$db_cache['all_user'][$uid]['grpid']])) unset($client_groups_rankup[$db_cache['all_user'][$uid]['grpid']]); } catch (Exception $e) { - enter_logfile($cfg,2,"TS3 error: ".$e->getCode().': '.$e->getMessage()." ; ".sprintf($lang['sgrprerr'], $name, $uid, $client['client_database_id'], $db_cache['groups'][$db_cache['all_user'][$uid]['grpid']]['sgidname'], $db_cache['all_user'][$uid]['grpid'])); + enter_logfile($cfg,2,"TS3 error: ".$e->getCode().': '.$e->getMessage()." ; ".sprintf($lang['sgrprerr'], $client['client_nickname'], $uid, $client['client_database_id'], $db_cache['groups'][$db_cache['all_user'][$uid]['grpid']]['sgidname'], $db_cache['all_user'][$uid]['grpid'])); + $db_cache['all_user'][$uid]['grouperror'] = $nowtime; } } } - usleep($cfg['teamspeak_query_command_delay']); - try { - $ts3->serverGroupClientAdd($rank['group'], $client['client_database_id']); - $db_cache['all_user'][$uid]['grpsince'] = $nowtime; - enter_logfile($cfg,5,sprintf($lang['sgrpadd'], $db_cache['groups'][$rank['group']]['sgidname'], $rank['group'], $name, $uid, $client['client_database_id'])); - if ($cfg['rankup_message_to_user_switch'] == 1) { - $days = $dtF->diff($dtT)->format('%a'); - $hours = $dtF->diff($dtT)->format('%h'); - $mins = $dtF->diff($dtT)->format('%i'); - $secs = $dtF->diff($dtT)->format('%s'); - sendmessage($ts3, $cfg, $uid, sprintf($cfg['rankup_message_to_user'],$days,$hours,$mins,$secs,$db_cache['groups'][$rank['group']]['sgidname'],$client['client_nickname']), 1, NULL, sprintf($lang['sgrprerr'], $name, $uid, $client['client_database_id'], $db_cache['groups'][$rank['group']]['sgidname'],$rank['group']), 2); + if(!isset($db_cache['all_user'][$uid]['grouperror']) || $db_cache['all_user'][$uid]['grouperror'] < ($nowtime - 300)) { + usleep($cfg['teamspeak_query_command_delay']); + try { + $ts3->serverGroupClientAdd($rank['group'], $client['client_database_id']); + $db_cache['all_user'][$uid]['grpsince'] = $nowtime; + enter_logfile($cfg,5,sprintf($lang['sgrpadd'], $db_cache['groups'][$rank['group']]['sgidname'], $rank['group'], $client['client_nickname'], $uid, $client['client_database_id'])); + if ($cfg['rankup_message_to_user_switch'] == 1) { + $days = $dtF->diff($dtT)->format('%a'); + $hours = $dtF->diff($dtT)->format('%h'); + $mins = $dtF->diff($dtT)->format('%i'); + $secs = $dtF->diff($dtT)->format('%s'); + sendmessage($ts3, $cfg, $uid, sprintf($cfg['rankup_message_to_user'],$days,$hours,$mins,$secs,$db_cache['groups'][$rank['group']]['sgidname'],$client['client_nickname']), 1, NULL, sprintf($lang['sgrprerr'], $name, $uid, $client['client_database_id'], $db_cache['groups'][$rank['group']]['sgidname'],$rank['group']), 2); + } + } catch (Exception $e) { + enter_logfile($cfg,2,"TS3 error: ".$e->getCode().': '.$e->getMessage()." ; ".sprintf($lang['sgrprerr'], $client['client_nickname'], $uid, $client['client_database_id'], $db_cache['groups'][$rank['group']]['sgidname'], $rank['group'])); + $db_cache['all_user'][$uid]['grouperror'] = $nowtime; } - } catch (Exception $e) { - enter_logfile($cfg,2,"TS3 error: ".$e->getCode().': '.$e->getMessage()." ; ".sprintf($lang['sgrprerr'], $name, $uid, $client['client_database_id'], $db_cache['groups'][$rank['group']]['sgidname'], $rank['group'])); } } if($grpcount == 1) { @@ -227,13 +233,14 @@ function calc_user($ts3,$mysqlcon,$lang,$cfg,$dbname,$allclients,$phpcommand,&$d } foreach($client_groups_rankup as $removegroup => $dummy) { - if($removegroup != NULL && $removegroup != 0 && $removegroup != $db_cache['all_user'][$uid]['grpid']){ + if($removegroup != NULL && $removegroup != 0 && $removegroup != $db_cache['all_user'][$uid]['grpid'] && (!isset($db_cache['all_user'][$uid]['grouperror']) || $db_cache['all_user'][$uid]['grouperror'] < ($nowtime - 300))){ try { usleep($cfg['teamspeak_query_command_delay']); $ts3->serverGroupClientDel($removegroup, $client['client_database_id']); - enter_logfile($cfg,5,sprintf("Removed WRONG servergroup %s (ID: %s) from user %s (unique Client-ID: %s; Client-database-ID %s).", $db_cache['groups'][$removegroup]['sgidname'], $removegroup, $name, $uid, $client['client_database_id'])); + enter_logfile($cfg,5,sprintf("Removed WRONG servergroup %s (ID: %s) from user %s (unique Client-ID: %s; Client-database-ID %s).", $db_cache['groups'][$removegroup]['sgidname'], $removegroup, $client['client_nickname'], $uid, $client['client_database_id'])); } catch (Exception $e) { - enter_logfile($cfg,2,"TS3 error: ".$e->getCode().': '.$e->getMessage()." ; ".sprintf($lang['sgrprerr'], $name, $uid, $client['client_database_id'], $db_cache['groups'][$removegroup]['sgidname'], $removegroup)); + enter_logfile($cfg,2,"TS3 error: ".$e->getCode().': '.$e->getMessage()." ; ".sprintf($lang['sgrprerr'], $client['client_nickname'], $uid, $client['client_database_id'], $db_cache['groups'][$removegroup]['sgidname'], $removegroup)); + $db_cache['all_user'][$uid]['grouperror'] = $nowtime; } } } @@ -295,7 +302,7 @@ function calc_user($ts3,$mysqlcon,$lang,$cfg,$dbname,$allclients,$phpcommand,&$d $db_cache['all_user'][$uid]['boosttime'] = 0; $db_cache['all_user'][$uid]['grpsince'] = 0; $db_cache['all_user'][$uid]['except'] = $except; - enter_logfile($cfg,5,sprintf($lang['adduser'], $name, $uid, $client['client_database_id'])); + enter_logfile($cfg,5,sprintf($lang['adduser'], $client['client_nickname'], $uid, $client['client_database_id'])); } $db_cache['all_user'][$uid]['name'] = $client['client_nickname']; $db_cache['all_user'][$uid]['lastseen'] = $nowtime; diff --git a/jobs/calc_userstats.php b/jobs/calc_userstats.php index 8423ac3..e2b241c 100644 --- a/jobs/calc_userstats.php +++ b/jobs/calc_userstats.php @@ -1,5 +1,5 @@ clientInfoDb($userstats['cldbid']); - $clientdesc = $mysqlcon->quote($clientinfo['client_description'], ENT_QUOTES); + if($clientinfo['client_description'] !== NULL) { + $clientdesc = $mysqlcon->quote($clientinfo['client_description'], ENT_QUOTES); + } else { + $clientdesc = "NULL"; + } if($clientinfo['client_totalconnections'] > 16777215) $clientinfo['client_totalconnections'] = 16777215; } catch (Exception $e) { if($e->getCode() == 512 || $e->getCode() == 1281) { @@ -81,8 +85,8 @@ function calc_userstats($ts3,$mysqlcon,$cfg,$dbname,&$db_cache) { $getcldbid = $ts3->clientFindDb($uuid, TRUE); if($getcldbid[0] != $userstats['cldbid']) { enter_logfile($cfg,4," Client (uuid: ".$uuid." cldbid: ".$userstats['cldbid'].") known by the Ranksystem changed its cldbid. New cldbid is ".$getcldbid[0]."."); + $db_cache['all_user'][$uuid]['cldbid'] = $getcldbid[0]; if($cfg['rankup_client_database_id_change_switch'] == 1) { - $db_cache['all_user'][$uuid]['cldbid'] = $getcldbid[0]; $sqlexec .= "UPDATE `$dbname`.`user` SET `count`=0,`idle`=0 WHERE `uuid`='$uuid';\nUPDATE `$dbname`.`stats_user` SET `count_week`=0,`count_month`=0,`idle_week`=0,`idle_month`=0,`active_week`=0,`active_month`=0 WHERE `uuid`='$uuid';\nDELETE FROM `$dbname`.`user_snapshot` WHERE `cldbid`='{$userstats['cldbid']}';\n"; enter_logfile($cfg,4," ".sprintf($lang['changedbid'], $userstats['name'], $uuid, $userstats['cldbid'], $getcldbid[0])); } else { @@ -116,7 +120,7 @@ function calc_userstats($ts3,$mysqlcon,$cfg,$dbname,&$db_cache) { enter_logfile($cfg,2,$lang['errorts3'].$e->getCode().': '.$e->getMessage()."; Error due command clientdbinfo for client-database-ID {$userstats['cldbid']} (permission: b_virtualserver_client_dbinfo needed)."); } - $clientdesc = $clientinfo['client_base64HashClientUID'] = $mysqlcon->quote('', ENT_QUOTES); + $clientdesc = $clientinfo['client_base64HashClientUID'] = "NULL"; $clientinfo['client_totalconnections'] = $clientinfo['client_total_bytes_uploaded'] = $clientinfo['client_total_bytes_downloaded'] = 0; } diff --git a/jobs/check_db.php b/jobs/check_db.php index ecfa5b2..50ce781 100644 --- a/jobs/check_db.php +++ b/jobs/check_db.php @@ -1,6 +1,6 @@ exec("DELETE FROM `$dbname`.`admin_addtime`;") === false) { } if($mysqlcon->exec("DELETE FROM `$dbname`.`addon_assign_groups`;") === false) { } - - try { - if($mysqlcon->exec("CREATE INDEX `serverusage_timestamp` ON `$dbname`.`server_usage` (`timestamp`)") === false) { } - if($mysqlcon->exec("CREATE INDEX `user_version` ON `$dbname`.`user` (`version`)") === false) { } - if($mysqlcon->exec("CREATE INDEX `user_cldbid` ON `$dbname`.`user` (`cldbid` ASC,`uuid`,`rank`)") === false) { } - if($mysqlcon->exec("CREATE INDEX `user_online` ON `$dbname`.`user` (`online`,`lastseen`)") === false) { } - } catch (Exception $e) { } } if(version_compare($cfg['version_current_using'], '1.3.19', '<')) { if($mysqlcon->exec("ALTER TABLE `$dbname`.`addons_config` MODIFY COLUMN `value` varchar(16000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;") === false) { } else { enter_logfile($cfg,4," [1.3.19] Adjusted table addons_config successfully."); } - + } + + if(version_compare($cfg['version_current_using'], '1.3.20', '<')) { + if($mysqlcon->exec("INSERT IGNORE INTO `$dbname`.`job_check` (`job_name`,`timestamp`) VALUES ('clean_user_iphash', '0') ON DUPLICATE KEY UPDATE `timestamp`=VALUES(`timestamp`);") === false) { } else { + enter_logfile($cfg,4," [1.3.20] Added new job_check values."); + } + } + + if(version_compare($cfg['version_current_using'], '1.3.21', '<')) { if($mysqlcon->exec("DELETE FROM `$dbname`.`admin_addtime`;") === false) { } if($mysqlcon->exec("DELETE FROM `$dbname`.`addon_assign_groups`;") === false) { } try { + if($mysqlcon->exec("CREATE INDEX `snapshot_id` ON `$dbname`.`user_snapshot` (`id`)") === false) { } + if($mysqlcon->exec("CREATE INDEX `snapshot_cldbid` ON `$dbname`.`user_snapshot` (`cldbid`)") === false) { } if($mysqlcon->exec("CREATE INDEX `serverusage_timestamp` ON `$dbname`.`server_usage` (`timestamp`)") === false) { } if($mysqlcon->exec("CREATE INDEX `user_version` ON `$dbname`.`user` (`version`)") === false) { } if($mysqlcon->exec("CREATE INDEX `user_cldbid` ON `$dbname`.`user` (`cldbid` ASC,`uuid`,`rank`)") === false) { } diff --git a/jobs/clean.php b/jobs/clean.php index 72bcf9e..44877e1 100644 --- a/jobs/clean.php +++ b/jobs/clean.php @@ -94,6 +94,25 @@ function clean($ts3,$mysqlcon,$lang,$cfg,$dbname,&$db_cache) { $sqlexec .= "DELETE FROM `$dbname`.`server_usage` WHERE `timestamp` < (UNIX_TIMESTAMP() - 31536000);\nDELETE `b` FROM `$dbname`.`user` AS `a` RIGHT JOIN `$dbname`.`stats_user` AS `b` ON `a`.`uuid`=`b`.`uuid` WHERE `a`.`uuid` IS NULL;\nUPDATE `$dbname`.`job_check` SET `timestamp`='{$nowtime}' WHERE `job_name`='clean_db';\nDELETE FROM `$dbname`.`csrf_token` WHERE `timestamp` < (UNIX_TIMESTAMP() - 3600);\nDELETE `h` FROM `$dbname`.`user_iphash` AS `h` LEFT JOIN `$dbname`.`user` AS `u` ON `u`.`uuid` = `h`.`uuid` WHERE (`u`.`uuid` IS NULL OR `u`.`online`!=1);\n"; enter_logfile($cfg,4,$lang['clean0003']); } + + // clean user_iphash + if ($db_cache['job_check']['clean_user_iphash']['timestamp'] < ($nowtime - 3500)) { + if(($sqlhashs = $mysqlcon->query("SELECT * FROM `$dbname`.`user_iphash`")->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE)) === false) { + enter_logfile($cfg,2,"clean user_iphash:".print_r($mysqlcon->errorInfo(), true)); + } + + $rem_uuids = ''; + foreach($sqlhashs as $uuid => $values) { + if(isset($db_cache['all_user'][$uuid]) && $db_cache['all_user'][$uuid]['lastseen'] < ($nowtime - 100)) { + $rem_uuids .= "'".$uuid."',"; + } + } + if($rem_uuids != '') { + $rem_uuids = substr($rem_uuids, 0, -1); + $sqlexec .= "DELETE FROM `$dbname`.`user_iphash` WHERE `uuid` IN ({$rem_uuids});\n"; + } + $sqlexec .= "UPDATE `$dbname`.`job_check` SET `timestamp`='$nowtime' WHERE `job_name`='clean_user_iphash';\n"; + } enter_logfile($cfg,6,"clean needs: ".(number_format(round((microtime(true) - $starttime), 5),5))); return($sqlexec); diff --git a/jobs/db_ex_imp.php b/jobs/db_ex_imp.php index 0c0a219..9569967 100644 --- a/jobs/db_ex_imp.php +++ b/jobs/db_ex_imp.php @@ -1,8 +1,9 @@ 600) { - if (!isset($db_cache['groups'][$sgid]) || $db_cache['groups'][$sgid]['iconid'] != $iconid || $iconarr["i".$iconid] > $db_cache['groups'][$sgid]['icondate']) { + if (!isset($db_cache['groups'][$sgid]) || $db_cache['groups'][$sgid]['iconid'] != $iconid || isset($iconarr["i".$iconid]) && $iconarr["i".$iconid] > $db_cache['groups'][$sgid]['icondate']) { try { check_shutdown($cfg); usleep($cfg['teamspeak_query_command_delay']); enter_logfile($cfg,5,sprintf($lang['upgrp0011'], $sgname, $sgid)); diff --git a/libs/smarty/.github/workflows/ci.yml b/libs/smarty/.github/workflows/ci.yml new file mode 100644 index 0000000..e82642a --- /dev/null +++ b/libs/smarty/.github/workflows/ci.yml @@ -0,0 +1,73 @@ +# https://help.github.com/en/categories/automating-your-workflow-with-github-actions + +on: + - pull_request + - push + +name: CI + +jobs: + tests: + name: Tests + + runs-on: ${{ matrix.os }} + + env: + PHP_EXTENSIONS: dom, json, libxml, mbstring, pdo_sqlite, soap, xml, xmlwriter + PHP_INI_VALUES: assert.exception=1, zend.assertions=1 + + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + + php-version: + - "7.1" + - "7.2" + - "7.3" + - "7.4" + - "8.0" + + compiler: + - default + + include: + - os: ubuntu-latest + php-version: "8.0" + compiler: jit + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Override PHP ini values for JIT compiler + if: matrix.compiler == 'jit' + run: echo "PHP_INI_VALUES::assert.exception=1, zend.assertions=1, opcache.enable=1, opcache.enable_cli=1, opcache.optimization_level=-1, opcache.jit=1255, opcache.jit_buffer_size=32M" >> $GITHUB_ENV + + - name: Install PHP with extensions + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + coverage: pcov + extensions: ${{ env.PHP_EXTENSIONS }} + ini-values: ${{ env.PHP_INI_VALUES }} + + - name: Validate composer.json and composer.lock + run: composer validate + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v2 + with: + path: vendor + key: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php-${{ matrix.php-version }}- + + - name: Install dependencies + if: steps.composer-cache.outputs.cache-hit != 'true' + run: composer install --prefer-dist --no-progress --no-suggest + + - name: Run tests with phpunit + run: ./phpunit.sh diff --git a/libs/smarty/Smarty.class.php b/libs/smarty/Smarty.class.php index a4840b7..0abbe6a 100644 --- a/libs/smarty/Smarty.class.php +++ b/libs/smarty/Smarty.class.php @@ -98,7 +98,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = '4.0.0-rc.0'; + const SMARTY_VERSION = '4.1.0'; /** * define variable scopes */ diff --git a/libs/smarty/plugins/function.mailto.php b/libs/smarty/plugins/function.mailto.php index ff8d18e..834d053 100644 --- a/libs/smarty/plugins/function.mailto.php +++ b/libs/smarty/plugins/function.mailto.php @@ -94,22 +94,19 @@ function smarty_function_mailto($params) ); return; } - // FIXME: (rodneyrehm) document.write() excues me what? 1998 has passed! if ($encode === 'javascript') { - $string = 'document.write(\'' . $text . '\');'; + $string = '' . $text . ''; $js_encode = ''; for ($x = 0, $_length = strlen($string); $x < $_length; $x++) { $js_encode .= '%' . bin2hex($string[ $x ]); } - return ''; + return ''; } elseif ($encode === 'javascript_charcode') { $string = '' . $text . ''; - for ($x = 0, $y = strlen($string); $x < $y; $x++) { + for ($x = 0, $_length = strlen($string); $x < $_length; $x++) { $ord[] = ord($string[ $x ]); } - $_ret = "\n"; - return $_ret; + return ''; } elseif ($encode === 'hex') { preg_match('!^(.*)(\?.*)$!', $address, $match); if (!empty($match[ 2 ])) { diff --git a/libs/smarty/plugins/function.math.php b/libs/smarty/plugins/function.math.php index 5d58284..fd5b3d1 100644 --- a/libs/smarty/plugins/function.math.php +++ b/libs/smarty/plugins/function.math.php @@ -28,7 +28,12 @@ function smarty_function_math($params, $template) 'int' => true, 'abs' => true, 'ceil' => true, + 'acos' => true, + 'acosh' => true, 'cos' => true, + 'cosh' => true, + 'deg2rad' => true, + 'rad2deg' => true, 'exp' => true, 'floor' => true, 'log' => true, @@ -39,27 +44,51 @@ function smarty_function_math($params, $template) 'pow' => true, 'rand' => true, 'round' => true, + 'asin' => true, + 'asinh' => true, 'sin' => true, + 'sinh' => true, 'sqrt' => true, 'srand' => true, - 'tan' => true + 'atan' => true, + 'atanh' => true, + 'tan' => true, + 'tanh' => true ); + // be sure equation parameter is present if (empty($params[ 'equation' ])) { trigger_error("math: missing equation parameter", E_USER_WARNING); return; } $equation = $params[ 'equation' ]; + + // Remove whitespaces + $equation = preg_replace('/\s+/', '', $equation); + + // Adapted from https://www.php.net/manual/en/function.eval.php#107377 + $number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number + $functionsOrVars = '((?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))'; + $operators = '[+\/*\^%-]'; // Allowed math operators + $regexp = '/^(('.$number.'|'.$functionsOrVars.'|('.$functionsOrVars.'\s*\((?1)+\)|\((?1)+\)))(?:'.$operators.'(?1))?)+$/'; + + if (!preg_match($regexp, $equation)) { + trigger_error("math: illegal characters", E_USER_WARNING); + return; + } + // make sure parenthesis are balanced if (substr_count($equation, '(') !== substr_count($equation, ')')) { trigger_error("math: unbalanced parenthesis", E_USER_WARNING); return; } + // disallow backticks if (strpos($equation, '`') !== false) { trigger_error("math: backtick character not allowed in equation", E_USER_WARNING); return; } + // also disallow dollar signs if (strpos($equation, '$') !== false) { trigger_error("math: dollar signs not allowed in equation", E_USER_WARNING); @@ -96,6 +125,7 @@ function smarty_function_math($params, $template) } $smarty_math_result = null; eval("\$smarty_math_result = " . $equation . ";"); + if (empty($params[ 'format' ])) { if (empty($params[ 'assign' ])) { return $smarty_math_result; diff --git a/libs/smarty/plugins/modifier.date_format.php b/libs/smarty/plugins/modifier.date_format.php index 8e7e0b6..45d97bd 100644 --- a/libs/smarty/plugins/modifier.date_format.php +++ b/libs/smarty/plugins/modifier.date_format.php @@ -26,8 +26,11 @@ * @return string |void * @uses smarty_make_timestamp() */ + function smarty_modifier_date_format($string, $format = null, $default_date = '', $formatter = 'auto') { + #$format = %d.%m.%Y %H:%M:%S + if ($format === null) { $format = Smarty::$_DATE_FORMAT; } @@ -78,7 +81,13 @@ function smarty_modifier_date_format($string, $format = null, $default_date = '' } $format = str_replace($_win_from, $_win_to, $format); } - return strftime($format, $timestamp); + + $new_format = date_format_to($format, 'date'); + #error_log("Smarty date format: ".$format." new format: ".$new_format, 0); + + $date = DateTimeImmutable::createFromFormat('U', $timestamp); + return $date->format($new_format); + #return strftime($format, $timestamp); } else { return date($format, $timestamp); } diff --git a/libs/smarty/plugins/shared.mb_str_replace.php b/libs/smarty/plugins/shared.mb_str_replace.php index 206cf9e..226d903 100644 --- a/libs/smarty/plugins/shared.mb_str_replace.php +++ b/libs/smarty/plugins/shared.mb_str_replace.php @@ -44,7 +44,7 @@ if (!function_exists('smarty_mb_str_replace')) { } } } else { - $parts = mb_split(preg_quote($search), $subject); + $parts = mb_split(preg_quote($search), $subject) ?: array(); $count = count($parts) - 1; $subject = implode($replace, $parts); } diff --git a/libs/smarty/sysplugins/smarty_internal_cacheresource_file.php b/libs/smarty/sysplugins/smarty_internal_cacheresource_file.php index abed98d..c77ae9e 100644 --- a/libs/smarty/sysplugins/smarty_internal_cacheresource_file.php +++ b/libs/smarty/sysplugins/smarty_internal_cacheresource_file.php @@ -196,8 +196,8 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource */ public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached) { - clearstatcache(true, $cached->lock_id); - if (is_file($cached->lock_id)) { + clearstatcache(true, $cached->lock_id ?? ''); + if (null !== $cached->lock_id && is_file($cached->lock_id)) { $t = filemtime($cached->lock_id); return $t && (time() - $t < $smarty->locking_timeout); } else { diff --git a/libs/smarty/sysplugins/smarty_internal_compile_function.php b/libs/smarty/sysplugins/smarty_internal_compile_function.php index d0f2b0f..84e9584 100644 --- a/libs/smarty/sysplugins/smarty_internal_compile_function.php +++ b/libs/smarty/sysplugins/smarty_internal_compile_function.php @@ -157,7 +157,7 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase $output = "template->compiled->nocache_hash}%%*/smarty->ext->_tplFunction->restoreTemplateVariables(\\\$_smarty_tpl, '{$_name}');?>\n"; $output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\";\n?>"; - $output .= "template->compiled->nocache_hash}', \$_smarty_tpl->compiled->nocache_hash, ob_get_clean());\n"; + $output .= "template->compiled->nocache_hash}', \$_smarty_tpl->compiled->nocache_hash ?? '', ob_get_clean());\n"; $output .= "}\n}\n"; $output .= "/*/ {$_funcName}_nocache */\n\n"; $output .= "?>\n"; diff --git a/libs/smarty/sysplugins/smarty_internal_config_file_compiler.php b/libs/smarty/sysplugins/smarty_internal_config_file_compiler.php index 90c5dce..a9b940e 100644 --- a/libs/smarty/sysplugins/smarty_internal_config_file_compiler.php +++ b/libs/smarty/sysplugins/smarty_internal_config_file_compiler.php @@ -158,7 +158,7 @@ class Smarty_Internal_Config_File_Compiler } // template header code $template_header = - "template->source->filepath}' */ ?>\n"; $code = 'smarty->ext->configLoad->_loadConfigVars($_smarty_tpl, ' . diff --git a/libs/smarty/sysplugins/smarty_internal_runtime_codeframe.php b/libs/smarty/sysplugins/smarty_internal_runtime_codeframe.php index 983ca61..b5361c9 100644 --- a/libs/smarty/sysplugins/smarty_internal_runtime_codeframe.php +++ b/libs/smarty/sysplugins/smarty_internal_runtime_codeframe.php @@ -45,7 +45,7 @@ class Smarty_Internal_Runtime_CodeFrame $properties[ 'cache_lifetime' ] = $_template->cache_lifetime; } $output = "source->filepath) . "' */\n\n"; $output .= "/* @var Smarty_Internal_Template \$_smarty_tpl */\n"; $dec = "\$_smarty_tpl->_decodeProperties(\$_smarty_tpl, " . var_export($properties, true) . ',' . diff --git a/libs/smarty/sysplugins/smarty_internal_template.php b/libs/smarty/sysplugins/smarty_internal_template.php index bae22a7..0c877f0 100644 --- a/libs/smarty/sysplugins/smarty_internal_template.php +++ b/libs/smarty/sysplugins/smarty_internal_template.php @@ -24,6 +24,7 @@ * * @method bool mustCompile() */ + #[\AllowDynamicProperties] class Smarty_Internal_Template extends Smarty_Internal_TemplateBase { /** diff --git a/libs/smarty/sysplugins/smarty_internal_templatecompilerbase.php b/libs/smarty/sysplugins/smarty_internal_templatecompilerbase.php index 6a8dc9c..2726161 100644 --- a/libs/smarty/sysplugins/smarty_internal_templatecompilerbase.php +++ b/libs/smarty/sysplugins/smarty_internal_templatecompilerbase.php @@ -1135,7 +1135,7 @@ abstract class Smarty_Internal_TemplateCompilerBase flush(); } $e = new SmartyCompilerException($error_text); - $e->line = $line; + $e->setLine($line); $e->source = trim(preg_replace('![\t\r\n]+!', ' ', $match[ $line - 1 ])); $e->desc = $args; $e->template = $this->template->source->filepath; diff --git a/libs/smarty/sysplugins/smarty_internal_templateparser.php b/libs/smarty/sysplugins/smarty_internal_templateparser.php index a065c94..a2dd0d6 100644 --- a/libs/smarty/sysplugins/smarty_internal_templateparser.php +++ b/libs/smarty/sysplugins/smarty_internal_templateparser.php @@ -2397,6 +2397,9 @@ public static $yy_action = array( } // line 749 "../smarty/lexer/smarty_internal_templateparser.y" public function yy_r94(){ + if ($this->security && $this->security->static_classes !== array()) { + $this->compiler->trigger_template_error('dynamic static class not allowed by security setting'); + } $prefixVar = $this->compiler->getNewPrefixVariable(); if ($this->yystack[$this->yyidx + -2]->minor['var'] === '\'smarty\'') { $this->compiler->appendPrefixCode("compiler->compileTag('private_special_variable',array(),$this->yystack[$this->yyidx + -2]->minor['smarty_internal_index']).';?>'); diff --git a/libs/smarty/sysplugins/smartycompilerexception.php b/libs/smarty/sysplugins/smartycompilerexception.php index f7ad39b..8833aa5 100644 --- a/libs/smarty/sysplugins/smartycompilerexception.php +++ b/libs/smarty/sysplugins/smartycompilerexception.php @@ -16,12 +16,12 @@ class SmartyCompilerException extends SmartyException } /** - * The line number of the template error - * - * @type int|null + * @param int $line */ - public $line = null; - + public function setLine($line) + { + $this->line = $line; + } /** * The template source snippet relating to the error * diff --git a/libs/ts3_lib/Adapter/ServerQuery/Event.php b/libs/ts3_lib/Adapter/ServerQuery/Event.php index 1f3747c..3889809 100644 --- a/libs/ts3_lib/Adapter/ServerQuery/Event.php +++ b/libs/ts3_lib/Adapter/ServerQuery/Event.php @@ -115,7 +115,7 @@ class TeamSpeak3_Adapter_ServerQuery_Event implements ArrayAccess /** * @ignore */ - public function offsetExists($offset) + public function offsetExists($offset): bool { return array_key_exists($offset, $this->data) ? TRUE : FALSE; } @@ -123,6 +123,7 @@ class TeamSpeak3_Adapter_ServerQuery_Event implements ArrayAccess /** * @ignore */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { if(!$this->offsetExists($offset)) @@ -136,7 +137,7 @@ class TeamSpeak3_Adapter_ServerQuery_Event implements ArrayAccess /** * @ignore */ - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { throw new TeamSpeak3_Node_Exception("event '" . $this->getType() . "' is read only"); } @@ -144,7 +145,7 @@ class TeamSpeak3_Adapter_ServerQuery_Event implements ArrayAccess /** * @ignore */ - public function offsetUnset($offset) + public function offsetUnset($offset): void { unset($this->data[$offset]); } diff --git a/libs/ts3_lib/Helper/String.php b/libs/ts3_lib/Helper/String.php index 76b2df6..be91f48 100644 --- a/libs/ts3_lib/Helper/String.php +++ b/libs/ts3_lib/Helper/String.php @@ -469,7 +469,10 @@ class TeamSpeak3_Helper_String implements ArrayAccess, Iterator, Countable { if(!$this->isUtf8()) { - $this->string = utf8_encode($this->string); + $this->string = iconv('ISO-8859-1', 'UTF-8', $this->string); + #utf8_encode($this->string); + #iconv('ISO-8859-1', 'UTF-8', $this->string); + #mb_convert_encoding($this->string, 'UTF-8', mb_list_encodings()); } return $this; @@ -853,7 +856,7 @@ class TeamSpeak3_Helper_String implements ArrayAccess, Iterator, Countable /** * @ignore */ - public function count() + public function count(): int { return strlen($this->string); } @@ -861,7 +864,7 @@ class TeamSpeak3_Helper_String implements ArrayAccess, Iterator, Countable /** * @ignore */ - public function rewind() + public function rewind(): void { $this->position = 0; } @@ -869,7 +872,7 @@ class TeamSpeak3_Helper_String implements ArrayAccess, Iterator, Countable /** * @ignore */ - public function valid() + public function valid(): bool { return $this->position < $this->count(); } @@ -877,7 +880,7 @@ class TeamSpeak3_Helper_String implements ArrayAccess, Iterator, Countable /** * @ignore */ - public function key() + public function key(): mixed { return $this->position; } @@ -885,7 +888,7 @@ class TeamSpeak3_Helper_String implements ArrayAccess, Iterator, Countable /** * @ignore */ - public function current() + public function current(): mixed { return new TeamSpeak3_Helper_Char($this->string[$this->position]); } @@ -893,7 +896,7 @@ class TeamSpeak3_Helper_String implements ArrayAccess, Iterator, Countable /** * @ignore */ - public function next() + public function next(): void { $this->position++; } @@ -901,7 +904,7 @@ class TeamSpeak3_Helper_String implements ArrayAccess, Iterator, Countable /** * @ignore */ - public function offsetExists($offset) + public function offsetExists($offset): bool { return ($offset < strlen($this->string)) ? TRUE : FALSE; } @@ -909,6 +912,7 @@ class TeamSpeak3_Helper_String implements ArrayAccess, Iterator, Countable /** * @ignore */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return ($this->offsetExists($offset)) ? new TeamSpeak3_Helper_Char($this->string[$offset]) : null; @@ -917,7 +921,7 @@ class TeamSpeak3_Helper_String implements ArrayAccess, Iterator, Countable /** * @ignore */ - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { if(!$this->offsetExists($offset)) return; @@ -927,7 +931,7 @@ class TeamSpeak3_Helper_String implements ArrayAccess, Iterator, Countable /** * @ignore */ - public function offsetUnset($offset) + public function offsetUnset($offset): void { if(!$this->offsetExists($offset)) return; diff --git a/libs/ts3_lib/Node/Abstract.php b/libs/ts3_lib/Node/Abstract.php index 4c8abc9..2f8e723 100644 --- a/libs/ts3_lib/Node/Abstract.php +++ b/libs/ts3_lib/Node/Abstract.php @@ -474,7 +474,7 @@ abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAcces /** * @ignore */ - public function count() + public function count(): int { $this->verifyNodeList(); @@ -484,7 +484,7 @@ abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAcces /** * @ignore */ - public function current() + public function current(): mixed { $this->verifyNodeList(); @@ -494,7 +494,7 @@ abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAcces /** * @ignore */ - public function getChildren() + public function getChildren(): ?RecursiveIterator { $this->verifyNodeList(); @@ -504,7 +504,7 @@ abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAcces /** * @ignore */ - public function hasChildren() + public function hasChildren(): bool { $this->verifyNodeList(); @@ -524,7 +524,7 @@ abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAcces /** * @ignore */ - public function key() + public function key(): mixed { $this->verifyNodeList(); @@ -534,7 +534,7 @@ abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAcces /** * @ignore */ - public function valid() + public function valid(): bool { $this->verifyNodeList(); @@ -544,6 +544,7 @@ abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAcces /** * @ignore */ + #[\ReturnTypeWillChange] public function next() { $this->verifyNodeList(); @@ -554,6 +555,7 @@ abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAcces /** * @ignore */ + #[\ReturnTypeWillChange] public function rewind() { $this->verifyNodeList(); @@ -564,7 +566,7 @@ abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAcces /** * @ignore */ - public function offsetExists($offset) + public function offsetExists($offset): bool { return array_key_exists((string) $offset, $this->nodeInfo) ? TRUE : FALSE; } @@ -572,6 +574,7 @@ abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAcces /** * @ignore */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { if(!$this->offsetExists($offset)) @@ -590,6 +593,7 @@ abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAcces /** * @ignore */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { if(method_exists($this, "modify")) @@ -603,7 +607,7 @@ abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAcces /** * @ignore */ - public function offsetUnset($offset) + public function offsetUnset($offset): void { unset($this->nodeInfo[(string) $offset]); } diff --git a/other/_functions.php b/other/_functions.php index 502e3df..06ee883 100644 --- a/other/_functions.php +++ b/other/_functions.php @@ -6,6 +6,48 @@ function check_shutdown($cfg) { } } +function date_format_to($format, $syntax) { + $strf_syntax = [ + '%O', '%d', '%a', '%e', '%A', '%u', '%w', '%j', + '%V', + '%B', '%m', '%b', '%-m', + '%G', '%Y', '%y', + '%P', '%p', '%l', '%I', '%H', '%M', '%S', + '%z', '%Z', + '%s' + ]; + $date_syntax = [ + 'S', 'd', 'D', 'j', 'l', 'N', 'w', 'z', + 'W', + 'F', 'm', 'M', 'n', + 'o', 'Y', 'y', + 'a', 'A', 'g', 'h', 'H', 'i', 's', + 'O', 'T', + 'U' + ]; + switch ( $syntax ) { + case 'date': + $from = $strf_syntax; + $to = $date_syntax; + break; + + case 'strf': + $from = $date_syntax; + $to = $strf_syntax; + break; + + default: + return false; + } + $pattern = array_map( + function ( $s ) { + return '/(?$number_lines) { break; } @@ -123,11 +165,11 @@ function getlog($cfg,$number_lines,$filters,$filter2,$inactivefilter = NULL) { foreach($filters as $filter) { if(($filter != NULL && strstr($line, $filter) && $filter2 == NULL) || ($filter2 != NULL && strstr($line, $filter2) && $filter != NULL && strstr($line, $filter))) { if($filter == "CRITICAL" || $filter == "ERROR") { - array_push($lines, ''.htmlspecialchars($line).''); + array_push($lines, ''.$line.''); } elseif($filter == "WARNING") { - array_push($lines, ''.htmlspecialchars($line).''); + array_push($lines, ''.$line.''); } else { - array_push($lines, htmlspecialchars($line)); + array_push($lines, $line); } $lastfilter = $filter; if (count($lines)>$number_lines) { @@ -272,9 +314,11 @@ function rem_session_ts3() { unset($_SESSION[$rspathhex.'uuid_verified']); } -function select_channel($channellist, $cfg_cid) { +function select_channel($channellist, $cfg_cid, $multiple=NULL) { if(isset($channellist) && count($channellist)>0) { - $selectbox = ''; $channelarr = sort_channel_tree($channellist); foreach ($channelarr as $cid => $channel) { @@ -294,7 +338,7 @@ function select_channel($channellist, $cfg_cid) { $chname = htmlspecialchars($channel['channel_name']); if (isset($channel['iconid']) && $channel['iconid'] != 0) $iconid=$channel['iconid']."."; else $iconid="placeholder.png"; if ($cid != 0) { - if($cid == $cfg_cid) { + if($multiple !== 1 && $cid == $cfg_cid || $multiple === 1 && is_array($cfg_cid) && isset($cfg_cid[$cid])) { $selectbox .= '