#!/bin/php debug = true; $TKL->message("Timekeeper " . $version, "Timekeeper is running. (In debug mode)"); } else { $TKL->message("Timekeeper " . $version, "Timekeeper is running."); } // mutex here echo 'Looking for other ' . $argv[0] . ' here.' . PHP_EOL; $firstCount = false; $cmdLineReturnArray = []; exec("ps aux | grep $(whoami) | grep " . $argv[0], $cmdLineReturnArray); foreach ($cmdLineReturnArray as $cmd) { if (strpos($cmd, "/php")) { if ($firstCount) { die("Found another instance."); } $firstCount = true; } } $gamesList = json_decode(file_get_contents('https://overlord.pfip.au/e107_plugins/timekeeper/timekeeperClientServices/games.json'), true); $TKL->user = exec("whoami"); $TKL->Logging("Timekeeper " . $version . " initialised for " . $TKL->user, false); while (true) { set_time_limit(70); $startupTime = microtime(true); $TKL->CheckForGames($gamesList); $TKL->CheckTimeRemaining(); $TKL->burnTime($startupTime, 60); } exit; class timekeeperLocal { public $lastActiveGame = ''; public $user = ''; public $debug = false; public function test() { $this->message('test title', 'test message', ''); } /** * Send a message to the user. * *
Example usage:
     * $this->message('Alert','this is an important meassage.',1);
     * 
* * @param string $title The title to be displayed for the message. * @param string $messageText The body text of the message to be displayed. * @param int $urgency The urgency level for the message to be displayed * with.
1 = High
2 = Medium
3 = Low * * @return void */ public function message($title, $messageText, $urgency = '') { switch ($urgency) { case 1: $urgencyText = ' --urgency=critical'; break; case 2: $urgencyText = ' --urgency=normal'; break; case 3: $urgencyText = ' --urgency=low'; break; default: $urgencyText = ''; break; } exec('notify-send' . $urgencyText . ' "' . $title . '" "' . $messageText . '"'); } public function burnTime($startupTime, $burnTimeDuration) { if ($this->lastActiveGame == "") { sleep(20); return; } //echo 'Burning ' . (int) (60 - (microtime(true) - $startupTime)) . ' seconds' . PHP_EOL; //echo 'Burning from ' . microtime(true) . PHP_EOL; while (microtime(true) < ($startupTime + $burnTimeDuration)) { usleep(300); } } public function CheckForGames($listOfKnownGames) { foreach ($listOfKnownGames as $gameName) { $cmdLineReturnArray = []; exec("ps aux | grep $(whoami) | grep $gameName", $cmdLineReturnArray); //print_r($cmdLineReturnArray); foreach ($cmdLineReturnArray as $cmdLineReturn) { if ($this->cmdExceptions($cmdLineReturn)) { $this->AnounceGameDetected($gameName); return; } } } $this->AnounceGameNotDetected(); } private function cmdExceptions($cmdLineReturn) { if (strpos($cmdLineReturn, 'grep') != false) { return false; } elseif (strpos($cmdLineReturn, 'kiosk') != false) { return false; } elseif (strpos($cmdLineReturn, 'contentproc') != false) { return false; } elseif (strpos($cmdLineReturn, 'new-window') != false) { //opera helper exception return false; } elseif (strpos($cmdLineReturn, 'type=gpu-process') != false) { // opera helper exception return false; } return true; } private function AnounceGameDetected($game) { if ($this->lastActiveGame == "") { $this->lastActiveGame = $game; $minutesRemaining = file_get_contents('https://overlord.pfip.au/e107_plugins/timekeeper/timekeeperClientServices/timer.php?user=' . $this->user . '&game=' . $this->lastActiveGame); $this->message("Timekeeper", ucfirst($game) . " detected running." . PHP_EOL . "You have " . $minutesRemaining . " minutes remaining."); $this->Logging(ucfirst($game) . " detected running. " . $minutesRemaining . " minutes remaining."); } } private function AnounceGameNotDetected() { if ($this->lastActiveGame != "") { $this->lastActiveGame = ""; $this->message("Timekeeper", "No games detected running."); $this->Logging("No games detected running."); } //No games running so just read out the play time avalible //echo file_get_contents('https://overlord.pfip.tk/e107_plugins/timekeeper/timekeeperClientServices/timer.php?user=' . $this->user . '&game=' . $this->lastActiveGame); } public function CheckTimeRemaining() { if ($this->lastActiveGame != "") { $serverResponse = file_get_contents('https://overlord.pfip.au/e107_plugins/timekeeper/timekeeperClientServices/timer.php?user=' . $this->user . '&game=' . $this->lastActiveGame); //echo "==Debug==" . $serverResponse . "===="; $this->TimeLimitWarning($serverResponse); } } private function TimeLimitWarning($reply) { if (!is_numeric($reply)) { $this->message("Timekeeper", $reply); $this->KillGame(); return; } switch ($reply) { case 5: $this->message("Timekeeper", "You only have 5 minutes remaining."); break; case 1: $this->message("Timekeeper", "You only have 1 minute remaining."); break; case 0: $this->message("Timekeeper", "Your play time has expired."); $this->KillGame(); break; default: break; } } private function KillGame() { $gamePid = preg_split('/\s+/', exec("ps ax -f| grep $(whoami) | grep $this->lastActiveGame | grep -v grep | grep -v content"))[1]; if ($this->debug) { $this->message("Timekeeper", "Game PID-" . $gamePid . " should\nhave just been killed."); } else { for ($level = 0; $level < 3; $level++) { $this->Logging('Killing '.$this->lastActiveGame . " with killRoutine($level)."); if($this->killRoutine($level)) { return; } } } } private function killRoutine($level): bool{ $gamePid = preg_split('/\s+/', exec("ps ax -f| grep $(whoami) | grep $this->lastActiveGame | grep -v grep | grep -v content"))[1]; if(count($gamePid)>=2){ $this->Logging('Current pid '. $gamePid . "."); }else{ $this->Logging('Game is supposedly dead, bailing out now.'); return true; } switch ($level) { case 0: exec("kill -15 $gamePid"); break; case 1: exec("kill -9 $gamePid"); break; case 2: exec("pkill -15 $this->lastActiveGame"); break; case 3: exec("pkill -9 $this->lastActiveGame"); break; } sleep(10); return false; } /** * * Logging($message,$append = true); * * Write to the common log file. * *
Example usage:
     * $this->Logging('Hello this is a message.');
     * 
* * @param string $message The message to be written into the log file. * @param bool $append Set to false to overwrite the log file. * * @return void */ public function Logging($message, $append = true) { try { $filename = "timekeeper.log"; if ($append) { file_put_contents($filename, $message . PHP_EOL, FILE_APPEND); } else { file_put_contents($filename, $message . PHP_EOL); } } catch (Exception $ex) { $this->message("Error", "Logging can not be initialised." . PHP_EOL . $ex, 1); } } }