2018-02-27 16:20:49 +00:00
/// <reference path="ui/channel.ts" />
/// <reference path="client.ts" />
class CommandResult {
success : boolean ;
id : number ;
message : string ;
extra_message : string ;
json : any ;
constructor ( json ) {
this . json = json ;
this . id = json [ "id" ] ;
this . message = json [ "msg" ] ;
this . extra_message = "" ;
if ( json [ "extra_msg" ] ) this . extra_message = json [ "extra_msg" ] ;
this . success = this . id == 0 ;
}
}
class ReturnListener < T > {
resolve : ( value? : T | PromiseLike < T > ) = > void ;
reject : ( reason? : any ) = > void ;
code : string ;
timeout : NodeJS.Timer ;
}
class ServerConnection {
_client : TSClient ;
2018-06-20 19:05:35 +00:00
_remote_address : ServerAddress ;
2018-02-27 16:20:49 +00:00
_socket : WebSocket ;
2018-03-07 18:06:52 +00:00
_connectionState : ConnectionState = ConnectionState . UNCONNECTED ;
2018-04-11 15:56:09 +00:00
_handshakeHandler : HandshakeHandler ;
2018-02-27 16:20:49 +00:00
commandHandler : ConnectionCommandHandler ;
2018-03-07 18:06:52 +00:00
private _connectTimeoutHandler : NodeJS.Timer = undefined ;
2018-04-18 14:25:10 +00:00
private _connected : boolean = false ;
2018-02-27 16:20:49 +00:00
private _retCodeIdx : number ;
private _retListener : ReturnListener < CommandResult > [ ] ;
constructor ( client : TSClient ) {
this . _client = client ;
this . _socket = null ;
this . commandHandler = new ConnectionCommandHandler ( this ) ;
this . _retCodeIdx = 0 ;
this . _retListener = [ ] ;
}
on_connect : ( ) = > void = ( ) = > {
2018-04-11 15:56:09 +00:00
console . log ( "Socket connected" ) ;
chat . serverChat ( ) . appendMessage ( "Logging in..." ) ;
this . _handshakeHandler . startHandshake ( ) ;
2018-02-27 16:20:49 +00:00
} ;
private generateReturnCode ( ) : string {
return ( this . _retCodeIdx ++ ) . toString ( ) ;
}
2018-06-20 19:05:35 +00:00
startConnection ( address : ServerAddress , handshake : HandshakeHandler , timeout : number = 1000 ) {
2018-03-07 18:06:52 +00:00
if ( this . _connectTimeoutHandler ) {
clearTimeout ( this . _connectTimeoutHandler ) ;
this . _connectTimeoutHandler = null ;
this . disconnect ( ) ;
}
this . updateConnectionState ( ConnectionState . CONNECTING ) ;
2018-06-20 19:05:35 +00:00
this . _remote_address = address ;
2018-04-11 15:56:09 +00:00
this . _handshakeHandler = handshake ;
this . _handshakeHandler . setConnection ( this ) ;
2018-04-18 14:25:10 +00:00
this . _connected = false ;
2018-06-20 19:05:35 +00:00
chat . serverChat ( ) . appendMessage ( "Connecting to " + address . host + ":" + address . port ) ;
2018-02-27 16:20:49 +00:00
const self = this ;
try {
2018-03-07 18:06:52 +00:00
this . _connectTimeoutHandler = setTimeout ( ( ) = > {
this . disconnect ( ) ;
this . _client . handleDisconnect ( DisconnectReason . CONNECT_FAILURE ) ;
} , timeout ) ;
2018-04-11 15:56:09 +00:00
let sockCpy ;
2018-06-20 19:05:35 +00:00
this . _socket = ( sockCpy = new WebSocket ( 'wss:' + address . host + ":" + address . port ) ) ;
2018-03-07 18:06:52 +00:00
clearTimeout ( this . _connectTimeoutHandler ) ;
this . _connectTimeoutHandler = null ;
2018-04-11 15:56:09 +00:00
if ( this . _socket != sockCpy ) return ; //Connect timeouted
2018-03-07 19:14:36 +00:00
this . _socket . onopen = ( ) = > {
2018-04-11 15:56:09 +00:00
if ( this . _socket != sockCpy ) return ;
2018-04-18 14:25:10 +00:00
this . _connected = true ;
2018-03-07 19:14:36 +00:00
this . on_connect ( ) ;
2018-02-27 16:20:49 +00:00
} ;
2018-03-07 18:06:52 +00:00
this . _socket . onclose = event = > {
2018-04-11 15:56:09 +00:00
if ( this . _socket != sockCpy ) return ;
2018-04-18 14:25:10 +00:00
this . _client . handleDisconnect ( this . _connected ? DisconnectReason.CONNECTION_CLOSED : DisconnectReason.CONNECT_FAILURE , {
2018-03-07 18:06:52 +00:00
code : event.code ,
reason : event.reason ,
event : event
} ) ;
2018-02-27 16:20:49 +00:00
} ;
2018-03-07 19:14:36 +00:00
this . _socket . onerror = e = > {
2018-04-11 15:56:09 +00:00
if ( this . _socket != sockCpy ) return ;
2018-02-27 16:20:49 +00:00
console . log ( "Got error: (" + self . _socket . readyState + ")" ) ;
console . log ( e ) ;
} ;
2018-03-07 19:14:36 +00:00
this . _socket . onmessage = msg = > {
2018-04-11 15:56:09 +00:00
if ( this . _socket != sockCpy ) return ;
2018-03-07 18:06:52 +00:00
self . handleWebSocketMessage ( msg . data ) ;
2018-02-27 16:20:49 +00:00
} ;
2018-03-07 18:06:52 +00:00
this . updateConnectionState ( ConnectionState . INITIALISING ) ;
2018-02-27 16:20:49 +00:00
} catch ( e ) {
2018-03-07 18:06:52 +00:00
this . disconnect ( ) ;
this . _client . handleDisconnect ( DisconnectReason . CONNECT_FAILURE , e ) ;
2018-02-27 16:20:49 +00:00
}
}
2018-03-07 18:06:52 +00:00
updateConnectionState ( state : ConnectionState ) {
this . _connectionState = state ;
}
2018-03-07 19:14:36 +00:00
disconnect ( ) : boolean {
if ( this . _connectionState == ConnectionState . UNCONNECTED ) return false ;
this . updateConnectionState ( ConnectionState . UNCONNECTED ) ;
2018-03-07 18:06:52 +00:00
2018-03-07 19:14:36 +00:00
if ( this . _socket ) this . _socket . close ( 3000 + 0xFF , "request disconnect" ) ;
2018-02-27 16:20:49 +00:00
this . _socket = null ;
2018-03-07 18:06:52 +00:00
for ( let future of this . _retListener )
future . reject ( "Connection closed" ) ;
this . _retListener = [ ] ;
this . _retCodeIdx = 0 ;
2018-04-18 14:25:10 +00:00
this . _connected = false ;
2018-03-07 19:14:36 +00:00
return true ;
2018-02-27 16:20:49 +00:00
}
2018-03-07 18:06:52 +00:00
private handleWebSocketMessage ( data ) {
2018-02-27 16:20:49 +00:00
if ( typeof ( data ) === "string" ) {
2018-03-07 18:06:52 +00:00
let json ;
2018-02-27 16:20:49 +00:00
try {
json = JSON . parse ( data ) ;
} catch ( e ) {
console . error ( "Could not parse message json!" ) ;
alert ( e ) ; // error in the above string (in this case, yes)!
return ;
}
if ( json [ "type" ] === undefined ) {
console . log ( "Missing data type!" ) ;
return ;
}
if ( json [ "type" ] === "command" ) this . handleCommand ( json ) ;
else if ( json [ "type" ] === "WebRTC" ) this . _client . voiceConnection . handleControlPacket ( json ) ;
else {
console . log ( "Unknown command type " + json [ "type" ] ) ;
}
}
}
handleCommand ( json ) {
2018-04-16 18:38:35 +00:00
let group = log . group ( log . LogType . DEBUG , LogCategory . NETWORKING , "Handling command '%s'" , json [ "command" ] ) ;
group . log ( "Handling command '" + json [ "command" ] + "'" ) ;
group . group ( log . LogType . TRACE , "Json:" ) . collapsed ( true ) . log ( "%o" , json ) . end ( ) ;
2018-02-27 16:20:49 +00:00
2018-04-16 18:38:35 +00:00
try {
let fn = this . commandHandler [ json [ "command" ] ] ;
if ( fn === undefined ) {
group . log ( "Missing command '" + json [ "command" ] + "'" ) ;
return ;
}
fn . call ( this . commandHandler , json [ "data" ] ) ;
} finally {
group . end ( ) ;
2018-02-27 16:20:49 +00:00
}
}
2018-03-07 18:06:52 +00:00
sendData ( data : any ) { //TODO check stuff?
this . _socket . send ( data ) ;
2018-02-27 16:20:49 +00:00
}
2018-04-16 18:38:35 +00:00
private commandiefy ( input : any ) : string {
return JSON . stringify ( input , ( key , value ) = > {
switch ( typeof value ) {
case "boolean" : return value == true ? "1" : "0" ;
case "function" : return value ( ) ;
default :
return value ;
}
} ) ;
}
2018-08-10 19:30:58 +00:00
sendCommand ( command : string , data : any = { } , flags : string [ ] = [ ] , logResult : boolean = true ) : Promise < CommandResult > {
2018-02-27 16:20:49 +00:00
const _this = this ;
let result = new Promise < CommandResult > ( ( resolve , failed ) = > {
let _data = $ . isArray ( data ) ? data : [ data ] ;
let retCode = _data [ 0 ] [ "return_code" ] !== undefined ? _data [ 0 ] . return_code : _this.generateReturnCode ( ) ;
_data [ 0 ] . return_code = retCode ;
let listener = new ReturnListener < CommandResult > ( ) ;
listener . resolve = resolve ;
listener . reject = failed ;
listener . code = retCode ;
listener . timeout = setTimeout ( ( ) = > {
_this . _retListener . remove ( listener ) ;
listener . reject ( "timeout" ) ;
} , 1500 ) ;
this . _retListener . push ( listener ) ;
2018-04-16 18:38:35 +00:00
this . _socket . send ( this . commandiefy ( {
2018-02-27 16:20:49 +00:00
"type" : "command" ,
"command" : command ,
2018-08-10 19:30:58 +00:00
"data" : _data ,
"flags" : flags
2018-02-27 16:20:49 +00:00
} ) ) ;
} ) ;
return new Promise < CommandResult > ( ( resolve , failed ) = > {
result . then ( resolve ) . catch ( ex = > {
if ( logResult ) {
if ( ex instanceof CommandResult ) {
let res = ex ;
if ( ! res . success ) {
2018-08-10 19:30:58 +00:00
if ( res . id == 2568 ) { //Permission error
chat . serverChat ( ) . appendError ( "insufficient client permissions. Failed on permission {}" , this . _client . permissions . resolveInfo ( res . json [ "failed_permid" ] as number ) . name ) ;
} else {
chat . serverChat ( ) . appendError ( res . extra_message . length == 0 ? res.message : res.extra_message ) ;
}
2018-02-27 16:20:49 +00:00
}
} else if ( typeof ( ex ) == "string" ) {
2018-08-10 19:30:58 +00:00
chat . serverChat ( ) . appendError ( "Command execution results in " + ex ) ;
2018-02-27 16:20:49 +00:00
} else {
console . error ( "Invalid promise result type: " + typeof ( ex ) + ". Result:" ) ;
console . error ( ex ) ;
}
}
failed ( ex ) ;
} )
} ) ;
}
get connected ( ) : boolean {
return this . _socket && this . _socket . readyState == WebSocket . OPEN ;
}
/ * *
* HELPER METHODS
* /
joinChannel ( channel : ChannelEntry , password : string = "" ) : Promise < CommandResult > {
return this . sendCommand ( "clientmove" , [ {
"clid" : this . _client . getClientId ( ) ,
"cid" : channel . getChannelId ( ) ,
"cpw" : password
} ] )
}
sendMessage ( message : string , type : ChatType , target? : ChannelEntry | ClientEntry ) : Promise < CommandResult > {
if ( type == ChatType . SERVER )
return this . sendCommand ( "sendtextmessage" , { "targetmode" : 3 , "target" : 0 , "msg" : message } ) ;
else if ( type == ChatType . CHANNEL )
return this . sendCommand ( "sendtextmessage" , { "targetmode" : 2 , "target" : ( target as ChannelEntry ) . getChannelId ( ) , "msg" : message } ) ;
else if ( type == ChatType . CLIENT )
return this . sendCommand ( "sendtextmessage" , { "targetmode" : 1 , "target" : ( target as ClientEntry ) . clientId ( ) , "msg" : message } ) ;
}
updateClient ( key : string , value : string ) : Promise < CommandResult > {
2018-03-07 18:06:52 +00:00
let data = { } ;
2018-02-27 16:20:49 +00:00
data [ key ] = value ;
return this . sendCommand ( "clientupdate" , data ) ;
}
}
2018-04-11 15:56:09 +00:00
class HandshakeHandler {
readonly identity : Identity ;
readonly name? : string ;
private connection : ServerConnection ;
constructor ( identity : Identity , name? : string ) {
this . identity = identity ;
this . name = name ;
}
setConnection ( con : ServerConnection ) {
this . connection = con ;
this . connection . commandHandler [ "handshakeidentityproof" ] = this . handleCommandHandshakeIdentityProof . bind ( this ) ;
}
startHandshake() {
let data : any = {
intention : 0 ,
authentication_method : this.identity.type ( )
} ;
if ( this . identity . type ( ) == IdentitifyType . TEAMSPEAK ) {
data . publicKey = ( this . identity as TeamSpeakIdentity ) . publicKey ( ) ;
} else if ( this . identity . type ( ) == IdentitifyType . TEAFORO ) {
data . data = ( this . identity as TeaForumIdentity ) . identityDataJson ;
2018-09-21 21:25:03 +00:00
} else if ( this . identity . type ( ) == IdentitifyType . NICKNAME ) {
data [ "client_nickname" ] = this . identity . name ( ) ;
2018-04-11 15:56:09 +00:00
}
this . connection . sendCommand ( "handshakebegin" , data ) . catch ( error = > {
console . log ( error ) ;
//TODO here
2018-09-21 21:25:03 +00:00
} ) . then ( ( ) = > {
if ( this . identity . type ( ) == IdentitifyType . NICKNAME ) {
this . handshake_finished ( ) ;
}
2018-04-11 15:56:09 +00:00
} ) ;
}
private handleCommandHandshakeIdentityProof ( json ) {
let proof : string ;
if ( this . identity . type ( ) == IdentitifyType . TEAMSPEAK ) {
proof = ( this . identity as TeamSpeakIdentity ) . signMessage ( json [ 0 ] [ "message" ] ) ;
} else if ( this . identity . type ( ) == IdentitifyType . TEAFORO ) {
proof = ( this . identity as TeaForumIdentity ) . identitySign ;
2018-09-21 21:25:03 +00:00
} else if ( this . identity . type ( ) == IdentitifyType . NICKNAME ) {
//FIXME handle error this should never happen!
2018-04-11 15:56:09 +00:00
}
this . connection . sendCommand ( "handshakeindentityproof" , { proof : proof } ) . then ( ( ) = > {
2018-09-21 21:25:03 +00:00
this . handshake_finished ( ) ;
2018-04-11 15:56:09 +00:00
} ) . catch ( error = > {
console . error ( "Got login error" ) ;
console . log ( error ) ;
} ) ; //TODO handle error
}
2018-09-21 21:25:03 +00:00
private handshake_finished() {
this . connection . sendCommand ( "clientinit" , {
//TODO variables!
client_nickname : this.name ? this . name : this.identity.name ( ) ,
client_platform : navigator.platform ,
client_version : navigator.userAgent ,
//client_browser_engine: navigator.product
} ) ;
}
2018-04-11 15:56:09 +00:00
}
2018-02-27 16:20:49 +00:00
class ConnectionCommandHandler {
2018-03-07 18:06:52 +00:00
readonly connection : ServerConnection ;
2018-02-27 16:20:49 +00:00
constructor ( connection ) {
this . connection = connection ;
this [ "error" ] = this . handleCommandResult ;
this [ "channellist" ] = this . handleCommandChannelList ;
this [ "notifychannelcreated" ] = this . handleCommandChannelCreate ;
this [ "notifychanneldeleted" ] = this . handleCommandChannelDelete ;
2018-08-10 09:27:03 +00:00
this [ "notifychannelhide" ] = this . handleCommandChannelHide ;
this [ "notifychannelshow" ] = this . handleCommandChannelShow ;
2018-02-27 16:20:49 +00:00
this [ "notifycliententerview" ] = this . handleCommandClientEnterView ;
this [ "notifyclientleftview" ] = this . handleCommandClientLeftView ;
this [ "notifyclientmoved" ] = this . handleNotifyClientMoved ;
this [ "initserver" ] = this . handleCommandServerInit ;
this [ "notifychannelmoved" ] = this . handleNotifyChannelMoved ;
this [ "notifychanneledited" ] = this . handleNotifyChannelEdited ;
this [ "notifytextmessage" ] = this . handleNotifyTextMessage ;
this [ "notifyclientupdated" ] = this . handleNotifyClientUpdated ;
this [ "notifyserveredited" ] = this . handleNotifyServerEdited ;
this [ "notifyserverupdated" ] = this . handleNotifyServerUpdated ;
2018-08-10 19:30:58 +00:00
this [ "notifymusicplayerinfo" ] = this . handleNotifyMusicPlayerInfo ;
2018-02-27 16:20:49 +00:00
}
handleCommandResult ( json ) {
json = json [ 0 ] ; //Only one bulk
let code : string = json [ "return_code" ] ;
if ( code . length == 0 ) {
console . log ( "Invalid return code! (" + json + ")" ) ;
return ;
}
let retListeners = this . connection [ "_retListener" ] ;
for ( let e of retListeners ) {
if ( e . code != code ) continue ;
retListeners . remove ( e ) ;
let result = new CommandResult ( json ) ;
if ( result . success )
e . resolve ( result ) ;
else
e . reject ( result ) ;
break ;
}
}
handleCommandServerInit ( json ) {
//We could setup the voice channel
2018-03-07 18:06:52 +00:00
console . log ( "Setting up voice " ) ;
2018-02-27 16:20:49 +00:00
this . connection . _client . voiceConnection . createSession ( ) ;
json = json [ 0 ] ; //Only one bulk
2018-04-16 18:38:35 +00:00
this . connection . _client . clientId = parseInt ( json [ "aclid" ] ) ;
this . connection . _client . getClient ( ) . updateVariables ( { key : "client_nickname" , value : json [ "acn" ] } ) ;
2018-02-27 16:20:49 +00:00
2018-06-20 19:05:35 +00:00
let updates : {
key : string ,
value : string
} [ ] = [ ] ;
2018-02-27 16:20:49 +00:00
for ( let key in json ) {
if ( key === "aclid" ) continue ;
if ( key === "acn" ) continue ;
2018-06-20 19:05:35 +00:00
updates . push ( { key : key , value : json [ key ] } ) ;
2018-02-27 16:20:49 +00:00
}
2018-08-13 09:03:55 +00:00
this . connection . _client . channelTree . server . updateVariables ( false , . . . updates ) ;
2018-06-20 19:05:35 +00:00
2018-02-27 16:20:49 +00:00
chat . serverChat ( ) . name = this . connection . _client . channelTree . server . properties [ "virtualserver_name" ] ;
chat . serverChat ( ) . appendMessage ( "Connected as {0}" , true , this . connection . _client . getClient ( ) . createChatTag ( true ) ) ;
2018-04-11 15:56:09 +00:00
globalClient . onConnected ( ) ;
2018-02-27 16:20:49 +00:00
}
private createChannelFromJson ( json , ignoreOrder : boolean = false ) {
let tree = this . connection . _client . channelTree ;
2018-04-16 18:38:35 +00:00
let channel = new ChannelEntry ( parseInt ( json [ "cid" ] ) , json [ "channel_name" ] , tree . findChannel ( json [ "cpid" ] ) ) ;
2018-02-27 16:20:49 +00:00
tree . insertChannel ( channel ) ;
if ( json [ "channel_order" ] !== "0" ) {
let prev = tree . findChannel ( json [ "channel_order" ] ) ;
if ( ! prev && json [ "channel_order" ] != 0 ) {
if ( ! ignoreOrder ) {
console . error ( "Invalid channel order id!" ) ;
return ;
}
}
let parent = tree . findChannel ( json [ "cpid" ] ) ;
if ( ! parent && json [ "cpid" ] != 0 ) {
console . error ( "Invalid channel parent" ) ;
return ;
}
tree . moveChannel ( channel , prev , parent ) ; //TODO test if channel exists!
}
if ( ignoreOrder ) {
for ( let ch of tree . channels ) {
if ( ch . properties . channel_order == channel . channelId ) {
tree . moveChannel ( ch , channel , channel . parent ) ; //Corrent the order :)
}
}
}
2018-04-16 18:38:35 +00:00
let updates : {
key : string ,
value : string
} [ ] = [ ] ;
2018-02-27 16:20:49 +00:00
for ( let key in json ) {
if ( key === "cid" ) continue ;
if ( key === "cpid" ) continue ;
if ( key === "invokerid" ) continue ;
if ( key === "invokername" ) continue ;
if ( key === "invokeruid" ) continue ;
if ( key === "reasonid" ) continue ;
2018-04-16 18:38:35 +00:00
updates . push ( { key : key , value : json [ key ] } ) ;
2018-02-27 16:20:49 +00:00
}
2018-04-16 18:38:35 +00:00
channel . updateVariables ( . . . updates ) ;
2018-02-27 16:20:49 +00:00
}
handleCommandChannelList ( json ) {
console . log ( "Got " + json . length + " new channels" ) ;
for ( let index = 0 ; index < json . length ; index ++ )
this . createChannelFromJson ( json [ index ] , true ) ;
}
handleCommandChannelCreate ( json ) {
this . createChannelFromJson ( json [ 0 ] ) ;
}
2018-08-10 09:27:03 +00:00
handleCommandChannelShow ( json ) {
this . createChannelFromJson ( json [ 0 ] ) ; //TODO may chat?
}
2018-02-27 16:20:49 +00:00
handleCommandChannelDelete ( json ) {
let tree = this . connection . _client . channelTree ;
console . log ( "Got " + json . length + " channel deletions" ) ;
for ( let index = 0 ; index < json . length ; index ++ ) {
let channel = tree . findChannel ( json [ index ] [ "cid" ] ) ;
if ( ! channel ) {
console . error ( "Invalid channel onDelete (Unknown channel)" ) ;
continue ;
}
tree . deleteChannel ( channel ) ;
}
}
2018-08-10 09:27:03 +00:00
handleCommandChannelHide ( json ) {
let tree = this . connection . _client . channelTree ;
console . log ( "Got " + json . length + " channel hides" ) ;
for ( let index = 0 ; index < json . length ; index ++ ) {
let channel = tree . findChannel ( json [ index ] [ "cid" ] ) ;
if ( ! channel ) {
console . error ( "Invalid channel on hide (Unknown channel)" ) ;
continue ;
}
tree . deleteChannel ( channel ) ;
}
}
2018-02-27 16:20:49 +00:00
handleCommandClientEnterView ( json ) {
json = json [ 0 ] ; //Only one bulk
let tree = this . connection . _client . channelTree ;
let client : ClientEntry ;
let channel = tree . findChannel ( json [ "ctid" ] ) ;
let old_channel = tree . findChannel ( json [ "cfid" ] ) ;
client = tree . findClient ( json [ "clid" ] ) ;
if ( ! client ) {
2018-04-30 21:57:21 +00:00
if ( parseInt ( json [ "client_type_exact" ] ) == ClientType . CLIENT_MUSIC ) {
client = new MusicClientEntry ( parseInt ( json [ "clid" ] ) , json [ "client_nickname" ] ) ;
} else {
client = new ClientEntry ( parseInt ( json [ "clid" ] ) , json [ "client_nickname" ] ) ;
}
2018-02-27 16:20:49 +00:00
client = tree . insertClient ( client , channel ) ;
} else {
2018-03-07 19:14:36 +00:00
if ( client == this . connection . _client . getClient ( ) )
2018-02-27 16:20:49 +00:00
chat . channelChat ( ) . name = channel . channelName ( ) ;
tree . moveClient ( client , channel ) ;
}
if ( json [ "reasonid" ] == ViewReasonId . VREASON_USER_ACTION ) {
if ( old_channel ) {
chat . serverChat ( ) . appendMessage ( "{0} appeared from {1} to {2}" , true , client . createChatTag ( true ) , old_channel . createChatTag ( true ) , channel . createChatTag ( true ) ) ;
} else {
chat . serverChat ( ) . appendMessage ( "{0} connected to channel {1}" , true , client . createChatTag ( true ) , channel . createChatTag ( true ) ) ;
}
}
2018-04-16 18:38:35 +00:00
let updates : {
key : string ,
value : string
} [ ] = [ ] ;
2018-02-27 16:20:49 +00:00
for ( let key in json ) {
if ( key == "cfid" ) continue ;
if ( key == "ctid" ) continue ;
if ( key === "invokerid" ) continue ;
if ( key === "invokername" ) continue ;
if ( key === "invokeruid" ) continue ;
if ( key === "reasonid" ) continue ;
2018-04-16 18:38:35 +00:00
updates . push ( { key : key , value : json [ key ] } ) ;
2018-02-27 16:20:49 +00:00
}
2018-04-16 18:38:35 +00:00
client . updateVariables ( . . . updates ) ;
2018-04-30 21:57:21 +00:00
if ( client instanceof LocalClientEntry )
this . connection . _client . controlBar . updateVoice ( ) ;
2018-02-27 16:20:49 +00:00
}
handleCommandClientLeftView ( json ) {
json = json [ 0 ] ; //Only one bulk
let tree = this . connection . _client . channelTree ;
let client = tree . findClient ( json [ "clid" ] ) ;
if ( ! client ) {
2018-05-09 09:50:05 +00:00
console . error ( "Unknown client left!" ) ;
2018-02-27 16:20:49 +00:00
return 0 ;
}
if ( client == this . connection . _client . getClient ( ) ) {
2018-03-07 18:06:52 +00:00
if ( json [ "reasonid" ] == ViewReasonId . VREASON_BAN )
this . connection . _client . handleDisconnect ( DisconnectReason . CLIENT_BANNED , json ) ;
else if ( json [ "reasonid" ] == ViewReasonId . VREASON_SERVER_KICK )
this . connection . _client . handleDisconnect ( DisconnectReason . CLIENT_KICKED , json ) ;
2018-03-24 22:38:01 +00:00
else if ( json [ "reasonid" ] == ViewReasonId . VREASON_SERVER_SHUTDOWN )
this . connection . _client . handleDisconnect ( DisconnectReason . SERVER_CLOSED , json ) ;
else if ( json [ "reasonid" ] == ViewReasonId . VREASON_SERVER_STOPPED )
this . connection . _client . handleDisconnect ( DisconnectReason . SERVER_CLOSED , json ) ;
2018-03-07 18:06:52 +00:00
else
this . connection . _client . handleDisconnect ( DisconnectReason . UNKNOWN , json ) ;
2018-02-27 16:20:49 +00:00
return ;
}
let channel_from = tree . findChannel ( json [ "cfid" ] ) ;
let channel_to = tree . findChannel ( json [ "ctid" ] ) ;
if ( json [ "reasonid" ] == ViewReasonId . VREASON_USER_ACTION ) {
chat . serverChat ( ) . appendMessage ( "{0} disappeared from {1} to {2}" , true , client . createChatTag ( true ) , channel_from . createChatTag ( true ) , channel_to . createChatTag ( true ) ) ;
} else if ( json [ "reasonid" ] == ViewReasonId . VREASON_SERVER_LEFT ) {
chat . serverChat ( ) . appendMessage ( "{0} left the server ({1})" , true , client . createChatTag ( true ) , json [ "reasonmsg" ] ) ;
} else if ( json [ "reasonid" ] == ViewReasonId . VREASON_SERVER_KICK ) {
chat . serverChat ( ) . appendError ( "{0} was kicked from the server by {1}. ({2})" ,
client . createChatTag ( true ) ,
ClientEntry . chatTag ( json [ "invokerid" ] , json [ "invokername" ] , json [ "invokeruid" ] ) ,
json [ "reasonmsg" ]
) ;
} else if ( json [ "reasonid" ] == ViewReasonId . VREASON_BAN ) {
//"Mulus" was banned for 1 second from the server by "WolverinDEV" (Sry brauchte kurz ein opfer :P <3 (Nohomo))
let duration = "permanently" ;
if ( json [ "bantime" ] )
duration = "for " + formatDate ( Number . parseInt ( json [ "bantime" ] ) ) ;
chat . serverChat ( ) . appendError ( "{0} was banned {1} by {2}. ({3})" ,
client . createChatTag ( true ) ,
duration ,
ClientEntry . chatTag ( json [ "invokerid" ] , json [ "invokername" ] , json [ "invokeruid" ] ) ,
json [ "reasonmsg" ]
) ;
} else {
2018-05-09 09:50:05 +00:00
console . error ( "Unknown client left reason!" ) ;
2018-02-27 16:20:49 +00:00
}
tree . deleteClient ( client ) ;
}
handleNotifyClientMoved ( json ) {
json = json [ 0 ] ; //Only one bulk
let tree = this . connection . _client . channelTree ;
let client = tree . findClient ( json [ "clid" ] ) ;
let channel_to = tree . findChannel ( json [ "ctid" ] ) ;
let channel_from = tree . findChannel ( json [ "cfid" ] ) ;
if ( ! client ) {
2018-05-09 09:50:05 +00:00
console . error ( "Unknown client move (Client)!" ) ;
2018-02-27 16:20:49 +00:00
return 0 ;
}
if ( ! channel_to ) {
2018-05-09 09:50:05 +00:00
console . error ( "Unknown client move (Channel to)!" ) ;
2018-02-27 16:20:49 +00:00
return 0 ;
}
if ( ! channel_from ) //Not critical
2018-05-09 09:50:05 +00:00
console . error ( "Unknown client move (Channel from)!" ) ;
2018-02-27 16:20:49 +00:00
2018-04-30 21:57:21 +00:00
let self = client instanceof LocalClientEntry ;
if ( self ) {
2018-03-07 19:14:36 +00:00
chat . channelChat ( ) . name = channel_to . channelName ( ) ;
2018-03-24 22:38:01 +00:00
for ( let entry of client . channelTree . clientsByChannel ( client . currentChannel ( ) ) )
if ( entry !== client ) entry . getAudioController ( ) . stopAudio ( true ) ;
2018-04-30 21:57:21 +00:00
this . connection . _client . controlBar . updateVoice ( channel_to ) ;
2018-03-24 22:38:01 +00:00
}
tree . moveClient ( client , channel_to ) ;
2018-03-07 19:14:36 +00:00
2018-02-27 16:20:49 +00:00
if ( json [ "reasonid" ] == ViewReasonId . VREASON_MOVED ) {
2018-04-30 21:57:21 +00:00
chat . serverChat ( ) . appendMessage ( self ? "You was moved by {3} from channel {1} to {2}" : "{0} was moved from channel {1} to {2} by {3}" , true ,
2018-02-27 16:20:49 +00:00
client . createChatTag ( true ) ,
channel_from ? channel_from . createChatTag ( true ) : undefined ,
channel_to . createChatTag ( true ) ,
ClientEntry . chatTag ( json [ "invokerid" ] , json [ "invokername" ] , json [ "invokeruid" ] )
) ;
} else if ( json [ "reasonid" ] == ViewReasonId . VREASON_USER_ACTION ) {
2018-04-30 21:57:21 +00:00
chat . serverChat ( ) . appendMessage ( self ? "You switched from channel {1} to {2}" : "{0} switched from channel {1} to {2}" , true ,
2018-02-27 16:20:49 +00:00
client . createChatTag ( true ) ,
channel_from ? channel_from . createChatTag ( true ) : undefined ,
channel_to . createChatTag ( true )
) ;
}
}
handleNotifyChannelMoved ( json ) {
json = json [ 0 ] ; //Only one bulk
for ( let key in json )
console . log ( "Key: " + key + " Value: " + json [ key ] ) ;
let tree = this . connection . _client . channelTree ;
let channel = tree . findChannel ( json [ "cid" ] ) ;
if ( ! channel ) {
console . error ( "Unknown channel move (Channel)!" ) ;
return 0 ;
}
let prev = tree . findChannel ( json [ "order" ] ) ;
if ( ! prev && json [ "order" ] != 0 ) {
console . error ( "Unknown channel move (prev)!" ) ;
return 0 ;
}
let parent = tree . findChannel ( json [ "cpid" ] ) ;
if ( ! parent && json [ "cpid" ] != 0 ) {
console . error ( "Unknown channel move (parent)!" ) ;
return 0 ;
}
tree . moveChannel ( channel , prev , parent ) ;
}
handleNotifyChannelEdited ( json ) {
json = json [ 0 ] ; //Only one bulk
let tree = this . connection . _client . channelTree ;
let channel = tree . findChannel ( json [ "cid" ] ) ;
if ( ! channel ) {
console . error ( "Unknown channel edit (Channel)!" ) ;
return 0 ;
}
2018-04-16 18:38:35 +00:00
let updates : {
key : string ,
value : string
} [ ] = [ ] ;
2018-02-27 16:20:49 +00:00
for ( let key in json ) {
if ( key === "cid" ) continue ;
if ( key === "invokerid" ) continue ;
if ( key === "invokername" ) continue ;
if ( key === "invokeruid" ) continue ;
if ( key === "reasonid" ) continue ;
2018-04-16 18:38:35 +00:00
updates . push ( { key : key , value : json [ key ] } ) ;
2018-02-27 16:20:49 +00:00
}
2018-04-16 18:38:35 +00:00
channel . updateVariables ( . . . updates ) ;
2018-02-27 16:20:49 +00:00
}
handleNotifyTextMessage ( json ) {
json = json [ 0 ] ; //Only one bulk
//TODO chat format?
let mode = json [ "targetmode" ] ;
if ( mode == 1 ) {
2018-04-11 15:56:09 +00:00
let invoker = this . connection . _client . channelTree . findClient ( json [ "invokerid" ] ) ;
let target = this . connection . _client . channelTree . findClient ( json [ "target" ] ) ;
if ( ! invoker ) { //TODO spawn chat (Client is may invisible)
2018-05-09 09:50:05 +00:00
console . error ( "Got private message from invalid client!" ) ;
2018-04-11 15:56:09 +00:00
return ;
}
if ( ! target ) { //TODO spawn chat (Client is may invisible)
2018-05-09 09:50:05 +00:00
console . error ( "Got private message from invalid client!" ) ;
2018-04-11 15:56:09 +00:00
return ;
}
2018-02-27 16:20:49 +00:00
if ( invoker == this . connection . _client . getClient ( ) ) {
target . chat ( true ) . appendMessage ( "<< " + json [ "msg" ] ) ;
} else {
invoker . chat ( true ) . appendMessage ( ">> " + json [ "msg" ] ) ;
}
} else if ( mode == 2 ) {
2018-04-11 15:56:09 +00:00
chat . channelChat ( ) . appendMessage ( "{0} >> {1}" , true , ClientEntry . chatTag ( json [ "invokerid" ] , json [ "invokername" ] , json [ "invokeruid" ] , true ) , json [ "msg" ] )
2018-02-27 16:20:49 +00:00
} else if ( mode == 3 ) {
2018-04-11 15:56:09 +00:00
chat . serverChat ( ) . appendMessage ( "{0} >> {1}" , true , ClientEntry . chatTag ( json [ "invokerid" ] , json [ "invokername" ] , json [ "invokeruid" ] , true ) , json [ "msg" ] ) ;
2018-02-27 16:20:49 +00:00
}
}
handleNotifyClientUpdated ( json ) {
json = json [ 0 ] ; //Only one bulk
let client = this . connection . _client . channelTree . findClient ( json [ "clid" ] ) ;
if ( ! client ) {
2018-05-09 09:50:05 +00:00
console . error ( "Tried to update an non existing client" ) ;
2018-02-27 16:20:49 +00:00
return ;
}
2018-04-16 18:38:35 +00:00
let updates : {
key : string ,
value : string
} [ ] = [ ] ;
2018-02-27 16:20:49 +00:00
for ( let key in json ) {
if ( key == "clid" ) continue ;
2018-04-16 18:38:35 +00:00
updates . push ( { key : key , value : json [ key ] } ) ;
2018-02-27 16:20:49 +00:00
}
2018-04-16 18:38:35 +00:00
client . updateVariables ( . . . updates ) ;
2018-02-27 16:20:49 +00:00
if ( this . connection . _client . selectInfo . currentSelected == client )
this . connection . _client . selectInfo . update ( ) ;
}
handleNotifyServerEdited ( json ) {
json = json [ 0 ] ;
2018-06-20 19:05:35 +00:00
let updates : {
key : string ,
value : string
} [ ] = [ ] ;
2018-02-27 16:20:49 +00:00
for ( let key in json ) {
if ( key === "invokerid" ) continue ;
if ( key === "invokername" ) continue ;
if ( key === "invokeruid" ) continue ;
if ( key === "reasonid" ) continue ;
2018-06-20 19:05:35 +00:00
updates . push ( { key : key , value : json [ key ] } ) ;
2018-02-27 16:20:49 +00:00
}
2018-08-13 09:03:55 +00:00
this . connection . _client . channelTree . server . updateVariables ( false , . . . updates ) ;
2018-06-20 19:05:35 +00:00
if ( this . connection . _client . selectInfo . currentSelected == this . connection . _client . channelTree . server )
this . connection . _client . selectInfo . update ( ) ;
2018-02-27 16:20:49 +00:00
}
handleNotifyServerUpdated ( json ) {
json = json [ 0 ] ;
2018-06-20 19:05:35 +00:00
let updates : {
key : string ,
value : string
} [ ] = [ ] ;
2018-02-27 16:20:49 +00:00
for ( let key in json ) {
if ( key === "invokerid" ) continue ;
if ( key === "invokername" ) continue ;
if ( key === "invokeruid" ) continue ;
if ( key === "reasonid" ) continue ;
2018-06-20 19:05:35 +00:00
updates . push ( { key : key , value : json [ key ] } ) ;
2018-02-27 16:20:49 +00:00
}
2018-08-13 09:03:55 +00:00
this . connection . _client . channelTree . server . updateVariables ( true , . . . updates ) ;
2018-02-27 16:20:49 +00:00
let info = this . connection . _client . selectInfo ;
if ( info . currentSelected instanceof ServerEntry )
info . update ( ) ;
}
2018-08-10 19:30:58 +00:00
handleNotifyMusicPlayerInfo ( json ) {
json = json [ 0 ] ;
let bot = this . connection . _client . channelTree . find_client_by_dbid ( json [ "botid" ] ) ;
if ( ! bot || ! ( bot instanceof MusicClientEntry ) ) {
log . warn ( LogCategory . CLIENT , "Got music player info for unknown or invalid bot! (ID: %i, Entry: %o)" , json [ "botid" ] , bot ) ;
return ;
}
bot . handlePlayerInfo ( json ) ;
}
2018-02-27 16:20:49 +00:00
}