docker-tmserver/xaseco/plugins/plugin.rasp_jukebox.php

1903 lines
76 KiB
PHP
Raw Permalink Normal View History

2022-06-26 17:43:44 +02:00
<?php
/* vim: set noexpandtab tabstop=2 softtabstop=2 shiftwidth=2: */
/**
* Jukebox plugin.
* Allow players to add tracks to the 'jukebox' so they can play favorites
* without waiting. Each player can only have one track in jukebox at a time.
* Also allows to add a track from TMX, and provides related chat commands,
* including TMX searches.
* Finally, handles the voting and passing for chat-based votes.
* Updated by Xymph
*
* Dependencies: requires plugin.rasp_votes.php, plugin.track.php, chat.records2.php;
* used by plugin.rasp_votes.php
*/
require_once('includes/rasp.funcs.php'); // functions for the RASP plugins
require_once('includes/tmxinfosearcher.inc.php'); // provides TMX searches
// Register events and chat commands with aseco
Aseco::registerEvent('onSync', 'init_jbhistory');
Aseco::registerEvent('onEndRace', 'rasp_endrace');
Aseco::registerEvent('onNewChallenge', 'rasp_newtrack');
// handles action id's "101"-"2000" for jukeboxing max. 1900 tracks
// handles action id's "-101"-"-2000" for listing max. 1900 authors
// handles action id's "-2001"-"-2100" for dropping max. 100 jukeboxed tracks
// handles action id's "-6001"-"-7900" for invoking /karma on max. 1900 tracks
// handles action id's "5201"-"5700" for invoking /tmxinfo on max. 500 tracks
// handles action id's "5701"-"6200" for invoking /add on max. 500 tracks
// handles action id's "6201"-"6700" for invoking /admin add on max. 500 tracks
// handles action id's "6701"-"7200" for invoking /xlist auth: on max. 500 authors
Aseco::registerEvent('onPlayerManialinkPageAnswer', 'event_jukebox');
Aseco::addChatCommand('list', 'Lists tracks currently on the server (see: /list help)');
Aseco::addChatCommand('jukebox', 'Sets track to be played next (see: /jukebox help)');
if (ABBREV_COMMANDS) {
Aseco::addChatCommand('jb', 'Sets a track to be played next (see: /jb help)');
function chat_jb($aseco, $command) { chat_jukebox($aseco, $command); }
}
Aseco::addChatCommand('autojuke', 'Jukeboxes track from /list (see: /autojuke help)');
if (ABBREV_COMMANDS) {
Aseco::addChatCommand('aj', 'Jukeboxes track from /list (see: /aj help)');
function chat_aj($aseco, $command) { chat_autojuke($aseco, $command); }
}
Aseco::addChatCommand('add', 'Adds a track directly from TMX (<ID> {sec})');
Aseco::addChatCommand('y', 'Votes Yes for a TMX track or chat-based vote');
Aseco::addChatCommand('history', 'Shows the 10 most recently played tracks');
Aseco::addChatCommand('xlist', 'Lists tracks on TMX (see: /xlist help)');
// called @ onEndRace
function rasp_endrace($aseco, $data) {
global $rasp, $tmxadd, $jukebox, $jukebox_check, $jukebox_skipleft, $jukebox_adminnoskip,
$jukebox_in_window, $tmxplaying, $autosave_matchsettings, $replays_counter, $replays_total;
// check for relay server
if ($aseco->server->isrelay) return;
// check for & cancel ongoing TMX vote
if (!empty($tmxadd)) {
$aseco->console('Vote by {1} to add {2} reset!',
$tmxadd['login'], stripColors($tmxadd['name'], false));
$message = $rasp->messages['JUKEBOX_CANCEL'][0];
if ($jukebox_in_window && function_exists('send_window_message'))
send_window_message($aseco, $message, true);
else
$aseco->client->query('ChatSendServerMessage', $aseco->formatColors($message));
$tmxadd = array();
// disable all vote panels
if ($aseco->server->getGame() == 'TMF')
allvotepanels_off($aseco);
}
// reset UID check
$jukebox_check = '';
// check for jukeboxed track(s)
if (!empty($jukebox)) {
if ($aseco->debug) {
$aseco->console_text('rasp_endrace step1 - $jukebox:' . CRLF .
print_r($jukebox, true));
}
// skip jukeboxed track(s) if their requesters left
if ($jukebox_skipleft) {
// go over jukeboxed tracks
while ($next = array_shift($jukebox)) {
// check if requester is still online, or was admin
foreach ($aseco->server->players->player_list as $pl) {
if ($pl->login == $next['Login'] ||
($jukebox_adminnoskip && $aseco->isAnyAdminL($next['Login']))) {
// found player, so proceed to play this track
// put it back for rasp_newtrack to remove
$uid = $next['uid'];
$jukebox = array_merge(array($uid => $next), $jukebox);
break 2; // exit foreach & while
}
}
// player offline, so report skip
$message = '{RASP Jukebox} Skipping Next Challenge ' . stripColors($next['Name'], false) . ' because requester ' . stripColors($next['Nick'], false) . ' left';
$aseco->console_text($message);
$message = formatText($rasp->messages['JUKEBOX_SKIPLEFT'][0],
stripColors($next['Name']), stripColors($next['Nick']));
if ($jukebox_in_window && function_exists('send_window_message'))
send_window_message($aseco, $message, true);
else
$aseco->client->query('ChatSendServerMessage', $aseco->formatColors($message));
// throw 'jukebox changed' event
$aseco->releaseEvent('onJukeboxChanged', array('skip', $next));
}
// if jukebox went empty, bail out
if (!isset($next)) return;
} else {
// just play the next track
$next = array_shift($jukebox);
// put it back for rasp_newtrack to remove
$uid = $next['uid'];
$jukebox = array_merge(array($uid => $next), $jukebox);
}
// remember UID of next track to check whether it really plays
$jukebox_check = $uid;
if ($aseco->debug) {
$aseco->console_text('rasp_endrace step2 - $jukebox_check: ' . $jukebox_check);
$aseco->console_text('rasp_endrace step2 - $jukebox:' . CRLF .
print_r($jukebox, true));
}
// if a TMX track, add it to server
if ($next['tmx']) {
if ($aseco->debug) {
$aseco->console_text('{RASP Jukebox} ' . $next['source'] . ' challenge filename is ' . $next['FileName']);
}
$rtn = $aseco->client->query('AddChallenge', $next['FileName']);
if (!$rtn) {
trigger_error('[' . $aseco->client->getErrorCode() . '] AddChallenge - ' . $aseco->client->getErrorMessage(), E_USER_WARNING);
return;
} else {
// throw 'tracklist changed' event
$aseco->releaseEvent('onTracklistChanged', array('juke', $next['FileName']));
}
}
// select jukebox/TMX track as next challenge
$rtn = $aseco->client->query('ChooseNextChallenge', $next['FileName']);
if (!$rtn) {
trigger_error('[' . $aseco->client->getErrorCode() . '] ChooseNextChallenge - ' . $aseco->client->getErrorMessage(), E_USER_WARNING);
} else {
// check for TMF United
if ($aseco->server->getGame() == 'TMF' && $aseco->server->packmask != 'Stadium') {
// report track change from TMX or jukebox
if ($next['tmx']) {
$logmsg = '{RASP Jukebox} Setting Next Challenge to [' . $next['Env'] . '] ' . stripColors($next['Name'], false) . ', file downloaded from ' . $next['source'];
// remember it for later removal
$tmxplaying = $next['FileName'];
} else {
$logmsg = '{RASP Jukebox} Setting Next Challenge to [' . $next['Env'] . '] ' . stripColors($next['Name'], false) . ', requested by ' . stripColors($next['Nick'], false);
}
$message = formatText($rasp->messages['JUKEBOX_NEXTENV'][0],
$next['Env'], stripColors($next['Name']), stripColors($next['Nick']));
} else { // TMN(F)
// report track change from TMX or jukebox
if ($next['tmx']) {
$logmsg = '{RASP Jukebox} Setting Next Challenge to ' . stripColors($next['Name'], false) . ', file downloaded from ' . $next['source'];
// remember it for later removal
$tmxplaying = $next['FileName'];
} else {
$logmsg = '{RASP Jukebox} Setting Next Challenge to ' . stripColors($next['Name'], false) . ', requested by ' . stripColors($next['Nick'], false);
}
$message = formatText($rasp->messages['JUKEBOX_NEXT'][0],
stripColors($next['Name']), stripColors($next['Nick']));
}
$aseco->console_text($logmsg);
if ($jukebox_in_window && function_exists('send_window_message'))
send_window_message($aseco, $message, true);
else
$aseco->client->query('ChatSendServerMessage', $aseco->formatColors($message));
}
} else {
// reset just in case current track was replayed
$replays_counter = 0;
$replays_total = 0;
}
// check for autosaving tracklist
if ($autosave_matchsettings != '') {
$rtn = $aseco->client->query('SaveMatchSettings', 'MatchSettings/' . $autosave_matchsettings);
if (!$rtn) {
trigger_error('[' . $aseco->client->getErrorCode() . '] SaveMatchSettings - ' . $aseco->client->getErrorMessage(), E_USER_WARNING);
} else {
// should a random filter be added?
if ($aseco->settings['writetracklist_random']) {
$tracksfile = $aseco->server->trackdir . 'MatchSettings/' . $autosave_matchsettings;
// read the match settings file
if (!$list = @file_get_contents($tracksfile)) {
trigger_error('Could not read match settings file ' . $tracksfile . ' !', E_USER_WARNING);
} else {
// insert random filter after <gameinfos> section
$list = preg_replace('/<\/gameinfos>/', '$0' . CRLF . CRLF .
"\t<filter>" . CRLF .
"\t\t<random_map_order>1</random_map_order>" . CRLF .
"\t</filter>", $list);
// write out the match settings file
if (!@file_put_contents($tracksfile, $list)) {
trigger_error('Could not write match settings file ' . $tracksfile . ' !', E_USER_WARNING);
}
}
}
}
}
} // rasp_endrace
// called @ onNewChallenge
function rasp_newtrack($aseco, $data) {
global $rasp, $buffersize, $jukebox, $jb_buffer, $tmxplaying, $tmxplayed,
$jukebox_check, $jukebox_failed, $jukebox_permadd, $replays_counter, $replays_total;
// check for relay server
if ($aseco->server->isrelay) return;
// don't duplicate replayed track in history
if (!empty($jb_buffer)) {
$previous = array_pop($jb_buffer);
// put back previous track if different
if ($previous != $data->uid)
$jb_buffer[] = $previous;
}
// remember current track in history
if (count($jb_buffer) >= $buffersize) {
// drop oldest track if buffer full
array_shift($jb_buffer);
}
// append current track to history
$jb_buffer[] = $data->uid;
// write track history to file in case of XASECO restart
if ($fp = @fopen($aseco->server->trackdir . $aseco->settings['trackhist_file'], 'wb')) {
foreach ($jb_buffer as $uid)
fwrite($fp, $uid . CRLF);
fclose($fp);
} else {
trigger_error('Could not write track history file ' . $aseco->server->trackdir . $aseco->settings['trackhist_file'] . ' !', E_USER_WARNING);
}
// process jukebox
if (!empty($jukebox)) {
if ($aseco->debug) {
$aseco->console_text('rasp_newtrack step1 - $data->uid: ' . $data->uid);
$aseco->console_text('rasp_newtrack step1 - $jukebox_check: ' . $jukebox_check);
$aseco->console_text('rasp_newtrack step1 - $jukebox:' . CRLF .
print_r($jukebox, true));
}
// look for current track in jukebox
if (array_key_exists($data->uid, $jukebox)) {
if ($aseco->debug) {
$message = '{RASP Jukebox} Current Challenge ' .
stripColors($jukebox[$data->uid]['Name'], false) . ' loaded - index: ' .
array_search($data->uid, array_keys($jukebox));
$aseco->console_text($message);
}
// check for /replay-ed track
if ($jukebox[$data->uid]['source'] == 'Replay')
$replays_counter++;
else
$replays_counter = 0;
if (substr($jukebox[$data->uid]['source'], -6) == 'Replay') // AdminReplay
$replays_total++;
else
$replays_total = 0;
// remove loaded track
$play = $jukebox[$data->uid];
unset($jukebox[$data->uid]);
if ($aseco->debug) {
$aseco->console_text('rasp_newtrack step2a - $jukebox:' . CRLF .
print_r($jukebox, true));
}
// throw 'jukebox changed' event
$aseco->releaseEvent('onJukeboxChanged', array('play', $play));
} else {
// look for intended track in jukebox
if ($jukebox_check != '') {
if (array_key_exists($jukebox_check, $jukebox)) {
if ($aseco->debug) {
$message = '{RASP Jukebox} Intended Challenge ' .
stripColors($jukebox[$jukebox_check]['Name'], false) . ' dropped - index: ' .
array_search($jukebox_check, array_keys($jukebox));
$aseco->console_text($message);
}
// drop stuck track
$stuck = $jukebox[$jukebox_check];
unset($jukebox[$jukebox_check]);
if ($aseco->debug) {
$aseco->console_text('rasp_newtrack step2b - $jukebox:' . CRLF .
print_r($jukebox, true));
}
// throw 'jukebox changed' event
$aseco->releaseEvent('onJukeboxChanged', array('drop', $stuck));
} else {
if ($aseco->debug) {
$message = '{RASP Jukebox} Intended Challenge ' . $jukebox_check . ' not found!';
$aseco->console_text($message);
}
}
}
}
}
// remove previous TMX track from server
if ($tmxplayed) {
// unless it is permanent
if (!$jukebox_permadd) {
if ($aseco->debug) {
$aseco->console_text('rasp_newtrack step3 - remove: ' . $tmxplayed);
}
$rtn = $aseco->client->query('RemoveChallenge', $tmxplayed);
if (!$rtn) {
trigger_error('[' . $aseco->client->getErrorCode() . '] RemoveChallenge - ' . $aseco->client->getErrorMessage(), E_USER_WARNING);
} else {
// throw 'tracklist changed' event
$aseco->releaseEvent('onTracklistChanged', array('unjuke', $tmxplayed));
}
}
$tmxplayed = false;
}
// check whether current track was from TMX
if ($tmxplaying) {
// remember it for removal afterwards
$tmxplayed = $tmxplaying;
$tmxplaying = false;
}
} // rasp_newtrack
// calls function disp_recs() from chat.records2.php
function chat_list($aseco, $command) {
global $feature_karma; // from rasp.settings.php
$player = $command['author'];
$login = $player->login;
// check for relay server
if ($aseco->server->isrelay) {
$message = formatText($aseco->getChatMessage('NOTONRELAY'));
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
// split params into array
$arglist = preg_replace('/ +/', ' ', $command['params']);
$command['params'] = explode(' ', $arglist);
$cmdcount = count($command['params']);
if ($cmdcount == 1 && $command['params'][0] == 'help') {
if ($aseco->server->getGame() == 'TMN') {
$help = '{#black}/list$g will show tracks in rotation on the server:' . LF;
$help .= ' - {#black}help$g, displays this help information' . LF;
$help .= ' - {#black}nofinish$g, tracks you haven\'t completed' . LF;
$help .= ' - {#black}norank$g, tracks you don\'t have a rank on' . LF;
$help .= ' - {#black}nogold$g, tracks you didn\'t beat gold time on' . LF;
$help .= ' - {#black}noauthor$g, tracks you didn\'t beat author time on' . LF;
$help .= ' - {#black}norecent$g, tracks you didn\'t play recently' . LF;
$help .= ' - {#black}best$g/{#black}worst$g, tracks with your best/worst records' . LF;
$help .= ' - {#black}longest$g/{#black}shortest$g, the longest/shortest tracks' . LF;
$help .= ' - {#black}newest$g/{#black}oldest #$g, newest/oldest # tracks (def: 50)' . LF;
$help .= ' - {#black}xxx$g, where xxx is part of a track or author name' . LF;
if ($feature_karma) {
$help .= ' - {#black}novote$g, tracks you didn\'t karma vote for' . LF;
$help .= ' - {#black}karma +/-#$g, display all tracks with karma >= or <=' . LF
. ' given value (example: {#black}/list karma -3$g shows all' . LF
. ' tracks with karma equal or worse than -3)' . LF;
}
$help .= LF . 'Pick an Id number from the list, and use {#black}/jukebox #';
// display popup message
$aseco->client->query('SendDisplayServerMessageToLogin', $login, $aseco->formatColors($help), 'OK', '', 0);
} elseif ($aseco->server->getGame() == 'TMF') {
$header = '{#black}/list$g will show tracks in rotation on the server:';
$help = array();
$help[] = array('...', '{#black}help',
'Displays this help information');
$help[] = array('...', '{#black}nofinish',
'Shows tracks you haven\'t completed');
$help[] = array('...', '{#black}norank',
'Shows tracks you don\'t have a rank on');
$help[] = array('...', '{#black}nogold',
'Shows tracks you didn\'t beat gold ' .
($aseco->server->gameinfo->mode == Gameinfo::STNT ? 'score on' : 'time on'));
$help[] = array('...', '{#black}noauthor',
'Shows tracks you didn\'t beat author '.
($aseco->server->gameinfo->mode == Gameinfo::STNT ? 'score on' : 'time on'));
$help[] = array('...', '{#black}norecent',
'Shows tracks you didn\'t play recently');
$help[] = array('...', '{#black}best$g/{#black}worst',
'Shows tracks with your best/worst records');
if ($aseco->server->gameinfo->mode != Gameinfo::STNT) {
$help[] = array('...', '{#black}longest$g/{#black}shortest',
'Shows the longest/shortest tracks');
}
$help[] = array('...', '{#black}newest$g/{#black}oldest #',
'Shows newest/oldest # tracks (def: 50)');
$help[] = array('...', '{#black}xxx',
'Where xxx is part of a track or author name');
if ($aseco->server->packmask != 'Stadium') {
$help[] = array('...', '{#black}env:zzz',
'Where zzz is an environment from: stadium,');
$help[] = array('', '',
'bay,coast,island,alpine/snow,desert/speed,rally');
$help[] = array('...', '{#black}xxx env:zzz',
'Combines the name and environment searches');
}
if ($feature_karma) {
$help[] = array('...', '{#black}novote',
'Shows tracks you didn\'t karma vote for');
$help[] = array('...', '{#black}karma +/-#',
'Shows all tracks with karma >= or <=');
$help[] = array('', '',
'given value (example: {#black}/list karma -3$g shows all');
$help[] = array('', '',
'tracks with karma equal or worse than -3)');
}
$help[] = array();
$help[] = array('Pick an Id number from the list, and use {#black}/jukebox #');
// display ManiaLink message
display_manialink($login, $header, array('Icons64x64_1', 'TrackInfo', -0.01), $help, array(1.1, 0.05, 0.3, 0.75), 'OK');
}
return;
}
elseif ($cmdcount == 1 && $command['params'][0] == 'nofinish') {
getChallengesNoFinish($player);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'norank') {
getChallengesNoRank($player);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'nogold') {
getChallengesNoGold($player);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'noauthor') {
getChallengesNoAuthor($player);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'norecent') {
getChallengesNoRecent($player);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'best') {
// avoid interference from possible parameters
$command['params'] = '';
// display player records, best first
disp_recs($aseco, $command, true); // from chat.records2.php
return;
}
elseif ($cmdcount == 1 && $command['params'][0] == 'worst') {
// avoid interference from possible parameters
$command['params'] = '';
// display player records, worst first
disp_recs($aseco, $command, false); // from chat.records2.php
return;
}
elseif ($cmdcount == 1 && $command['params'][0] == 'longest') {
getChallengesByLength($player, false);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'shortest') {
getChallengesByLength($player, true);
}
elseif ($cmdcount >= 1 && $command['params'][0] == 'newest') {
$count = 50; // default
if ($cmdcount == 2 && is_numeric($command['params'][1]) && $command['params'][1] > 0)
$count = intval($command['params'][1]);
getChallengesByAdd($player, true, $count);
}
elseif ($cmdcount >= 1 && $command['params'][0] == 'oldest') {
$count = 50; // default
if ($cmdcount == 2 && is_numeric($command['params'][1]) && $command['params'][1] > 0)
$count = intval($command['params'][1]);
getChallengesByAdd($player, false, $count);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'novote' && $feature_karma) {
getChallengesNoVote($player);
}
elseif ($cmdcount == 2 && $command['params'][0] == 'karma' && $feature_karma) {
$karmaval = intval($command['params'][1]);
getChallengesByKarma($player, $karmaval);
}
elseif ($cmdcount >= 1 && strlen($command['params'][0]) > 0) {
// check for TMUF
if ($aseco->server->getGame() == 'TMF' && $aseco->server->packmask != 'Stadium') {
$env = '*'; // wildcard
// find and delete optional env: parameter
foreach ($command['params'] as &$param) {
if (strtolower(substr($param, 0, 4)) == 'env:') {
$env = substr($param, 4);
// map external to internal envs, allowing abbreviations
if (stripos('desert', $env) === 0)
$env = 'speed';
elseif (stripos('snow', $env) === 0)
$env = 'alpine';
$param = ''; // drop env:zzz from arglist
}
}
// rebuild parameter list
$arglist = trim(implode(' ', $command['params']));
// set wildcard name if searching for env
if ($arglist == '') $arglist = '*';
getAllChallenges($player, $arglist, $env);
} else { // TMN(F)/TMS/TMO
getAllChallenges($player, $arglist, '*'); // wildcard
}
}
else {
getAllChallenges($player, '*', '*'); // wildcards
}
if (empty($player->tracklist)) {
$message = '{#server}> {#error}No tracks found, try again!';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
if ($aseco->server->getGame() == 'TMN') {
// display popup message
if (count($player->msgs) == 2) {
$aseco->client->query('SendDisplayServerMessageToLogin', $login, $player->msgs[1], 'OK', '', 0);
} else { // > 2
$aseco->client->query('SendDisplayServerMessageToLogin', $login, $player->msgs[1], 'Close', 'Next', 0);
}
} elseif ($aseco->server->getGame() == 'TMF') {
// display ManiaLink message
display_manialink_multi($player);
}
} // chat_list
function chat_jukebox($aseco, $command) {
global $rasp, $feature_jukebox, $jukebox_in_window, $jukebox, $jb_buffer;
$player = $command['author'];
$login = $player->login;
// check for relay server
if ($aseco->server->isrelay) {
$message = formatText($aseco->getChatMessage('NOTONRELAY'));
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
if ($feature_jukebox || $aseco->allowAbility($player, 'chat_jukebox')) {
// check parameter
$param = $command['params'];
if (is_numeric($param) && $param >= 0) {
if (empty($player->tracklist)) {
$message = $rasp->messages['LIST_HELP'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
// check for track by this player in jukebox
if (!$aseco->allowAbility($player, 'chat_jb_multi')) {
foreach ($jukebox as $key) {
if ($login == $key['Login']) {
$message = $rasp->messages['JUKEBOX_ALREADY'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
}
}
// find track by given #
$jid = ltrim($param, '0');
$jid--;
if (array_key_exists($jid, $player->tracklist)) {
$uid = $player->tracklist[$jid]['uid'];
// check if track is already queued in jukebox
if (array_key_exists($uid, $jukebox)) { // find by uid in jukebox
$message = $rasp->messages['JUKEBOX_DUPL'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
// check if track was recently played
elseif (in_array($uid, $jb_buffer)) {
$message = $rasp->messages['JUKEBOX_REPEAT'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
// if not an admin with this ability, bail out
if (!$aseco->allowAbility($player, 'chat_jb_recent'))
return;
}
// check track vs. server settings
if ($aseco->server->getGame() == 'TMF')
$rtn = $aseco->client->query('CheckChallengeForCurrentServerParams', $player->tracklist[$jid]['filename']);
else
$rtn = true;
if (!$rtn) {
trigger_error('[' . $aseco->client->getErrorCode() . '] CheckChallengeForCurrentServerParams - ' . $aseco->client->getErrorMessage(), E_USER_WARNING);
$message = formatText($rasp->messages['JUKEBOX_IGNORED'][0],
stripColors($player->tracklist[$jid]['name']), $aseco->client->getErrorMessage());
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
} else {
// add track to jukebox
$jukebox[$uid]['FileName'] = $player->tracklist[$jid]['filename'];
$jukebox[$uid]['Name'] = $player->tracklist[$jid]['name'];
$jukebox[$uid]['Env'] = $player->tracklist[$jid]['environment'];
$jukebox[$uid]['Login'] = $player->login;
$jukebox[$uid]['Nick'] = $player->nickname;
$jukebox[$uid]['source'] = 'Jukebox';
$jukebox[$uid]['tmx'] = false;
$jukebox[$uid]['uid'] = $uid;
$message = formatText($rasp->messages['JUKEBOX'][0],
stripColors($player->tracklist[$jid]['name']),
stripColors($player->nickname));
if ($jukebox_in_window && function_exists('send_window_message'))
send_window_message($aseco, $message, false);
else
$aseco->client->query('ChatSendServerMessage', $aseco->formatColors($message));
// throw 'jukebox changed' event
$aseco->releaseEvent('onJukeboxChanged', array('add', $jukebox[$uid]));
}
} else {
$message = $rasp->messages['JUKEBOX_NOTFOUND'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
}
}
elseif ($param == 'list') {
if (!empty($jukebox)) {
$message = $rasp->messages['JUKEBOX_LIST'][0];
$i = 1;
foreach ($jukebox as $item) {
$message .= '{#highlite}' . $i . '{#emotic}.[{#highlite}' . stripColors($item['Name']) . '{#emotic}], ';
$i++;
}
$message = substr($message, 0, strlen($message)-2); // strip trailing ", "
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
} else {
$message = $rasp->messages['JUKEBOX_EMPTY'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
}
}
elseif ($param == 'display') {
if (!empty($jukebox)) {
if ($aseco->server->getGame() == 'TMN') {
$head = 'Upcoming tracks in the jukebox:' . LF . 'Id Name / Requester' . LF;
$msg = '';
$tid = 1;
$lines = 0;
$player->msgs = array();
$player->msgs[0] = 1;
foreach ($jukebox as $item) {
$trackname = $item['Name'];
if (!$aseco->settings['lists_colortracks'])
$trackname = stripColors($trackname);
$msg .= '$g' . str_pad($tid, 2, '0', STR_PAD_LEFT) . '. {#black}'
. $trackname . '$z / {#black}' . stripColors($item['Nick']) . LF;
$tid++;
if (++$lines > 9) {
$player->msgs[] = $aseco->formatColors($head . $msg);
$lines = 0;
$msg = '';
}
}
// add if last batch exists
if ($msg != '')
$player->msgs[] = $aseco->formatColors($head . $msg);
// display popup message
if (count($player->msgs) == 2) {
$aseco->client->query('SendDisplayServerMessageToLogin', $login, $player->msgs[1], 'OK', '', 0);
} else { // > 2
$aseco->client->query('SendDisplayServerMessageToLogin', $login, $player->msgs[1], 'Close', 'Next', 0);
}
} elseif ($aseco->server->getGame() == 'TMF') {
// determine admin ability to drop all jukeboxed tracks
$dropall = $aseco->allowAbility($player, 'dropjukebox');
$head = 'Upcoming tracks in the jukebox:';
$page = array();
if ($aseco->server->packmask != 'Stadium')
if ($aseco->settings['clickable_lists'])
$page[] = array('Id', 'Name (click to drop)', 'Env', 'Requester');
else
$page[] = array('Id', 'Name', 'Env', 'Requester');
else
if ($aseco->settings['clickable_lists'])
$page[] = array('Id', 'Name (click to drop)', 'Requester');
else
$page[] = array('Id', 'Name', 'Requester');
$tid = 1;
$lines = 0;
$player->msgs = array();
// reserve extra width for $w tags
$extra = ($aseco->settings['lists_colortracks'] ? 0.2 : 0);
if ($aseco->server->packmask != 'Stadium')
$player->msgs[0] = array(1, $head, array(1.25+$extra, 0.1, 0.6+$extra, 0.15, 0.4), array('Icons128x128_1', 'LoadTrack', 0.02));
else
$player->msgs[0] = array(1, $head, array(1.10+$extra, 0.1, 0.6+$extra, 0.4), array('Icons128x128_1', 'LoadTrack', 0.02));
foreach ($jukebox as $item) {
$trackname = $item['Name'];
if (!$aseco->settings['lists_colortracks'])
$trackname = stripColors($trackname);
// add clickable button if admin with 'dropjukebox' ability or track by this player
if ($aseco->settings['clickable_lists'] && $tid <= 100 &&
($dropall || $item['Login'] == $login))
$trackname = array('{#black}' . $trackname, -2000-$tid); // action id
else
$trackname = '{#black}' . $trackname;
if ($aseco->server->packmask != 'Stadium')
$page[] = array(str_pad($tid, 2, '0', STR_PAD_LEFT) . '.',
$trackname, $item['Env'],
'{#black}' . stripColors($item['Nick']));
else
$page[] = array(str_pad($tid, 2, '0', STR_PAD_LEFT) . '.',
$trackname,
'{#black}' . stripColors($item['Nick']));
$tid++;
if (++$lines > 14) {
if ($aseco->allowAbility($player, 'clearjukebox')) {
$page[] = array();
if ($aseco->server->packmask != 'Stadium')
$page[] = array('', array('{#emotic} Clear Entire Jukebox', 20), '', ''); // action id
else
$page[] = array('', array('{#emotic} Clear Entire Jukebox', 20), ''); // action id
}
$player->msgs[] = $page;
$lines = 0;
$page = array();
if ($aseco->server->packmask != 'Stadium')
if ($aseco->settings['clickable_lists'])
$page[] = array('Id', 'Name (click to drop)', 'Env', 'Requester');
else
$page[] = array('Id', 'Name', 'Env', 'Requester');
else
if ($aseco->settings['clickable_lists'])
$page[] = array('Id', 'Name (click to drop)', 'Requester');
else
$page[] = array('Id', 'Name', 'Requester');
}
}
// add if last batch exists
if (count($page) > 1) {
if ($aseco->allowAbility($player, 'clearjukebox')) {
$page[] = array();
if ($aseco->server->packmask != 'Stadium')
$page[] = array('', array('{#emotic} Clear Entire Jukebox', 20), '', ''); // action id
else
$page[] = array('', array('{#emotic} Clear Entire Jukebox', 20), ''); // action id
}
$player->msgs[] = $page;
}
// display ManiaLink message
display_manialink_multi($player);
}
} else {
$message = $rasp->messages['JUKEBOX_EMPTY'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
}
}
elseif ($param == 'drop') {
// find track by current player
$uid = '';
foreach ($jukebox as $item) {
if ($item['Login'] == $login) {
$name = $item['Name'];
$uid = $item['uid'];
break;
}
}
if ($uid) {
// drop it from the jukebox
$drop = $jukebox[$uid];
unset($jukebox[$uid]);
$message = formatText($rasp->messages['JUKEBOX_DROP'][0],
stripColors($player->nickname), stripColors($name));
if ($jukebox_in_window && function_exists('send_window_message'))
send_window_message($aseco, $message, false);
else
$aseco->client->query('ChatSendServerMessage', $aseco->formatColors($message));
// throw 'jukebox changed' event
$aseco->releaseEvent('onJukeboxChanged', array('drop', $drop));
} else {
$message = $rasp->messages['JUKEBOX_NODROP'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
}
}
elseif ($param == 'help') {
if ($aseco->server->getGame() == 'TMN') {
$help = '{#black}/jukebox$g will add a track to the jukebox' . LF;
$help .= ' - {#black}help$g, displays this help information' . LF;
$help .= ' - {#black}list$g, shows upcoming tracks' . LF;
$help .= ' - {#black}display$g, displays upcoming tracks' . LF . ' and requesters' . LF;
$help .= ' - {#black}drop$g, drops your currently added track' . LF . ' so you can jukebox another' . LF;
$help .= ' - {#black}##$g, adds a track where ## is the track Id' . LF . ' from your most recent {#black}/list$g command';
// display popup message
$aseco->client->query('SendDisplayServerMessageToLogin', $login, $aseco->formatColors($help), 'OK', '', 0);
} elseif ($aseco->server->getGame() == 'TMF') {
$header = '{#black}/jukebox$g will add a track to the jukebox:';
$help = array();
$help[] = array('...', '{#black}help',
'Displays this help information');
$help[] = array('...', '{#black}list',
'Shows upcoming tracks');
$help[] = array('...', '{#black}display',
'Displays upcoming tracks and requesters');
$help[] = array('...', '{#black}drop',
'Drops your currently added track');
$help[] = array('...', '{#black}##',
'Adds a track where ## is the track Id');
$help[] = array('', '',
'from your most recent {#black}/list$g command');
// display ManiaLink message
display_manialink($login, $header, array('Icons64x64_1', 'TrackInfo', -0.01), $help, array(0.9, 0.05, 0.15, 0.7), 'OK');
}
} else {
$message = $rasp->messages['JUKEBOX_HELP'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
}
} else {
$message = $rasp->messages['NO_JUKEBOX'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
}
} // chat_jukebox
function chat_autojuke($aseco, $command) {
global $feature_karma, $buffersize, $jukebox, $jb_buffer; // from rasp.settings.php
$player = $command['author'];
$login = $player->login;
// check for relay server
if ($aseco->server->isrelay) {
$message = formatText($aseco->getChatMessage('NOTONRELAY'));
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
// split params into array
$command['params'] = explode(' ', preg_replace('/ +/', ' ', $command['params']));
$cmdcount = count($command['params']);
if ($cmdcount == 1 && $command['params'][0] == 'help') {
if ($aseco->server->getGame() == 'TMN') {
$help = '{#black}/autojuke$g will jukebox a track from /list selection:' . LF;
$help .= ' - {#black}help$g, displays this help information' . LF;
$help .= ' - {#black}nofinish$g, tracks you haven\'t completed' . LF;
$help .= ' - {#black}norank$g, tracks you don\'t have a rank on' . LF;
$help .= ' - {#black}nogold$g, tracks you didn\'t beat gold time on' . LF;
$help .= ' - {#black}noauthor$g, tracks you didn\'t beat author time on' . LF;
$help .= ' - {#black}norecent$g, tracks you didn\'t play recently' . LF;
$help .= ' - {#black}longest$g/{#black}shortest$g, the longest/shortest tracks' . LF;
$help .= ' - {#black}newest$g/{#black}oldest$g, the newest/oldest tracks' . LF;
if ($feature_karma) {
$help .= ' - {#black}novote$g, tracks you didn\'t karma vote for' . LF;
}
$help .= LF . 'The jukeboxed track is the first one from the' . LF
. 'chosen selection that is not in the track history.';
// display popup message
$aseco->client->query('SendDisplayServerMessageToLogin', $login, $aseco->formatColors($help), 'OK', '', 0);
} elseif ($aseco->server->getGame() == 'TMF') {
$header = '{#black}/autojuke$g will jukebox a track from /list selection:';
$help = array();
$help[] = array('...', '{#black}help',
'Displays this help information');
$help[] = array('...', '{#black}nofinish',
'Selects tracks you haven\'t completed');
$help[] = array('...', '{#black}norank',
'Selects tracks you don\'t have a rank on');
$help[] = array('...', '{#black}nogold',
'Selects tracks you didn\'t beat gold ' .
($aseco->server->gameinfo->mode == Gameinfo::STNT ? 'score on' : 'time on'));
$help[] = array('...', '{#black}noauthor',
'Selects tracks you didn\'t beat author '.
($aseco->server->gameinfo->mode == Gameinfo::STNT ? 'score on' : 'time on'));
$help[] = array('...', '{#black}norecent',
'Selects tracks you didn\'t play recently');
if ($aseco->server->gameinfo->mode != Gameinfo::STNT) {
$help[] = array('...', '{#black}longest$g/{#black}shortest',
'Selects the longest/shortest tracks');
}
$help[] = array('...', '{#black}newest$g/{#black}oldest',
'Selects the newest/oldest tracks');
if ($feature_karma) {
$help[] = array('...', '{#black}novote',
'Selects tracks you didn\'t karma vote for');
}
$help[] = array();
$help[] = array('The jukeboxed track is the first one from the chosen selection');
$help[] = array('that is not in the track history.');
// display ManiaLink message
display_manialink($login, $header, array('Icons64x64_1', 'TrackInfo', -0.01), $help, array(1.1, 0.05, 0.3, 0.75), 'OK');
}
return;
}
elseif ($cmdcount == 1 && $command['params'][0] == 'nofinish') {
getChallengesNoFinish($player);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'norank') {
getChallengesNoRank($player);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'nogold') {
getChallengesNoGold($player);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'noauthor') {
getChallengesNoAuthor($player);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'norecent') {
getChallengesNoRecent($player);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'longest') {
getChallengesByLength($player, false);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'shortest') {
getChallengesByLength($player, true);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'newest') {
getChallengesByAdd($player, true, $buffersize+1);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'oldest') {
getChallengesByAdd($player, false, $buffersize+1);
}
elseif ($cmdcount == 1 && $command['params'][0] == 'novote' && $feature_karma) {
getChallengesNoVote($player);
}
else {
$message = '{#server}> {#error}Invalid selection, try again!';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
if (empty($player->tracklist)) {
$message = '{#server}> {#error}No tracks found, try again!';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
// find first available track
$ctr = 1;
$found = false;
foreach ($player->tracklist as $key) {
if (!array_key_exists($key['uid'], $jukebox) && !in_array($key['uid'], $jb_buffer)) {
$found = true;
break;
}
$ctr++;
}
if ($found) {
// jukebox it
$command['params'] = $ctr;
chat_jukebox($aseco, $command);
} else {
$message = '{#server}> {#highlite}' . $command['params'][0] . '{#error} tracks currently unavailable, try again later!';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
}
} // chat_autojuke
function chat_add($aseco, $command) {
global $rasp, $feature_jukebox, $feature_tmxadd, $jukebox_in_window, $jukebox,
$tmxadd, $tmxtmpdir, $chatvote, $plrvotes, $allow_spec_startvote,
$r_expire_num, $ta_show_num, $ta_expire_start, $auto_vote_starter;
$player = $command['author'];
$login = $player->login;
// check for relay server
if ($aseco->server->isrelay) {
$message = formatText($aseco->getChatMessage('NOTONRELAY'));
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $player->login);
return;
}
$sections = array('TMO' => 'original',
'TMS' => 'sunrise',
'TMN' => 'nations',
'TMU' => 'united',
'TMNF' => 'tmnforever');
// check whether jukebox & /add are enabled
if ($feature_jukebox && $feature_tmxadd) {
// check whether this player is spectator
if (!$allow_spec_startvote && $aseco->isSpectator($player)) {
$message = $rasp->messages['NO_SPECTATORS'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
// check for ongoing TMX or chat vote
if (!empty($tmxadd) || !empty($chatvote)) {
$message = $rasp->messages['VOTE_ALREADY'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
// check for special 'trackref' parameter & write file
if ($command['params'] == 'trackref' && $aseco->allowAbility($player, 'chat_add_tref')) {
build_tmx_trackref($aseco);
$message = '{#server}> {#emotic}Wrote trackref.txt files';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
// split params into array
$command['params'] = explode(' ', preg_replace('/ +/', ' ', $command['params']));
// check for valid TMX ID
if (is_numeric($command['params'][0]) && $command['params'][0] >= 0) {
$trkid = ltrim($command['params'][0], '0');
$source = 'TMX';
$section = $aseco->server->getGame();
if ($section == 'TMF' && isset($command['params'][1])) {
$section = strtoupper($command['params'][1]);
if (!array_key_exists($section, $sections)) {
$message = '{#server}> {#error}No such section on TMX!';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
} else { // TMN/TMS/TMO or no section
if ($section == 'TMF') {
if ($aseco->server->packmask == 'Stadium')
$section = 'TMNF';
else
$section = 'TMU';
}
}
// try to load the track from TMX
$remotefile = 'http://' . $sections[$section] . '.tm-exchange.com/get.aspx?action=trackgbx&id=' . $trkid;
$file = http_get_file($remotefile);
if ($file === false || $file == -1) {
$message = '{#server}> {#error}Error downloading, or wrong TMX section, or TMX is down!';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
} else {
// check for maximum online track size (256 KB)
if (strlen($file) >= 256 * 1024) {
$message = formatText($rasp->messages['TRACK_TOO_LARGE'][0],
round(strlen($file) / 1024));
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
$sepchar = substr($aseco->server->trackdir, -1, 1);
$partialdir = $tmxtmpdir . $sepchar . $trkid . '.Challenge.gbx';
$localfile = $aseco->server->trackdir . $partialdir;
if ($aseco->debug) {
$aseco->console_text('/add - tmxtmpdir=' . $tmxtmpdir);
$aseco->console_text('/add - path + filename=' . $partialdir);
$aseco->console_text('/add - aseco->server->trackdir = ' . $aseco->server->trackdir);
}
if ($nocasepath = file_exists_nocase($localfile)) {
if (!unlink($nocasepath)) {
$message = '{#server}> {#error}Error erasing old file. Please contact admin.';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
}
if (!$lfile = @fopen($localfile, 'wb')) {
$message = '{#server}> {#error}Error creating file. Please contact admin.';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
if (!fwrite($lfile, $file)) {
$message = '{#server}> {#error}Error saving file - unable to write data. Please contact admin.';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
fclose($lfile);
return;
}
fclose($lfile);
$newtrk = getChallengeData($localfile, true); // 2nd parm is whether or not to get players & votes required
if ($newtrk['votes'] == 500 && $newtrk['name'] == 'Not a GBX file') {
$message = '{#server}> {#error}No such track on ' . $source;
if ($source == 'TMX' && $aseco->server->getGame() == 'TMF')
$message .= ' section ' . $section;
$message .= '!';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
unlink($localfile);
return;
}
// dummy player to easily obtain entire track list
$list = new Player();
getAllChallenges($list, '*', '*');
// check for track presence on server
$ctr = 1;
foreach ($list->tracklist as $key) {
if ($key['uid'] == $newtrk['uid']) {
$message = $rasp->messages['ADD_PRESENTJB'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
unlink($localfile);
// jukebox already available track
$player->tracklist = $list->tracklist;
$command['params'] = $ctr;
chat_jukebox($aseco, $command);
unset($list);
return;
}
$ctr++;
}
unset($list);
// check for track presence in jukebox via previous /add
if (isset($jukebox[$newtrk['uid']])) {
$message = $rasp->messages['ADD_DUPL'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
unlink($localfile);
return;
}
// rename ID filename to track's name
$md5new = md5_file($localfile);
$filename = trim(utf8_decode(stripColors($newtrk['name'])));
$filename = preg_replace('/[^A-Za-z0-9 \'#=+~_,.-]/', '_', $filename);
$filename = preg_replace('/ +/', ' ', preg_replace('/_+/', '_', $filename));
$partialdir = $tmxtmpdir . $sepchar . $filename . '_' . $trkid . '.Challenge.gbx';
// insure unique filename by incrementing sequence number,
// if not a duplicate track
$i = 1;
$dupl = false;
while ($nocasepath = file_exists_nocase($aseco->server->trackdir . $partialdir)) {
$md5old = md5_file($nocasepath);
if ($md5old == $md5new) {
$dupl = true;
$partialdir = str_replace($aseco->server->trackdir, '', $nocasepath);
break;
} else {
$partialdir = $tmxtmpdir . $sepchar . $filename . '_' . $trkid . '-' . $i++ . '.Challenge.gbx';
}
}
if ($dupl) {
unlink($localfile);
} else {
rename($localfile, $aseco->server->trackdir . $partialdir);
}
// check track vs. server settings
if ($aseco->server->getGame() == 'TMF')
$rtn = $aseco->client->query('CheckChallengeForCurrentServerParams', $partialdir);
else
$rtn = true;
if (!$rtn) {
trigger_error('[' . $aseco->client->getErrorCode() . '] CheckChallengeForCurrentServerParams - ' . $aseco->client->getErrorMessage(), E_USER_WARNING);
$message = formatText($rasp->messages['JUKEBOX_IGNORED'][0],
stripColors($newtrk['name']), $aseco->client->getErrorMessage());
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
} else {
// start /add vote
$tmxadd['filename'] = $partialdir;
$tmxadd['votes'] = $newtrk['votes'];
$tmxadd['name'] = $newtrk['name'];
$tmxadd['environment'] = $newtrk['environment'];
$tmxadd['login'] = $player->login;
$tmxadd['nick'] = $player->nickname;
$tmxadd['source'] = $source;
$tmxadd['uid'] = $newtrk['uid'];
// reset votes, rounds counter, TA interval counter & start time
$plrvotes = array();
$r_expire_num = 0;
$ta_show_num = 0;
$ta_expire_start = time_playing($aseco); // from plugin.track.php
// compile & show chat message
$message = formatText($rasp->messages['JUKEBOX_ADD'][0],
stripColors($tmxadd['nick']),
stripColors($tmxadd['name']),
$tmxadd['source'], $tmxadd['votes']);
$message = str_replace('{br}', LF, $message); // split long message
if ($jukebox_in_window && function_exists('send_window_message'))
send_window_message($aseco, $message, true);
else
$aseco->client->query('ChatSendServerMessage', $aseco->formatColors($message));
// enable all vote panels
if ($aseco->server->getGame() == 'TMF' && function_exists('allvotepanels_on'))
allvotepanels_on($aseco, $login, $aseco->formatColors('{#emotic}'));
// vote automatically by vote starter?
if ($auto_vote_starter) chat_y($aseco, $command);
}
}
} else {
$message = '{#server}> {#error}You must include a TMX Track_ID!';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
}
} else {
$message = $rasp->messages['NO_ADD'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
}
} // chat_add
function build_tmx_trackref($aseco) {
global $tmxdir, $tmxtmpdir;
$td = $aseco->server->trackdir . $tmxdir;
if (is_dir($td)) {
$dir = opendir($td);
$fp = fopen($td . '/trackref.txt', 'w');
while (($file = readdir($dir)) !== false) {
if (strtolower(substr($file, -4)) == '.gbx') {
$ci = getChallengeData($td . '/' . $file, false);
$file = str_ireplace('.challenge.gbx', '', $file);
fwrite($fp, $file . "\t" . $ci['environment'] . "\t" . $ci['author'] . "\t" . stripColors($ci['name']) . "\t" . $ci['coppers'] . CRLF);
}
}
fclose($fp);
closedir($dir);
}
$td = $aseco->server->trackdir . $tmxtmpdir;
if (is_dir($td)) {
$dir = opendir($td);
$fp = fopen($td . '/trackref.txt', 'w');
while (($file = readdir($dir)) !== false) {
if (strtolower(substr($file, -4)) == '.gbx') {
$ci = getChallengeData($td . '/' . $file, false);
$file = str_ireplace('.challenge.gbx', '', $file);
fwrite($fp, $file . "\t" . $ci['environment'] . "\t" . $ci['author'] . "\t" . stripColors($ci['name']) . "\t" . $ci['coppers'] . CRLF);
}
}
fclose($fp);
closedir($dir);
}
} // build_tmx_trackref
function chat_y($aseco, $command) {
global $rasp, $tmxadd, $plrvotes, $chatvote, $jukebox, $allow_spec_voting,
$jukebox_in_window, $vote_in_window, $feature_tmxadd, $feature_votes,
$ladder_fast_restart;
$player = $command['author'];
$login = $player->login;
// check for relay server
if ($aseco->server->isrelay) {
$message = formatText($aseco->getChatMessage('NOTONRELAY'));
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $player->login);
return;
}
// check whether this player is spectator but not any admin
if (!$allow_spec_voting && $aseco->isSpectator($player) && !$aseco->isAnyAdmin($player)) {
$message = $rasp->messages['NO_SPECTATORS'][0];
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
// check whether this player already voted
if (in_array($login, $plrvotes)) {
$message = '{#server}> {#error}You have already voted!';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
// check for ongoing TMX vote
if (!empty($tmxadd) && $tmxadd['votes'] >= 0) {
$votereq = $tmxadd['votes'];
$votereq--;
// check for sufficient votes
if ($votereq > 0) {
// remind all players to vote
$tmxadd['votes'] = $votereq;
$message = formatText($rasp->messages['JUKEBOX_Y'][0],
$votereq, ($votereq == 1 ? '' : 's'),
stripColors($tmxadd['name']));
if ($jukebox_in_window && function_exists('send_window_message'))
send_window_message($aseco, $message, false);
else
$aseco->client->query('ChatSendServerMessage', $aseco->formatColors($message));
// register this player's vote
$plrvotes[] = $login;
// disable panel in case /y was used to vote
if ($aseco->server->getGame() == 'TMF')
votepanel_off($aseco, $login);
} else {
// pass, so add it to jukebox
$uid = $tmxadd['uid'];
$jukebox[$uid]['FileName'] = $tmxadd['filename'];
$jukebox[$uid]['Name'] = $tmxadd['name'];
$jukebox[$uid]['Env'] = $tmxadd['environment'];
$jukebox[$uid]['Login'] = $tmxadd['login'];
$jukebox[$uid]['Nick'] = $tmxadd['nick'];
$jukebox[$uid]['source'] = $tmxadd['source'];
$jukebox[$uid]['tmx'] = true;
$jukebox[$uid]['uid'] = $uid;
// show chat message
$message = formatText($rasp->messages['JUKEBOX_PASS'][0],
stripColors($tmxadd['name']));
if ($jukebox_in_window && function_exists('send_window_message'))
send_window_message($aseco, $message, false);
else
$aseco->client->query('ChatSendServerMessage', $aseco->formatColors($message));
// clear for next vote
$tmxadd = array();
// disable all vote panels
if ($aseco->server->getGame() == 'TMF')
allvotepanels_off($aseco);
// throw 'jukebox changed' event
$aseco->releaseEvent('onJukeboxChanged', array('add', $jukebox[$uid]));
}
}
// check for ongoing chat vote
elseif (!empty($chatvote) && $chatvote['votes'] >= 0) {
$votereq = $chatvote['votes'];
$votereq--;
// check for sufficient votes
if ($votereq > 0) {
// remind players to vote
$chatvote['votes'] = $votereq;
$message = formatText($rasp->messages['VOTE_Y'][0],
$votereq, ($votereq == 1 ? '' : 's'),
$chatvote['desc']);
if ($vote_in_window && function_exists('send_window_message'))
send_window_message($aseco, $message, false);
else
$aseco->client->query('ChatSendServerMessage', $aseco->formatColors($message));
// register this player's vote
$plrvotes[] = $login;
// disable panel in case /y was used to vote
if ($aseco->server->getGame() == 'TMF')
votepanel_off($aseco, $login);
} else {
// show chat message
$message = formatText($rasp->messages['VOTE_PASS'][0],
$chatvote['desc']);
if ($vote_in_window && function_exists('send_window_message'))
send_window_message($aseco, $message, false);
else
$aseco->client->query('ChatSendServerMessage', $aseco->formatColors($message));
// pass, so perform action
switch ($chatvote['type']) {
case 0: // endround
$aseco->client->query('ForceEndRound');
$aseco->console('Vote by {1} forced round end!',
$chatvote['login']);
break;
case 1: // ladder
if ($ladder_fast_restart) {
global $atl_restart; // from plugin.autotime.php
// perform quick restart
if (isset($atl_restart)) $atl_restart = true;
if ($aseco->server->gameinfo->mode == Gameinfo::CUP)
// don't clear scores if in TMF Cup mode
$aseco->client->query('ChallengeRestart', true);
else
$aseco->client->query('ChallengeRestart');
} else {
// prepend current track to start of jukebox
$uid = $aseco->server->challenge->uid;
$jukebox = array_reverse($jukebox, true);
$jukebox[$uid]['FileName'] = $aseco->server->challenge->filename;
$jukebox[$uid]['Name'] = $aseco->server->challenge->name;
$jukebox[$uid]['Env'] = $aseco->server->challenge->environment;
$jukebox[$uid]['Login'] = $chatvote['login'];
$jukebox[$uid]['Nick'] = $chatvote['nick'];
$jukebox[$uid]['source'] = 'Ladder';
$jukebox[$uid]['tmx'] = false;
$jukebox[$uid]['uid'] = $uid;
$jukebox = array_reverse($jukebox, true);
if ($aseco->debug) {
$aseco->console_text('/ladder pass - $jukebox:' . CRLF .
print_r($jukebox, true));
}
// throw 'jukebox changed' event
$aseco->releaseEvent('onJukeboxChanged', array('restart', $jukebox[$uid]));
// ...and skip to it
if ($aseco->server->gameinfo->mode == Gameinfo::CUP)
// don't clear scores if in TMF Cup mode
$aseco->client->query('NextChallenge', true);
else
$aseco->client->query('NextChallenge');
}
$aseco->console('Vote by {1} restarted track for ladder!',
$chatvote['login']);
break;
case 2: // replay
// prepend current track to start of jukebox
$uid = $aseco->server->challenge->uid;
$jukebox = array_reverse($jukebox, true);
$jukebox[$uid]['FileName'] = $aseco->server->challenge->filename;
$jukebox[$uid]['Name'] = $aseco->server->challenge->name;
$jukebox[$uid]['Env'] = $aseco->server->challenge->environment;
$jukebox[$uid]['Login'] = $chatvote['login'];
$jukebox[$uid]['Nick'] = $chatvote['nick'];
$jukebox[$uid]['source'] = 'Replay';
$jukebox[$uid]['tmx'] = false;
$jukebox[$uid]['uid'] = $uid;
$jukebox = array_reverse($jukebox, true);
if ($aseco->debug) {
$aseco->console_text('/replay pass - $jukebox:' . CRLF .
print_r($jukebox, true));
}
$aseco->console('Vote by {1} replays track after finish!',
$chatvote['login']);
// throw 'jukebox changed' event
$aseco->releaseEvent('onJukeboxChanged', array('replay', $jukebox[$uid]));
break;
case 3: // skip
// skip immediately to next track
if ($aseco->server->gameinfo->mode == Gameinfo::CUP)
// don't clear scores if in TMF Cup mode
$aseco->client->query('NextChallenge', true);
else
$aseco->client->query('NextChallenge');
$aseco->console('Vote by {1} skips this track!',
$chatvote['login']);
break;
case 4: // kick
$rtn = $aseco->client->query('Kick', $chatvote['target']);
if (!$rtn) {
trigger_error('[' . $aseco->client->getErrorCode() . '] Kick - ' . $aseco->client->getErrorMessage(), E_USER_WARNING);
} else {
$aseco->console('Vote by {1} kicked player {2}!',
$chatvote['login'], $chatvote['target']);
}
break;
case 6: // ignore
$rtn = $aseco->client->query('Ignore', $chatvote['target']);
if (!$rtn) {
trigger_error('[' . $aseco->client->getErrorCode() . '] Ignore - ' . $aseco->client->getErrorMessage(), E_USER_WARNING);
} else {
// check if in global mute/ignore list
if (!in_array($chatvote['target'], $aseco->server->mutelist)) {
// add player to list
$aseco->server->mutelist[] = $chatvote['target'];
}
$aseco->console('Vote by {1} ignored player {2}!',
$chatvote['login'], $chatvote['target']);
}
break;
case 5: // add - can't occur here
break;
}
// clear for next vote
$chatvote = array();
// disable all vote panels
if ($aseco->server->getGame() == 'TMF')
allvotepanels_off($aseco);
}
// all quiet on the voting front :)
} else {
$message = '{#server}> {#error}There is no vote right now!';
if ($feature_tmxadd) {
if ($feature_votes) {
$message .= ' Use {#highlite}$i/add <ID>{#error} or see {#highlite}$i/helpvote{#error} to start one.';
} else {
$message .= ' Use {#highlite}$i/add <ID>{#error} to start one.';
}
} else {
if ($feature_votes) {
$message .= ' See {#highlite}$i/helpvote{#error} to start one.';
} else {
$message .= '';
}
}
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
}
} // chat_y
// called @ onSync
function init_jbhistory($aseco, $data) {
global $buffersize, $jb_buffer;
// read track history from file in case of XASECO restart
$jb_buffer = array();
if ($fp = @fopen($aseco->server->trackdir . $aseco->settings['trackhist_file'], 'rb')) {
while (!feof($fp)) {
$uid = rtrim(fgets($fp));
if ($uid != '') $jb_buffer[] = $uid;
}
fclose($fp);
// keep only most recent $buffersize entries
$jb_buffer = array_slice($jb_buffer, -$buffersize);
// drop current (last) track as rasp_newtrack() will add it back
array_pop($jb_buffer);
}
} // init_jbhistory
function chat_history($aseco, $command) {
global $rasp, $jb_buffer;
$player = $command['author'];
// check for relay server
if ($aseco->server->isrelay) {
$message = formatText($aseco->getChatMessage('NOTONRELAY'));
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $player->login);
return;
}
if (!empty($jb_buffer)) {
$message = $rasp->messages['HISTORY'][0];
// loop over last 10 (max) entries in buffer
for ($i = 1, $j = count($jb_buffer)-1; $i <= 10 && $j >= 0; $i++, $j--) {
// get track name from UID
$query = 'SELECT Name FROM challenges
WHERE Uid=' . quotedString($jb_buffer[$j]);
$res = mysql_query($query);
$row = mysql_fetch_object($res);
mysql_free_result($res);
$message .= '{#highlite}' . $i . '{#emotic}.[{#highlite}' . stripColors($row->Name) . '{#emotic}], ';
}
$message = substr($message, 0, strlen($message)-2); // strip trailing ", "
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $player->login);
return;
} else {
$message = '{#server}> {#error}No track history available!';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $player->login);
return;
}
} // chat_history
function chat_xlist($aseco, $command) {
$player = $command['author'];
$login = $player->login;
// split params into array
$command['params'] = explode(' ', preg_replace('/ +/', ' ', $command['params']));
$cmdcount = count($command['params']);
$section = $aseco->server->getGame();
if ($section == 'TMF') {
if ($aseco->server->packmask == 'Stadium')
$section = 'TMNF';
else
$section = 'TMU';
}
if ($cmdcount == 1 && $command['params'][0] == 'help') {
if ($aseco->server->getGame() == 'TMN') {
$help = '{#black}/xlist$g will show tracks on TMX:' . LF;
$help .= ' - {#black}help$g, displays this help information' . LF;
$help .= ' - {#black}recent$g, the 10 most recent tracks' . LF;
$help .= ' - {#black}xxx$g, tracks matching (partial) name' . LF;
$help .= ' - {#black}auth:yyy$g, tracks matching (partial) author' . LF;
$help .= ' - {#black}env:zzz$g, where zzz is an environment from:' . LF;
$help .= ' stadium,bay,coast,island,snow,desert,rally' . LF;
$help .= ' - {#black}xxx auth:yyy env:zzz$g, combines any searches' . LF;
$help .= ' - {#black}tmx$g, selects a TMX section from:' . LF;
$help .= ' TMO,TMS,TMN,TMNF$n $m,TMU' . LF;
$help .= LF . 'Pick a TMX Id number from the list, and use {#black}/add #$g';
// display popup message
$aseco->client->query('SendDisplayServerMessageToLogin', $login, $aseco->formatColors($help), 'OK', '', 0);
} elseif ($aseco->server->getGame() == 'TMF') {
$header = '{#black}/xlist$g will show tracks on TMX:';
$help = array();
$help[] = array('...', '{#black}help',
'Displays this help information');
$help[] = array('...', '{#black}recent',
'Lists the 10 most recent tracks');
$help[] = array('...', '{#black}xxx',
'Lists tracks matching (partial) name');
$help[] = array('...', '{#black}auth:yyy',
'Lists tracks matching (partial) author');
$help[] = array('...', '{#black}env:zzz',
'Where zzz is an environment from: stadium,');
$help[] = array('', '',
'bay,coast,island,snow/alpine,desert/speed,rally');
$help[] = array('...', '{#black}xxx auth:yyy env:zzz',
'Combines the name, author and/or env searches');
$help[] = array('...', '{#black}tmx',
'Selects a TMX section from:');
$help[] = array('', '',
'TMO,TMS,TMN,TMNF,TMU');
$help[] = array();
$help[] = array('Pick a TMX Id number from the list, and use {#black}/add # {sec}');
// display ManiaLink message
display_manialink($login, $header, array('Icons64x64_1', 'TrackInfo', -0.01), $help, array(1.2, 0.05, 0.35, 0.8), 'OK');
}
return;
}
elseif ($command['params'][0] == 'recent') {
// check for optional <tmx> parameter
if (isset($command['params'][1]) &&
strtolower(substr($command['params'][1], 0, 2)) == 'tm')
$section = strtoupper($command['params'][1]);
// get 10 most recent tracks
$tracks = new TMXInfoSearcher($section, '', '', '', true);
} else {
$name = '';
$auth = '';
$env = '';
// collect search parameters
foreach ($command['params'] as $param) {
if (strtolower(substr($param, 0, 5)) == 'auth:') {
$auth = substr($param, 5);
} elseif (strtolower(substr($param, 0, 4)) == 'env:') {
$env = substr($param, 4);
// map internal to external envs
if (strtolower($env) == 'speed')
$env = 'desert';
elseif (strtolower($env) == 'alpine')
$env = 'snow';
} elseif (strtolower(substr($param, 0, 2)) == 'tm' &&
// only if last parameter
$param == end($command['params'])) {
$section = strtoupper($param);
} else {
if ($name == '')
$name = $param;
else // concatenate words in name
$name .= '%20' . $param;
}
}
// search for matching tracks
$tracks = new TMXInfoSearcher($section, $name, $auth, $env, false);
}
// check for any results
if (!$tracks->valid()) {
$message = '{#server}> {#error}No tracks found, or TMX is down!';
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
return;
}
$player->tracklist = array();
if ($aseco->server->getGame() == 'TMN') {
$head = 'Tracks On TMX Section {#black}' . $section . '$g:' . LF . 'Id TMX Name Author' . LF;
$msg = '';
$tid = 1;
$lines = 0;
$player->msgs = array();
$player->msgs[0] = 1;
// list all found tracks
foreach ($tracks as $row) {
$msg .= '$z' . str_pad($tid, 3, '0', STR_PAD_LEFT) . '. {#black}' .
str_pad($row->id, 7) . ' ' . str_pad($row->name, 20) . '$z ' .
$row->author . LF;
$tid++;
if (++$lines > 9) {
$player->msgs[] = $aseco->formatColors($head . $msg);
$lines = 0;
$msg = '';
}
}
// add if last batch exists
if ($msg != '')
$player->msgs[] = $aseco->formatColors($head . $msg);
// display popup message
if (count($player->msgs) == 2) {
$aseco->client->query('SendDisplayServerMessageToLogin', $login, $player->msgs[1], 'OK', '', 0);
} else { // > 2
$aseco->client->query('SendDisplayServerMessageToLogin', $login, $player->msgs[1], 'Close', 'Next', 0);
}
} elseif ($aseco->server->getGame() == 'TMF') {
$adminadd = $aseco->allowAbility($player, 'add');
$head = 'Tracks On TMX Section {#black}' . $section . '$g:';
$msg = array();
if ($aseco->settings['clickable_lists'])
if ($adminadd)
$msg[] = array('Id', 'TMX', 'Name (click to /add)', '$nAdmin', 'Author', 'Env');
else
$msg[] = array('Id', 'TMX', 'Name (click to /add)', 'Author', 'Env');
else
$msg[] = array('Id', 'TMX', 'Name', 'Author', 'Env');
$tid = 1;
$lines = 0;
$player->msgs = array();
if ($adminadd && $aseco->settings['clickable_lists'])
$player->msgs[0] = array(1, $head, array(1.55, 0.12, 0.16, 0.6, 0.1, 0.4, 0.17), array('Icons128x128_1', 'LoadTrack', 0.02));
else
$player->msgs[0] = array(1, $head, array(1.45, 0.12, 0.16, 0.6, 0.4, 0.17), array('Icons128x128_1', 'LoadTrack', 0.02));
// list all found tracks
foreach ($tracks as $row) {
$tmxid = '{#black}' . $row->id;
$name = '{#black}' . $row->name;
$author = $row->author;
// add clickable buttons
if ($aseco->settings['clickable_lists'] && $tid <= 500) {
$tmxid = array($tmxid, $tid+5200); // action ids
$name = array($name, $tid+5700);
$author = array($author, $tid+6700);
// store track in player object for action buttons
$trkarr = array();
$trkarr['id'] = $row->id;
$trkarr['section'] = $row->section;
$trkarr['author'] = $row->author;
$player->tracklist[] = $trkarr;
}
if ($adminadd)
if ($aseco->settings['clickable_lists'] && $tid <= 500)
$msg[] = array(str_pad($tid, 3, '0', STR_PAD_LEFT) . '.',
$tmxid, $name, array('Add', $tid+6200), $author, $row->envir);
else
$msg[] = array(str_pad($tid, 3, '0', STR_PAD_LEFT) . '.',
$tmxid, $name, 'Add', $author, $row->envir);
else
$msg[] = array(str_pad($tid, 3, '0', STR_PAD_LEFT) . '.',
$tmxid, $name, $author, $row->envir);
$tid++;
if (++$lines > 14) {
$player->msgs[] = $msg;
$lines = 0;
$msg = array();
if ($aseco->settings['clickable_lists'])
if ($adminadd)
$msg[] = array('Id', 'TMX', 'Name (click to /add)', '$nAdmin', 'Author', 'Env');
else
$msg[] = array('Id', 'TMX', 'Name (click to /add)', 'Author', 'Env');
else
$msg[] = array('Id', 'TMX', 'Name', 'Author', 'Env');
}
}
// add if last batch exists
if (count($msg) > 1)
$player->msgs[] = $msg;
// display ManiaLink message
display_manialink_multi($player);
}
} // chat_xlist
// called @ onPlayerManialinkPageAnswer
// Handles ManiaLink jukebox responses
// [0]=PlayerUid, [1]=Login, [2]=Answer
function event_jukebox($aseco, $answer) {
global $jukebox;
// leave actions outside 101 - 2000, -2000 - -101, -2100 - -2001,
// -6001 - -7900 & 5201 - 7200 to other handlers
if ($answer[2] >= 101 && $answer[2] <= 2000) {
// get player
$player = $aseco->server->players->getPlayer($answer[1]);
// log clicked command
$aseco->console('player {1} clicked command "/jukebox {2}"',
$player->login, $answer[2]-100);
// jukebox selected track
$command = array();
$command['author'] = $player;
$command['params'] = $answer[2]-100;
chat_jukebox($aseco, $command);
}
elseif ($answer[2] >= -7900 && $answer[2] <= -6001) {
// get player
$player = $aseco->server->players->getPlayer($answer[1]);
// log clicked command
$aseco->console('player {1} clicked command "/karma {2}"',
$player->login, abs($answer[2])-6000);
// karma selected track
$command = array();
$command['author'] = $player;
$command['params'] = abs($answer[2])-6000;
chat_karma($aseco, $command);
}
elseif ($answer[2] >= -2000 && $answer[2] <= -101) {
// get player
$player = $aseco->server->players->getPlayer($answer[1]);
$author = $player->tracklist[abs($answer[2])-101]['author'];
// close main window because /list can take a while
mainwindow_off($aseco, $player->login);
// log clicked command
$aseco->console('player {1} clicked command "/list {2}"',
$player->login, $author);
// search for tracks by author
$command = array();
$command['author'] = $player;
$command['params'] = $author;
chat_list($aseco, $command);
}
elseif ($answer[2] >= -2100 && $answer[2] <= -2001) {
// get player
$player = $aseco->server->players->getPlayer($answer[1]);
$login = $player->login;
// determine admin ability to drop all jukeboxed tracks
if ($aseco->allowAbility($player, 'dropjukebox')) {
// log clicked command
$aseco->console('player {1} clicked command "/admin dropjukebox {2}"',
$login, abs($answer[2])-2000);
// drop any jukeboxed track by admin
$command = array();
$command['author'] = $player;
$command['params'] = 'dropjukebox ' . (abs($answer[2])-2000);
chat_admin($aseco, $command);
// check whether last track was dropped
if (empty($jukebox)) {
// close main window
mainwindow_off($aseco, $login);
} else {
// log clicked command
$aseco->console('player {1} clicked command "/jukebox display"', $login);
// display updated list
$command['params'] = 'display';
chat_jukebox($aseco, $command);
}
} else {
// log clicked command
$aseco->console('player {1} clicked command "/jukebox drop"', $login);
// drop user's jukeboxed track
$command = array();
$command['author'] = $player;
$command['params'] = 'drop';
chat_jukebox($aseco, $command);
// check whether last track was dropped
if (empty($jukebox)) {
// close main window
mainwindow_off($aseco, $login);
} else {
// log clicked command
$aseco->console('player {1} clicked command "/jukebox display"', $login);
// display updated list
$command['params'] = 'display';
chat_jukebox($aseco, $command);
}
}
}
elseif ($answer[2] >= 5201 && $answer[2] <= 5700) {
// get player & track ID
$player = $aseco->server->players->getPlayer($answer[1]);
$tmxid = $player->tracklist[$answer[2]-5201]['id'];
$section = $player->tracklist[$answer[2]-5201]['section'];
// log clicked command
$aseco->console('player {1} clicked command "/tmxinfo {2} {3}"',
$player->login, $tmxid, $section);
// /tmxinfo selected track
$command = array();
$command['author'] = $player;
$command['params'] = $tmxid . ' ' . $section;
chat_tmxinfo($aseco, $command);
}
elseif ($answer[2] >= 5701 && $answer[2] <= 6200) {
// get player & track ID
$player = $aseco->server->players->getPlayer($answer[1]);
$tmxid = $player->tracklist[$answer[2]-5701]['id'];
$section = $player->tracklist[$answer[2]-5701]['section'];
// log clicked command
$aseco->console('player {1} clicked command "/add {2} {3}"',
$player->login, $tmxid, $section);
// /add selected track
$command = array();
$command['author'] = $player;
$command['params'] = $tmxid . ' ' . $section;
chat_add($aseco, $command);
}
elseif ($answer[2] >= 6201 && $answer[2] <= 6700) {
// get player & track ID
$player = $aseco->server->players->getPlayer($answer[1]);
$tmxid = $player->tracklist[$answer[2]-6201]['id'];
$section = $player->tracklist[$answer[2]-6201]['section'];
// log clicked command
$aseco->console('player {1} clicked command "/admin add {2} {3}"',
$player->login, $tmxid, $section);
// /admin add selected track
$command = array();
$command['author'] = $player;
$command['params'] = 'add ' . $tmxid . ' ' . $section;
chat_admin($aseco, $command);
}
elseif ($answer[2] >= 6701 && $answer[2] <= 7200) {
// get player & track author
$player = $aseco->server->players->getPlayer($answer[1]);
$author = $player->tracklist[$answer[2]-6701]['author'];
$section = $player->tracklist[$answer[2]-6701]['section'];
// insure multi-word author is single parameter
$author = str_replace(' ', '%20', $author);
// log clicked command
$aseco->console('player {1} clicked command "/xlist auth:{2} {3}"',
$player->login, $author, $section);
// /xlist auth: selected author
$command = array();
$command['author'] = $player;
$command['params'] = 'auth:' . $author . ' ' . $section;
chat_xlist($aseco, $command);
}
} // event_jukebox
?>