@ -2,7 +2,8 @@ if(typeof process === 'object') {
// node.js only
var Channel = require ( './Channel' ) ;
var TrovoPubSubSocket = require ( './TrovoPubSubSocket' ) ;
var TrovoSocket = require ( './trovo.js/lib/socket/TrovoSocket' ) ;
// var TrovoSocket = require('./trovo.js/lib/socket/TrovoSocket');
var TrovoSocket = require ( './TrovoSocket' ) ;
var EventEmitter = require ( 'events' ) ;
}
@ -23,12 +24,14 @@ class TrovoChannel extends Channel {
_loadGiftData ( ) {
this . gifts = { } ;
console . log ( 'loadGiftData' , this . channelID ) ;
this . chat . client . GetGiftShop ( {
"channelID" : this . channelID ,
"channelOnly" : false ,
"includeOffShelf" : true ,
"customGift" : tru e
"customGift" : fals e
} ) . then ( ( data ) => {
console . log ( 'giftShop' , JSON . stringify ( data ) ) ;
for ( let info of data . getGiftShop . shopItemInfo ) {
this . gifts [ info . giftInfo . giftID ] = {
giftName : info . giftInfo . name ,
@ -55,6 +58,14 @@ class TrovoChannel extends Channel {
}
_getTestEvents ( ) {
return {
SuperCap : { "type" : "CHAT" , "channel_info" : { "channel_id" : "101588242" } , "data" : { "eid" : "1629482589166379_101588242_2886926797_1" , "chats" : [ { "type" : 6 , "content" : "balls" , "nick_name" : "vampirefrog" , "avatar" : "https://headicon.trovo.live/user/cioq4bqaaaaaabbllzj43qc7cy.jpeg?t=0" , "medals" : [ "creator" ] , "roles" : [ "streamer" ] , "message_id" : "1629482589139681695_101588242_101588242_2886927975_1" , "sender_id" : 101588242 , "uid" : 101588242 , "user_name" : "vampirefrog" , "content_data" : { "gift_display_name" : "Super Cap" , "gift_num" : 1 , "magicChatCurrencyInfo" : "2,1500" , "magicChatGiftID" : 520000995 , "normal_emote_enabled" : "" , "user_time" : 1629482588720 } , "custom_role" : "[{\"roleName\":\"streamer\",\"roleType\":100000}]" } ] } } ,
StaySafe : { "type" : "CHAT" , "data" : { "eid" : "1629482969285073_0_2886926853_1" , "chats" : [ { "type" : 5 , "content" : "{\"gift_id\":520010002,\"gift\":\"Stay Safe\",\"num\":1,\"gift_value\":100,\"value_type\":\"Mana\"}" , "nick_name" : "XSENKU" , "avatar" : "10.png" , "roles" : [ "follower" ] , "message_id" : "1629480612852370586_100039313_104364132_2886927975_1" , "sender_id" : 104364132 } ] } } ,
Join : { "type" : "CHAT" , "channel_info" : { "channel_id" : "101301301" } , "data" : { "eid" : "1629483241736358_101301301_2887057659_1" , "chats" : [ { "type" : 5004 , "content" : "just joined channel!" , "nick_name" : "t2kANONYMOUS" , "avatar" : "https://headicon.trovo.live/user/fqwrybqaaaaaayhef65cuwlxcy.jpeg?t=0" , "roles" : [ "follower" ] , "message_id" : "1629483241418427441_101301301_102509868_2887057787_1" , "sender_id" : 102509868 , "uid" : 102509868 , "user_name" : "t2kAN0NYN0US" , "content_data" : { "chatShowAuth" : "100000|100001" , "chatViewerThreshold" : 100 , "normal_emote_enabled" : "" , "viewers" : 69 } , "custom_role" : "[{\"roleName\":\"follower\",\"roleType\":100006}]" } ] } } ,
Follow : { "type" : "CHAT" , "channel_info" : { "channel_id" : "101301301" } , "data" : { "eid" : "1629483281504129_101301301_2887057659_1" , "chats" : [ { "type" : 5003 , "content" : "just followed channel!" , "nick_name" : "mvpIMMORTAL" , "avatar" : "https://headicon.trovo.live/default/1.png" , "roles" : [ "follower" ] , "message_id" : "1629483281187938299_101301301_103085572_2887057787_1" , "sender_id" : 103085572 , "uid" : 103085572 , "user_name" : "mvpIMMORTAL" , "content_data" : { "chatShowAuth" : "100000|100001" , "chatViewerThreshold" : 100 , "normal_emote_enabled" : "" , "viewers" : 70 } , "custom_role" : "[{\"roleName\":\"follower\",\"roleType\":100006}]" } ] } } ,
Boost : { "type" : "CHAT" , "data" : { "eid" : "1629483226522550_0_2886926853_1" , "chats" : [ { "type" : 5007 , "content" : "{title} has casted a spell rocket and the channel will be boosted to front page!" , "nick_name" : "" , "message_id" : "1629482666829442093_101301301_0_2886927750_1" } ] } } ,
} ;
return {
FOLLOW : {
unknownInt : 101379536 ,
@ -318,32 +329,133 @@ class TrovoChannel extends Channel {
* /
}
_handleChat ( chat ) {
switch ( chat . type ) {
case 5003 :
this . emit ( 'message' , {
type : 'follow' ,
id : chat . message _id ,
original : chat ,
username : chat . user _name || chat . nick _name ,
displayName : chat . nick _name ,
avatar : chat . avatar ,
} ) ;
break ;
case 5004 :
this . emit ( 'message' , {
type : 'join' ,
id : chat . message _id ,
original : chat ,
username : chat . user _name || chat . nick _name ,
displayName : chat . nick _name ,
avatar : chat . avatar ,
} ) ;
break ;
case 5009 :
break ;
case 6 :
this . emit ( 'message' , {
type : 'gift' ,
id : chat . message _id ,
original : chat ,
message : chat . content ,
spans : this . _parseEmotes ( chat . content ) ,
giftType : chat . content _data . gift _display _name || 'Super Cap' ,
currency : 'ELIXIR' ,
value : 1 ,
amount : chat . content _data . gift _num ,
icon : null ,
username : chat . user _name || chat . nick _name ,
displayName : chat . nick _name ,
avatar : chat . avatar ,
} ) ;
break ;
case 5 :
let data = JSON . parse ( chat . content ) ;
let giftData ;
if ( data . gift _id && ( data . gift _id in this . gifts ) )
giftData = this . gifts [ data . gift _id ] ;
let message = '' ;
this . emit ( 'message' , {
type : 'gift' ,
id : chat . message _id ,
original : chat ,
message : message ,
spans : this . _parseEmotes ( message ) ,
giftType : data . gift ,
currency : data . value _type ,
value : data . gift _value ,
amount : data . num ,
icon : giftData && giftData . icon ,
username : chat . user _name || chat . nick _name ,
displayName : chat . nick _name ,
avatar : chat . avatar ,
} ) ;
break ;
default :
var testEvents = this . _getTestEvents ( ) ;
if ( chat . content in testEvents && testEvents [ chat . content ] . data && testEvents [ chat . content ] . data . chats ) {
for ( let testChat of testEvents [ chat . content ] . data . chats ) {
this . _handleChat ( testChat ) ;
}
} else {
this . emit ( 'message' , {
type : 'chat' ,
id : chat . message _id ,
original : chat ,
text : chat . content ,
spans : this . _parseEmotes ( chat . content ) ,
username : chat . user _name || chat . nick _name ,
displayName : chat . nick _name ,
avatar : chat . avatar ,
} ) ;
}
}
}
_createChannelWS ( ) {
var testEvents = this . _getTestEvents ( ) ;
console . log ( '_createChannelWS' ) ;
this . emit ( 'verbose' , 'Opening WebSocket ' + this . channelName ) ;
var emitter = new EventEmitter ( ) ;
this . ws = new TrovoSocket ( this . channelID , emitter ) ;
emitter . on ( 'socketMessage' , ( event ) => {
this . emit ( 'verbose' , 'RECV ' + Buffer . from ( event . data ) . toString ( 'base64' ) ) ;
} ) ;
emitter . on ( 'chatMessage' , ( message ) => {
this . emit ( 'verbose' , 'chatMessage ' + JSON . stringify ( message ) ) ;
if ( message . user == this . channelName && testEvents [ message . content ] ) {
this . _handleChatEvent ( message . content . replace ( /[0-9]+$/ , '' ) , testEvents [ message . content ] ) ;
this . ws = new TrovoSocket ( this . chat . settings . clientId , this . channelID ) ;
this . ws . on ( 'verbose' , ( msg ) => { console . log ( 'TROVO SOCKET' , msg ) ; } ) ;
this . ws . on ( 'CHAT' , ( data ) => {
if ( ! data || ! data . chats )
return ;
for ( let chat of data . chats ) {
this . _handleChat ( chat ) ;
}
this . _handleChatMessage ( message ) ;
} ) ;
emitter . on ( 'chatEvent' , ( type , data ) => {
this . _handleChatEvent ( type , data ) ;
} ) ;
emitter . on ( 'socketOpen' , ( event ) => {
this . state = 'joined' ;
this . emit ( 'joined' , { } ) ;
} ) ;
this . ws . connect ( ) ;
// var emitter = new EventEmitter();
// this.ws = new TrovoSocket(this.channelID, emitter);
// emitter.on('socketMessage', (event) => {
// this.emit('verbose', 'RECV ' + Buffer.from(event.data).toString('base64'));
// });
// emitter.on('chatMessage', (message) => {
// this.emit('verbose', 'chatMessage ' + JSON.stringify(message));
// if(message.user == this.channelName && testEvents[message.content]) {
// this._handleChatEvent(message.content.replace(/[0-9]+$/, ''), testEvents[message.content]);
// return;
// }
// this._handleChatMessage(message);
// });
// emitter.on('chatEvent', (type, data) => {
// this._handleChatEvent(type, data);
// });
// emitter.on('socketOpen', (event) => {
// this.state = 'joined';
// this.emit('joined', {});
// });
this . pubWs = new TrovoPubSubSocket ( this . channelID ) ;
this . pubWs . on ( 'MESSAGE' , ( data ) => {
if ( data && data . data && data . data . message ) {
@ -396,6 +508,7 @@ class TrovoChannel extends Channel {
}
_parseEmotes ( str ) {
str = str || '' ;
var spans = [ ] ;
var state = 'none' , emote = '' , span = '' ;
@ -457,22 +570,24 @@ class TrovoChannel extends Channel {
return 'https://headicon.trovo.live/user/' + iconURL + '?max_age=31536000&imageView2/2/w/100/h/100/format/webp'
}
_handleChatMessage ( message ) {
this . emit ( 'message' , {
type : 'chat' ,
id : message . identifier ,
original : message ,
text : message . content ,
spans : this . _parseEmotes ( message . content ) ,
username : message . accountName ,
displayName : message . user ,
avatar : this . _getAvatarUrl ( message . iconURL )
} ) ;
}
_handleChatEvent ( type , data ) {
console . log ( 'chatEvent' , type , data ) ;
this . emit ( 'verbose' , 'handleChatEvent ' + type + ' ' + JSON . stringify ( data ) ) ;
switch ( type ) {
case 'CHAT' :
for ( let chat in data . chats ) {
this . emit ( 'message' , {
type : 'chat' ,
id : chat . uid ,
original : chat ,
text : chat . content ,
spans : this . _parseEmotes ( chat . content ) ,
username : chat . user _name ,
displayName : chat . nick _name ,
avatar : chat . avatar ,
} ) ;
}
break ;
case 'GIFT' :
case 'CUSTOM_SPELL' :
var message , giftId , currency , value , amount , giftName , icon ;
@ -542,24 +657,24 @@ class TrovoChannel extends Channel {
break ;
case 'GIFT_SUBS' :
// this.emit('message', {
// type: 'giftSub',
// id: msg.id,
// original: msg,
// username: msg.sender.username,
// displayName: msg.sender.displayname,
// avatar: msg.sender.avatar,
// receiver: msg.receiver
// type: 'giftSub',
// id: msg.id,
// original: msg,
// username: msg.sender.username,
// displayName: msg.sender.displayname,
// avatar: msg.sender.avatar,
// receiver: msg.receiver
// });
break ;
case 'RECEIVE_SUB' :
// this.emit('message', {
// type: 'giftSubReceive',
// id: data.id,
// original: data,
// username: data.accountName,
// displayName: data.user,
// avatar: this._getAvatarUrl(data.iconURL),
// gifter: msg.gifter
// type: 'giftSubReceive',
// id: data.id,
// original: data,
// username: data.accountName,
// displayName: data.user,
// avatar: this._getAvatarUrl(data.iconURL),
// gifter: msg.gifter
// });
break ;
case 'SUBSCRIBE_CHANNEL' :
@ -574,13 +689,13 @@ class TrovoChannel extends Channel {
break ;
case 'RAID' :
// this.emit('message', {
// type: 'host',
// id: data.id,
// original: data,
// username: data.accountName,
// displayName: data.user,
// avatar: this._getAvatarUrl(data.iconURL),
// viewers: null // TODO get this?
// type: 'host',
// id: data.id,
// original: data,
// username: data.accountName,
// displayName: data.user,
// avatar: this._getAvatarUrl(data.iconURL),
// viewers: null // TODO get this?
// });
break ;
}
@ -596,9 +711,72 @@ class TrovoChannel extends Channel {
} ) ;
}
getStatus ( ) {
getStatus ( original ) {
return new Promise ( ( resolve , reject ) => {
resolve ( { viewers : this . viewerCount , platform : this . chat . getPlatformName ( ) } ) ;
this . chat . client . GetLiveInfo ( this . channelName ) . then ( ( result ) => {
if ( original ) {
resolve ( result ) ;
return ;
}
let audienceType = null ;
let audienceTypeOptions = [ {
value : "CHANNEL_AUDIENCE_TYPE_FAMILYFRIENDLY" ,
label : "For all viewers"
} , {
value : "CHANNEL_AUDIENCE_TYPE_TEEN" ,
label : "13+ content"
} , {
value : "CHANNEL_AUDIENCE_TYPE_EIGHTEENPLUS" ,
label : "18+ content"
} , {
value : "CHANNEL_AUDIENCE_TYPE_PERSONALVIEWS" ,
label : "Personal views"
} ] ;
for ( let a of audienceTypeOptions ) {
if ( result . getLiveInfo . channelInfo . audiType == a . value ) {
audienceType = a . label ;
}
}
let ret = {
platform : this . chat . getPlatformName ( ) ,
clientId : this . chat . id ,
channelId : this . id ,
user : {
avatar : result . getLiveInfo . streamerInfo . faceUrl ,
displayName : result . getLiveInfo . streamerInfo . nickName
} ,
channel : {
description : result . getLiveInfo . streamerInfo . info
} ,
stream : {
isLive : result . getLiveInfo . isLive ,
startTime : result . getLiveInfo . programInfo . startTm ,
viewers : result . getLiveInfo . channelInfo . viewers ,
title : result . getLiveInfo . programInfo . title ,
preview : result . getLiveInfo . programInfo . coverUrl ,
language : result . getLiveInfo . channelInfo . languageName ,
audienceType : audienceType ,
category : {
id : result . getLiveInfo . categoryInfo . id ,
name : result . getLiveInfo . categoryInfo . name ,
}
} ,
chat : {
}
} ;
this . chat . client . GetUserFollowCount ( result . getLiveInfo . streamerInfo . uid ) . then ( ( followCountResult ) => {
ret . user . followers = followCountResult . getUserFollowCount . followerCount ;
ret . user . following = followCountResult . getUserFollowCount . followingCount ;
resolve ( ret ) ;
} , ( err ) => {
resolve ( ret ) ;
} ) ;
} , reject ) ;
} ) ;
}
}