#!/usr/bin/php close(); } exit; } function enter_logfile($logpath,$timezone,$loglevel,$logtext,$norotate = false) { global $phpcommand; $file = $logpath.'ranksystem.log'; if ($loglevel == 1) { $loglevel = " CRITICAL "; } elseif ($loglevel == 2) { $loglevel = " ERROR "; } elseif ($loglevel == 3) { $loglevel = " WARNING "; } elseif ($loglevel == 4) { $loglevel = " NOTICE "; } elseif ($loglevel == 5) { $loglevel = " INFO "; } elseif ($loglevel == 6) { $loglevel = " DEBUG "; } $loghandle = fopen($file, 'a'); fwrite($loghandle, DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''))->setTimeZone(new DateTimeZone($timezone))->format("Y-m-d H:i:s.u ").$loglevel.$logtext."\n"); fclose($loghandle); if($norotate == false && filesize($file) > 5242880) { $loghandle = fopen($file, 'a'); fwrite($loghandle, DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''))->setTimeZone(new DateTimeZone($timezone))->format("Y-m-d H:i:s.u ")." NOTICE Logfile filesie of 5 MiB reached.. Rotate logfile.\n"); fclose($loghandle); $file2 = "$file.old"; if (file_exists($file2)) unlink($file2); rename($file, $file2); $loghandle = fopen($file, 'a'); fwrite($loghandle, DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''))->setTimeZone(new DateTimeZone($timezone))->format("Y-m-d H:i:s.u ")." NOTICE Rotated logfile...\n"); fclose($loghandle); } } require_once(substr(__DIR__,0,-4).'other/config.php'); require_once(substr(__DIR__,0,-4).'other/phpcommand.php'); if(isset($_SERVER['HTTP_HOST']) || isset($_SERVER['REMOTE_ADDR'])) { shutdown($mysqlcon, $logpath, $timezone, 1, "Request to start the Ranksystem from ".$_SERVER['REMOTE_ADDR'].". It seems the request came not from the command line!", 1); } if(version_compare(phpversion(), '5.5.0', '<')) { shutdown($mysqlcon, $logpath, $timezone, 1, "Your PHP version (".phpversion().") is below 5.5.0. Update of PHP is required!"); } if(!function_exists('simplexml_load_file')) { shutdown($mysqlcon, $logpath, $timezone, 1, "SimpleXML is missed. Installation of SimpleXML is required!"); } if(!in_array('curl', get_loaded_extensions())) { shutdown($mysqlcon, $logpath, $timezone, 1, "PHP cURL is missed. Installation of PHP cURL is required!"); } if(!in_array('zip', get_loaded_extensions())) { shutdown($mysqlcon, $logpath, $timezone, 1, "PHP Zip is missed. Installation of PHP Zip is required!"); } enter_logfile($logpath,$timezone,5,"###################################################################"); enter_logfile($logpath,$timezone,5,""); enter_logfile($logpath,$timezone,5,"###################################################################"); enter_logfile($logpath,$timezone,5,"Initialize Bot..."); require_once(substr(__DIR__,0,-4).'libs/ts3_lib/TeamSpeak3.php'); require_once(substr(__DIR__,0,-4).'jobs/calc_user.php'); require_once(substr(__DIR__,0,-4).'jobs/get_avatars.php'); require_once(substr(__DIR__,0,-4).'jobs/update_groups.php'); require_once(substr(__DIR__,0,-4).'jobs/calc_serverstats.php'); require_once(substr(__DIR__,0,-4).'jobs/calc_userstats.php'); require_once(substr(__DIR__,0,-4).'jobs/clean.php'); require_once(substr(__DIR__,0,-4).'jobs/check_db.php'); require_once(substr(__DIR__,0,-4).'jobs/handle_messages.php'); require_once(substr(__DIR__,0,-4).'jobs/update_rs.php'); enter_logfile($logpath,$timezone,6,"Running on OS: ".php_uname("s")." ".php_uname("r")); enter_logfile($logpath,$timezone,6,"Using PHP Version: ".phpversion()); enter_logfile($logpath,$timezone,6,"Database Version: ".$mysqlcon->getAttribute(PDO::ATTR_SERVER_VERSION)); $currvers = check_db($mysqlcon,$lang,$dbname,$timezone,$currvers,$logpath); enter_logfile($logpath,$timezone,5,"Check Ranksystem files for updates..."); if(isset($currvers) && isset($newversion) && $newversion != NULL && version_compare($newversion, $currvers, '>')) { update_rs($mysqlcon,$lang,$dbname,$logpath,$timezone,$newversion,$phpcommand); } enter_logfile($logpath,$timezone,5,"Check Ranksystem files for updates [done]"); function check_shutdown($timezone,$logpath) { if(!is_file(substr(__DIR__,0,-4).'logs/pid')) { shutdown($mysqlcon, $logpath, $timezone, 5, "Received signal to stop!"); } } enter_logfile($logpath,$timezone,5,"Ranksystem Version: ".$currvers); enter_logfile($logpath,$timezone,5,"Loading addons..."); require_once(substr(__DIR__,0,-4).'other/load_addons_config.php'); $addons_config = load_addons_config($mysqlcon,$lang,$dbname,$timezone,$logpath); if($addons_config['assign_groups_active']['value'] == '1') { enter_logfile($logpath,$timezone,5," Addon: 'assign_groups' [ON]"); include(substr(__DIR__,0,-4).'jobs/addon_assign_groups.php'); define('assign_groups',1); } else { enter_logfile($logpath,$timezone,5," Addon: 'assign_groups' [OFF]"); } enter_logfile($logpath,$timezone,5,"Loading addons [done]"); enter_logfile($logpath,$timezone,5,"Connect to TS3 Server (Address: \"".$ts['host']."\" Voice-Port: \"".$ts['voice']."\" Query-Port: \"".$ts['query']."\")."); try { $ts3 = TeamSpeak3::factory("serverquery://".$ts['user'].":".$ts['pass']."@".$ts['host'].":".$ts['query']."/?server_port=".$ts['voice']."&blocking=0"); enter_logfile($logpath,$timezone,5," Connection to TS3 Server established."); try { usleep($slowmode); $ts3->notifyRegister("textprivate"); $ts3->notifyRegister("textchannel"); $ts3->notifyRegister("textserver"); TeamSpeak3_Helper_Signal::getInstance()->subscribe("notifyTextmessage", "handle_messages"); } catch (Exception $e) { enter_logfile($logpath,$timezone,2," Error due register notifyTextmessage ".$e->getCode().': '.$e->getMessage()); } try { usleep($slowmode); $ts3->selfUpdate(array('client_nickname' => $queryname)); } catch (Exception $e) { try { usleep($slowmode); $ts3->selfUpdate(array('client_nickname' => $queryname2)); } catch (Exception $e) { enter_logfile($logpath,$timezone,2,$lang['error'].$e->getCode().': '.$e->getMessage()); } } usleep($slowmode); $whoami = $ts3->whoami(); if($defchid != 0) { try { usleep($slowmode); $ts3->clientMove($whoami['client_id'],$defchid); enter_logfile($logpath,$timezone,5," Joined to specified Channel."); } catch (Exception $e) { if($e->getCode() != 770) { enter_logfile($logpath,$timezone,5," Could not join specified channel."); } else { enter_logfile($logpath,$timezone,5," Joined to specified channel."); } } } else { enter_logfile($logpath,$timezone,4," No channel defined where the Ranksystem Bot should be entered."); } enter_logfile($logpath,$timezone,5,"Config check started..."); if(($groupslist = $mysqlcon->query("SELECT * FROM $dbname.groups")->fetchAll(PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC)) === false) { enter_logfile($logpath,$timezone,1," Select on DB failed for group check: ".print_r($mysqlcon->errorInfo(), true)); } $checkgroups = 0; if(isset($groupslist) && $groupslist != NULL) { if(isset($grouptime) && $grouptime != NULL) { foreach($grouptime as $time => $groupid) { if(!isset($groupslist[$groupid]) && $groupid != NULL) { $checkgroups++; } } } if(isset($boostarr) && $boostarr != NULL) { foreach($boostarr as $groupid => $value) { if(!isset($groupslist[$groupid]) && $groupid != NULL) { $checkgroups++; } } } if(isset($exceptgroup) && $exceptgroup != NULL) { foreach($exceptgroup as $groupid => $value) { if(!isset($groupslist[$groupid]) && $groupid != NULL) { $checkgroups++; } } } } if($checkgroups > 0) { enter_logfile($logpath,$timezone,4," Found servergroups in config, which are unknown. Redownload all servergroups from TS3 server."); if($mysqlcon->exec("DELETE FROM groups;") === false) { enter_logfile($logpath,$timezone,2," Executing SQL commands failed: ".print_r($mysqlcon->errorInfo(), true)); } $nobreak = 1; $sqlexec = ''; $serverinfo = $ts3->serverInfo(); $select_arr = array(); $sqlexec .= update_groups($ts3,$mysqlcon,$lang,$dbname,$slowmode,$timezone,$serverinfo,$logpath,$grouptime,$boostarr,$exceptgroup,$select_arr,$nobreak); if($mysqlcon->exec($sqlexec) === false) { enter_logfile($logpath,$timezone,2,"Executing SQL commands failed: ".print_r($mysqlcon->errorInfo(), true)); } unset($sqlexec, $select_arr, $groupslist); $errcnf = 0; enter_logfile($logpath,$timezone,4," Downloading of servergroups finished. Recheck the config."); if(($groupslist = $mysqlcon->query("SELECT * FROM $dbname.groups")->fetchAll(PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC)) === false) { enter_logfile($logpath,$timezone,1," Select on DB failed for group check: ".print_r($mysqlcon->errorInfo(), true)); } if(isset($groupslist) && $groupslist != NULL) { if(isset($grouptime) && $grouptime != NULL) { foreach($grouptime as $time => $groupid) { if(!isset($groupslist[$groupid]) && $groupid != NULL) { enter_logfile($logpath,$timezone,1,' '.sprintf($lang['upgrp0001'], $groupid, $lang['wigrptime'])); $errcnf++; } } } if(isset($boostarr) && $boostarr != NULL) { foreach($boostarr as $groupid => $value) { if(!isset($groupslist[$groupid]) && $groupid != NULL) { enter_logfile($logpath,$timezone,2,' '.sprintf($lang['upgrp0001'], $groupid, $lang['wiboost'])); } } } if(isset($exceptgroup) && $exceptgroup != NULL) { foreach($exceptgroup as $groupid => $value) { if(!isset($groupslist[$groupid]) && $groupid != NULL) { enter_logfile($logpath,$timezone,2,' '.sprintf($lang['upgrp0001'], $groupid, $lang['wiexgrp'])); } } } } if($errcnf > 0) { shutdown($mysqlcon, $logpath, $timezone, 1, "Critical Config error!"); } else { enter_logfile($logpath,$timezone,4," No critical problems found! All seems to be fine..."); } } if(($lastupdate = $mysqlcon->query("SELECT timestamp FROM $dbname.job_check WHERE job_name='last_update'")->fetch()) === false) { enter_logfile($logpath,$timezone,1," Select on DB failed for job check: ".print_r($mysqlcon->errorInfo(), true)); } else { if($lastupdate['timestamp'] != 0 && ($lastupdate['timestamp'] + 10) > time()) { if(isset($adminuuid) && $adminuuid != NULL) { foreach ($adminuuid as $clientid) { usleep($slowmode); try { $ts3->clientGetByUid($clientid)->message(sprintf($lang['upmsg2'], $currvers)); enter_logfile($logpath,$timezone,4," ".sprintf($lang['upusrinf'], $clientid)); } catch (Exception $e) { enter_logfile($logpath,$timezone,6," ".sprintf($lang['upusrerr'], $clientid)); } } } } } unset($groupslist,$errcnf,$checkgroups); enter_logfile($logpath,$timezone,5,"Config check [done]"); enter_logfile($logpath,$timezone,5,"Bot starts now his work!"); $looptime = $rotated_cnt = 0; $rotated = ''; usleep(3000000); while(1) { $sqlexec=''; $starttime = microtime(true); $weekago = time() - 604800; $monthago = time() - 2592000; if(($get_db_data = $mysqlcon->query("SELECT * FROM $dbname.user; SELECT MAX(timestamp) AS timestamp FROM $dbname.user_snapshot; SELECT version, COUNT(version) AS count FROM $dbname.user GROUP BY version ORDER BY count DESC; SELECT MAX(timestamp) AS timestamp FROM $dbname.server_usage; SELECT * FROM $dbname.job_check; SELECT uuid FROM $dbname.stats_user; SELECT timestamp FROM $dbname.user_snapshot WHERE timestamp > $weekago ORDER BY timestamp ASC LIMIT 1; SELECT timestamp FROM $dbname.user_snapshot WHERE timestamp > $monthago ORDER BY timestamp ASC LIMIT 1; SELECT * FROM $dbname.groups; SELECT * FROM $dbname.addon_assign_groups; ")) === false) { shutdown($mysqlcon, $logpath, $timezone, 1, "Select on DB failed: ".print_r($mysqlcon->errorInfo(), true)); } $count_select = 0; $select_arr = array(); while($single_select = $get_db_data) { $fetched_array = $single_select->fetchAll(PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC); $count_select++; switch ($count_select) { case 1: $select_arr['all_user'] = $fetched_array; break; case 2: $select_arr['max_timestamp_user_snapshot'] = $fetched_array; break; case 3: $select_arr['count_version_user'] = $fetched_array; break; case 4: $select_arr['max_timestamp_server_usage'] = $fetched_array; break; case 5: $select_arr['job_check'] = $fetched_array; break; case 6: $select_arr['uuid_stats_user'] = $fetched_array; break; case 7: $select_arr['usersnap_min_week'] = $fetched_array; break; case 8: $select_arr['usersnap_min_month'] = $fetched_array; break; case 9: $select_arr['groups'] = $fetched_array; break; case 10: $select_arr['addon_assign_groups'] = $fetched_array; break 2; } $get_db_data->nextRowset(); } unset($get_db_data, $fetched_array, $single_select); check_shutdown($timezone,$logpath); $addons_config = load_addons_config($mysqlcon,$lang,$dbname,$timezone,$logpath); $ts3->clientListReset(); usleep($slowmode); $allclients = $ts3->clientList(); $ts3->serverInfoReset(); usleep($slowmode); $serverinfo = $ts3->serverInfo(); $sqlexec .= calc_user($ts3,$mysqlcon,$lang,$dbname,$slowmode,$timezone,$grouptime,$boostarr,$resetbydbchange,$msgtouser,$currvers,$substridle,$exceptuuid,$exceptgroup,$allclients,$logpath,$rankupmsg,$ignoreidle,$exceptcid,$resetexcept,$phpcommand,$select_arr); get_avatars($ts3,$slowmode,$timezone,$logpath,$avatar_delay); $sqlexec .= clean($ts3,$mysqlcon,$lang,$dbname,$slowmode,$timezone,$cleanclients,$cleanperiod,$logpath,$select_arr); $sqlexec .= calc_serverstats($ts3,$mysqlcon,$dbname,$dbtype,$slowmode,$timezone,$serverinfo,$substridle,$grouptime,$logpath,$ts,$currvers,$upchannel,$select_arr,$phpcommand,$adminuuid); $sqlexec .= calc_userstats($ts3,$mysqlcon,$dbname,$slowmode,$timezone,$logpath,$select_arr); $sqlexec .= update_groups($ts3,$mysqlcon,$lang,$dbname,$slowmode,$timezone,$serverinfo,$logpath,$grouptime,$boostarr,$exceptgroup,$select_arr); if($addons_config['assign_groups_active']['value'] == '1') { if(!defined('assign_groups')) { enter_logfile($logpath,$timezone,5,"Loading new addon..."); enter_logfile($logpath,$timezone,5," Addon: 'assign_groups' [ON]"); include(substr(__DIR__,0,-4).'jobs/addon_assign_groups.php'); define('assign_groups',1); enter_logfile($logpath,$timezone,5,"Loading new addon [done]"); } $sqlexec .= addon_assign_groups($addons_config,$ts3,$dbname,$slowmode,$timezone,$logpath,$allclients,$select_arr); } if($mysqlcon->exec($sqlexec) === false) { enter_logfile($logpath,$timezone,2,"Executing SQL commands failed: ".print_r($mysqlcon->errorInfo(), true)); } unset($sqlexec, $select_arr); $looptime = microtime(true) - $starttime; $rotated = substr((number_format(round($looptime, 5),5) . ';' . $rotated),0,79); if($looptime < 1) { $loopsleep = (1 - $looptime) * 1000000; //enter_logfile($logpath,$timezone,6,"last loop: ".round($looptime, 5)." sec."); usleep($loopsleep); } elseif($slowmode == 0) { //enter_logfile($logpath,$timezone,6,"last loop: ".round($looptime, 5)." sec."); $rotated_cnt++; if($rotated_cnt > 3600) { $rotated_arr = explode(';', $rotated); $sum_time = 0; foreach ($rotated_arr as $time) { $sum_time = $sum_time + $time; } if(($sum_time / 10) > 1) { $rotated_cnt = 0; enter_logfile($logpath,$timezone,4," Your Ranksystem seems to be slow. This is not a big deal, but it needs more ressources then necessary."); enter_logfile($logpath,$timezone,4," Here you'll find some information to optimize it: https://ts-n.net/ranksystem.php#optimize"); enter_logfile($logpath,$timezone,4," Last 10 runtimes in seconds (lower values are better): ".$rotated); foreach ($uniqueid as $clientid) { usleep($slowmode); try { $ts3->clientGetByUid($clientid)->message("\nYour Ranksystem seems to be slow. This is not a big deal, but it needs more ressources then necessary.\nHere you'll find some information to optimize it: [URL]https://ts-n.net/ranksystem.php#optimize[/URL]\nLast 10 runtimes in seconds (lower values are better):\n".$rotated); } catch (Exception $e) { } } } } } } } catch (Exception $e) { enter_logfile($logpath,$timezone,2,$lang['error'].$e->getCode().': '.$e->getMessage()); $offline_status = array(110,257,258,1024,1026,1031,1032,1033,1034,1280,1793); if(in_array($e->getCode(), $offline_status)) { if($mysqlcon->exec("UPDATE $dbname.stats_server SET server_status='0'") === false) { enter_logfile($logpath,$timezone,2,$lang['error'].print_r($mysqlcon->errorInfo(), true)); } } } ?>