2013-12-17 17:38:44 +01:00
< ? php
2014-02-10 22:54:49 +01:00
namespace ManiaControl\Update ;
2013-12-17 17:38:44 +01:00
use ManiaControl\Admin\AuthenticationManager ;
2014-04-16 01:22:31 +02:00
use ManiaControl\Callbacks\CallbackManager ;
2013-12-17 17:38:44 +01:00
use ManiaControl\Callbacks\CallbackListener ;
2014-01-31 00:04:40 +01:00
use ManiaControl\Callbacks\TimerListener ;
2013-12-17 17:38:44 +01:00
use ManiaControl\Commands\CommandListener ;
2014-02-10 16:52:16 +01:00
use ManiaControl\Files\FileUtil ;
2014-02-10 22:54:49 +01:00
use ManiaControl\ManiaControl ;
2013-12-17 17:38:44 +01:00
use ManiaControl\Players\Player ;
use ManiaControl\Players\PlayerManager ;
2014-01-28 16:23:50 +01:00
use ManiaControl\Plugins\Plugin ;
2014-04-16 01:22:31 +02:00
use ManiaControl\Plugins\PluginMenu ;
2013-12-17 17:38:44 +01:00
/**
2013-12-31 18:42:54 +01:00
* Manager checking for ManiaControl Core and Plugin Updates
2013-12-17 17:38:44 +01:00
*
* @ author steeffeen & kremsy
2014-04-12 12:14:37 +02:00
* @ copyright ManiaControl Copyright © 2014 ManiaControl Team
* @ license http :// www . gnu . org / licenses / GNU General Public License , Version 3
2013-12-17 17:38:44 +01:00
*/
2014-01-31 00:04:40 +01:00
class UpdateManager implements CallbackListener , CommandListener , TimerListener {
2014-01-19 22:32:09 +01:00
/*
2013-12-17 17:38:44 +01:00
* Constants
*/
2014-01-31 16:55:01 +01:00
const SETTING_ENABLEUPDATECHECK = 'Enable Automatic Core Update Check' ;
const SETTING_UPDATECHECK_INTERVAL = 'Core Update Check Interval (Hours)' ;
const SETTING_UPDATECHECK_CHANNEL = 'Core Update Channel (release, beta, nightly)' ;
const SETTING_PERFORM_BACKUPS = 'Perform Backup before Updating' ;
const SETTING_AUTO_UPDATE = 'Perform update automatically' ;
const SETTING_PERMISSION_UPDATE = 'Update Core' ;
const SETTING_PERMISSION_UPDATECHECK = 'Check Core Update' ;
const CHANNEL_RELEASE = 'release' ;
const CHANNEL_BETA = 'beta' ;
const CHANNEL_NIGHTLY = 'nightly' ;
2014-01-20 21:54:58 +01:00
2014-01-19 22:32:09 +01:00
/*
2013-12-17 17:38:44 +01:00
* Private Properties
*/
private $maniaControl = null ;
2014-02-10 22:54:49 +01:00
/** @var UpdateData $coreUpdateData */
2013-12-17 17:38:44 +01:00
private $coreUpdateData = null ;
2014-02-10 22:18:03 +01:00
private $currentBuildDate = " " ;
2013-12-17 17:38:44 +01:00
/**
2014-01-19 22:32:09 +01:00
* Create a new Update Manager
2013-12-17 17:38:44 +01:00
*
2013-12-31 17:17:40 +01:00
* @ param ManiaControl $maniaControl
2013-12-17 17:38:44 +01:00
*/
public function __construct ( ManiaControl $maniaControl ) {
$this -> maniaControl = $maniaControl ;
2014-01-20 21:54:58 +01:00
2013-12-17 17:38:44 +01:00
// Init settings
$this -> maniaControl -> settingManager -> initSetting ( $this , self :: SETTING_ENABLEUPDATECHECK , true );
2014-01-21 19:12:55 +01:00
$this -> maniaControl -> settingManager -> initSetting ( $this , self :: SETTING_AUTO_UPDATE , true );
2014-02-10 16:46:41 +01:00
$this -> maniaControl -> settingManager -> initSetting ( $this , self :: SETTING_UPDATECHECK_INTERVAL , 1 );
2014-02-13 14:58:04 +01:00
// TODO: 'nightly' only during dev
$this -> maniaControl -> settingManager -> initSetting ( $this , self :: SETTING_UPDATECHECK_CHANNEL , self :: CHANNEL_NIGHTLY );
2013-12-31 18:25:07 +01:00
$this -> maniaControl -> settingManager -> initSetting ( $this , self :: SETTING_PERFORM_BACKUPS , true );
2014-01-20 21:54:58 +01:00
2013-12-17 17:38:44 +01:00
// Register for callbacks
2014-02-10 16:46:41 +01:00
$updateInterval = $this -> maniaControl -> settingManager -> getSetting ( $this , self :: SETTING_UPDATECHECK_INTERVAL );
$this -> maniaControl -> timerManager -> registerTimerListening ( $this , 'hourlyUpdateCheck' , 1000 * 60 * 60 * $updateInterval );
2014-02-19 10:43:37 +01:00
$this -> maniaControl -> callbackManager -> registerCallbackListener ( PlayerManager :: CB_PLAYERCONNECT , $this , 'handlePlayerJoined' );
$this -> maniaControl -> callbackManager -> registerCallbackListener ( PlayerManager :: CB_PLAYERDISCONNECT , $this , 'autoUpdate' );
2014-04-16 01:22:31 +02:00
$this -> maniaControl -> callbackManager -> registerCallbackListener ( CallbackManager :: CB_MP_PLAYERMANIALINKPAGEANSWER , $this , 'handleManialinkPageAnswer' );
2014-01-21 19:36:09 +01:00
2014-01-31 16:55:01 +01:00
//define Permissions
$this -> maniaControl -> authenticationManager -> definePermissionLevel ( self :: SETTING_PERMISSION_UPDATE , AuthenticationManager :: AUTH_LEVEL_ADMIN );
$this -> maniaControl -> authenticationManager -> definePermissionLevel ( self :: SETTING_PERMISSION_UPDATECHECK , AuthenticationManager :: AUTH_LEVEL_MODERATOR );
2014-01-20 21:54:58 +01:00
2013-12-17 17:38:44 +01:00
// Register for chat commands
$this -> maniaControl -> commandManager -> registerCommandListener ( 'checkupdate' , $this , 'handle_CheckUpdate' , true );
2013-12-31 18:25:07 +01:00
$this -> maniaControl -> commandManager -> registerCommandListener ( 'coreupdate' , $this , 'handle_CoreUpdate' , true );
2014-04-16 00:28:43 +02:00
$this -> maniaControl -> commandManager -> registerCommandListener ( 'pluginupdate' , $this , 'handle_PluginUpdate' , true );
2014-02-10 21:32:41 +01:00
2014-02-10 22:18:03 +01:00
$this -> currentBuildDate = $this -> getNightlyBuildDate ();
2014-04-16 17:54:18 +02:00
$this -> pluginInstallMenu = new PluginInstallMenu ( $maniaControl );
$this -> maniaControl -> configurator -> addMenu ( $this -> pluginInstallMenu );
2013-12-17 17:38:44 +01:00
}
/**
2014-02-10 16:46:41 +01:00
* Perform Hourly Update Check
2013-12-17 17:38:44 +01:00
*
2014-01-31 00:04:40 +01:00
* @ param $time
2013-12-17 17:38:44 +01:00
*/
2014-02-01 18:33:06 +01:00
public function hourlyUpdateCheck ( $time ) {
2013-12-17 17:38:44 +01:00
$updateCheckEnabled = $this -> maniaControl -> settingManager -> getSetting ( $this , self :: SETTING_ENABLEUPDATECHECK );
2014-01-28 16:23:50 +01:00
if ( ! $updateCheckEnabled ) {
2013-12-31 17:17:40 +01:00
// Automatic update check disabled
2014-01-28 16:23:50 +01:00
if ( $this -> coreUpdateData ) {
2014-01-20 21:54:58 +01:00
$this -> coreUpdateData = null ;
}
2013-12-17 17:38:44 +01:00
return ;
}
2014-02-01 18:33:06 +01:00
2014-02-10 21:32:41 +01:00
//Check if a new Core Update is Available
2014-04-15 11:33:06 +02:00
$self = $this ;
$maniaControl = $this -> maniaControl ;
$this -> checkCoreUpdateAsync ( function ( UpdateData $updateData ) use ( $self , $maniaControl , $time ) {
$buildDate = strtotime ( $self -> getCurrentBuildDate ());
2014-02-10 22:54:49 +01:00
$releaseTime = strtotime ( $updateData -> releaseDate );
2014-02-10 21:32:41 +01:00
if ( $buildDate < $releaseTime ) {
2014-04-15 11:33:06 +02:00
$updateChannel = $maniaControl -> settingManager -> getSetting ( $self , UpdateManager :: SETTING_UPDATECHECK_CHANNEL );
if ( $updateChannel != UpdateManager :: CHANNEL_NIGHTLY ) {
$maniaControl -> log ( 'New ManiaControl Version ' . $updateData -> version . ' available!' );
2014-02-10 22:18:03 +01:00
} else {
2014-04-15 11:33:06 +02:00
$maniaControl -> log ( 'New Nightly Build (' . $updateData -> releaseDate . ') available!' );
2014-02-10 22:18:03 +01:00
}
2014-04-15 11:33:06 +02:00
$self -> setCoreUpdateData ( $updateData );
$self -> autoUpdate ( $time );
2014-02-10 21:32:41 +01:00
}
}, true );
2013-12-17 17:38:44 +01:00
}
/**
* Handle ManiaControl PlayerJoined callback
*
2014-02-19 15:44:00 +01:00
* @ param Player $player
2013-12-17 17:38:44 +01:00
*/
2014-02-19 15:44:00 +01:00
public function handlePlayerJoined ( Player $player ) {
2014-01-28 16:23:50 +01:00
if ( ! $this -> coreUpdateData ) {
2014-01-20 21:54:58 +01:00
return ;
}
2013-12-31 17:17:40 +01:00
// Announce available update
2014-01-31 16:55:01 +01:00
if ( ! $this -> maniaControl -> authenticationManager -> checkPermission ( $player , self :: SETTING_PERMISSION_UPDATE )) {
2014-01-20 21:54:58 +01:00
return ;
}
2014-02-10 21:32:41 +01:00
2014-02-10 22:18:03 +01:00
$buildDate = strtotime ( $this -> currentBuildDate );
2014-02-10 22:54:49 +01:00
$releaseTime = strtotime ( $this -> coreUpdateData -> releaseDate );
2014-02-10 21:32:41 +01:00
if ( $buildDate < $releaseTime ) {
2014-02-10 22:18:03 +01:00
$updateChannel = $this -> maniaControl -> settingManager -> getSetting ( $this , self :: SETTING_UPDATECHECK_CHANNEL );
if ( $updateChannel != self :: CHANNEL_NIGHTLY ) {
$this -> maniaControl -> chat -> sendInformation ( 'New ManiaControl Version ' . $this -> coreUpdateData -> version . ' available!' , $player -> login );
} else {
2014-02-10 22:54:49 +01:00
$this -> maniaControl -> chat -> sendSuccess ( 'New Nightly Build (' . $this -> coreUpdateData -> releaseDate . ') available!' , $player -> login );
2014-02-10 22:18:03 +01:00
}
2014-02-10 21:32:41 +01:00
}
2013-12-17 17:38:44 +01:00
}
2014-01-20 21:54:58 +01:00
/**
2014-02-01 18:33:06 +01:00
* Perform automatic update as soon as a the Server is empty ( also every hour got checked when its empty )
2014-01-20 21:54:58 +01:00
*
2014-02-01 18:33:06 +01:00
* @ param mixed $callback
2014-01-20 21:54:58 +01:00
*/
2014-02-01 18:33:06 +01:00
public function autoUpdate ( $callback ) {
$autoUpdate = $this -> maniaControl -> settingManager -> getSetting ( $this , self :: SETTING_AUTO_UPDATE );
if ( ! $autoUpdate ) {
2014-01-21 19:12:55 +01:00
return ;
}
2014-01-28 16:23:50 +01:00
if ( count ( $this -> maniaControl -> playerManager -> getPlayers ()) > 0 ) {
2014-01-20 21:54:58 +01:00
return ;
}
2014-02-10 21:32:41 +01:00
if ( ! $this -> coreUpdateData ) {
2014-01-20 21:54:58 +01:00
return ;
}
2014-04-14 14:38:00 +02:00
$version = $this -> maniaControl -> client -> getVersion ();
if ( $this -> coreUpdateData -> minDedicatedBuild > $version -> build ){
return ;
}
2014-02-10 22:18:03 +01:00
$buildDate = strtotime ( $this -> currentBuildDate );
2014-02-10 22:54:49 +01:00
$releaseTime = strtotime ( $this -> coreUpdateData -> releaseDate );
2014-02-10 21:32:41 +01:00
if ( $buildDate && $buildDate >= $releaseTime ) {
return ;
}
$this -> maniaControl -> log ( " Starting Update to Version v { $this -> coreUpdateData -> version } ... " );
2014-01-20 21:54:58 +01:00
$performBackup = $this -> maniaControl -> settingManager -> getSetting ( $this , self :: SETTING_PERFORM_BACKUPS );
2014-01-28 16:23:50 +01:00
if ( $performBackup && ! $this -> performBackup ()) {
2014-01-20 21:54:58 +01:00
$this -> maniaControl -> log ( " Creating Backup failed! " );
}
2014-02-10 21:32:41 +01:00
$this -> performCoreUpdate ( $this -> coreUpdateData );
2014-01-20 21:54:58 +01:00
}
2014-02-01 18:33:06 +01:00
2013-12-17 17:38:44 +01:00
/**
* Handle //checkupdate command
*
2014-01-20 21:54:58 +01:00
* @ param array $chatCallback
2013-12-31 17:17:40 +01:00
* @ param Player $player
2013-12-17 17:38:44 +01:00
*/
public function handle_CheckUpdate ( array $chatCallback , Player $player ) {
2014-01-31 16:55:01 +01:00
if ( ! $this -> maniaControl -> authenticationManager -> checkPermission ( $player , self :: SETTING_PERMISSION_UPDATECHECK )) {
2013-12-17 17:38:44 +01:00
$this -> maniaControl -> authenticationManager -> sendNotAllowed ( $player );
return ;
}
2014-01-19 22:32:09 +01:00
$updateChannel = $this -> maniaControl -> settingManager -> getSetting ( $this , self :: SETTING_UPDATECHECK_CHANNEL );
2014-01-28 16:23:50 +01:00
if ( $updateChannel != self :: CHANNEL_NIGHTLY ) {
2014-01-19 22:32:09 +01:00
// Check update and send result message
2014-02-10 22:54:49 +01:00
$this -> checkCoreUpdateAsync ( function ( UpdateData $updateData ) use ( & $player ) {
2014-02-10 22:18:03 +01:00
if ( ! $updateData ) {
$this -> maniaControl -> chat -> sendInformation ( 'No Update available!' , $player -> login );
return ;
}
2014-04-14 14:38:00 +02:00
$version = $this -> maniaControl -> client -> getVersion ();
if ( $updateData -> minDedicatedBuild > $version -> build ){
$this -> maniaControl -> chat -> sendError ( " No new Build for this Server-version available! " , $player -> login );
return ;
}
2014-02-10 22:18:03 +01:00
$this -> maniaControl -> chat -> sendSuccess ( 'Update for Version ' . $updateData -> version . ' available!' , $player -> login );
});
2014-01-20 21:54:58 +01:00
} else {
2014-01-19 22:32:09 +01:00
// Special nightly channel updating
2014-02-10 22:54:49 +01:00
$this -> checkCoreUpdateAsync ( function ( UpdateData $updateData ) use ( & $player ) {
2014-02-10 22:18:03 +01:00
if ( ! $updateData ) {
$this -> maniaControl -> chat -> sendInformation ( 'No Update available!' , $player -> login );
2014-01-19 22:32:09 +01:00
return ;
}
2014-02-10 22:18:03 +01:00
2014-04-14 14:38:00 +02:00
$version = $this -> maniaControl -> client -> getVersion ();
if ( $updateData -> minDedicatedBuild > $version -> build ){
$this -> maniaControl -> chat -> sendError ( " No new Build for this Server-version available! " , $player -> login );
return ;
}
2014-02-10 22:18:03 +01:00
$buildTime = strtotime ( $this -> currentBuildDate );
2014-02-10 22:54:49 +01:00
$releaseTime = strtotime ( $updateData -> releaseDate );
2014-02-10 22:18:03 +01:00
if ( $buildTime != '' ) {
if ( $buildTime >= $releaseTime ) {
$this -> maniaControl -> chat -> sendInformation ( 'No new Build available, current build: ' . date ( " Y-m-d " , $buildTime ) . '!' , $player -> login );
return ;
}
2014-02-10 22:54:49 +01:00
$this -> maniaControl -> chat -> sendSuccess ( 'New Nightly Build (' . $updateData -> releaseDate . ') available, current build: ' . $this -> currentBuildDate . '!' , $player -> login );
2014-02-10 22:18:03 +01:00
} else {
2014-02-10 22:54:49 +01:00
$this -> maniaControl -> chat -> sendSuccess ( 'New Nightly Build (' . $updateData -> releaseDate . ') available!' , $player -> login );
2014-02-10 22:18:03 +01:00
}
}, true );
2013-12-17 17:38:44 +01:00
}
2014-01-19 22:32:09 +01:00
}
2014-04-16 01:22:31 +02:00
/**
* Handle PlayerManialinkPageAnswer callback
*
* @ param array $callback
*/
public function handleManialinkPageAnswer ( array $callback ) {
$actionId = $callback [ 1 ][ 2 ];
$update = ( strpos ( $actionId , PluginMenu :: ACTION_PREFIX_UPDATEPLUGIN ) === 0 );
2014-04-16 22:53:14 +02:00
$install = ( strpos ( $actionId , PluginInstallMenu :: ACTION_PREFIX_INSTALLPLUGIN ) === 0 );
2014-04-16 01:22:31 +02:00
$login = $callback [ 1 ][ 1 ];
$player = $this -> maniaControl -> playerManager -> getPlayer ( $login );
if ( $update ) {
$pluginClass = substr ( $actionId , strlen ( PluginMenu :: ACTION_PREFIX_UPDATEPLUGIN ));
2014-04-16 01:38:28 +02:00
if ( $pluginClass == 'All' ) {
$this -> checkPluginsUpdate ( $player );
} else {
$newUpdate = $this -> checkPluginUpdate ( $pluginClass );
if ( $newUpdate != false ) {
$newUpdate -> pluginClass = $pluginClass ;
$this -> updatePlugin ( $newUpdate , $player , true );
}
2014-04-16 01:22:31 +02:00
}
}
2014-04-16 22:53:14 +02:00
if ( $install ) {
$pluginId = substr ( $actionId , strlen ( PluginInstallMenu :: ACTION_PREFIX_INSTALLPLUGIN ));
$url = ManiaControl :: URL_WEBSERVICE . 'plugins?id=' . $pluginId ;
$dataJson = FileUtil :: loadFile ( $url );
$pluginVersions = json_decode ( $dataJson );
if ( $pluginVersions && isset ( $pluginVersions [ 0 ])) {
$pluginData = $pluginVersions [ 0 ];
$this -> installPlugin ( $pluginData , $player , true );
}
}
2014-04-16 01:22:31 +02:00
}
2014-01-19 22:32:09 +01:00
/**
* Get the Build Date of the local Nightly Build Version
*
2014-02-10 22:18:03 +01:00
* @ return String $buildTime
2014-01-19 22:32:09 +01:00
*/
private function getNightlyBuildDate () {
$nightlyBuildDateFile = ManiaControlDir . '/core/nightly_build.txt' ;
2014-01-28 16:23:50 +01:00
if ( ! file_exists ( $nightlyBuildDateFile )) {
2014-02-10 22:18:03 +01:00
return '' ;
2014-01-20 21:54:58 +01:00
}
2014-01-19 22:32:09 +01:00
$fileContent = file_get_contents ( $nightlyBuildDateFile );
return $fileContent ;
2013-12-17 17:38:44 +01:00
}
2014-02-15 18:26:31 +01:00
/**
* Get the CurrentBuildDate
*
* @ return string
*/
public function getCurrentBuildDate () {
return $this -> currentBuildDate ;
}
2014-02-10 21:32:41 +01:00
/**
* Set the Build Date of the local Nightly Build Version
*
* @ param $date
* @ return mixed
*/
private function setNightlyBuildDate ( $date ) {
$nightlyBuildDateFile = ManiaControlDir . '/core/nightly_build.txt' ;
$success = file_put_contents ( $nightlyBuildDateFile , $date );
2014-02-10 22:18:03 +01:00
$this -> currentBuildDate = $date ;
2014-02-10 21:32:41 +01:00
return $success ;
}
2013-12-31 18:25:07 +01:00
/**
* Handle //coreupdate command
*
2014-01-20 21:54:58 +01:00
* @ param array $chatCallback
2013-12-31 18:25:07 +01:00
* @ param Player $player
*/
public function handle_CoreUpdate ( array $chatCallback , Player $player ) {
2014-01-28 16:23:50 +01:00
if ( ! $this -> maniaControl -> authenticationManager -> checkPermission ( $player , self :: SETTING_PERMISSION_UPDATE )) {
2013-12-31 18:25:07 +01:00
$this -> maniaControl -> authenticationManager -> sendNotAllowed ( $player );
return ;
}
2014-01-20 21:54:58 +01:00
2014-04-14 14:38:00 +02:00
$this -> checkCoreUpdateAsync ( function ( UpdateData $updateData ) use ( & $player ) {
2014-02-10 22:54:49 +01:00
if ( ! $updateData ) {
$this -> maniaControl -> chat -> sendError ( 'Update is currently not possible!' , $player -> login );
return ;
}
2014-04-14 14:38:00 +02:00
$version = $this -> maniaControl -> client -> getVersion ();
if ( $updateData -> minDedicatedBuild > $version -> build ){
$this -> maniaControl -> chat -> sendError ( " ManiaControl update version requires a newer Dedicated Server version! " , $player -> login );
return ;
}
2014-02-10 22:54:49 +01:00
$this -> maniaControl -> chat -> sendInformation ( " Starting Update to Version v { $updateData -> version } ... " , $player -> login );
$this -> maniaControl -> log ( " Starting Update to Version v { $updateData -> version } ... " );
$performBackup = $this -> maniaControl -> settingManager -> getSetting ( $this , self :: SETTING_PERFORM_BACKUPS );
if ( $performBackup && ! $this -> performBackup ()) {
$this -> maniaControl -> chat -> sendError ( 'Creating backup failed.' , $player -> login );
$this -> maniaControl -> log ( " Creating backup failed. " );
}
2014-01-28 16:23:50 +01:00
2014-02-10 22:54:49 +01:00
$this -> performCoreUpdate ( $updateData , $player );
}, true );
2014-01-24 19:00:26 +01:00
}
2014-01-24 18:50:47 +01:00
2014-04-16 00:28:43 +02:00
/**
* Handle //pluginupdate command
*
* @ param array $chatCallback
* @ param Player $player
*/
public function handle_PluginUpdate ( array $chatCallback , Player $player ) {
if ( ! $this -> maniaControl -> authenticationManager -> checkPermission ( $player , self :: SETTING_PERMISSION_UPDATE )) {
$this -> maniaControl -> authenticationManager -> sendNotAllowed ( $player );
return ;
}
$this -> checkPluginsUpdate ( $player );
}
2014-04-16 00:14:58 +02:00
/**
* Checks if there are outdated plugins active .
2014-04-16 01:38:28 +02:00
* @ param Player $player
2014-04-16 00:14:58 +02:00
*/
2014-04-16 00:28:43 +02:00
public function checkPluginsUpdate ( Player $player = null ) {
2014-04-15 23:49:27 +02:00
$this -> maniaControl -> log ( '[UPDATE] Checking plugins for newer versions ...' );
2014-04-16 00:14:58 +02:00
$outdatedPlugins = array ();
2014-04-16 00:28:43 +02:00
foreach ( $this -> maniaControl -> pluginManager -> getPluginClasses () as $pluginClass ) {
2014-04-15 23:49:27 +02:00
$pluginData = $this -> checkPluginUpdate ( $pluginClass );
2014-04-16 00:28:43 +02:00
if ( $pluginData != false ) {
$pluginData -> pluginClass = $pluginClass ;
2014-04-16 00:14:58 +02:00
$outdatedPlugins [] = $pluginData ;
2014-04-15 23:49:27 +02:00
$this -> maniaControl -> log ( '[UPDATE] ' . $pluginClass . ': There is a newer version available: ' . $pluginData -> currentVersion -> version . '!' );
}
}
2014-04-16 00:14:58 +02:00
2014-04-16 00:28:43 +02:00
if ( count ( $outdatedPlugins ) > 0 ) {
2014-04-16 00:14:58 +02:00
$this -> maniaControl -> log ( '[UPDATE] Checking plugins: COMPLETE, there are ' . count ( $outdatedPlugins ) . ' outdated plugins, now updating ...' );
2014-04-16 00:28:43 +02:00
if ( $player ) {
$this -> maniaControl -> chat -> sendInformation ( 'Checking plugins: COMPLETE, there are ' . count ( $outdatedPlugins ) . ' outdated plugins, now updating ...' , $player -> login );
}
2014-04-16 00:14:58 +02:00
$this -> performPluginsBackup ();
2014-04-16 00:28:43 +02:00
foreach ( $outdatedPlugins as $plugin ) {
$this -> updatePlugin ( $plugin , $player );
2014-04-16 00:14:58 +02:00
}
} else {
$this -> maniaControl -> log ( '[UPDATE] Checking plugins: COMPLETE, all plugins are up-to-date!' );
2014-04-16 00:28:43 +02:00
if ( $player ) {
$this -> maniaControl -> chat -> sendInformation ( 'Checking plugins: COMPLETE, all plugins are up-to-date!' , $player -> login );
}
2014-04-16 00:14:58 +02:00
}
2014-04-15 23:49:27 +02:00
}
2013-12-17 17:38:44 +01:00
/**
* Check given Plugin Class for Update
*
2013-12-31 17:17:40 +01:00
* @ param string $pluginClass
2013-12-17 17:38:44 +01:00
* @ return mixed
*/
public function checkPluginUpdate ( $pluginClass ) {
2014-01-28 16:23:50 +01:00
if ( is_object ( $pluginClass )) {
2013-12-17 17:38:44 +01:00
$pluginClass = get_class ( $pluginClass );
}
2014-01-28 16:23:50 +01:00
/** @var Plugin $pluginClass */
2014-01-20 21:54:58 +01:00
$pluginId = $pluginClass :: getId ();
2014-02-15 18:41:03 +01:00
$url = ManiaControl :: URL_WEBSERVICE . 'plugins?id=' . $pluginId ;
2014-02-10 16:52:16 +01:00
$dataJson = FileUtil :: loadFile ( $url );
2013-12-17 17:38:44 +01:00
$pluginVersions = json_decode ( $dataJson );
2014-01-28 16:23:50 +01:00
if ( ! $pluginVersions || ! isset ( $pluginVersions [ 0 ])) {
2013-12-17 17:38:44 +01:00
return false ;
}
2014-01-20 21:54:58 +01:00
$pluginData = $pluginVersions [ 0 ];
2013-12-17 17:38:44 +01:00
$pluginVersion = $pluginClass :: getVersion ();
2014-04-15 23:49:27 +02:00
if ( $pluginData -> currentVersion -> version <= $pluginVersion ) {
2013-12-17 17:38:44 +01:00
return false ;
}
return $pluginData ;
}
2014-04-16 14:16:37 +02:00
/**
* Check for updates
*
* @ return mixed
*/
public function getPluginsUpdates () {
$pluginUpdates = array ();
$pluginsWS = array ();
$url = ManiaControl :: URL_WEBSERVICE . 'plugins' ;
$dataJson = FileUtil :: loadFile ( $url );
$pluginVersions = json_decode ( $dataJson );
if ( ! $pluginVersions || ! isset ( $pluginVersions [ 0 ])) {
return false ;
}
foreach ( $pluginVersions as $plugin ) {
$pluginsWS [ $plugin -> id ] = $plugin ;
}
/** @var Plugin $pluginClass */
foreach ( $this -> maniaControl -> pluginManager -> getPluginClasses () as $pluginClass ) {
$pluginId = $pluginClass :: getId ();
if ( array_key_exists ( $pluginId , $pluginsWS )) {
if ( $pluginsWS [ $pluginId ] -> currentVersion -> version > $pluginClass :: getVersion ()) {
$pluginUpdates [ $pluginId ] = $pluginsWS [ $pluginId ];
}
}
}
if ( empty ( $pluginUpdates )) {
return false ;
}
return $pluginUpdates ;
}
2014-04-16 00:28:43 +02:00
/**
* Update pluginfile
*
* @ param $pluginData
* @ param Player $player
2014-04-16 01:22:31 +02:00
* @ param bool $reopen
2014-04-16 00:28:43 +02:00
*/
2014-04-16 01:22:31 +02:00
private function updatePlugin ( $pluginData , Player $player = null , $reopen = false ) {
$this -> maniaControl -> fileReader -> loadFile ( $pluginData -> currentVersion -> url , function ( $updateFileContent , $error ) use ( & $updateData , & $player , & $pluginData , & $reopen ) {
2014-04-16 00:14:58 +02:00
$this -> maniaControl -> log ( '[UPDATE] Now updating ' . $pluginData -> name . ' ...' );
2014-04-16 00:28:43 +02:00
if ( $player ) {
$this -> maniaControl -> chat -> sendInformation ( 'Now updating ' . $pluginData -> name . ' ...' , $player -> login );
}
2014-04-16 00:14:58 +02:00
$tempDir = ManiaControlDir . '/temp/' ;
if ( ! is_dir ( $tempDir )) {
mkdir ( $tempDir );
}
$updateFileName = $tempDir . $pluginData -> currentVersion -> zipfile ;
$bytes = file_put_contents ( $updateFileName , $updateFileContent );
if ( ! $bytes || $bytes <= 0 ) {
trigger_error ( " Couldn't save plugin Zip. " );
if ( $player ) {
$this -> maniaControl -> chat -> sendError ( 'Update failed: Couldn\'t save plugin zip!' , $player -> login );
}
return false ;
}
$zip = new \ZipArchive ();
$result = $zip -> open ( $updateFileName );
if ( $result !== true ) {
trigger_error ( " Couldn't open plugin Zip. ( { $result } ) " );
if ( $player ) {
$this -> maniaControl -> chat -> sendError ( 'Update failed: Couldn\'t open plugin zip!' , $player -> login );
}
return false ;
}
$zip -> extractTo ( ManiaControlDir . '/plugins' );
$zip -> close ();
unlink ( $updateFileName );
@ rmdir ( $tempDir );
$this -> maniaControl -> log ( '[UPDATE] Successfully updated ' . $pluginData -> name . '!' );
2014-04-16 00:28:43 +02:00
if ( $player ) {
$this -> maniaControl -> chat -> sendSuccess ( 'Successfully updated ' . $pluginData -> name . '!' , $player -> login );
$this -> maniaControl -> pluginManager -> deactivatePlugin ( $pluginData -> pluginClass );
$this -> maniaControl -> pluginManager -> activatePlugin ( $pluginData -> pluginClass );
2014-04-16 01:22:31 +02:00
if ( $reopen ) {
$menuId = $this -> maniaControl -> configurator -> getMenuId ( 'Plugins' );
$this -> maniaControl -> configurator -> reopenMenu ( $player , $menuId );
}
2014-04-16 00:28:43 +02:00
}
2014-04-16 00:14:58 +02:00
});
}
2014-04-16 22:53:14 +02:00
/**
* Update pluginfile
*
* @ param $pluginData
* @ param Player $player
* @ param bool $reopen
*/
private function installPlugin ( $pluginData , Player $player , $reopen = false ) {
$this -> maniaControl -> fileReader -> loadFile ( $pluginData -> currentVersion -> url , function ( $installFileContent , $error ) use ( & $updateData , & $player , & $pluginData , & $reopen ) {
$pluginsDirectory = ManiaControlDir . '/plugins/' ;
$pluginFiles = scandir ( $pluginsDirectory );
$this -> maniaControl -> log ( '[UPDATE] Now installing ' . $pluginData -> name . ' ...' );
$this -> maniaControl -> chat -> sendInformation ( 'Now installing ' . $pluginData -> name . ' ...' , $player -> login );
$tempDir = ManiaControlDir . '/temp/' ;
if ( ! is_dir ( $tempDir )) {
mkdir ( $tempDir );
}
$installFileName = $tempDir . $pluginData -> currentVersion -> zipfile ;
$bytes = file_put_contents ( $installFileName , $installFileContent );
if ( ! $bytes || $bytes <= 0 ) {
trigger_error ( " Couldn't save plugin Zip. " );
$this -> maniaControl -> chat -> sendError ( 'Install failed: Couldn\'t save plugin zip!' , $player -> login );
return false ;
}
$zip = new \ZipArchive ();
$result = $zip -> open ( $installFileName );
if ( $result !== true ) {
trigger_error ( " Couldn't open plugin Zip. ( { $result } ) " );
$this -> maniaControl -> chat -> sendError ( 'Install failed: Couldn\'t open plugin zip!' , $player -> login );
return false ;
}
$zip -> extractTo ( ManiaControlDir . '/plugins' );
$zip -> close ();
unlink ( $installFileName );
@ rmdir ( $tempDir );
$pluginFilesAfter = scandir ( $pluginsDirectory );
$newFiles = array_diff ( $pluginFilesAfter , $pluginFiles );
$classesBefore = get_declared_classes ();
foreach ( $newFiles as $newFile ) {
$filePath = $pluginsDirectory . $newFile ;
if ( is_file ( $filePath )) {
$success = include_once $filePath ;
if ( ! $success ) {
trigger_error ( " Error loading File ' { $filePath } '! " );
}
continue ;
}
$dirPath = $pluginsDirectory . $newFile ;
if ( is_dir ( $dirPath )) {
$this -> maniaControl -> pluginManager -> loadPluginFiles ( $dirPath );
continue ;
}
}
$classesAfter = get_declared_classes ();
$newClasses = array_diff ( $classesAfter , $classesBefore );
foreach ( $newClasses as $className ) {
if ( ! $this -> maniaControl -> pluginManager -> isPluginClass ( $className )) {
continue ;
}
/** @var Plugin $className */
$this -> maniaControl -> pluginManager -> addPluginClass ( $className );
$className :: prepare ( $this -> maniaControl );
if ( $this -> maniaControl -> pluginManager -> isPluginActive ( $className )) {
continue ;
}
if ( ! $this -> maniaControl -> pluginManager -> getSavedPluginStatus ( $className )) {
continue ;
}
}
$this -> maniaControl -> log ( '[UPDATE] Successfully installed ' . $pluginData -> name . '!' );
$this -> maniaControl -> chat -> sendSuccess ( 'Successfully installed ' . $pluginData -> name . '!' , $player -> login );
if ( $reopen ) {
$menuId = $this -> maniaControl -> configurator -> getMenuId ( 'Install Plugins' );
$this -> maniaControl -> configurator -> reopenMenu ( $player , $menuId );
}
});
}
2014-04-15 11:33:06 +02:00
/**
* Set Core Update Data
*
* @ param UpdateData $coreUpdateData
*/
public function setCoreUpdateData ( UpdateData $coreUpdateData = null ) {
$this -> coreUpdateData = $coreUpdateData ;
}
2014-02-10 21:32:41 +01:00
/**
2014-02-10 22:54:49 +01:00
* Checks a core update Asynchronously
2014-02-10 21:32:41 +01:00
*
* @ param $function
* @ param bool $ignoreVersion
*/
private function checkCoreUpdateAsync ( $function , $ignoreVersion = false ) {
$updateChannel = $this -> getCurrentUpdateChannelSetting ();
2014-02-15 18:41:03 +01:00
$url = ManiaControl :: URL_WEBSERVICE . 'versions?update=1¤t=1&channel=' . $updateChannel ;
2014-02-10 21:32:41 +01:00
$this -> maniaControl -> fileReader -> loadFile ( $url , function ( $dataJson , $error ) use ( & $function , $ignoreVersion ) {
$versions = json_decode ( $dataJson );
if ( ! $versions || ! isset ( $versions [ 0 ])) {
return ;
}
2014-02-10 22:54:49 +01:00
$updateData = new UpdateData ( $versions [ 0 ]);
2014-02-10 21:32:41 +01:00
if ( ! $ignoreVersion && $updateData -> version <= ManiaControl :: VERSION ) {
return ;
}
2014-04-14 14:38:00 +02:00
2014-02-10 21:32:41 +01:00
call_user_func ( $function , $updateData );
});
}
2013-12-31 18:25:07 +01:00
/**
* Perform a Backup of ManiaControl
*
* @ return bool
*/
private function performBackup () {
$backupFolder = ManiaControlDir . '/backup/' ;
2014-01-28 16:23:50 +01:00
if ( ! is_dir ( $backupFolder )) {
2014-01-20 21:54:58 +01:00
mkdir ( $backupFolder );
}
2014-01-19 22:32:09 +01:00
$backupFileName = $backupFolder . 'backup_' . ManiaControl :: VERSION . '_' . date ( 'y-m-d' ) . '_' . time () . '.zip' ;
2014-01-20 21:54:58 +01:00
$backupZip = new \ZipArchive ();
2014-01-28 16:23:50 +01:00
if ( $backupZip -> open ( $backupFileName , \ZipArchive :: CREATE ) !== TRUE ) {
2013-12-31 18:25:07 +01:00
trigger_error ( " Couldn't create Backup Zip! " );
return false ;
}
2014-01-20 21:54:58 +01:00
$excludes = array ( '.' , '..' , 'backup' , 'logs' , 'ManiaControl.log' );
$pathInfo = pathInfo ( ManiaControlDir );
2013-12-31 18:25:07 +01:00
$parentPath = $pathInfo [ 'dirname' ] . '/' ;
2014-01-20 21:54:58 +01:00
$dirName = $pathInfo [ 'basename' ];
2013-12-31 18:25:07 +01:00
$backupZip -> addEmptyDir ( $dirName );
$this -> zipDirectory ( $backupZip , ManiaControlDir , strlen ( $parentPath ), $excludes );
$backupZip -> close ();
return true ;
}
2014-04-16 00:14:58 +02:00
/**
* Perform a Backup of the plugins
*
* @ return bool
*/
private function performPluginsBackup () {
$backupFolder = ManiaControlDir . '/backup/' ;
if ( ! is_dir ( $backupFolder )) {
mkdir ( $backupFolder );
}
$backupFileName = $backupFolder . 'backup_plugins_' . date ( 'y-m-d' ) . '_' . time () . '.zip' ;
$backupZip = new \ZipArchive ();
if ( $backupZip -> open ( $backupFileName , \ZipArchive :: CREATE ) !== TRUE ) {
trigger_error ( " Couldn't create Backup Zip! " );
return false ;
}
$excludes = array ( '.' , '..' );
$pathInfo = pathInfo ( ManiaControlDir . '/plugins' );
$parentPath = $pathInfo [ 'dirname' ] . '/' ;
$dirName = $pathInfo [ 'basename' ];
$backupZip -> addEmptyDir ( $dirName );
$this -> zipDirectory ( $backupZip , ManiaControlDir . '/plugins' , strlen ( $parentPath ), $excludes );
$backupZip -> close ();
return true ;
}
2013-12-31 18:25:07 +01:00
/**
* Add a complete Directory to the ZipArchive
*
* @ param \ZipArchive $zipArchive
2014-01-20 21:54:58 +01:00
* @ param string $folderName
* @ param int $prefixLength
* @ param array $excludes
2013-12-31 18:25:07 +01:00
* @ return bool
*/
private function zipDirectory ( \ZipArchive & $zipArchive , $folderName , $prefixLength , array $excludes = array ()) {
$folderHandle = opendir ( $folderName );
2014-01-28 16:23:50 +01:00
if ( ! $folderHandle ) {
2013-12-31 18:25:07 +01:00
trigger_error ( " Couldn't open Folder ' { $folderName } ' for Backup! " );
return false ;
}
2014-01-20 21:54:58 +01:00
while ( false !== ( $file = readdir ( $folderHandle ))) {
2014-01-28 16:23:50 +01:00
if ( in_array ( $file , $excludes )) {
2014-01-20 21:54:58 +01:00
continue ;
}
$filePath = $folderName . '/' . $file ;
2013-12-31 18:25:07 +01:00
$localPath = substr ( $filePath , $prefixLength );
2014-01-28 16:23:50 +01:00
if ( is_file ( $filePath )) {
2013-12-31 18:25:07 +01:00
$zipArchive -> addFile ( $filePath , $localPath );
continue ;
}
2014-01-28 16:23:50 +01:00
if ( is_dir ( $filePath )) {
2013-12-31 18:25:07 +01:00
$zipArchive -> addEmptyDir ( $localPath );
$this -> zipDirectory ( $zipArchive , $filePath , $prefixLength , $excludes );
continue ;
}
}
closedir ( $folderHandle );
return true ;
}
2013-12-27 23:26:27 +01:00
/**
* Perform a Core Update
*
2014-02-10 22:54:49 +01:00
* @ param object $updateData
* @ param $player
2013-12-27 23:26:27 +01:00
* @ return bool
*/
2014-02-10 22:54:49 +01:00
private function performCoreUpdate ( UpdateData $updateData , Player $player = null ) {
2014-01-28 16:23:50 +01:00
if ( ! $this -> checkPermissions ()) {
2014-03-31 21:41:05 +02:00
if ( $player ) {
$this -> maniaControl -> chat -> sendError ( 'Update failed: Incorrect file system permissions!' , $player -> login );
2014-02-09 18:22:47 +01:00
}
$this -> maniaControl -> log ( 'Update failed!' );
2014-01-28 16:23:50 +01:00
return false ;
}
2014-01-24 19:00:26 +01:00
2014-02-10 22:54:49 +01:00
if ( ! isset ( $updateData -> url ) && ! isset ( $updateData -> releaseDate )) {
2014-03-31 21:41:05 +02:00
if ( $player ) {
2014-02-10 21:32:41 +01:00
$this -> maniaControl -> chat -> sendError ( 'Update failed: No update Data available!' , $player -> login );
2013-12-27 23:26:27 +01:00
}
2014-02-10 21:32:41 +01:00
$this -> maniaControl -> log ( 'Update failed: No update Data available!' );
return false ;
2013-12-27 23:26:27 +01:00
}
2014-02-09 18:22:47 +01:00
$this -> maniaControl -> fileReader -> loadFile ( $updateData -> url , function ( $updateFileContent , $error ) use ( & $updateData , & $player ) {
$tempDir = ManiaControlDir . '/temp/' ;
if ( ! is_dir ( $tempDir )) {
mkdir ( $tempDir );
}
$updateFileName = $tempDir . basename ( $updateData -> url );
$bytes = file_put_contents ( $updateFileName , $updateFileContent );
if ( ! $bytes || $bytes <= 0 ) {
trigger_error ( " Couldn't save Update Zip. " );
2014-03-31 21:41:05 +02:00
if ( $player ) {
2014-02-09 18:22:47 +01:00
$this -> maniaControl -> chat -> sendError ( 'Update failed: Couldn\'t save Update zip!' , $player -> login );
}
return false ;
}
$zip = new \ZipArchive ();
$result = $zip -> open ( $updateFileName );
if ( $result !== true ) {
trigger_error ( " Couldn't open Update Zip. ( { $result } ) " );
2014-03-31 21:41:05 +02:00
if ( $player ) {
2014-02-09 18:22:47 +01:00
$this -> maniaControl -> chat -> sendError ( 'Update failed: Couldn\'t open Update zip!' , $player -> login );
}
return false ;
}
$zip -> extractTo ( ManiaControlDir );
$zip -> close ();
unlink ( $updateFileName );
@ rmdir ( $tempDir );
2014-02-10 21:32:41 +01:00
//Set the Nightly Build Date
2014-02-10 22:54:49 +01:00
$this -> setNightlyBuildDate ( $updateData -> releaseDate );
2014-02-10 21:32:41 +01:00
2014-03-31 21:41:05 +02:00
if ( $player ) {
2014-02-09 18:22:47 +01:00
$this -> maniaControl -> chat -> sendSuccess ( 'Update finished!' , $player -> login );
}
$this -> maniaControl -> log ( " Update finished! " );
$this -> maniaControl -> restart ();
return true ;
});
2013-12-27 23:26:27 +01:00
return true ;
}
2014-01-28 16:23:50 +01:00
/**
* Function checks if ManiaControl has sufficient access to files to update them .
*
* @ return bool
*/
private function checkPermissions () {
2014-02-10 22:54:49 +01:00
$writableDirectories = array ( '/core/' , '/plugins/' );
$path = ManiaControlDir ;
2014-01-28 16:23:50 +01:00
foreach ( $writableDirectories as $writableDirecotry ) {
2014-02-10 22:54:49 +01:00
$dir = new \RecursiveDirectoryIterator ( $path . $writableDirecotry );
foreach ( new \RecursiveIteratorIterator ( $dir ) as $filename => $file ) {
if ( substr ( $filename , - 1 ) != '.' && substr ( $filename , - 2 ) != '..' ) {
if ( ! is_writable ( $filename )) {
$this -> maniaControl -> log ( 'Cannot update: the file/directory "' . $filename . '" is not writable!' );
2014-01-28 16:23:50 +01:00
return false ;
}
}
}
}
return true ;
}
2014-01-24 19:00:26 +01:00
2013-12-27 23:26:27 +01:00
/**
* Retrieve the Update Channel Setting
*
* @ return string
*/
private function getCurrentUpdateChannelSetting () {
$updateChannel = $this -> maniaControl -> settingManager -> getSetting ( $this , self :: SETTING_UPDATECHECK_CHANNEL );
$updateChannel = strtolower ( $updateChannel );
2014-01-28 16:23:50 +01:00
if ( ! in_array ( $updateChannel , array ( self :: CHANNEL_RELEASE , self :: CHANNEL_BETA , self :: CHANNEL_NIGHTLY ))) {
2013-12-27 23:26:27 +01:00
$updateChannel = self :: CHANNEL_RELEASE ;
}
return $updateChannel ;
}
2013-12-17 17:38:44 +01:00
}