2013-12-31 12:25:03 +01:00
< ? php
namespace ManiaControl\Maps ;
2014-01-14 18:27:54 +01:00
2014-01-28 20:09:09 +01:00
use ManiaControl\Admin\AuthenticationManager ;
2013-12-31 12:25:03 +01:00
use ManiaControl\Callbacks\CallbackListener ;
2014-04-28 15:26:08 +02:00
use ManiaControl\Callbacks\CallbackManager ;
2014-04-28 20:50:38 +02:00
use ManiaControl\Callbacks\Callbacks ;
2013-12-31 12:25:03 +01:00
use ManiaControl\Commands\CommandListener ;
use ManiaControl\Formatter ;
use ManiaControl\ManiaControl ;
use ManiaControl\Players\Player ;
2014-05-09 11:58:33 +02:00
use Maniaplanet\DedicatedServer\Xmlrpc\NextMapException ;
2013-12-31 12:25:03 +01:00
/**
* MapQueue Class
*
2014-05-02 17:50:30 +02:00
* @ author ManiaControl Team < mail @ maniacontrol . com >
* @ copyright 2014 ManiaControl Team
* @ license http :// www . gnu . org / licenses / GNU General Public License , Version 3
2013-12-31 12:25:03 +01:00
*/
class MapQueue implements CallbackListener , CommandListener {
2014-04-12 12:14:37 +02:00
/*
2013-12-31 12:25:03 +01:00
* Constants
*/
2014-01-14 18:27:54 +01:00
const CB_MAPQUEUE_CHANGED = 'MapQueue.MapQueueBoxChanged' ;
2013-12-31 12:25:03 +01:00
2014-01-28 20:09:09 +01:00
const SETTING_SKIP_MAP_ON_LEAVE = 'Skip Map when the requester leaves' ;
const SETTING_SKIP_MAPQUEUE_ADMIN = 'Skip Map when admin leaves' ;
2014-04-28 13:29:19 +02:00
const SETTING_MAPLIMIT_PLAYER = 'Maximum maps per player in the Map-Queue (-1 = unlimited)' ;
const SETTING_MAPLIMIT_ADMIN = 'Maximum maps per admin (Admin+) in the Map-Queue (-1 = unlimited)' ;
2014-04-28 15:26:08 +02:00
const SETTING_BUFFERSIZE = 'Size of the Map-Queue buffer (recently played maps)' ;
2014-01-28 20:09:09 +01:00
const SETTING_PERMISSION_CLEAR_MAPQUEUE = 'Clear Mapqueue' ;
2014-04-28 15:26:08 +02:00
const SETTING_PERMISSION_QUEUE_BUFFER = 'Queue maps in buffer' ;
2013-12-31 12:25:03 +01:00
const ADMIN_COMMAND_CLEAR_MAPQUEUE = 'clearmapqueue' ;
2014-01-14 18:27:54 +01:00
const ADMIN_COMMAND_CLEAR_JUKEBOX = 'clearjukebox' ;
2014-05-02 17:50:30 +02:00
2014-04-12 12:14:37 +02:00
/*
* Private Properties
2013-12-31 12:25:03 +01:00
*/
private $maniaControl = null ;
private $queuedMaps = array ();
private $nextMap = null ;
2014-04-28 15:26:08 +02:00
private $buffer = array ();
2014-05-09 11:58:33 +02:00
private $nextNoQueue = false ;
/**
* Don ' t queue on the next MapChange
*/
public function dontQueueNextMapChange () {
$this -> nextNoQueue = true ;
}
2013-12-31 12:25:03 +01:00
/**
2013-12-31 12:36:49 +01:00
* Create a new server MapQueue
2013-12-31 12:25:03 +01:00
*
* @ param ManiaControl $maniaControl
*/
public function __construct ( ManiaControl $maniaControl ) {
$this -> maniaControl = $maniaControl ;
2014-04-28 20:50:38 +02:00
$this -> maniaControl -> callbackManager -> registerCallbackListener ( Callbacks :: ENDMAP , $this , 'endMap' );
$this -> maniaControl -> callbackManager -> registerCallbackListener ( Callbacks :: BEGINMAP , $this , 'beginMap' );
2014-04-28 15:26:08 +02:00
$this -> maniaControl -> callbackManager -> registerCallbackListener ( CallbackManager :: CB_AFTERINIT , $this , 'handleAfterInit' );
2013-12-31 12:25:03 +01:00
// Init settings
$this -> maniaControl -> settingManager -> initSetting ( $this , self :: SETTING_SKIP_MAP_ON_LEAVE , true );
$this -> maniaControl -> settingManager -> initSetting ( $this , self :: SETTING_SKIP_MAPQUEUE_ADMIN , false );
2014-04-28 13:29:19 +02:00
$this -> maniaControl -> settingManager -> initSetting ( $this , self :: SETTING_MAPLIMIT_PLAYER , 1 );
$this -> maniaControl -> settingManager -> initSetting ( $this , self :: SETTING_MAPLIMIT_ADMIN , - 1 );
2014-04-28 15:26:08 +02:00
$this -> maniaControl -> settingManager -> initSetting ( $this , self :: SETTING_BUFFERSIZE , 10 );
2013-12-31 12:25:03 +01:00
2014-01-28 20:09:09 +01:00
$this -> maniaControl -> authenticationManager -> definePermissionLevel ( self :: SETTING_PERMISSION_CLEAR_MAPQUEUE , AuthenticationManager :: AUTH_LEVEL_MODERATOR );
2014-04-28 15:26:08 +02:00
$this -> maniaControl -> authenticationManager -> definePermissionLevel ( self :: SETTING_PERMISSION_QUEUE_BUFFER , AuthenticationManager :: AUTH_LEVEL_ADMIN );
2014-01-28 20:09:09 +01:00
2013-12-31 12:25:03 +01:00
//Register Admin Commands
2014-05-01 01:41:19 +02:00
$this -> maniaControl -> commandManager -> registerCommandListener ( self :: ADMIN_COMMAND_CLEAR_JUKEBOX , $this , 'command_ClearMapQueue' , true , 'Clears the Map-Queue.' );
$this -> maniaControl -> commandManager -> registerCommandListener ( self :: ADMIN_COMMAND_CLEAR_MAPQUEUE , $this , 'command_ClearMapQueue' , true , 'Clears the Map-Queue.' );
$this -> maniaControl -> commandManager -> registerCommandListener ( array ( 'jb' , 'jukebox' , 'mapqueue' ), $this , 'command_MapQueue' , false , 'Shows current maps in Map-Queue.' );
2013-12-31 12:25:03 +01:00
}
2014-04-28 15:26:08 +02:00
/**
* Adds current map to buffer on startup
*/
public function handleAfterInit () {
2014-05-02 17:50:30 +02:00
$currentMap = $this -> maniaControl -> mapManager -> getCurrentMap ();
2014-04-28 15:26:08 +02:00
$this -> buffer [] = $currentMap -> uid ;
}
2013-12-31 12:25:03 +01:00
/**
2013-12-31 12:36:49 +01:00
* Clears the map - queue via admin command clearmap queue
2014-01-14 18:27:54 +01:00
*
2014-05-02 18:21:38 +02:00
* @ param array $chatCallback
* @ param Player $admin
2013-12-31 12:25:03 +01:00
*/
2014-05-02 18:21:38 +02:00
public function command_ClearMapQueue ( array $chatCallback , Player $admin ) {
2014-01-17 22:35:14 +01:00
$this -> clearMapQueue ( $admin );
}
2014-05-02 17:50:30 +02:00
/**
2014-05-02 18:21:38 +02:00
* Clear the Map Queue
2014-05-02 17:50:30 +02:00
*
2014-05-02 18:21:38 +02:00
* @ param Player $admin
2014-05-02 17:50:30 +02:00
*/
2014-05-02 18:21:38 +02:00
public function clearMapQueue ( Player $admin ) {
2014-05-02 17:50:30 +02:00
if ( ! $this -> maniaControl -> authenticationManager -> checkPermission ( $admin , self :: SETTING_PERMISSION_CLEAR_MAPQUEUE )) {
$this -> maniaControl -> authenticationManager -> sendNotAllowed ( $admin );
return ;
}
if ( count ( $this -> queuedMaps ) == 0 ) {
$this -> maniaControl -> chat -> sendError ( '$fa0There are no maps in the jukebox!' , $admin -> login );
return ;
}
$title = $this -> maniaControl -> authenticationManager -> getAuthLevelName ( $admin -> authLevel );
//Destroy map - queue list
$this -> queuedMaps = array ();
$this -> maniaControl -> chat -> sendInformation ( '$fa0' . $title . ' $<$fff' . $admin -> nickname . '$> cleared the Queued-Map list!' );
$this -> maniaControl -> log ( $title . ' ' . Formatter :: stripCodes ( $admin -> nickname ) . ' cleared the Queued-Map list!' );
// Trigger callback
$this -> maniaControl -> callbackManager -> triggerCallback ( self :: CB_MAPQUEUE_CHANGED , array ( 'clear' ));
}
2014-04-28 15:26:08 +02:00
/**
* Handles the mapqueue / jukebox command
*
2014-05-02 18:21:38 +02:00
* @ param array $chatCallback
2014-04-28 15:26:08 +02:00
* @ param Player $player
*/
2014-05-02 18:21:38 +02:00
public function command_MapQueue ( array $chatCallback , Player $player ) {
$chatCommands = explode ( ' ' , $chatCallback [ 1 ][ 2 ]);
2014-04-28 12:31:33 +02:00
2014-05-02 17:50:30 +02:00
if ( isset ( $chatCommands [ 1 ])) {
if ( $chatCommands [ 1 ] == ' ' || $chatCommands [ 1 ] == 'list' ) {
2014-04-28 12:31:33 +02:00
$this -> showMapQueue ( $player );
2014-05-02 17:50:30 +02:00
} elseif ( $chatCommands [ 1 ] == 'display' ) {
2014-04-28 12:31:33 +02:00
$this -> showMapQueueManialink ( $player );
2014-05-02 17:50:30 +02:00
} elseif ( $chatCommands [ 1 ] == 'clear' ) {
2014-04-28 12:31:33 +02:00
$this -> clearMapQueue ( $player );
}
} else {
$this -> showMapQueue ( $player );
}
}
2014-04-28 15:26:08 +02:00
/**
* Shows current mapqueue in the chat
*
2014-05-02 18:21:38 +02:00
* @ param Player $player
2014-04-28 15:26:08 +02:00
*/
2014-05-02 18:21:38 +02:00
public function showMapQueue ( Player $player ) {
2014-05-02 17:50:30 +02:00
if ( count ( $this -> queuedMaps ) == 0 ) {
2014-04-28 12:31:33 +02:00
$this -> maniaControl -> chat -> sendError ( '$fa0There are no maps in the jukebox!' , $player -> login );
return ;
}
$message = '$fa0Upcoming maps in the Map-Queue:' ;
2014-05-02 17:50:30 +02:00
$i = 1 ;
foreach ( $this -> queuedMaps as $queuedMap ) {
$message .= ' $<$fff' . $i . '$>. [$<$fff' . Formatter :: stripCodes ( $queuedMap [ 1 ] -> name ) . '$>]' ;
2014-04-28 12:31:33 +02:00
$i ++ ;
}
$this -> maniaControl -> chat -> sendInformation ( $message , $player -> login );
}
2014-04-28 15:26:08 +02:00
/**
* Shows current mapqueue in a manialink
*
2014-05-02 18:21:38 +02:00
* @ param Player $player
2014-04-28 15:26:08 +02:00
*/
2014-05-02 18:21:38 +02:00
public function showMapQueueManialink ( Player $player ) {
2014-05-02 17:50:30 +02:00
if ( count ( $this -> queuedMaps ) == 0 ) {
2014-04-28 12:31:33 +02:00
$this -> maniaControl -> chat -> sendError ( '$fa0There are no maps in the jukebox!' , $player -> login );
return ;
}
$maps = array ();
2014-05-02 17:50:30 +02:00
foreach ( $this -> queuedMaps as $queuedMap ) {
2014-04-28 12:31:33 +02:00
$maps [] = $queuedMap [ 1 ];
}
$this -> maniaControl -> mapManager -> mapList -> showMapList ( $player , $maps );
}
2014-04-28 15:26:08 +02:00
/**
* Returns the current queue buffer
*
* @ return array
*/
public function getQueueBuffer () {
return $this -> buffer ;
}
2014-04-28 12:31:33 +02:00
/**
* Adds map as first map in queue ( for / replay )
*
2014-05-02 18:21:38 +02:00
* @ param Player $player
* @ param Map $map
2014-04-28 12:31:33 +02:00
*/
2014-05-02 18:21:38 +02:00
public function addFirstMapToMapQueue ( Player $player , Map $map ) {
2014-04-27 00:55:39 +02:00
if ( $map ) {
if ( array_key_exists ( $map -> uid , $this -> queuedMaps )) {
unset ( $this -> queuedMaps [ $map -> uid ]);
}
2014-05-04 13:02:53 +02:00
array_unshift ( $this -> queuedMaps , array ( $player , $map , true ));
2014-04-27 00:55:39 +02:00
}
}
2014-01-28 20:14:21 +01:00
/**
2013-12-31 12:25:03 +01:00
* Adds a Map to the map - queue
2014-01-14 18:27:54 +01:00
*
2014-05-02 18:21:38 +02:00
* @ param string $login
* @ param string $uid
2013-12-31 12:25:03 +01:00
*/
2014-01-14 18:27:54 +01:00
public function addMapToMapQueue ( $login , $uid ) {
2013-12-31 12:25:03 +01:00
$player = $this -> maniaControl -> playerManager -> getPlayer ( $login );
2014-04-28 13:29:19 +02:00
//Check if player is allowed to add (another) map
$admin = false ;
2014-05-02 17:50:30 +02:00
if ( $this -> maniaControl -> authenticationManager -> checkRight ( $player , 2 ) || $this -> maniaControl -> authenticationManager -> checkRight ( $player , 3 ) || $this -> maniaControl -> authenticationManager -> checkRight ( $player , 4 )) {
2014-04-28 13:29:19 +02:00
$admin = true ;
}
$mapsForPlayer = 0 ;
2014-05-02 17:50:30 +02:00
foreach ( $this -> queuedMaps as $queuedMap ) {
if ( $queuedMap [ 0 ] -> login == $login ) {
2014-04-28 13:29:19 +02:00
$mapsForPlayer ++ ;
}
}
$maxPlayer = $this -> maniaControl -> settingManager -> getSetting ( $this , self :: SETTING_MAPLIMIT_PLAYER );
$maxAdmin = $this -> maniaControl -> settingManager -> getSetting ( $this , self :: SETTING_MAPLIMIT_ADMIN );
2014-05-02 17:50:30 +02:00
if ( $admin && $maxAdmin != - 1 ) {
if ( $mapsForPlayer == $maxAdmin ) {
$this -> maniaControl -> chat -> sendError ( 'You already have $<$fff' . $maxAdmin . '$> map(s) in the Map-Queue!' , $login );
2014-04-28 13:29:19 +02:00
return ;
}
2014-05-02 17:50:30 +02:00
} elseif ( ! $admin && $maxPlayer != - 1 ) {
if ( $mapsForPlayer == $maxPlayer ) {
$this -> maniaControl -> chat -> sendError ( 'You already have $<$fff' . $maxPlayer . '$> map(s) in the Map-Queue!' , $login );
2014-04-28 13:29:19 +02:00
return ;
}
}
2013-12-31 12:25:03 +01:00
//Check if the map is already juked
2014-01-28 20:09:09 +01:00
if ( array_key_exists ( $uid , $this -> queuedMaps )) {
2014-04-28 13:29:19 +02:00
$this -> maniaControl -> chat -> sendError ( 'That map is already in the Map-Queue!' , $login );
2013-12-31 12:25:03 +01:00
return ;
}
//TODO recently maps not able to add to queue-amps setting, and management
2014-04-28 15:26:08 +02:00
// Check if map is in the buffer
2014-05-02 17:50:30 +02:00
if ( in_array ( $uid , $this -> buffer )) {
2014-04-28 15:26:08 +02:00
$this -> maniaControl -> chat -> sendError ( 'That map has recently been played!' , $login );
if ( ! $this -> maniaControl -> authenticationManager -> checkPermission ( $player , self :: SETTING_PERMISSION_CLEAR_MAPQUEUE )) {
return ;
}
}
2013-12-31 12:25:03 +01:00
$map = $this -> maniaControl -> mapManager -> getMapByUid ( $uid );
$this -> queuedMaps [ $uid ] = array ( $player , $map );
2014-04-28 12:31:33 +02:00
$this -> maniaControl -> chat -> sendInformation ( '$fa0$<$fff' . $map -> name . '$> has been added to the Map-Queue by $<$fff' . $player -> nickname . '$>.' );
2013-12-31 12:25:03 +01:00
// Trigger callback
$this -> maniaControl -> callbackManager -> triggerCallback ( self :: CB_MAPQUEUE_CHANGED , array ( 'add' , $this -> queuedMaps [ $uid ]));
}
/**
2014-05-09 19:05:08 +02:00
* Remove a Map from the Map queue
2014-01-14 18:27:54 +01:00
*
2014-05-02 18:21:38 +02:00
* @ param Player $player
* @ param string $uid
2013-12-31 12:25:03 +01:00
*/
2014-01-28 20:09:09 +01:00
public function removeFromMapQueue ( Player $player , $uid ) {
if ( ! isset ( $this -> queuedMaps [ $uid ])) {
return ;
}
2014-05-09 19:05:08 +02:00
/** @var Map $map */
2014-01-28 20:09:09 +01:00
$map = $this -> queuedMaps [ $uid ][ 1 ];
2013-12-31 12:25:03 +01:00
unset ( $this -> queuedMaps [ $uid ]);
2014-01-28 20:09:09 +01:00
2014-04-28 12:31:33 +02:00
$this -> maniaControl -> chat -> sendInformation ( '$fa0$<$fff' . $map -> name . '$> is removed from the Map-Queue by $<$fff' . $player -> nickname . '$>.' );
2014-01-28 20:09:09 +01:00
// Trigger callback
$this -> maniaControl -> callbackManager -> triggerCallback ( self :: CB_MAPQUEUE_CHANGED , array ( 'remove' , $map ));
2013-12-31 12:25:03 +01:00
}
/**
* Called on endmap
2014-01-14 18:27:54 +01:00
*
2014-02-19 16:27:56 +01:00
* @ param Map $map
2013-12-31 12:25:03 +01:00
*/
2014-05-09 11:58:33 +02:00
public function endMap ( Map $map = null ) {
//Don't queue next map (for example on skip to map)
if ( $this -> nextNoQueue ){
$this -> nextNoQueue = false ;
return ;
}
2013-12-31 12:25:03 +01:00
$this -> nextMap = null ;
2014-05-02 17:50:30 +02:00
if ( $this -> maniaControl -> settingManager -> getSetting ( $this , self :: SETTING_SKIP_MAP_ON_LEAVE ) == true ) {
2013-12-31 12:25:03 +01:00
//Skip Map if requester has left
2014-05-02 17:50:30 +02:00
foreach ( $this -> queuedMaps as $queuedMap ) {
2013-12-31 12:25:03 +01:00
$player = $queuedMap [ 0 ];
2014-05-04 13:02:53 +02:00
// Check if map is added via replay vote/command
if ( isset ( $queuedMap [ 2 ]) && $queuedMap [ 2 ] === true ) {
break ;
}
2013-12-31 12:25:03 +01:00
//found player, so play this map
2014-03-31 21:41:05 +02:00
if ( $this -> maniaControl -> playerManager -> getPlayer ( $player -> login )) {
2013-12-31 12:25:03 +01:00
break ;
}
2014-05-02 17:50:30 +02:00
if ( $this -> maniaControl -> settingManager -> getSetting ( $this , self :: SETTING_SKIP_MAPQUEUE_ADMIN ) == false ) {
2013-12-31 12:36:49 +01:00
//Check if the queuer is a admin
2014-01-28 20:09:09 +01:00
if ( $player -> authLevel > 0 ) {
2013-12-31 12:25:03 +01:00
break ;
}
}
// Trigger callback
$this -> maniaControl -> callbackManager -> triggerCallback ( self :: CB_MAPQUEUE_CHANGED , array ( 'skip' , $queuedMap [ 0 ]));
2013-12-31 12:36:49 +01:00
//Player not found, so remove the map from the mapqueue
2013-12-31 12:25:03 +01:00
array_shift ( $this -> queuedMaps );
2014-05-02 17:50:30 +02:00
$this -> maniaControl -> chat -> sendInformation ( '$fa0$<$fff' . $queuedMap [ 0 ] -> name . '$> is skipped because $<' . $player -> nickname . '$> left the game!' );
2013-12-31 12:25:03 +01:00
}
}
$this -> nextMap = array_shift ( $this -> queuedMaps );
2013-12-31 12:36:49 +01:00
//Check if Map Queue is empty
2014-03-31 21:54:51 +02:00
if ( ! $this -> nextMap || ! isset ( $this -> nextMap [ 1 ])) {
2013-12-31 12:25:03 +01:00
return ;
2014-01-14 18:27:54 +01:00
}
2013-12-31 12:25:03 +01:00
$map = $this -> nextMap [ 1 ];
2014-05-09 11:58:33 +02:00
/** @var Map $map */
2014-05-02 17:50:30 +02:00
$this -> maniaControl -> chat -> sendInformation ( '$fa0Next map will be $<$fff' . $map -> name . '$> as requested by $<' . $this -> nextMap [ 0 ] -> nickname . '$>.' );
2013-12-31 12:25:03 +01:00
2014-05-09 11:58:33 +02:00
try {
$this -> maniaControl -> client -> setNextMapIdent ( $map -> uid );
} catch ( NextMapException $e ){
}
2013-12-31 12:25:03 +01:00
}
2014-04-28 15:26:08 +02:00
/**
* Called on begin map
*
* @ param Map $map
*/
public function beginMap ( Map $map ) {
2014-05-02 17:50:30 +02:00
if ( in_array ( $map -> uid , $this -> buffer )) {
2014-04-28 15:26:08 +02:00
return ;
}
2014-05-02 17:50:30 +02:00
if ( count ( $this -> buffer ) >= $this -> maniaControl -> settingManager -> getSetting ( $this , self :: SETTING_BUFFERSIZE )) {
2014-04-28 15:26:08 +02:00
array_shift ( $this -> buffer );
}
$this -> buffer [] = $map -> uid ;
}
2013-12-31 12:25:03 +01:00
/**
* Returns the next Map if the next map is a queuedmap or null if it ' s not
2014-01-14 18:27:54 +01:00
*
2014-05-02 18:21:38 +02:00
* @ return Map
2013-12-31 12:25:03 +01:00
*/
2014-01-14 18:27:54 +01:00
public function getNextMap () {
2013-12-31 12:25:03 +01:00
return $this -> nextMap ;
}
2014-01-14 18:27:54 +01:00
2014-01-14 20:35:31 +01:00
/**
* Returns the first Queued Map
*
* @ return array ( Player $player , Map $map )
*/
public function getNextQueuedMap () {
2014-05-02 17:50:30 +02:00
foreach ( $this -> queuedMaps as $queuedMap ) {
2014-01-14 20:35:31 +01:00
//return the first Queued Map
return $queuedMap ;
}
return null ;
}
2013-12-31 12:25:03 +01:00
/**
* Returns a list with the indexes of the queued maps
2014-01-14 18:27:54 +01:00
*
2013-12-31 12:25:03 +01:00
* @ return array
*/
2014-01-14 18:27:54 +01:00
public function getQueuedMapsRanking () {
$i = 1 ;
2013-12-31 12:25:03 +01:00
$queuedMaps = array ();
2014-05-02 17:50:30 +02:00
foreach ( $this -> queuedMaps as $queuedMap ) {
2014-03-19 14:00:24 +01:00
$map = $queuedMap [ 1 ];
2013-12-31 12:25:03 +01:00
$queuedMaps [ $map -> uid ] = $i ;
$i ++ ;
}
return $queuedMaps ;
}
2014-01-28 20:09:09 +01:00
/**
* Returns the Queuer of a Map
*
* @ param $uid
* @ return mixed
*/
public function getQueuer ( $uid ) {
return $this -> queuedMaps [ $uid ][ 0 ];
}
2013-12-31 12:25:03 +01:00
/**
* Dummy Function for testing
*/
2014-01-14 18:27:54 +01:00
public function printAllMaps () {
2014-05-02 17:50:30 +02:00
foreach ( $this -> queuedMaps as $map ) {
2013-12-31 12:25:03 +01:00
$map = $map [ 1 ];
var_dump ( $map -> name );
}
}
2014-04-12 12:14:37 +02:00
}