2019-07-17 19:37:18 +02:00
# include <set>
2019-07-19 22:55:03 +02:00
# include <iomanip>
2019-07-17 19:37:18 +02:00
# include <netinet/in.h>
2019-07-19 22:55:03 +02:00
# include <log/LogUtils.h>
2019-09-14 12:06:48 +02:00
# include <misc/strobf.h>
2019-07-19 22:55:03 +02:00
# include "../InstanceHandler.h"
# include "../manager/ConversationManager.h"
# include "../music/MusicBotManager.h"
# include "../client/music/MusicClient.h"
# include "../client/voice/VoiceClient.h"
# include "./ConnectedClient.h"
2019-07-17 19:37:18 +02:00
using namespace ts ;
using namespace ts : : server ;
using namespace std ;
using namespace std : : chrono ;
extern InstanceHandler * serverInstance ;
std : : deque < std : : string > split ( std : : string str , std : : string sep ) {
char * cstr = const_cast < char * > ( str . c_str ( ) ) ;
char * current ;
std : : deque < std : : string > arr ;
current = strtok ( cstr , sep . c_str ( ) ) ;
while ( current ! = NULL ) {
arr . push_back ( current ) ;
current = strtok ( NULL , sep . c_str ( ) ) ;
}
return arr ;
}
# define ERR(sender, msg) \
do { \
send_message ( sender , msg ) ; \
return true ; \
} while ( false )
# define TLEN(index) if(arguments.size() < index) ERR(serverInstance->musicRoot(), "Invalid argument count");
# define TARG(index, type) (arguments.size() > index && arguments[index] == type)
# define TMUSIC(bot) if(!bot->current_player()) ERR(serverInstance->musicRoot(), "Im not playing a song!");
# define GBOT(var, ignore_disabled) \
auto var = this - > selectedBot . lock ( ) ; \
if ( ! var ) var = dynamic_pointer_cast < MusicClient > ( target ) ; \
if ( ! var ) { \
send_message ( serverInstance - > musicRoot ( ) , " Please select a music bot! ( " + ts : : config : : music : : command_prefix + " mbot select <id>) " ) ; \
return true ; \
} \
if ( ! ignore_disabled & & var - > properties ( ) [ property : : CLIENT_DISABLED ] . as < bool > ( ) ) { \
2020-01-24 02:57:58 +01:00
send_message ( serverInstance - > musicRoot ( ) , strobf ( " This bot has been disabled. Upgrade your TeaSpeak license to use more bots. " ) . string ( ) ) ; \
return true ; \
2019-07-17 19:37:18 +02:00
}
inline string filterUrl ( string in ) {
size_t index = 0 ;
while ( ( index = in . find ( " [URL " ) ) ! = std : : string : : npos & & index < in . length ( ) ) {
auto end = in . find ( ' ] ' , index ) ;
in . replace ( index , end - index + 1 , " " , 0 ) ;
}
while ( ( index = in . find ( " [/URL " ) ) ! = std : : string : : npos & & index < in . length ( ) ) {
auto end = in . find ( ' ] ' , index ) ;
in . replace ( index , end - index + 1 , " " , 0 ) ;
}
return in ;
}
inline void permissionableCommand ( ConnectedClient * client , stringstream & ss , const std : : string & cmd , permission : : PermissionType perm , permission : : PermissionType sec = permission : : unknown ) {
2020-01-26 14:21:34 +01:00
auto permA = perm = = permission : : unknown | | permission : : v2 : : permission_granted ( 1 , client - > calculate_permission ( perm , client - > getChannelId ( ) ) ) ;
auto permB = permA | | ( sec ! = permission : : unknown & & permission : : v2 : : permission_granted ( 1 , client - > calculate_permission ( sec , client - > getChannelId ( ) ) ) ) ;
2019-07-17 19:37:18 +02:00
if ( ! ( permA | | permB ) ) {
ss < < " [color=red] " < < cmd < < " [/color] " < < endl ;
} else {
ss < < " [color=green] " < < cmd < < " [/color] " < < endl ;
}
}
inline std : : string bot_volume ( float vol ) {
auto volume = to_string ( vol * 100 ) ;
auto idx = volume . find ( ' . ' ) ;
return volume . substr ( 0 , idx + 2 ) ;
}
//FIXME add chat command for channel commander (within bot settings)
//Return true if blocked
bool ConnectedClient : : handleTextMessage ( ChatMessageMode mode , std : : string text , const std : : shared_ptr < ConnectedClient > & target ) {
if ( text . length ( ) < ts : : config : : music : : command_prefix . length ( ) ) return false ;
if ( text . find ( ts : : config : : music : : command_prefix ) ! = 0 ) return false ;
2019-07-19 22:55:03 +02:00
if ( ! this - > currentChannel )
return false ;
2019-07-17 19:37:18 +02:00
std : : string command = text . substr ( ts : : config : : music : : command_prefix . length ( ) ) ;
auto arguments = command . find ( ' ' ) ! = - 1 ? split ( command . substr ( command . find ( ' ' ) + 1 ) , " " ) : deque < string > { } ;
command = command . substr ( 0 , command . find ( ' ' ) ) ;
debugMessage ( this - > getServerId ( ) , " Having command \" " + command + " \" . " ) ;
for ( const auto & arg : arguments )
debugMessage ( this - > getServerId ( ) , " Argument: ' " + arg + " ' " ) ;
# define PERM_CHECK_BOT(perm, reqperm, err) \
2020-01-26 14:21:34 +01:00
if ( bot - > properties ( ) [ property : : CLIENT_OWNER ] ! = this - > getClientDatabaseId ( ) & & \
! permission : : v2 : : permission_granted ( bot - > calculate_permission ( permission : : reqperm , bot - > getChannelId ( ) ) , this - > calculate_permission ( permission : : perm , bot - > getChannelId ( ) ) ) ) { \
2019-07-17 19:37:18 +02:00
send_message ( serverInstance - > musicRoot ( ) , err ) ; \
return true ; \
}
2020-01-25 23:42:37 +01:00
//TODO: Correct error message print!
2019-07-17 19:37:18 +02:00
# define HANDLE_CMD_ERROR(_message) \
2020-01-25 23:42:37 +01:00
send_message ( serverInstance - > musicRoot ( ) , string ( _message ) + " : action failed " ) ;
/*
2019-07-17 19:37:18 +02:00
if ( result . extraProperties . count ( " extra_msg " ) > 0 ) \
send_message ( serverInstance - > musicRoot ( ) , string ( _message ) + " : " + result . extraProperties [ " extra_msg " ] ) ; \
else if ( result . extraProperties . count ( " failed_permid " ) > 0 ) \
send_message ( serverInstance - > musicRoot ( ) , string ( _message ) + " . (Missing permission " + permission : : resolvePermissionData ( ( permission : : PermissionType ) stoull ( result . extraProperties [ " failed_permid " ] ) ) - > name + " ) " ) ; \
else \
send_message ( serverInstance - > musicRoot ( ) , string ( _message ) + " : " + result . error . message ) ;
2020-01-25 23:42:37 +01:00
*/
2019-07-17 19:37:18 +02:00
# define JOIN_ARGS(variable, index) \
string variable ; \
{ \
stringstream ss ; \
for ( auto it = arguments . begin ( ) + index ; it ! = arguments . end ( ) ; it + + ) \
ss < < * it < < ( it + 1 = = arguments . end ( ) ? " " : " " ) ; \
variable = ss . str ( ) ; \
}
handle_text_command_fn_t function ;
if ( mode = = ChatMessageMode : : TEXTMODE_SERVER ) {
function = [ & ] ( const shared_ptr < ConnectedClient > & sender , const string & message ) {
2019-08-20 13:46:23 +02:00
this - > notifyTextMessage ( ChatMessageMode : : TEXTMODE_SERVER , sender , 0 , 0 , system_clock : : now ( ) , message ) ;
2019-07-17 19:37:18 +02:00
} ;
} else if ( mode = = ChatMessageMode : : TEXTMODE_CHANNEL ) {
function = [ & ] ( const shared_ptr < ConnectedClient > & sender , const string & message ) {
2019-08-20 13:46:23 +02:00
this - > notifyTextMessage ( ChatMessageMode : : TEXTMODE_CHANNEL , sender , 0 , 0 , system_clock : : now ( ) , message ) ;
2019-07-17 19:37:18 +02:00
} ;
} else if ( mode = = ChatMessageMode : : TEXTMODE_PRIVATE ) {
function = [ & , target ] ( const shared_ptr < ConnectedClient > & sender , const string & message ) {
2019-08-20 13:46:23 +02:00
this - > notifyTextMessage ( ChatMessageMode : : TEXTMODE_PRIVATE , target , this - > getClientId ( ) , 0 , system_clock : : now ( ) , message ) ;
2019-07-17 19:37:18 +02:00
} ;
}
return handle_text_command ( mode , command , arguments , function , target ) ;
}
bool ConnectedClient : : handle_text_command (
ChatMessageMode mode ,
const string & command ,
const deque < string > & arguments ,
const function < void ( const shared_ptr < ConnectedClient > & , const string & ) > & send_message ,
const shared_ptr < ConnectedClient > & target ) {
if ( command = = " mbot " ) {
if ( ! config : : music : : enabled ) {
send_message ( serverInstance - > musicRoot ( ) , " Music bots are not enabled! Enable them via the server config! " ) ;
return true ;
}
if ( TARG ( 0 , " create " ) ) {
Command cmd ( " " ) ;
auto result = this - > handleCommandMusicBotCreate ( cmd ) ;
2020-01-25 23:42:37 +01:00
if ( result . error_code ( ) ) {
result . release_details ( ) ;
2019-07-17 19:37:18 +02:00
HANDLE_CMD_ERROR ( " Failed to create music bot " ) ;
return true ;
}
send_message ( serverInstance - > musicRoot ( ) , " Bot created " ) ;
return true ;
} else if ( TARG ( 0 , " list " ) ) {
bool server = false ;
if ( TARG ( 1 , " server " ) )
server = true ;
string locationStr = server ? " on this server " : " in this channel " ;
2020-01-26 14:21:34 +01:00
if ( ! permission : : v2 : : permission_granted ( 1 , this - > calculate_permission ( server ? permission : : b_client_music_server_list : permission : : b_client_music_channel_list , this - > getChannelId ( ) ) ) ) {
2019-07-17 19:37:18 +02:00
send_message ( serverInstance - > musicRoot ( ) , " You don't have the permission to list all music bots " + locationStr ) ;
return true ;
}
auto mbots = this - > server - > getClientsByChannel < MusicClient > ( server ? nullptr : this - > currentChannel ) ;
if ( mbots . empty ( ) )
send_message ( serverInstance - > musicRoot ( ) , " There are no music bots " + locationStr ) ;
else {
send_message ( serverInstance - > musicRoot ( ) , " There are " + to_string ( mbots . size ( ) ) + " music bots " + locationStr + " : " ) ;
for ( const auto & mbot : mbots ) {
if ( mbot - > properties ( ) [ property : : CLIENT_DISABLED ] . as < bool > ( ) ) {
send_message ( serverInstance - > musicRoot ( ) , " - [color=red] " + to_string ( mbot - > getClientDatabaseId ( ) ) + " | " + mbot - > getDisplayName ( ) + " [DISABLED][/color] " ) ;
} else {
send_message ( serverInstance - > musicRoot ( ) , " - [color=green] " + to_string ( mbot - > getClientDatabaseId ( ) ) + " | " + mbot - > getDisplayName ( ) + " [/color] " ) ;
}
}
}
return true ;
} else if ( TARG ( 0 , " select " ) ) {
TLEN ( 2 ) ;
if ( arguments [ 1 ] . find_first_not_of ( " 0123456789 " ) ! = std : : string : : npos ) {
send_message ( serverInstance - > musicRoot ( ) , " Invalid bot id " ) ;
return true ;
}
auto botId = static_cast < ClientDbId > ( stoll ( arguments [ 1 ] ) ) ;
auto bot = this - > server - > musicManager - > findBotById ( botId ) ;
if ( ! bot ) ERR ( serverInstance - > musicRoot ( ) , " Could not find target bot " ) ;
2020-01-26 14:21:34 +01:00
if ( bot - > properties ( ) [ property : : CLIENT_OWNER ] ! = this - > getClientDatabaseId ( ) & &
! permission : : v2 : : permission_granted ( 1 , this - > calculate_permission ( permission : : b_client_music_channel_list , this - > getChannelId ( ) ) ) & &
! permission : : v2 : : permission_granted ( 1 , this - > calculate_permission ( permission : : b_client_music_server_list , this - > getChannelId ( ) ) ) ) { //No perms for listing
2019-07-17 19:37:18 +02:00
send_message ( serverInstance - > musicRoot ( ) , " You don't have the permission to select a music bot " ) ;
return true ;
}
this - > selectedBot = bot ;
send_message ( serverInstance - > musicRoot ( ) , " You successfully select the bot " + to_string ( botId ) + " | " + bot - > getDisplayName ( ) ) ;
return true ;
} else if ( TARG ( 0 , " rename " ) ) {
TLEN ( 2 ) ;
GBOT ( bot , true ) ;
stringstream ss ;
for ( auto it = arguments . begin ( ) + 1 ; it ! = arguments . end ( ) ; it + + )
ss < < * it < < ( it + 1 = = arguments . end ( ) ? " " : " " ) ;
string name = ss . str ( ) ;
Command cmd ( " " ) ;
cmd [ " client_nickname " ] = ss . str ( ) ;
auto result = this - > handleCommandClientEdit ( cmd , bot ) ;
2020-01-25 23:42:37 +01:00
if ( result . error_code ( ) ) {
2019-07-17 19:37:18 +02:00
HANDLE_CMD_ERROR ( " Failed to rename bot " ) ;
2020-01-25 23:42:37 +01:00
result . release_details ( ) ;
2019-07-17 19:37:18 +02:00
return true ;
}
send_message ( serverInstance - > musicRoot ( ) , " Name successfully changed! " ) ;
return true ;
} else if ( TARG ( 0 , " delete " ) ) {
GBOT ( bot , true ) ;
PERM_CHECK_BOT ( i_client_music_delete_power , i_client_music_needed_delete_power , " You don't have the permission to rename this music bot " ) ;
this - > server - > musicManager - > deleteBot ( bot ) ;
send_message ( bot , " You successfully deleted this music bot! " ) ;
return true ;
} else if ( TARG ( 0 , " yt " ) | | TARG ( 0 , " soundcloud " ) | | TARG ( 0 , " sc " ) ) {
TLEN ( 2 ) ;
GBOT ( bot , false ) ;
PERM_CHECK_BOT ( i_client_music_play_power , i_client_music_needed_play_power , " You don't have the permission to play something this music bot " ) ;
auto playlist = bot - > playlist ( ) ;
if ( ! playlist ) {
send_message ( bot , " bot hasnt a playlist! " ) ;
return true ;
}
JOIN_ARGS ( url , 1 ) ;
send_message ( bot , " Queueing video " + url ) ;
playlist - > add_song ( this - > ref ( ) , filterUrl ( url ) , " YouTube " ) ;
return true ;
} else if ( TARG ( 0 , " stream " ) ) {
TLEN ( 2 ) ;
GBOT ( bot , false ) ;
PERM_CHECK_BOT ( i_client_music_play_power , i_client_music_needed_play_power , " You don't have the permission to play something this music bot " ) ;
auto playlist = bot - > playlist ( ) ;
if ( ! playlist ) {
send_message ( bot , " bot hasnt a playlist! " ) ;
return true ;
}
JOIN_ARGS ( url , 1 ) ;
send_message ( bot , " Queueing video " + url ) ;
playlist - > add_song ( this - > ref ( ) , filterUrl ( url ) , " FFMpeg " ) ;
return true ;
} else if ( TARG ( 0 , " player " ) ) {
TLEN ( 2 ) ;
GBOT ( bot , false ) ;
PERM_CHECK_BOT ( i_client_music_play_power , i_client_music_needed_play_power , " You don't have the permission to play something this music bot " ) ;
auto playlist = bot - > playlist ( ) ;
if ( ! playlist ) {
send_message ( bot , " bot hasnt a playlist! " ) ;
return true ;
}
JOIN_ARGS ( url , 2 ) ;
send_message ( bot , " Queueing video " + url ) ;
playlist - > add_song ( this - > ref ( ) , filterUrl ( url ) , arguments [ 1 ] ) ;
return true ;
} else if ( TARG ( 0 , " forward " ) ) {
TLEN ( 2 ) ;
GBOT ( bot , false ) ;
PERM_CHECK_BOT ( i_client_music_play_power , i_client_music_needed_play_power , " You don't have the permission to play something this music bot " ) ;
TMUSIC ( bot ) ;
if ( arguments [ 1 ] . find_first_not_of ( " 0123456789 " ) ! = std : : string : : npos ) {
send_message ( bot , " Invalid number of seconds! " ) ;
return true ;
}
threads : : Thread ( [ bot , arguments ] ( ) {
bot - > current_player ( ) - > forward ( seconds ( stoll ( arguments [ 1 ] ) ) ) ;
} ) . detach ( ) ;
send_message ( bot , " Skipped " + to_string ( stoll ( arguments [ 1 ] ) ) + " seconds! " ) ;
return true ;
} else if ( TARG ( 0 , " rewind " ) ) {
TLEN ( 2 ) ;
GBOT ( bot , false ) ;
PERM_CHECK_BOT ( i_client_music_play_power , i_client_music_needed_play_power , " You don't have the permission to play something this music bot " ) ;
TMUSIC ( bot ) ;
if ( arguments [ 1 ] . find_first_not_of ( " 0123456789 " ) ! = std : : string : : npos ) {
send_message ( bot , " Invalid number of seconds! " ) ;
return true ;
}
threads : : Thread ( [ bot , arguments ] ( ) {
bot - > current_player ( ) - > rewind ( seconds ( stoll ( arguments [ 1 ] ) ) ) ;
} ) . detach ( ) ;
send_message ( bot , " Rewind " + to_string ( stoll ( arguments [ 1 ] ) ) + " seconds! " ) ;
return true ;
} else if ( TARG ( 0 , " stop " ) ) {
GBOT ( bot , true ) ;
PERM_CHECK_BOT ( i_client_music_play_power , i_client_music_needed_play_power , " You don't have the permission to play something this music bot " ) ;
TMUSIC ( bot ) ;
bot - > current_player ( ) - > stop ( ) ;
send_message ( bot , " Music stopped! " ) ;
return true ;
} else if ( TARG ( 0 , " pause " ) ) {
GBOT ( bot , false ) ;
PERM_CHECK_BOT ( i_client_music_play_power , i_client_music_needed_play_power , " You don't have the permission to play something this music bot " ) ;
TMUSIC ( bot ) ;
bot - > current_player ( ) - > pause ( ) ;
send_message ( bot , " Music paused! " ) ;
return true ;
} else if ( TARG ( 0 , " play " ) ) {
if ( arguments . size ( ) > = 2 ) {
GBOT ( bot , false ) ;
PERM_CHECK_BOT ( i_client_music_play_power , i_client_music_needed_play_power , " You don't have the permission to play something this music bot " ) ;
auto playlist = bot - > playlist ( ) ;
if ( ! playlist ) {
send_message ( bot , " bot hasnt a playlist! " ) ;
return true ;
}
send_message ( bot , " Queueing video " + arguments [ 1 ] ) ;
playlist - > add_song ( this - > ref ( ) , filterUrl ( arguments [ 1 ] ) , " " ) ;
return true ;
} else {
GBOT ( bot , false ) ;
PERM_CHECK_BOT ( i_client_music_play_power , i_client_music_needed_play_power , " You don't have the permission to play something this music bot " ) ;
TMUSIC ( bot ) ;
bot - > current_player ( ) - > play ( ) ;
send_message ( bot , " Music started! " ) ;
return true ;
}
} else if ( TARG ( 0 , " info " ) ) {
GBOT ( bot , true ) ;
PERM_CHECK_BOT ( i_client_music_info , i_client_music_needed_info , " You don't have the permission to display the music bot information " ) ;
send_message ( bot , " Music bot info: " ) ;
send_message ( bot , " Bot id : " + to_string ( bot - > getClientDatabaseId ( ) ) ) ;
send_message ( bot , " Bot name: " + bot - > getDisplayName ( ) ) ;
send_message ( bot , " Bot volume: " + bot_volume ( bot - > volumeModifier ( ) ) ) ;
send_message ( bot , " State: " + to_string ( bot - > player_state ( ) ) ) ;
if ( bot - > current_player ( ) ) {
auto player = bot - > current_player ( ) ;
send_message ( bot , " Play state: player open " ) ;
send_message ( bot , " State : " + string ( : : music : : stateNames [ player - > state ( ) ] ) ) ;
send_message ( bot , " Title : " + player - > songTitle ( ) ) ;
send_message ( bot , " Description : " + player - > songDescription ( ) ) ;
send_message ( bot , " Timeline : " + to_string ( duration_cast < seconds > ( player - > currentIndex ( ) ) . count ( ) ) + " / " + to_string ( duration_cast < seconds > ( player - > length ( ) ) . count ( ) ) ) ;
send_message ( bot , " Buffered : " + to_string ( duration_cast < seconds > ( player - > bufferedUntil ( ) - player - > currentIndex ( ) ) . count ( ) ) + " seconds " ) ;
} else {
send_message ( bot , " Play state: not playing " ) ;
}
auto bot_playlist = bot - > playlist ( ) ;
if ( bot_playlist ) {
send_message ( bot , " Playlist ID : " + to_string ( bot_playlist - > playlist_id ( ) ) ) ;
send_message ( bot , " Playlist size : " + to_string ( bot_playlist - > list_songs ( ) . size ( ) ) ) ;
} else {
send_message ( bot , " Playlist ID : No playlist assigned " ) ;
}
return true ;
} else if ( TARG ( 0 , " queue " ) | | TARG ( 0 , " playlist " ) | | TARG ( 0 , " pl " ) ) {
GBOT ( bot , false ) ;
PERM_CHECK_BOT ( i_client_music_info , i_client_music_needed_info , " You don't have the permission to display the music bot information " ) ;
auto bot_playlist = bot - > playlist ( ) ;
if ( bot_playlist ) {
send_message ( bot , " Playlist ID : " + to_string ( bot_playlist - > playlist_id ( ) ) ) ;
send_message ( bot , " Playlist entries ( " + to_string ( bot_playlist - > list_songs ( ) . size ( ) ) + " ): [color=orange]orange[/color] = currently index " ) ;
set < ClientDbId > dbids ;
for ( const auto & song : bot_playlist - > list_songs ( ) )
dbids . insert ( song - > invoker ) ;
auto dbinfo = serverInstance - > databaseHelper ( ) - > queryDatabaseInfo ( this - > getServer ( ) , deque < ClientDbId > ( dbids . begin ( ) , dbids . end ( ) ) ) ;
auto current_song = bot_playlist - > currently_playing ( ) ;
for ( const auto & song : bot_playlist - > list_songs ( ) ) {
string invoker = " unknown " ;
for ( const auto & e : dbinfo ) {
if ( e - > cldbid = = song - > invoker ) {
invoker = " [URL=client://0/ " + e - > uniqueId + " ~ " + e - > lastName + " ] " + e - > lastName + " [/URL] " ;
break ;
}
}
string data = " \" " + song - > url + " \" added by " + invoker ;
if ( song - > id = = current_song )
data = " [color=orange] " + data + " [/color] " ;
send_message ( bot , " - " + data ) ;
}
} else {
send_message ( bot , " The bot hasn't a playlist " ) ;
}
return true ;
} else if ( TARG ( 0 , " next " ) ) {
GBOT ( bot , false ) ;
PERM_CHECK_BOT ( i_client_music_play_power , i_client_music_needed_play_power , " You don't have the permission to play something this music bot " ) ;
bot - > forwardSong ( ) ;
auto song = bot - > current_song ( ) ;
if ( song )
send_message ( bot , " Replaying next song ( " + song - > getUrl ( ) + " ) " ) ;
else send_message ( bot , " Queue is empty! Could not forward! " ) ;
return true ;
} else if ( TARG ( 0 , " volume " ) ) {
GBOT ( bot , false ) ;
PERM_CHECK_BOT ( i_client_music_play_power , i_client_music_needed_play_power , " You don't have the permission to play something this music bot " ) ;
if ( arguments . size ( ) < 2 ) {
send_message ( bot , " Current volume: " + bot_volume ( bot - > volumeModifier ( ) ) ) ;
return true ;
}
if ( arguments [ 1 ] . find_first_not_of ( " .-0123456789 " ) ! = std : : string : : npos ) {
send_message ( bot , " Invalid volume! " ) ;
return true ;
}
auto volume = stof ( arguments [ 1 ] ) ;
if ( volume < 0 | | volume > 100 ) {
send_message ( bot , " Invalid volume! Volume must be greater or equal to zero and less or equal then one! " ) ;
return true ;
}
2020-01-26 14:21:34 +01:00
auto max_volume = this - > calculate_permission ( permission : : i_client_music_create_modify_max_volume , 0 ) ;
if ( max_volume . has_value & & ! permission : : v2 : : permission_granted ( volume , max_volume ) ) {
send_message ( bot , " You don't have the permission to use higher volumes that " + to_string ( max_volume . value ) + " % " ) ;
2020-01-24 02:57:58 +01:00
return true ;
}
2019-07-17 19:37:18 +02:00
bot - > volume_modifier ( volume / 100 ) ;
send_message ( bot , " Volume successfully changed to " + bot_volume ( bot - > volumeModifier ( ) ) ) ;
return true ;
} else if ( TARG ( 0 , " formats " ) ) {
auto providers = : : music : : manager : : registeredTypes ( ) ;
stringstream ss ;
ss < < " Available providers: " < < endl ;
for ( const auto & prov : providers ) {
ss < < " " < < prov - > providerName < < " : " < < endl ;
ss < < " Description: " < < prov - > providerDescription < < endl ;
auto fmts = prov - > availableFormats ( ) ;
ss < < " Supported formats: ( " < < fmts . size ( ) < < " ) " < < endl ;
for ( const auto & fmt : fmts )
ss < < " - " < < fmt < < endl ;
auto prots = prov - > availableProtocols ( ) ;
ss < < " Supported protocols: ( " < < prots . size ( ) < < " ) " < < endl ;
for ( const auto & fmt : prots )
ss < < " - " < < fmt < < endl ;
}
send_message ( serverInstance - > musicRoot ( ) , ss . str ( ) ) ;
return true ;
} else if ( TARG ( 0 , " settings " ) ) {
GBOT ( bot , false ) ;
PERM_CHECK_BOT ( i_client_music_play_power , i_client_music_needed_play_power , " You don't have the permission to change anything on the bot " ) ; //TODO FIXME!
if ( TARG ( 1 , " bot " ) ) {
const static vector < string > editable_properties = {
" client_nickname " ,
" client_player_volume " ,
" client_is_channel_commander " ,
" client_version " ,
" client_country " ,
" client_platform " ,
" client_bot_type " ,
" client_uptime_mode " ,
" client_is_priority_speaker " ,
" client_flag_notify_song_change "
} ;
if ( arguments . size ( ) < 3 ) {
send_message ( bot , " Bot properties: " ) ;
for ( const auto & property : bot - > properties ( ) - > list_properties ( ~ 0 ) ) {
if ( find ( editable_properties . begin ( ) , editable_properties . end ( ) , property . type ( ) . name ) = = editable_properties . end ( ) ) continue ;
send_message ( bot , " - " + property . type ( ) . name + " = " + property . value ( ) + " " + ( property . default_value ( ) = = property . value ( ) ? " (default) " : " " ) ) ;
}
} else if ( arguments . size ( ) < 4 ) {
if ( find ( editable_properties . begin ( ) , editable_properties . end ( ) , arguments [ 2 ] ) = = editable_properties . end ( ) ) {
send_message ( bot , " Unknown property or property is not editable. " ) ;
return true ;
}
const std : : shared_ptr < property : : PropertyDescription > & property_info = property : : info < property : : ClientProperties > ( arguments [ 2 ] ) ;
if ( ! property_info | | property_info - > type_property = = property : : PROP_TYPE_UNKNOWN | | property_info - > property_index = = property : : CLIENT_UNDEFINED ) {
send_message ( bot , " Unknown property " + arguments [ 2 ] + " . " ) ;
return true ;
}
auto prop = bot - > properties ( ) [ ( property : : ClientProperties ) property_info - > property_index ] ;
send_message ( bot , " Bot property " + property_info - > name + " = " + prop . value ( ) + " " + ( property_info - > default_value = = prop . value ( ) ? " (default) " : " " ) ) ;
return true ;
} else {
Command cmd ( " " ) ;
JOIN_ARGS ( value , 3 ) ;
cmd [ arguments [ 2 ] ] = value ;
auto result = this - > handleCommandClientEdit ( cmd , bot ) ;
2020-01-25 23:42:37 +01:00
if ( result . error_code ( ) ) {
2019-07-17 19:37:18 +02:00
HANDLE_CMD_ERROR ( " Failed to change bot property " ) ;
2020-01-25 23:42:37 +01:00
result . release_details ( ) ;
2019-07-17 19:37:18 +02:00
return true ;
}
send_message ( serverInstance - > musicRoot ( ) , " Property successfully changed! " ) ;
return true ;
}
return true ;
} else if ( TARG ( 1 , " playlist " ) ) {
auto playlist = bot - > playlist ( ) ;
if ( ! playlist ) {
send_message ( bot , " Bot hasn't a playlist! " ) ;
return true ;
}
if ( arguments . size ( ) < 3 ) {
send_message ( bot , " Playlist properties: " ) ;
for ( const auto & property : playlist - > properties ( ) . list_properties ( property : : FLAG_PLAYLIST_VARIABLE ) ) {
send_message ( bot , " - " + property . type ( ) . name + " = " + property . value ( ) + " " + ( property . default_value ( ) = = property . value ( ) ? " (default) " : " " ) ) ;
}
} else if ( arguments . size ( ) < 4 ) {
const std : : shared_ptr < property : : PropertyDescription > & property_info = property : : info < property : : PlaylistProperties > ( arguments [ 2 ] ) ;
if ( ! property_info | | property_info - > type_property = = property : : PROP_TYPE_UNKNOWN | | property_info - > property_index = = property : : PLAYLIST_UNDEFINED ) {
send_message ( bot , " Unknown property " + arguments [ 2 ] + " . " ) ;
return true ;
}
auto prop = playlist - > properties ( ) [ ( property : : PlaylistProperties ) property_info - > property_index ] ;
send_message ( bot , " Bot property " + property_info - > name + " = " + prop . value ( ) + " " + ( property_info - > default_value = = prop . value ( ) ? " (default) " : " " ) ) ;
} else {
const std : : shared_ptr < property : : PropertyDescription > & property_info = property : : info < property : : PlaylistProperties > ( arguments [ 2 ] ) ;
if ( ! property_info | | property_info - > type_property = = property : : PROP_TYPE_UNKNOWN | | property_info - > property_index = = property : : PLAYLIST_UNDEFINED ) {
send_message ( bot , " Unknown property " + arguments [ 2 ] + " . " ) ;
return true ;
}
JOIN_ARGS ( value , 3 ) ;
if ( ! property_info - > validate_input ( value ) ) {
send_message ( bot , " Please enter a valid value! " ) ;
return true ;
}
if ( ( property_info - > flags & property : : FLAG_USER_EDITABLE ) = = 0 ) {
send_message ( bot , " This property isnt changeable! " ) ;
return true ;
}
playlist - > properties ( ) [ ( property : : PlaylistProperties ) property_info - > property_index ] = value ;
send_message ( bot , " Property successfully changed " ) ;
return true ;
}
} else {
send_message ( bot , " Please enter a valid setting mode " ) ;
}
return true ;
}
} else if ( command = = " help " ) {
//send_message(serverInstance->musicRoot(), " ̶.̶̶m̶̶b̶̶o̶̶t̶̶ ̶̶f̶̶o̶̶r̶̶m̶̶a̶̶t̶̶s (Not supported yet)");
stringstream ss ;
ss < < " Available music bot commands: ([color=green]green[/color] = permission granted | [color=red]red[/color] = insufficient permissions) " < < endl ;
2020-01-26 14:21:34 +01:00
bool has_list_server = permission : : v2 : : permission_granted ( 1 , this - > calculate_permission ( permission : : b_client_music_server_list , this - > getChannelId ( ) ) ) ;
bool has_list_channel = permission : : v2 : : permission_granted ( 1 , this - > calculate_permission ( permission : : b_client_music_channel_list , this - > getChannelId ( ) ) ) ;
2019-07-17 19:37:18 +02:00
permissionableCommand ( this , ss , string ( ) + " .mbot list [<[color= " + ( has_list_server ? " green " : " red " ) + " ]server[/color]|[color= " + ( has_list_channel ? " green " : " red " ) + " ]channel[/color]>] " , permission : : b_client_music_channel_list , permission : : b_client_music_server_list ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot select <id> " , permission : : b_client_music_channel_list , permission : : b_client_music_server_list ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot formats " , permission : : unknown ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot create " , permission : : b_client_music_create_temporary ) ; // [<type>]
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot info " , permission : : i_client_music_info ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot rename " , permission : : i_client_music_rename_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot delete " , permission : : i_client_music_delete_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot yt <video url> " , permission : : i_client_music_play_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot soundcloud <video url> " , permission : : i_client_music_play_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot stream <stream url> (For supported protocols|formats see ' " + ts : : config : : music : : command_prefix + " mbot formats') " , permission : : i_client_music_play_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot player <provider> <data> " , permission : : i_client_music_play_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot play " , permission : : i_client_music_play_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot play <url> " , permission : : i_client_music_play_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot volume <0-100> " , permission : : i_client_music_play_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot forward <seconds> " , permission : : i_client_music_play_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot rewind <seconds> " , permission : : i_client_music_play_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot pause " , permission : : i_client_music_play_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot stop " , permission : : i_client_music_play_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot next " , permission : : i_client_music_play_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot <playlist|pl> " , permission : : i_client_music_play_power ) ;
permissionableCommand ( this , ss , " " + ts : : config : : music : : command_prefix + " mbot settings <playlist|bot> [name] [value] " , permission : : i_client_music_modify_power ) ;
send_message ( serverInstance - > musicRoot ( ) , ss . str ( ) ) ;
return true ;
} else if ( command = = " dummy " ) {
if ( TARG ( 0 , " timerevent " ) ) {
send_message ( _this . lock ( ) , " Sending command dummy_timerevent " ) ;
this - > sendCommand ( Command ( " dummy_timerevent " ) ) ;
return true ;
} else if ( TARG ( 0 , " rd " ) ) {
send_message ( _this . lock ( ) , " Sending command rd " ) ;
Command cmd ( " rd " ) ;
cmd [ " msg " ] = " Hello world " ;
this - > sendCommand ( cmd ) ;
return true ;
} else if ( TARG ( 0 , " connectfailed " ) ) {
send_message ( _this . lock ( ) , " Sending command dummy_connectfailed " ) ;
Command cmd ( " dummy_connectfailed " ) ;
cmd [ " status " ] = 1797 ;
this - > sendCommand ( cmd ) ;
return true ;
}
send_message ( _this . lock ( ) , " Invalid dummy command! " ) ;
send_message ( _this . lock ( ) , " - timerevent " ) ;
send_message ( _this . lock ( ) , " - connectfailed " ) ;
send_message ( _this . lock ( ) , " - rd " ) ;
return true ;
} else if ( command = = " protocol " ) {
if ( TARG ( 0 , " generation " ) ) {
auto vc = dynamic_pointer_cast < VoiceClient > ( _this . lock ( ) ) ;
if ( ! vc ) return false ;
send_message ( _this . lock ( ) , " Packet generations: " ) ;
for ( const auto & type : {
protocol : : PacketTypeInfo : : Command ,
protocol : : PacketTypeInfo : : CommandLow ,
protocol : : PacketTypeInfo : : Ack ,
protocol : : PacketTypeInfo : : AckLow ,
protocol : : PacketTypeInfo : : Voice ,
protocol : : PacketTypeInfo : : VoiceWhisper ,
protocol : : PacketTypeInfo : : Ping ,
protocol : : PacketTypeInfo : : Pong } ) {
auto id = vc - > getConnection ( ) - > getPacketIdManager ( ) . currentPacketId ( type ) ;
auto gen = vc - > getConnection ( ) - > getPacketIdManager ( ) . generationId ( type ) ;
send_message ( _this . lock ( ) , " OUT " + type . name ( ) + " => generation: " + to_string ( gen ) + " id: " + to_string ( id ) ) ;
auto & buffer = vc - > getConnection ( ) - > packet_buffers ( ) [ type . type ( ) ] ;
send_message ( _this . lock ( ) , " IN " + type . name ( ) + " => generation: " + to_string ( buffer . generation ( 0 ) ) + " id: " + to_string ( buffer . current_index ( ) ) ) ;
}
return true ;
} else if ( TARG ( 0 , " disconnect " ) ) {
auto vc = dynamic_pointer_cast < VoiceClient > ( _this . lock ( ) ) ;
if ( ! vc ) return false ;
send_message ( _this . lock ( ) , " You'll timeout " ) ;
2020-01-24 02:57:58 +01:00
Command cmd ( " notifyclientupdated " ) ;
vc - > sendCommand ( cmd ) ;
2019-07-17 19:37:18 +02:00
return true ;
} else if ( TARG ( 0 , " resetip " ) ) {
auto vc = dynamic_pointer_cast < VoiceClient > ( _this . lock ( ) ) ;
if ( ! vc ) return false ;
send_message ( _this . lock ( ) , " I lost your IP address. I'm so dump :) " ) ;
memset ( & vc - > remote_address , 0 , sizeof ( vc - > remote_address ) ) ;
memset ( & vc - > address_info , 0 , sizeof ( vc - > address_info ) ) ;
send_message ( _this . lock ( ) , " Hey, we got the address back " ) ;
return true ;
} else if ( TARG ( 0 , " fb " ) ) {
this - > increaseFloodPoints ( 0xFF8F ) ;
send_message ( _this . lock ( ) , " Done :) " ) ;
return true ;
2019-10-20 12:09:28 +02:00
} else if ( TARG ( 0 , " binary " ) ) {
2020-01-24 02:57:58 +01:00
send_message ( _this . lock ( ) , " Send binary message " ) ;
this - > sendCommand ( Command { " \02 \03 \04 \22 " } ) ;
return true ;
2019-07-17 19:37:18 +02:00
}
send_message ( _this . lock ( ) , " Invalid protocol command! " ) ;
send_message ( _this . lock ( ) , " - generation " ) ;
send_message ( _this . lock ( ) , " - disconnect " ) ;
send_message ( _this . lock ( ) , " - resetip " ) ;
send_message ( _this . lock ( ) , " - fb " ) ;
return true ;
} else if ( command = = " sleep " ) {
if ( arguments . empty ( ) | | arguments [ 0 ] . find_first_not_of ( " 0123456789 " ) ! = string : : npos ) {
send_message ( _this . lock ( ) , " Invalid argument! Requires a number in ms. " ) ;
return true ;
}
send_message ( _this . lock ( ) , " Sleeping for " + to_string ( stoll ( arguments [ 0 ] ) ) + " ! " ) ;
auto end = system_clock : : now ( ) + milliseconds ( stoll ( arguments [ 0 ] ) ) ;
threads : : self : : sleep_until ( end ) ;
send_message ( _this . lock ( ) , " Done! " ) ;
return true ;
2019-07-19 22:55:03 +02:00
} else if ( command = = " conversation " ) {
if ( TARG ( 0 , " history " ) ) {
system_clock : : time_point timestamp_begin = system_clock : : now ( ) ;
system_clock : : time_point timestamp_end ;
size_t message_count = 100 ;
if ( arguments . size ( ) > 1 ) {
timestamp_begin - = seconds ( stoll ( arguments [ 1 ] ) ) ;
}
if ( arguments . size ( ) > 2 ) {
timestamp_end = system_clock : : now ( ) - seconds ( stoll ( arguments [ 2 ] ) ) ;
}
if ( arguments . size ( ) > 3 ) {
message_count = stoll ( arguments [ 3 ] ) ;
}
auto time_str = [ ] ( const system_clock : : time_point & tp ) {
using system_clock_duration = std : : chrono : : system_clock : : duration ;
auto converted_timep = std : : chrono : : time_point_cast < system_clock_duration > ( tp ) ;
auto seconds_since_epoch = std : : chrono : : system_clock : : to_time_t ( tp ) ;
ostringstream os ;
os < < std : : put_time ( std : : localtime ( & seconds_since_epoch ) , " %Y %b %d %H:%M:%S " ) ;
return os . str ( ) ;
} ;
send_message ( _this . lock ( ) , " Looking up history from " + time_str ( timestamp_end ) + " to " + time_str ( timestamp_begin ) + " . Max messages: " + to_string ( message_count ) ) ;
auto conversation = this - > server - > conversation_manager ( ) - > get_or_create ( this - > currentChannel - > channelId ( ) ) ;
auto data = conversation - > message_history ( timestamp_begin , message_count , timestamp_end ) ;
send_message ( _this . lock ( ) , " Entries: " + to_string ( data . size ( ) ) ) ;
for ( auto & entry : data ) {
send_message ( _this . lock ( ) , " < " + time_str ( entry - > message_timestamp ) + " > " + entry - > sender_name + " : " + entry - > message ) ;
}
return true ;
}
2019-07-17 19:37:18 +02:00
}
send_message ( serverInstance - > musicRoot ( ) , " Invalid channel command. " ) ;
send_message ( serverInstance - > musicRoot ( ) , " Type " + ts : : config : : music : : command_prefix + " help for a command overview " ) ;
return false ;
}